{"generated":"2026-10-13 11:59 UTC","score":{"findings":2124,"wins":14,"critical":1,"landed":3,"losses":0,"filesAudited":133,"filesTouched":323},"audits":[{"file":"Mathlib/Analysis/Normed/Affine/MazurUlam.lean","at":"2026-10-13","decls":11,"commit":"f69ff8554f5","n":12},{"file":"Mathlib/Topology/Algebra/SeparationQuotient/FiniteDimensional.lean","at":"2026-10-13","decls":1,"commit":"f69ff8554f5","n":2},{"file":"Mathlib/Probability/Independence/ZeroOne.lean","at":"2026-10-13","decls":38,"commit":"f69ff8554f5","n":16},{"file":"Mathlib/Algebra/Category/ModuleCat/Biproducts.lean","at":"2026-10-13","decls":16,"commit":"f93fe19494d","n":12},{"file":"Mathlib/Data/Set/Countable.lean","at":"2026-10-07","decls":54,"commit":"4beb549110a","n":20},{"file":"Mathlib/Topology/Order/Basic.lean","at":"2026-10-07","decls":83,"commit":"4beb549110a","n":83},{"file":"Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean","at":"2026-10-07","decls":7,"commit":"4beb549110a","n":10},{"file":"Mathlib/Topology/Category/Stonean/Basic.lean","at":"2026-10-07","decls":22,"commit":"4beb549110a","n":10},{"file":"Mathlib/Logic/Function/Conjugate.lean","at":"2026-10-07","decls":23,"commit":"4beb549110a","n":5},{"file":"Mathlib/MeasureTheory/VectorMeasure/Relations.lean","at":"2026-10-07","decls":23,"commit":"4beb549110a","n":7},{"file":"Mathlib/RingTheory/ZMod/Torsion.lean","at":"2026-10-07","decls":2,"commit":"4beb549110a","n":3},{"file":"Mathlib/Data/String/Basic.lean","at":"2026-10-07","decls":12,"commit":"4beb549110a","n":5},{"file":"Mathlib/Algebra/Polynomial/Smeval.lean","at":"2026-10-07","decls":38,"commit":"4beb549110a","n":7},{"file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","at":"2026-10-07","decls":47,"commit":"4beb549110a","n":37},{"file":"Mathlib/CategoryTheory/Shift/Pullback.lean","at":"2026-10-07","decls":21,"commit":"4beb549110a","n":4},{"file":"Mathlib/Tactic/Widget/SelectPanelUtils.lean","at":"2026-10-07","decls":5,"commit":"4beb549110a","n":5},{"file":"Mathlib/Geometry/Euclidean/Inversion/Calculus.lean","at":"2026-10-07","decls":9,"commit":"4beb549110a","n":3},{"file":"Mathlib/RingTheory/AdicCompletion/RingHom.lean","at":"2026-10-07","decls":11,"commit":"4beb549110a","n":4},{"file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","at":"2026-10-07","decls":48,"commit":"4beb549110a","n":43},{"file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","at":"2026-10-07","decls":67,"commit":"4beb549110a","n":33},{"file":"Mathlib/Algebra/Homology/Localization.lean","at":"2026-10-07","decls":39,"commit":"4beb549110a","n":26},{"file":"Mathlib/Topology/Category/TopCat/EffectiveEpi.lean","at":"2026-10-07","decls":2,"commit":"4beb549110a","n":2},{"file":"Mathlib/Tactic/ClickSuggestions/FindPremises.lean","at":"2026-10-07","decls":17,"commit":"4beb549110a","n":3},{"file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","at":"2026-10-07","decls":40,"commit":"4beb549110a","n":41},{"file":"Mathlib/Combinatorics/SimpleGraph/VertexCover.lean","at":"2026-10-07","decls":28,"commit":"4beb549110a","n":5},{"file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","at":"2026-10-07","decls":37,"commit":"4beb549110a","n":24},{"file":"Mathlib/Algebra/Star/StarRingHom.lean","at":"2026-10-07","decls":69,"commit":"e6bbacd0e1b","n":31},{"file":"Mathlib/Data/Set/Card/Arithmetic.lean","at":"2026-10-07","decls":19,"commit":"e6bbacd0e1b","n":16},{"file":"Mathlib/Analysis/ODE/Transform.lean","at":"2026-10-07","decls":19,"commit":"e6bbacd0e1b","n":9},{"file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","at":"2026-10-07","decls":55,"commit":"e6bbacd0e1b","n":62},{"file":"Mathlib/Data/Nat/Factorial/DoubleFactorial.lean","at":"2026-10-07","decls":9,"commit":"e6bbacd0e1b","n":7},{"file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","at":"2026-10-07","decls":45,"commit":"e6bbacd0e1b","n":49},{"file":"Mathlib/Probability/Distributions/SetBernoulli.lean","at":"2026-10-07","decls":19,"commit":"e6bbacd0e1b","n":11},{"file":"Mathlib/MeasureTheory/Integral/IntervalIntegral/TrapezoidalRule.lean","at":"2026-10-07","decls":14,"commit":"e6bbacd0e1b","n":10},{"file":"Mathlib/GroupTheory/GroupAction/SubMulAction/Combination.lean","at":"2026-10-07","decls":22,"commit":"e6bbacd0e1b","n":11},{"file":"Mathlib/Probability/Moments/Variance.lean","at":"2026-10-07","decls":61,"commit":"e6bbacd0e1b","n":55},{"file":"Mathlib/RingTheory/Ideal/MinimalPrime/Colon.lean","at":"2026-10-07","decls":1,"commit":"e6bbacd0e1b","n":5},{"file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","at":"2026-10-07","decls":58,"commit":"e6bbacd0e1b","n":53},{"file":"Mathlib/LinearAlgebra/Matrix/Polynomial.lean","at":"2026-10-07","decls":4,"commit":"e6bbacd0e1b","n":9},{"file":"Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean","at":"2026-10-07","decls":13,"commit":"e6bbacd0e1b","n":13},{"file":"Mathlib/Analysis/Complex/Harmonic/Analytic.lean","at":"2026-10-07","decls":5,"commit":"e6bbacd0e1b","n":9},{"file":"Mathlib/MeasureTheory/Function/LpSeminorm/ChebyshevMarkov.lean","at":"2026-10-07","decls":8,"commit":"e6bbacd0e1b","n":7},{"file":"Mathlib/Analysis/InnerProductSpace/Dual.lean","at":"2026-10-07","decls":21,"commit":"e6bbacd0e1b","n":7},{"file":"Mathlib/Topology/Algebra/Order/Floor.lean","at":"2026-10-07","decls":33,"commit":"e6bbacd0e1b","n":4},{"file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","at":"2026-10-07","decls":51,"commit":"ade5dcd9754","n":37},{"file":"Mathlib/Topology/Algebra/Nonarchimedean/AdicTopology.lean","at":"2026-10-07","decls":26,"commit":"ade5dcd9754","n":7},{"file":"Mathlib/Data/Finsupp/MonomialOrder.lean","at":"2026-10-07","decls":26,"commit":"ade5dcd9754","n":9},{"file":"Mathlib/Algebra/Ring/SumsOfSquares.lean","at":"2026-10-07","decls":23,"commit":"ade5dcd9754","n":7},{"file":"Mathlib/NumberTheory/PrimeCounting.lean","at":"2026-10-07","decls":57,"commit":"ade5dcd9754","n":6},{"file":"Mathlib/Combinatorics/SimpleGraph/Dart.lean","at":"2026-10-07","decls":24,"commit":"4e77f237dc2","n":7},{"file":"Mathlib/Probability/Kernel/Posterior.lean","at":"2026-10-07","decls":25,"commit":"4e77f237dc2","n":6},{"file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","at":"2026-10-07","decls":55,"commit":"4e77f237dc2","n":36},{"file":"Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean","at":"2026-10-07","decls":20,"commit":"4e77f237dc2","n":4},{"file":"Mathlib/Algebra/Category/MonCat/Colimits.lean","at":"2026-10-07","decls":19,"commit":"4e77f237dc2","n":7},{"file":"Mathlib/Analysis/SpecialFunctions/Trigonometric/Sinc.lean","at":"2026-10-07","decls":14,"commit":"4e77f237dc2","n":4},{"file":"Mathlib/Algebra/Algebra/Pi.lean","at":"2026-10-07","decls":35,"commit":"4a7d04df926","n":5},{"file":"Mathlib/Algebra/Module/LinearMap/End.lean","at":"2026-10-07","decls":63,"commit":"4a7d04df926","n":45},{"file":"Mathlib/Probability/Distributions/Binomial.lean","at":"2026-10-07","decls":23,"commit":"4a7d04df926","n":3},{"file":"Mathlib/RingTheory/Polynomial/Selmer.lean","at":"2026-10-07","decls":3,"commit":"4a7d04df926","n":8},{"file":"Mathlib/Order/UpperLower/Closure.lean","at":"2026-10-07","decls":54,"commit":"4a7d04df926","n":28},{"file":"Mathlib/Analysis/Normed/Operator/Fredholm/Basic.lean","at":"2026-10-06","decls":54,"commit":"f0d58cda75d","n":7},{"file":"Mathlib/Analysis/Normed/Operator/Fredholm/Open.lean","at":"2026-10-06","decls":7,"commit":"f0d58cda75d","n":4},{"file":"Mathlib/Algebra/Module/LinearMap/Index.lean","at":"2026-10-06","decls":16,"commit":"f0d58cda75d","n":8},{"file":"Mathlib/NumberTheory/Padics/Measure/Basic.lean","at":"2026-10-06","decls":38,"commit":"f0d58cda75d","n":11},{"file":"Mathlib/NumberTheory/Padics/Measure/AmiceTransform.lean","at":"2026-10-06","decls":12,"commit":"f0d58cda75d","n":9},{"file":"Mathlib/NumberTheory/Padics/Measure/Monoid.lean","at":"2026-10-06","decls":22,"commit":"f0d58cda75d","n":8},{"file":"Mathlib/NumberTheory/Padics/Measure/Topology.lean","at":"2026-10-06","decls":2,"commit":"f0d58cda75d","n":6},{"file":"Mathlib/Analysis/SpecialFunctions/RegularizedHypergeometric.lean","at":"2026-10-06","decls":42,"commit":"f0d58cda75d","n":9},{"file":"Mathlib/Analysis/SpecialFunctions/Bessel.lean","at":"2026-10-06","decls":12,"commit":"f0d58cda75d","n":6},{"file":"Mathlib/Analysis/FunctionalSpaces/BesselPotentialSpace.lean","at":"2026-10-06","decls":47,"commit":"f0d58cda75d","n":8},{"file":"Mathlib/Dynamics/SymbolicDynamics/Basic.lean","at":"2026-10-06","decls":32,"commit":"f0d58cda75d","n":12},{"file":"Mathlib/Combinatorics/Hypergraph/Basic.lean","at":"2026-10-06","decls":48,"commit":"f0d58cda75d","n":7},{"file":"Mathlib/RingTheory/Etale/Finite.lean","at":"2026-10-06","decls":21,"commit":"f0d58cda75d","n":5},{"file":"Mathlib/NumberTheory/ModularForms/LFunction.lean","at":"2026-10-06","decls":14,"commit":"1adb2afba87","n":3},{"file":"Mathlib/Geometry/Group/WordMetric.lean","at":"2026-10-06","decls":13,"commit":"1adb2afba87","n":2},{"file":"Mathlib/Geometry/Euclidean/Volume/Def.lean","at":"2026-10-06","decls":1,"commit":"1adb2afba87","n":1},{"file":"Mathlib/NumberTheory/NumberField/DirichletDensity.lean","at":"2026-10-06","decls":14,"commit":"1adb2afba87","n":5},{"file":"Mathlib/Probability/Process/LimitProcess.lean","at":"2026-10-06","decls":30,"commit":"1adb2afba87","n":4},{"file":"Mathlib/Analysis/InnerProductSpace/NormDet.lean","at":"2026-10-06","decls":28,"commit":"1adb2afba87","n":4},{"file":"Mathlib/Probability/Decision/BayesEstimator.lean","at":"2026-10-06","decls":13,"commit":"1adb2afba87","n":4},{"file":"Mathlib/AlgebraicGeometry/Morphisms/FlatRank.lean","at":"2026-10-06","decls":18,"commit":"1adb2afba87","n":9},{"file":"Mathlib/Analysis/SpecialFunctions/FrullaniIntegral.lean","at":"2026-10-06","decls":9,"commit":"1adb2afba87","n":7},{"file":"Mathlib/NumberTheory/FundamentalDiscriminant.lean","at":"2026-10-06","decls":8,"commit":"4beb549110a","n":5},{"file":"Mathlib/Analysis/Complex/BranchLogRoot.lean","at":"2026-10-06","decls":2,"commit":"4beb549110a","n":5},{"file":"Mathlib/NumberTheory/AlmostPrime.lean","at":"2026-10-06","decls":11,"commit":"4beb549110a","n":6},{"file":"Mathlib/Probability/Distributions/Bernoulli.lean","at":"2026-10-06","decls":23,"commit":"4beb549110a","n":3},{"file":"Mathlib/NumberTheory/ModularForms/RamanujanFormula.lean","at":"2026-10-06","decls":10,"commit":"4beb549110a","n":5},{"file":"Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Truncated.lean","at":"2026-10-06","decls":12,"commit":"4beb549110a","n":4},{"file":"Mathlib/Analysis/Complex/ValueDistribution/SecondMainTheorem.lean","at":"2026-10-06","decls":2,"commit":"4beb549110a","n":3},{"file":"Mathlib/MeasureTheory/Measure/ResolventTransform.lean","at":"2026-10-06","decls":10,"commit":"4beb549110a","n":3},{"file":"Mathlib/Combinatorics/Enumerative/Pentagonal/EulerFunction.lean","at":"2026-10-06","decls":13,"commit":"4beb549110a","n":4},{"file":"Mathlib/Topology/LocallyFinsupp/Pushforward.lean","at":"2026-10-06","decls":4,"commit":"4beb549110a","n":4},{"file":"Mathlib/AlgebraicGeometry/AlgebraicCycle/Basic.lean","at":"2026-10-06","decls":19,"commit":"4beb549110a","n":5},{"file":"Mathlib/Geometry/Convex/ConvexSpace/Barycenter.lean","at":"2026-10-06","decls":7,"commit":"4beb549110a","n":4},{"file":"Mathlib/RingTheory/DedekindDomain/Ideal/Basic.lean","at":"2026-10-06","decls":33,"commit":"4beb549110a","n":6},{"file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","at":"2026-10-06","decls":55,"commit":"4beb549110a","n":38},{"file":"Mathlib/RingTheory/Kaehler/Basic.lean","at":"2026-10-06","decls":69,"commit":"4beb549110a","n":59},{"file":"Mathlib/CategoryTheory/ObjectProperty/Comma.lean","at":"2026-10-06","decls":6,"commit":"4beb549110a","n":4},{"file":"Mathlib/RepresentationTheory/Homological/GroupCohomology/Shapiro.lean","at":"2026-10-06","decls":2,"commit":"4beb549110a","n":3},{"file":"Mathlib/Tactic/Inclusion/Extension/IntervalDyadicReal/BinarySplit.lean","at":"2026-10-06","decls":4,"commit":"4beb549110a","n":3},{"file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","at":"2026-10-06","decls":38,"commit":"4beb549110a","n":28},{"file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","at":"2026-10-06","decls":40,"commit":"4beb549110a","n":25},{"file":"Mathlib/Topology/SeparatedMap.lean","at":"2026-10-06","decls":29,"commit":"4beb549110a","n":8},{"file":"Mathlib/Algebra/Homology/HomotopyCategory/Acyclic.lean","at":"2026-10-06","decls":8,"commit":"4beb549110a","n":6},{"file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","at":"2026-10-06","decls":46,"commit":"4beb549110a","n":37},{"file":"Mathlib/Algebra/Module/StablyFree/FreeOfInvertible.lean","at":"2026-10-06","decls":4,"commit":"4beb549110a","n":2},{"file":"Mathlib/RingTheory/Valuation/RankOne.lean","at":"2026-10-06","decls":24,"commit":"4beb549110a","n":16},{"file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean","at":"2026-10-06","decls":32,"commit":"4beb549110a","n":6},{"file":"Mathlib/Algebra/Order/Sub/Unbundled/Hom.lean","at":"2026-10-06","decls":6,"commit":"4beb549110a","n":6},{"file":"Mathlib/Topology/ContinuousMap/LocallyConstant.lean","at":"2026-10-06","decls":6,"commit":"4beb549110a","n":4},{"file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","at":"2026-10-06","decls":49,"commit":"4beb549110a","n":27},{"file":"Mathlib/Logic/Godel/GodelBetaFunction.lean","at":"2026-10-06","decls":8,"commit":"4beb549110a","n":5},{"file":"Mathlib/Data/Nat/Squarefree.lean","at":"2026-10-06","decls":54,"commit":"4beb549110a","n":36},{"file":"Mathlib/Analysis/Analytic/CPolynomial.lean","at":"2026-10-06","decls":61,"commit":"4beb549110a","n":32},{"file":"Mathlib/CategoryTheory/Sites/Hypercover/ZeroFamily.lean","at":"2026-10-06","decls":12,"commit":"4beb549110a","n":5},{"file":"Mathlib/Dynamics/Ergodic/Action/Regular.lean","at":"2026-10-06","decls":2,"commit":"4beb549110a","n":3},{"file":"Mathlib/Data/List/Pairwise.lean","at":"2026-10-06","decls":30,"commit":"4beb549110a","n":6},{"file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","at":"2026-10-06","decls":129,"commit":"4beb549110a","n":54},{"file":"Mathlib/CategoryTheory/Monoidal/Widesubcategory.lean","at":"2026-10-06","decls":9,"commit":"4beb549110a","n":4},{"file":"Mathlib/RingTheory/Localization/Away/AdjoinRoot.lean","at":"2026-10-06","decls":6,"commit":"4beb549110a","n":4},{"file":"Mathlib/Data/Multiset/MapFold.lean","at":"2026-10-06","decls":79,"commit":"4beb549110a","n":46},{"file":"Mathlib/Combinatorics/Enumerative/Pentagonal/Basic.lean","at":"2026-10-06","decls":12,"commit":"4beb549110a","n":3},{"file":"Mathlib/Tactic/NormNum/Abs.lean","at":"2026-10-06","decls":5,"commit":"4beb549110a","n":4},{"file":"Mathlib/Util/ElabWithoutMVars.lean","at":"2026-10-06","decls":1,"commit":"4beb549110a","n":3},{"file":"Mathlib/Analysis/Complex/Conformal.lean","at":"2026-10-06","decls":22,"commit":"4beb549110a","n":7},{"file":"Mathlib/Algebra/Algebra/Equiv.lean","at":"2026-10-06","decls":169,"commit":"4beb549110a","n":61},{"file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","at":"2026-10-06","decls":40,"commit":"4beb549110a","n":25},{"file":"Mathlib/Tactic/Ring.lean","at":"2026-10-06","decls":0,"commit":"4beb549110a","n":0},{"file":"Mathlib/Lean/Meta/KAbstractPositions.lean","at":"2026-10-06","decls":3,"commit":"4beb549110a","n":3},{"file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","at":"2026-10-06","decls":40,"commit":"4beb549110a","n":38},{"file":"Mathlib/RingTheory/Bialgebra/GroupLike.lean","at":"2026-10-06","decls":16,"commit":"4beb549110a","n":6},{"file":"Mathlib/Data/Fintype/OfMap.lean","at":"2026-10-06","decls":12,"commit":"4beb549110a","n":5},{"file":"Mathlib/Algebra/Group/TypeTags/Hom.lean","at":"2026-10-06","decls":21,"commit":"4beb549110a","n":6}],"findings":[{"id":"RT-20261006-8fb999","file":"Mathlib/NumberTheory/ModularForms/LFunction.lean","decl":"ModularForm.L","line":135,"sev":"CRITICAL","status":"pr-open","cat":"correctness","pattern":"junk-at-removable-singularity","claim":"`ModularForm.L hk f s := Λ hk f s * (2 / Gammaℂ s)` is 0 at s = 0 for every modular form (Gammaℂ 0 = 0, x/0 = 0), but whenever valueAtInfty f = a₀ ≠ 0 (e.g. every Eisenstein series normalised at ∞) Λ has a simple pole at 0 with residue -a₀ which cancels the zero of 1/Γ: the L-function has a removable singularity there with value -a₀, and Mathlib's `L hk f` is discontinuous at 0. For E₄, `L hk E₄ 0 = 0` while `L hk E₄ s → -1` (classically L(E₄, 0) = 240 ζ(0) ζ(-3) = -1). Undocumented; Mathlib's own Riemann/Hurwitz zeta fills exactly this removable singularity with `Function.update`.","fix":"Define `L hk f := Function.update (fun s ↦ Λ hk f s * (2 / Gammaℂ s)) 0 (-valueAtInfty f)` (as `hurwitzZetaEven` does), add `L_zero`, `L_of_ne_zero`, continuity at 0, and repair `differentiable_L` / `hasSum_L`.","ev":"import Mathlib.NumberTheory.ModularForms.LFunction\nimport Mathlib.NumberTheory.ModularForms.EisensteinSeries.QExpansion\nopen UpperHalfPlane hiding I\nopen Filter Topology Complex ModularForm\n\ntheorem tendsto_s_mul_Gammaℂ : Tendsto (fun s : ℂ ↦ s * Gammaℂ s) (𝓝[≠] 0) (𝓝 2) := by\n  have h1 : ∀ m : ℕ, (1 : ℂ) ≠ -m := fun m h ↦ by\n    have := congrArg Complex.re h\n    simp at this\n    linarith [(m.cast_nonneg : (0:ℝ) ≤ m)]\n  have hG : Tendsto (fun s : ℂ ↦ Complex.Gamma (s + 1)) (𝓝[≠] 0) (𝓝 1) := by\n    have hg : ContinuousAt Complex.Gamma 1 := (differentiableAt_Gamma (1 : ℂ) h1).continuousAt\n    have h2 : Tendsto (fun s : ℂ ↦ s + 1) (𝓝 0) (𝓝 1) :=\n      (by fun_prop : Continuous (fun s : ℂ ↦ s + 1)).tendsto' 0 1 (by simp)\n    have hc := (hg.tendsto.comp h2).mono_left (nhdsWithin_le_nhds (s := {0}ᶜ))\n    rw [Complex.Gamma_one] at hc\n    exact hc\n  have hP : Tendsto (fun s : ℂ ↦ (2 * (Real.pi : ℂ)) ^ (-s)) (𝓝[≠] 0) (𝓝 1) := by\n    have hne : (2 * (Real.pi : ℂ)) ≠ 0 := by\n      exact_mod_cast (by positivity : (2 * Real.pi : ℝ) ≠ 0)\n    have hc : ContinuousAt (fun s : ℂ ↦ (2 * (Real.pi : ℂ)) ^ (-s)) 0 :=\n      (continuousAt_const_cpow hne).comp continuous_neg.continuousAt\n    simpa using hc.tendsto.mono_left nhdsWithin_le_nhds\n  have := (hP.const_mul 2).mul hG\n  rw [mul_one, mul_one] at this\n  refine this.congr' ?_\n  filter_upwards [self_mem_nhdsWithin] with s (hs : s ≠ 0)\n  rw [Gammaℂ, Complex.Gamma_add_one s hs]\n  ring\n\ntheorem valueAtInfty_E₄ : valueAtInfty (E₄ : ℍ → ℂ) = 1 := by\n  have h := EisensteinSeries.E_qExpansion_coeff (k := 4) (by norm_num) (by decide) 0\n  rw [ite_eq_left (rfl : (0 : ℕ) = 0)] at h\n  rw [← h, qExpansion_coeff_zero one_pos]\n  · exact ModularFormClass.analyticAt_cuspFunction_zero E₄ one_pos one_mem_strictPeriods_SL\n  · exact SlashInvariantFormClass.periodic_comp_ofComplex E₄ one_mem_strictPeriods_SL\n\n/-- `L(E₄, 0)` is `0` in Mathlib, but `L(E₄, s) → -1` as `s → 0`. -/\nexample (hk : (0 : ℤ) < 4) :\n    ModularForm.L hk E₄ 0 = 0 ∧ Tendsto (ModularForm.L hk E₄) (𝓝[≠] 0) (𝓝 (-1)) := by\n  refine ⟨by simp [ModularForm.L, Gammaℂ], ?_⟩\n  have hΛ := (ModularForm.weakFEPair hk E₄).Λ_residue_zero\n  have := hΛ.mul ((tendsto_s_mul_Gammaℂ).inv₀ two_ne_zero |>.const_mul 2)\n  simp only [ModularForm.weakFEPair_f₀, smul_eq_mul, valueAtInfty_E₄] at this\n  rw [show -(1 : ℂ) * (2 * 2⁻¹) = -1 by norm_num] at this\n  refine this.congr' ?_\n  filter_upwards [self_mem_nhdsWithin] with s (hs : s ≠ 0)\n  simp only [ModularForm.L, ModularForm.Λ]\n  field_simp\n","evr":"compiles","astraV":"agrees","astraS":"A2 tried the MeromorphicAt 'ignore the value at the point' convention, the normalizations (factor 2, cusp-width h^s which is 1 at s = 0) and the pole at s = k (separate since k > 0); none rescues the value: L(f,s) = (sΛ)(2/(sΓℂ)) → -a₀ while the definition gives 0. Rates it MAJOR. Qualification adopted: the discrepancy needs a₀ = valueAtInfty f ≠ 0, not merely 'non-cusp' (a form can vanish at ∞ but not at another cusp). Endorses the Function.update repair, mirroring hurwitzZetaEven; hasSum_L unchanged, differentiable_L proof needs adjusting.","pr":44547,"res":"Re-graded MAJOR→CRITICAL on 2026-10-07 by the user: the definition of ModularForm.L itself was wrong at s = 0 (junk value 0 from x / Gammaℂ 0 instead of the true value), which is the CRITICAL class (wrong definition / junk value).","at":"2026-10-07","commit":"1adb2afba87"},{"id":"RT-20261007-85920e","file":"Mathlib/Algebra/Algebra/Pi.lean","decl":"Pi.algebraMap","line":278,"sev":"MAJOR","status":"confirmed","cat":"reuse","pattern":"second-construction","claim":"Second construction: `Pi.algebraMap ι R A : (ι → R) →ₗ[R] (ι → A)` ('apply an algebra map component-wise along a vector', added in #37201) is built by hand (`toFun v := algebraMap R A ∘ v` with its own `map_add'`/`map_smul'` proofs), although it is `rfl`-equal to `LinearMap.compLeft (Algebra.linearMap R A) ι` and to the linear map underlying `AlgHom.compLeft (Algebra.ofId R A) ι`, defined earlier in the same file (and already present when `Pi.algebraMap` was introduced). Its only uses are in LinearAlgebra/LinearIndependent/BaseChange.lean. Its name also collides with the file's `Pi.algebraMap_def`/`Pi.algebraMap_apply`, which are about the instance map `algebraMap R (Π i, A i)`, not this definition.","fix":"Deprecate `Pi.algebraMap` in favour of `LinearMap.compLeft (Algebra.linearMap R A) ι` (or `(AlgHom.compLeft (Algebra.ofId R A) ι).toLinearMap`) and repoint the BaseChange uses.","ev":"hunts/algebra-pi/probe1.lean: `Pi.algebraMap ι R A = (AlgHom.compLeft (Algebra.ofId R A) ι).toLinearMap := rfl` and `Pi.algebraMap ι R A = LinearMap.compLeft (Algebra.linearMap R A) ι := rfl` compile (master 4e77f237dc2).","evr":"compiles","astraV":"agrees","astraS":"Astra A2 (hunts/algebra-pi/A2.answer.md): no concrete reason to retain the separate construction; AlgHom.compLeft preceded it when it was introduced (#37201), no special transparency need, both replacements fit all BaseChange uses (tower identities are function compositions); `Pi.algebraMap_def/_apply` concern a different map. Deprecation justified. MAJOR.","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261006-546cb9","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"Path.Homotopy.transReflReparamAux","line":84,"sev":"MAJOR","status":"pr-open","cat":"reuse","pattern":"parallel-reparametrisation-helper","claim":"transReflReparamAux t is (unitInterval.qRight (t, 0) : ℝ) from Mathlib/Topology/Homotopy/HSpaces.lean: `unitInterval.qRight_zero_right (t : I) : (qRight (t, 0) : ℝ) = if (t : ℝ) ≤ 1 / 2 then (2 : ℝ) * t else 1` states its defining formula verbatim. The def and its four helper lemmas (continuous_/_mem_I/_zero/_one) rebuild continuous_qRight, (qRight _).2, qRight_zero_left 0 and qRight_one_left 0. HSpaces costs one extra module over Topology.Homotopy.Path (import closure 3424 vs 3423).","fix":"Move unitInterval.qRight and its lemmas next to Path.reparam (or into Topology/UnitInterval.lean), then use `fun t => qRight (t, 0)` in place of transReflReparamAux and its four helper lemmas.","ev":"hunts/fundgroupoid/batch0/probe1.lean (section R1): `example (t : I) : transReflReparamAux t = (qRight (t, 0) : ℝ) := by rw [qRight_zero_right]; rfl` and `example : (fun t : I => (⟨transReflReparamAux t, transReflReparamAux_mem_I t⟩ : I)) = fun t => qRight (t, 0) := by funext t; ext1; rw [qRight_zero_right]; rfl`; import sizes in imp2.lean/imp3.lean","evr":"compiles","astraV":"agrees","astraS":"Agrees (A2 claim 6): `qRight` already supplies continuity and both endpoint values; no import cycle (HSpaces imports only Homotopy.Basic and Topology.Path, already inherited via Homotopy.Path); `qRight_zero_right` gives the conditional the existing proof needs. Import timing unmeasured. Rated MAJOR.","pr":44584,"res":"Re-graded MINOR→MAJOR on 2026-10-07 after comparing with the Tau Ceti red team's MAJOR duplicate-definition wins; Lean evidence unchanged, Astra A2 in hunts/regrade-dups/.","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-87b316","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/InducedMaps.lean","decl":"unitInterval.path01","line":111,"sev":"MAJOR","status":"landed","cat":"reuse","pattern":"second-construction","claim":"Second construction: `unitInterval.path01 : Path (0 : I) 1` (FundamentalGroupoid/InducedMaps.lean:111, the identity path) rebuilds `Path.id` (Topology/Path.lean:136, `@[simps!]`); equal by `rfl`. It sits in a section marked as an old proof whose helpers are due for review/deprecation.","fix":"Deprecate `path01` in favour of `Path.id`.","ev":"dupscan/defs/probe2.lean: `Path.id = unitInterval.path01 := rfl` compiles (import Mathlib), exit 0. Found by dupscan/DefEqScan.lean (same type, defeq bodies).","evr":"compiles","astraV":"agrees","astraS":"**ITEM 6: VERDICT: agrees** `protected` controls name lookup, not reducibility. `Path.id` already supplies the identity parametrization and generated simplification API. `path01` has no extra universe generality; the nearby **`upath01`** is the genuinely different lifted construction. There is particularly strong contextual evidence: `path01` belongs to an **“Old proof”** section explicitly calling for reviewing and deprecating obsolete helpers. Keep **`Path.id`** and deprecate `unitInterval.path01`. [Old-proof explanation and definitions](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/AlgebraicTopology/FundamentalGr","pr":44589,"res":"","at":"2026-10-13","commit":""},{"id":"RT-20261007-498fbf","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.derivCLM","line":58,"sev":"MAJOR","status":"pr-open","cat":"reuse","pattern":"clm-rebuilt-instead-of-composed","claim":"derivCLM is built from scratch with `mkCLM` and its own 8-line seminorm estimate, though it is definitionally equal to `SchwartzMap.evalCLM 𝕜 ℝ F 1 ∘L fderivCLM 𝕜 ℝ F`, that is to `lineDerivOpCLM 𝕜 𝓢(ℝ, F) 1`. Defined by that composition, `derivCLM_apply` is still `rfl` and the rest of the file compiles unchanged.","fix":"Move derivCLM below fderivCLM and define it as `SchwartzMap.evalCLM 𝕜 ℝ F 1 ∘L fderivCLM 𝕜 ℝ F`.","ev":"hunts/schwartz-deriv/batch0/Probe4.lean: `example : derivCLM 𝕜 F = lineDerivOpCLM 𝕜 𝓢(ℝ, F) (1 : ℝ) := by ext f x; rfl` and `example : derivCLM 𝕜 F = SchwartzMap.evalCLM 𝕜 ℝ F 1 ∘L fderivCLM 𝕜 ℝ F := by ext f x; rfl` compile. hunts/schwartz-deriv/batch0/CopyD.lean (derivCLM redefined as that composition after `end fderiv`, derivCLM_apply still `rfl`) compiles the whole file, including tsupport_derivCLM_subset and the 1-D integration-by-parts lemmas.","evr":"compiles","astraV":"agrees","astraS":"Agrees (A2 claim 3): the independent `mkCLM` construction duplicates `lineDerivOpCLM 𝕜 𝓢(ℝ, F) 1`; the alternatives do not depend on `derivCLM`, so reordering works; keeping `derivCLM` as a thin wrapper preserves the API and `derivCLM_apply := rfl`. Rated MAJOR.","pr":44583,"res":"Re-graded MINOR→MAJOR on 2026-10-07 after comparing with the Tau Ceti red team's MAJOR duplicate-definition wins; Lean evidence unchanged, Astra A2 in hunts/regrade-dups/.","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-e6d8f0","file":"Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean","decl":"CategoryTheory.Limits.parallelPairIsoMk","line":294,"sev":"MAJOR","status":"pr-open","cat":"reuse","pattern":"second-construction-same-file","claim":"Second construction (same file, 30 lines apart): `parallelPairIsoMk` (Equalizers.lean:294) and `parallelPair.ext` (Equalizers.lean:327) both build `F ≅ G` for `F G : WalkingParallelPair ⥤ C` from isos at `zero`/`one` and the two naturality squares, with identical signatures (including the `cat_disch` auto-params), identical `NatIso.ofComponents` data and `@[simps!]` lemmas with the same statements; they are equal by `rfl`. `parallelPair.ext` has 46 uses, `parallelPairIsoMk` 4.","fix":"Keep `parallelPair.ext`; make `parallelPairIsoMk` (and its `_hom_app`/`_inv_app` lemmas) deprecated aliases and repoint its 4 uses.","ev":"dupscan/body/probe.lean: `parallelPair.ext p q hl hr = parallelPairIsoMk p q hl hr := rfl` compiles on master 5478600feeb; `#check` of both simps lemmas shows the same statements.","evr":"compiles","astraV":"agrees","astraS":"Astra (dupscan/body/A2.answer.md item 1): the only historical API difference (default naturality proofs on parallelPairIsoMk) was removed in Jan 2026 when `.ext` gained the same defaults; same reducibility and projection lemmas; keep `parallelPair.ext` (far more uses), deprecate `parallelPairIsoMk` with aliases for its generated lemmas. MAJOR.","pr":44599,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-7ed001","file":"Mathlib/CategoryTheory/Limits/Shapes/Products.lean","decl":"CategoryTheory.Limits.piFunctor","line":715,"sev":"MAJOR","status":"landed","cat":"reuse","pattern":"second-construction-same-file","claim":"Second construction: `CategoryTheory.Limits.piFunctor` (Products.lean:715, `@[simps]`, added Feb 2026) is the functor `C ⥤ Type wᵒᵖ ⥤ C`, `X ↦ (α ↦ ∏ᶜ (fun _ : α ↦ X))`, that the same file already defines as `piConst` (L504, `@[implicit_reducible, simps]`, with `piConstAdj` built on it); the two are equal by `rfl`, each carrying its own simp lemmas. One use (Sites/Point/Skyscraper.lean).","fix":"Deprecate `piFunctor` in favour of `piConst` (migrating the skyscraper use).","ev":"dupscan/defs/probe.lean: `example [HasProducts.{w} C] : (piConst : C ⥤ Type wᵒᵖ ⥤ C) = piFunctor := rfl` compiles (import Mathlib), exit 0. Found by dupscan/DefScan.lean (identical type and body).","evr":"compiles","astraV":"agrees","astraS":"ITEM 1: VERDICT: agrees RATING 1: MAJOR The strongest defense is the genuine transparency difference: `rfl` does **not** guarantee identical elaboration or tactic behavior. But the history argues against an intentional two-interface design. `piFunctor` was [introduced in February 2026](https://github.com/leanprover-community/mathlib4/commit/3c2700df647c30459584d5fb4db0acf65f4cf122); `piConst` acquired `implicit_reducible` [in July to repair transparency-sensitive proofs](https://github.com/leanprover-community/mathlib4/commit/0f0a217d5d731dad8a22f3f7095634784d30ac14). Initially both simply had","pr":44592,"res":"merged by bors as 6a70a27ce75 on 2026-10-07 (joelriou: ready-for-review + bors merge)","at":"2026-10-07","commit":""},{"id":"RT-20261007-becba6","file":"Mathlib/CategoryTheory/Limits/Shapes/Products.lean","decl":"CategoryTheory.Limits.sigmaFunctor","line":725,"sev":"MAJOR","status":"landed","cat":"reuse","pattern":"second-construction-same-file","claim":"Second construction: `CategoryTheory.Limits.sigmaFunctor` (Products.lean:725, `@[simps]`) is the functor `C ⥤ Type w ⥤ C`, `X ↦ (α ↦ ∐ (fun _ : α ↦ X))`, already defined in the same file as `sigmaConst` (L521, `@[implicit_reducible, simps]`, with `sigmaConstAdj` and Limits/Preserves/SigmaConst.lean built on it, 27 uses); equal by `rfl`. `sigmaFunctor` itself has no use (AlgebraicGeometry's `Scheme.Cover.sigmaFunctor` is an unrelated declaration).","fix":"Deprecate `sigmaFunctor` in favour of `sigmaConst`.","ev":"dupscan/defs/probe.lean: `example [HasCoproducts.{w} C] : (sigmaConst : C ⥤ Type w ⥤ C) = sigmaFunctor := rfl` compiles, exit 0.","evr":"compiles","astraV":"agrees","astraS":"ITEM 2: VERDICT: agrees RATING 2: MAJOR The same historical evidence applies. The comment about possibly making `sigmaConst` an abbreviation identifies an automation concern; it does not establish a purpose for maintaining a second construction. The existing adjunction and [colimit-preservation API](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/Limits/Preserves/SigmaConst.lean) favor retaining `sigmaConst`, including its transparency setup. There is also a concrete error in the supplied usage evidence: [Cover/Sigma.lean](https://github.com/leanprover-c","pr":44592,"res":"merged by bors as 6a70a27ce75 on 2026-10-07 (joelriou: ready-for-review + bors merge)","at":"2026-10-07","commit":""},{"id":"RT-20261007-187ea0","file":"Mathlib/Data/Vector/Zip.lean","decl":"List.Vector.zipWith","line":25,"sev":"MAJOR","status":"pr-open","cat":"reuse","pattern":"second-construction","claim":"Second construction: `List.Vector.zipWith` (Data/Vector/Zip.lean:25) rebuilds `List.Vector.map₂` (Data/Vector/Defs.lean:139) — both are `⟨List.zipWith f x.1 y.1, _⟩` on equal-length vectors (equal by `funext; rfl`), and the duplication extends to the API (`zipWith_get` duplicates the simp lemma `get_map₂`).","fix":"Deprecate `zipWith` in favour of `map₂`, moving any missing lemmas.","ev":"dupscan/defs/probe2.lean: `List.Vector.map₂ f = List.Vector.zipWith f` by `funext x y; rfl` compiles (import Mathlib), exit 0. Found by dupscan/DefEqScan.lean (same type, defeq bodies).","evr":"compiles","astraV":"agrees","astraS":"**ITEM 4: VERDICT: agrees** Both operate on vectors of the same length; `zipWith` offers no additional truncation or length generality. Destructuring the subtypes versus projecting their lists does not establish a useful separate contract. `Zip` imports `Basic`, which imports `Defs`. More tellingly, `zipWith_get` duplicates the existing `[simp]` theorem `get_map₂`: the duplication extends into the theorem API. Keep **`List.Vector.map₂`**, transfer the useful remaining `zipWith` lemmas, and deprecate `zipWith`. [Existing indexing theorem](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Data/Vector/Basic.lean#L745), [Zi","pr":44593,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-a1d74d","file":"Mathlib/Logic/Equiv/Embedding.lean","decl":"Equiv.uniqueEmbeddingEquivResult","line":85,"sev":"MAJOR","status":"pr-open","cat":"reuse","pattern":"second-construction","claim":"Second construction: `Equiv.uniqueEmbeddingEquivResult : (α ↪ β) ≃ β` for `[Unique α]` (Logic/Equiv/Embedding.lean:85) rebuilds `Function.Embedding.oneEmbeddingEquiv` (Logic/Embedding/Basic.lean:261), which Equiv/Embedding.lean already imports (via Embedding/Set); same `toFun`/`invFun`, inverse laws re-proved; equal by `rfl`.","fix":"Deprecate `uniqueEmbeddingEquivResult` in favour of `oneEmbeddingEquiv`.","ev":"dupscan/defs/probe2.lean: `(Function.Embedding.oneEmbeddingEquiv : (α ↪ β) ≃ β) = Equiv.uniqueEmbeddingEquivResult := rfl` compiles (import Mathlib), exit 0. Found by dupscan/DefEqScan.lean (same type, defeq bodies).","evr":"compiles","astraV":"agrees","astraS":"**ITEM 2: VERDICT: agrees** `one` is an arbitrary type equipped with `Unique`, so neither construction is more general. Their computational fields coincide; the different injectivity and inverse proofs provide no distinction. Neither has a special reducibility or generated-simplification interface. The import chain is `Equiv.Embedding → Embedding.Set → Embedding.Basic`, so the higher definition can reuse the lower one without introducing dependencies. Keep **`Function.Embedding.oneEmbeddingEquiv`** and deprecate `Equiv.uniqueEmbeddingEquivResult`. The different namespaces do not supply a comparable source-object conversion API here. [Import c","pr":44595,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-998abd","file":"Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean","decl":"NumberField.mixedEmbedding.fundamentalCone.equivFinRank","line":336,"sev":"MAJOR","status":"pr-open","cat":"reuse","pattern":"second-construction","claim":"Second construction (verbatim copy): `NumberField.mixedEmbedding.fundamentalCone.equivFinRank` (CanonicalEmbedding/NormLeOne.lean:336) is word for word `NumberField.Units.equivFinRank` (Units/Regulator.lean:58), `Fintype.equivOfCardEq <| by rw [...]`, although NormLeOne.lean imports Units/Regulator.lean; the two `Fin (rank K) ≃ {w // w ≠ w₀}` are equal by `rfl` only because the copy is literal (the choice made by `Fintype.equivOfCardEq` is otherwise arbitrary).","fix":"Replace the cone definition by `NumberField.Units.equivFinRank K` (or deprecate it).","ev":"dupscan/defs/probe2.lean: `NumberField.Units.equivFinRank K = NumberField.mixedEmbedding.fundamentalCone.equivFinRank (K := K) := rfl` compiles (import Mathlib), exit 0. Found by dupscan/DefEqScan.lean (same type, defeq bodies).","evr":"compiles","astraV":"agrees","astraS":"**ITEM 5: VERDICT: agrees** The strongest potential defense—keeping the canonical-embedding development independent of regulators—fails: **`NormLeOne` directly imports `Units.Regulator`**. These use the same distinguished place, assumptions, and cardinality construction. The cone version makes `K` implicit, while the units version takes it explicitly; that is convenience, not different generality or an independently specified choice. Keep **`NumberField.Units.equivFinRank`** and replace the cone definition with its application. [Direct import](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/NumberTheory/NumberField/Ca","pr":44597,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-ee0394","file":"Mathlib/RepresentationTheory/Basic.lean","decl":"Representation.ofDistribMulAction","line":425,"sev":"MAJOR","status":"confirmed","cat":"reuse","pattern":"second-construction","claim":"Second construction: `Representation.ofDistribMulAction k G A` (RepresentationTheory/Basic.lean:425, 35 uses) re-builds by hand (`toFun` from `DistribMulAction.toAddMonoidEnd` plus `map_smul'`, `map_one'`, `map_mul'` proofs) the existing `DistribMulAction.toModuleEnd k A : G →* Module.End k A` (Algebra/Module/LinearMap/End.lean, imported), to which it is `rfl`-equal; no lemma relates the two. The name is reasonable representation-theoretic API and should stay; its body should be the existing construction.","fix":"Define `ofDistribMulAction k G A := DistribMulAction.toModuleEnd k A` (keeping the name and its simp lemmas) and add the bridge lemma.","ev":"hunts/linearmap-end/batch3/probe5.lean: `Representation.ofDistribMulAction k G A = DistribMulAction.toModuleEnd k A := rfl` compiles (master 4e77f237dc2).","evr":"compiles","astraV":"agrees","astraS":"Astra A2 item 2 (hunts/linearmap-end/A2.answer.md): agrees the body re-builds DistribMulAction.toModuleEnd by hand with no reason; keep the name, define it via the existing construction. MAJOR. (Item 1, Module.End.smulLeft: disagrees, MINOR — a convenience interface taking a raw central element, since End.lean cannot import Submonoid.center.)","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-3d9a05","file":"Mathlib/Tactic/Inclusion/Extension/IntervalDyadicReal/BinarySplit.lean","decl":"Inclusion.IntervalDyadicReal.midpoint","line":25,"sev":"MAJOR","status":"pr-open","cat":"reuse","pattern":"reprovable-from-existing-api","claim":"`midpoint a b` re-implements core's `Dyadic.shiftRight` by one bit: its body is exactly the `match` that defines `Dyadic.shiftRight (a + b) 1`, and `midpoint a b = (a + b) >>> (1 : Int)` holds by `rfl`.","fix":"Define `midpoint a b := (a + b) >>> (1 : Int)`, or use the shift directly in `binarySplitMap`.","ev":"-- hunts/binsplit/Probe2.lean\nexample (a b : Dyadic) : midpoint a b = (a + b) >>> (1 : Int) := rfl\nexample (a b : Dyadic) : midpoint a b = Dyadic.shiftRight (a + b) 1 := rfl","evr":"compiles","astraV":"agrees","astraS":"Agrees (A2 claim 7): core `Dyadic.shiftRight` performs exactly this constructor match (k + i, i = 1); the `rfl` is computational equality; `midpoint` can remain a wrapper around `Dyadic.shiftRight (a + b) 1`; no performance reason shown. Rated MAJOR.","pr":44582,"res":"Re-graded MINOR→MAJOR on 2026-10-07 after comparing with the Tau Ceti red team's MAJOR duplicate-definition wins; Lean evidence unchanged, Astra A2 in hunts/regrade-dups/.","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-bc0a5d","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightProfinite.isoOfBijective","line":196,"sev":"MAJOR","status":"pr-open","cat":"reuse","pattern":"restates-comphauslike-api","claim":"A second construction of `CompHausLike.isoOfBijective` (CompHausLike/Basic.lean:249, `noncomputable def isoOfBijective {X Y : CompHausLike.{u} P} (f : X ⟶ Y) (bij : Function.Bijective f) : X ≅ Y`), with the same body (`letI := isIso_of_bijective ..; asIso f`). The general def applies directly to `LightProfinite` and is definitionally equal (`rfl`). Zero uses in Mathlib: light-condensed code (Condensed/Discrete/LocallyConstant.lean:120, specialised in `LightCondSet.LocallyConstant`) already uses the `CompHausLike` one, and Profinite/CompHaus have no such copy.","fix":"Replace it by `@[deprecated] alias isoOfBijective := CompHausLike.isoOfBijective`, or delete it.","ev":"hunts/lightprofinite/batch2/probe1.lean (P3): `example (bij : Function.Bijective f) : LightProfinite.isoOfBijective f bij = CompHausLike.isoOfBijective f bij := rfl`; hunts/lightprofinite/batch2/src_fix.lean compiles with it deleted","evr":"compiles","astraV":"agrees","astraS":"Astra A2 item 1 (hunts/lightprofinite/A2.answer.md): no substantive reason to keep the copy; namespace discoverability supports at most an alias, not a copied implementation; the Profinite refactor (eed648ae898) removed the same quartet (isClosedMap, isIso_of_bijective, isoOfBijective, forget_reflectsIsomorphisms) and the LightProfinite refactor (2c270faa699) kept them — incomplete cleanup. Deprecate in favour of CompHausLike.isoOfBijective. MAJOR (the restated lemmas/instance individually MINOR).","pr":44601,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-b3b4e8","file":"Mathlib/Algebra/AddConstMap/Equiv.lean","decl":"AddConstEquiv.trans_toEquiv","line":128,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `AddConstEquiv.toEquiv_trans` (Algebra.AddConstMap.Equiv), `AddConstEquiv.trans_toEquiv` (Algebra.AddConstMap.Equiv) state exactly the same thing (Lean-checked). Reviewer: trans_toEquiv is generated by `@[simps! +simpRhs toEquiv apply]` on `trans`, and the manual @[simp] toEquiv_trans (next to toEquiv_symm) states the same rfl equation, with no comment. Drop `toEquiv` from the simps clause (or delete the manual lemma).","fix":"Deprecate `AddConstEquiv.trans_toEquiv` in favour of `AddConstEquiv.toEquiv_trans`.","ev":"dupscan/Check.lean: `example := (@AddConstEquiv.trans_toEquiv : type_of% @AddConstEquiv.toEquiv_trans)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 1, rating MAJOR): Both simplify the same projection. Dropping only `toEquiv` from the `simps` clause preserves the generated application lemma and avoids duplicate simp declarations.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-c48891","file":"Mathlib/Algebra/Algebra/Bilinear.lean","decl":"LinearMap.mul_apply_apply","line":49,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `LinearMap.mul_apply'` (Algebra.Algebra.Bilinear), `LinearMap.mul_apply_apply` (Algebra.Algebra.Bilinear) state exactly the same thing (Lean-checked). Reviewer: `def mul` carries `@[instance_reducible, simps!]`, which generates mul_apply_apply (R and A explicit). The manual @[simp] mul_apply' (implicit args) states the same thing, with no comment. Keep mul_apply' (11 qualified uses), drop `simps!`, and move the 4 mul_apply_apply uses over.","fix":"Deprecate `LinearMap.mul_apply_apply` in favour of `LinearMap.mul_apply'`.","ev":"dupscan/Check.lean: `example := (@LinearMap.mul_apply_apply : type_of% @LinearMap.mul_apply')` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 2, rating MAJOR): The generated lemma provides no additional simplification behavior; explicit `R` and `A` remain available through named arguments to `mul_apply'`.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the two declarations differ in which arguments are explicit, which Mathlib sometimes keeps deliberately for rewriting.","at":"2026-10-07","commit":""},{"id":"RT-20261006-2eca36","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.ofClass","line":68,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-default-coercion-docstring","claim":"The docstring says `AlgEquiv.ofClass` 'is declared as the default coercion from `F` to `A ≃ₐ[R] B`', but no coercion instance exists. There is no `CoeTC`/`Coe` instance mentioning `ofClass` anywhere in Mathlib, and with `f : F`, `[AlgEquivClass F R A₁ A₂]`, both `example : A₁ ≃ₐ[R] A₂ := f` and `:= ↑f` fail with 'Type mismatch'. Every caller writes `AlgEquiv.ofClass f` explicitly (Spectrum/Basic.lean:447, Determinant.lean:457, Trace.lean:310, NumberField/Basic.lean:230, Ideal/Over.lean:163). The sentence is stale; the coercion was presumably dropped around the 2026-09-08 rename from `toAlgEquiv`. Pattern sweep: the same probe shows `(f : A₁ ≃+* A₂)` and `(f : A₁ →ₐ[R] A₂)` also fail, so the identical sentence on `RingEquivClass.toRingEquiv` (Ring/Equiv.lean:113) and `AlgHom.ofClass` (Hom.lean:66, which also names the wrong codomain `α →+* β`) is stale too. The phrase occurs 43 times in Mathlib.","fix":"Delete the sentence 'This is declared as the default coercion from `F` to `A ≃ₐ[R] B`' (or restore a `CoeTC F (A ≃ₐ[R] B)` instance).","ev":"batch0/probe1.lean section P1: `variable {F : Type*} [EquivLike F A₁ A₂] [AlgEquivClass F R A₁ A₂] (f : F)`; `example : A₁ ≃ₐ[R] A₂ := f` -> error 'Type mismatch f has type F ... expected A₁ ≃ₐ[R] A₂' (probe1.out, L24); same for `:= ↑f` (L25), `example : A₁ ≃+* A₂ := f` (L29) and `example : A₁ →ₐ[R] A₂ := f` (L30); controls `example : A₁ ≃ A₂ := f` and `example : A₁ →+* A₂ := f` compile. `git grep -n 'AlgEquiv.ofClass' origin/master -- Mathlib` shows no instance.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-9c1a4d","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.coe_fun_injective","line":147,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"per-type-wrapper-of-dfunlike-lemma","claim":"`coe_fun_injective : Function.Injective fun e : A₁ ≃ₐ[R] A₂ => (e : A₁ → A₂)` is the generic `DFunLike.coe_injective`, which is also its whole proof. It has 0 uses anywhere in Mathlib: `git grep coe_fun_injective` finds only the declaration. `RingEquiv` and `MulEquiv` have no such wrapper and rely on `DFunLike.coe_injective`.","fix":"Deprecate `AlgEquiv.coe_fun_injective` in favour of `DFunLike.coe_injective`.","ev":"batch0/probe1.lean P3: `example : @Function.Injective (A₁ ≃ₐ[R] A₂) (A₁ → A₂) fun e => (e : A₁ → A₂) := DFunLike.coe_injective` compiles; `git -C ~/mathlib-redteam grep -n coe_fun_injective origin/master -- Mathlib` -> 1 hit (the declaration).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d24533","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.instCoeOutRingEquiv","line":156,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"coercion-projection-not-coe-tagged","claim":"The `CoeOut (A₁ ≃ₐ[R] A₂) (A₁ ≃+* A₂)` instance coerces through the projection `AlgEquiv.toRingEquiv`, which is not registered `@[coe]`. The sibling coercions are registered: `toLinearEquiv` (L151, `@[coe]`) and `toAlgHom` (L185, `@[coe]`). As a result, `(e : A₁ ≃+* A₂)` prints as `e.toRingEquiv` while `(e : A₁ ≃ₗ[R] A₂)` and `(e : A₁ →ₐ[R] A₂)` print as `↑e`. `norm_cast` also does not treat it as a cast: `attribute [norm_cast] AlgEquiv.toRingEquiv_toRingHom` is rejected ('Invalid norm_cast lemma: The right-hand side cannot start with a coe function'), so that `@[simp]` lemma cannot be `@[simp, norm_cast]` like its sibling `toAlgHom_toRingHom` (L209). After `attribute [coe] AlgEquiv.toRingEquiv`, the coercion prints as `↑e` and `norm_cast` accepts both `toRingEquiv_toRingHom` and `coe_toRingEquiv`. Mathlib already registers projections this way (`attribute [coe] LinearEquiv.toLinearMap`, Module/Equiv/Defs.lean:53).","fix":"Add `attribute [coe] AlgEquiv.toRingEquiv` and tag `toRingEquiv_toRingHom` and `coe_toRingEquiv` with `norm_cast`.","ev":"batch0/probe1.lean P7 L85 `attribute [norm_cast] AlgEquiv.toRingEquiv_toRingHom` -> error 'Invalid norm_cast lemma: The right-hand side cannot start with a coe function ↑e'; batch0/probe2.lean: `#check (e : A₁ ≃+* A₂)` -> `e.toRingEquiv`, `#check (e : A₁ ≃ₗ[R] A₂)` -> `↑e`; then `attribute [coe] AlgEquiv.toRingEquiv` makes it `↑e`, and `attribute [norm_cast] AlgEquiv.toRingEquiv_toRingHom` plus `attribute [norm_cast] AlgEquiv.coe_toRingEquiv` compile (probe2.out, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-90c337","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.coe_toEquiv","line":159,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"specialises-generic-simp-lemma","claim":"`@[simp] AlgEquiv.coe_toEquiv : ((e : A₁ ≃ A₂) : A₁ → A₂) = e` is the instance `F := A₁ ≃ₐ[R] A₂` of the generic `@[simp, norm_cast] lemma EquivLike.coe_coe {F} [EquivLike F α β] (e : F) : ((e : α ≃ β) : α → β) = e := rfl` (Logic/Equiv/Defs.lean:108). `EquivLike.coe_coe e` proves it verbatim. Even with `AlgEquiv.coe_toEquiv` in the simp set, `simp?` on its own statement (and on the applied form) reports `simp only [EquivLike.coe_coe]`, so simp never uses it. It has 0 uses by name in Mathlib, and RingTheory/DedekindDomain/Different.lean:158 already pairs `AlgEquiv.toEquiv_eq_coe` with `EquivLike.coe_coe`. `RingEquiv.coe_toEquiv` (Ring/Equiv.lean:170) and `MulEquiv.coe_toEquiv` (Group/Equiv/Defs.lean:215) follow the same pattern.","fix":"Deprecate `AlgEquiv.coe_toEquiv` in favour of `EquivLike.coe_coe` (or at least drop its `@[simp]`).","ev":"batch0/probe1.lean P2: `example : ((e : A₁ ≃ A₂) : A₁ → A₂) = e := EquivLike.coe_coe e` compiles; `example : ((e : A₁ ≃ A₂) : A₁ → A₂) = e := by simp?` -> 'Try this: simp only [EquivLike.coe_coe]'; same with `simp? [-AlgEquiv.coe_toEquiv]` and for `(e : A₁ ≃ A₂) x = e x`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-1a7f81","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.toAlgHom","line":186,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-docstring","claim":"The docstring is stale. It says the def exists only 'for symmetry with the other to*Hom projections' and that 'the simp normal form is to use the coercion of the `AlgHomClass.coeTC` instance'. No `AlgHomClass.coeTC` exists in Mathlib: `#check AlgHomClass.coeTC` gives 'Unknown constant', and git grep finds no `CoeTC F (A →ₐ[R] B)` instance. `toAlgHom` is now the coercion itself: the `CoeOut` instance at L191 uses it, `(e : A₁ →ₐ[R] A₂)` elaborates to `e.toAlgHom` (`with_reducible rfl`), and `toAlgHom_eq_coe` is deprecated as 'Now a syntactic equality'.","fix":"Replace the last two docstring sentences with one saying that `toAlgHom` is the coercion `A₁ ≃ₐ[R] A₂ → A₁ →ₐ[R] A₂` and `↑e` (= `e.toAlgHom`) is the simp normal form.","ev":"hunts/algequiv/batch1/probe1.lean (P5, P5b): `#check AlgHomClass.coeTC` -> error Unknown constant `AlgHomClass.coeTC`; `example : (e : A₁ →ₐ[R] A₂) = e.toAlgHom := by with_reducible rfl` compiles; `set_option pp.coercions false in #check ((e : A₁ ≃ₐ[R] A₂) : A₁ →ₐ[R] A₂)` prints `e.toAlgHom`. `git grep -n coeTC origin/master -- Mathlib` has only Equiv.lean:184 (this docstring) for AlgHom.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-33bc5c","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.toRingHom_toAlgHom","line":214,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reprovable-by-simp","claim":"`toRingHom_toAlgHom` (`RingHomClass.toRingHom e.toAlgHom = RingHomClass.toRingHom e.toRingEquiv`) is just the composite of the two adjacent simp lemmas `toAlgHom_toRingHom` and `toRingEquiv_toRingHom`: both sides simp to `RingHomClass.toRingHom e`, and `by simp` proves it. It has one consumer (RingTheory/AdjoinRoot.lean:1151, `rw [← AlgEquiv.toRingHom_toAlgHom]`).","fix":"Deprecate it, or keep it as a documented coherence lemma proved by `(toAlgHom_toRingHom e).trans (toRingEquiv_toRingHom e).symm`.","ev":"example : ((e : A₁ →ₐ[R] A₂) : A₁ →+* A₂) = ((e : A₁ ≃+* A₂) : A₁ →+* A₂) := by\n  simp only [AlgEquiv.toAlgHom_toRingHom, AlgEquiv.toRingEquiv_toRingHom]  -- hunts/algequiv/batch1/probe1.lean (P3, compiles; plain `by simp` too)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-bea43d","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.instInhabited","line":245,"sev":"MINOR","status":"confirmed","cat":"correctness","pattern":"non-defeq-instance-diamond","claim":"Data diamond. When `S` is a subsingleton semiring, `S ≃ₐ[R] S` has two `Inhabited` instances: this one (`default := refl`) and `Unique.instInhabited` from the `Unique (S ≃ₐ[R] T)` instance at L900 (`default := ofAlgHom default default`, which sends everything to `0`). They are propositionally equal but not defeq, even at `with_reducible_and_instances`. Elaboration picks `refl`, so the `@[simp]` lemma `AlgEquiv.default_apply : (default : S ≃ₐ[R] T) x = 0` makes no progress on `(default : S ≃ₐ[R] S) x`. `RingEquiv` has the same pattern (`Inhabited (R ≃+* R)` vs `Unique (M ≃+* N)`; rfl also fails there). (Same diamond reported from the `Unique` side at L900; `RingEquiv` has the same pattern.)","fix":"Replace the L900 `Unique (S ≃ₐ[R] T)` instance with a Prop-valued `Subsingleton` instance, keeping `Unique` as a `def`/`abbrev`, so that the only data-carrying `Inhabited` on `S ≃ₐ[R] S` is `refl`.","ev":"variable {S : Type*} [Semiring S] [Algebra R S] [Subsingleton S]\nexample (x : S) : (default : S ≃ₐ[R] S) x = x := rfl  -- compiles: refl instance chosen\nexample : @default (S ≃ₐ[R] S) ⟨AlgEquiv.refl⟩ =\n    @default (S ≃ₐ[R] S) (@Unique.instInhabited _ inferInstance) := by\n  with_reducible_and_instances rfl  -- fails (plain rfl fails too)\nexample : @default (S ≃ₐ[R] S) ⟨AlgEquiv.refl⟩ =\n    @default (S ≃ₐ[R] S) (@Unique.instInhabited _ inferInstance) := Subsingleton.elim _ _  -- compiles\nexample (x : S) : (default : S ≃ₐ[R] S) x = 0 := by simp only [AlgEquiv.default_apply]  -- simp made no progress\n-- hunts/algequiv/batch1/probe1.lean (P10); RingEquiv analogue in hunts/algequiv/batch1/probe2.lean (Q3)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-91a534","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.toRingEquiv_symm","line":315,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reversed-duplicate-of-adjacent-lemma","claim":"`toRingEquiv_symm : (e : A₁ ≃+* A₂).symm = e.symm` is exactly `(symm_toRingEquiv e).symm`, the next lemma in the file read right to left. It has no uses anywhere in Mathlib: `git grep -nw toRingEquiv_symm` hits only its own declaration and the unrelated StarAlgEquiv/StarRingEquiv lemmas.","fix":"Deprecate `AlgEquiv.toRingEquiv_symm` in favour of `← symm_toRingEquiv` / `(symm_toRingEquiv e).symm`.","ev":"batch2/probe1.lean U1: `example (e : A₁ ≃ₐ[R] A₂) : (e : A₁ ≃+* A₂).symm = e.symm := (symm_toRingEquiv e).symm` compiles; `git -C mathlib4 grep -nw toRingEquiv_symm origin/master -- Mathlib` -> 4 hits: Equiv.lean:315 (decl), StarAlgHom.lean:787/789, StarRingHom.lean:365 (other namespaces).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-45b678","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.symm_toRingEquiv","line":319,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"redundant-simp-lemma-blocks-other-simp-lemma","claim":"The @[simp] lemma `symm_toRingEquiv` is redundant as a simp lemma and makes the simp set non-confluent. `simp [-AlgEquiv.symm_toRingEquiv]` already proves it. Its RHS `(e : A₁ ≃+* A₂).symm` is not in simp normal form: `RingEquiv.symm_mk` matches `e.toRingEquiv.symm` by unfolding the non-subobject parent projection `AlgEquiv.toRingEquiv`. So simp sends `(e.symm : A₂ ≃+* A₁)` to the anonymous literal `{ toEquiv := ↑e.symm, map_mul' := ⋯, map_add' := ⋯ }` (traced rewrites: symm_toRingEquiv, RingEquiv.symm_mk, toEquiv_eq_coe, symm_toEquiv_eq_symm). Because simp rewrites subterms first, this fires before the file's own simp lemma `toRingEquiv_toRingHom`, and `simp` cannot prove `toRingEquiv_toRingHom e.symm`, which is `((e.symm : A₂ ≃+* A₁) : A₂ →+* A₁) = e.symm`. It gets stuck at `↑{ toEquiv := ↑e.symm, map_mul' := ⋯, map_add' := ⋯ } = ↑e.symm`. With @[simp] erased, simp proves that goal, the lemma itself, and the applied forms. (simpNF does not catch this, because simp always uses the lemma itself first.)","fix":"Drop @[simp] from `symm_toRingEquiv` (probe4 B1-B4 then pass; check the 11 downstream uses with a build), or stop `RingEquiv.symm_mk` from firing on the non-subobject projection `AlgEquiv.toRingEquiv`.","ev":"batch2/probe3.lean T1b: `example (e : A₁ ≃ₐ[R] A₂) : ((e.symm : A₂ ≃+* A₁) : A₂ →+* A₁) = e.symm := by simp` -> unsolved goal `↑{ toEquiv := ↑e.symm, map_mul' := ⋯, map_add' := ⋯ } = ↑e.symm`; T1c the same goal with `simp [-AlgEquiv.symm_toRingEquiv]` compiles; T1d `:= toRingEquiv_toRingHom e.symm` compiles; T2 trace shows `simp only [symm_toRingEquiv, RingEquiv.symm_mk, toEquiv_eq_coe, symm_toEquiv_eq_symm]` producing the literal. batch2/probe1.lean R1f: `example (e) : (e.symm : A₂ ≃+* A₁) = (e : A₁ ≃+* A₂).symm := by simp [-AlgEquiv.symm_toRingEquiv]` compiles. batch2/probe4.lean: after `attribute [-simp] AlgEquiv.symm_toRingEquiv`, B1-B4 all compile.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6c7a73","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.symm_toAddEquiv","line":323,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-coe-simp-companion","claim":"The @[simp] lemmas `symm_toAddEquiv`/`symm_toMulEquiv` push the class coercions `AddEquivClass.toAddEquiv`/`MulEquivClass.toMulEquiv` inside `symm`, giving `⇑(↑e : A₁ ≃+ A₂).symm`. The file has no simp lemma taking that, or even `⇑(↑e : A₁ ≃+ A₂)`, back to `⇑e`/`⇑e.symm`. RingEquiv has `coe_toAddEquiv`, `coe_toMulEquiv`, `coe_coe_toAddEquiv_symm` and `coe_coe_toMulEquiv_symm` for exactly this. As a result `simp` fails on the rfl-true goals `(e.symm : A₂ ≃+ A₁) x = e.symm x`, `(e.symm : A₂ ≃+ A₁) (x + y) = e.symm x + e.symm y` and `(e.symm : A₂ ≃* A₁) (x * y) = e.symm x * e.symm y`, leaving `(↑e).symm x = e.symm x`. It also makes no progress on `(e : A₁ ≃+ A₂) x = e x`. The same goals pass with the RingEquiv analogues.","fix":"Add `@[simp] coe_toAddEquiv : ⇑(e : A₁ ≃+ A₂) = e`, `@[simp] coe_toAddEquiv_symm : ⇑(e : A₁ ≃+ A₂).symm = e.symm` and the MulEquiv versions (all `rfl`), mirroring RingEquiv.","ev":"batch2/probe2.lean S1a `example (e : A₁ ≃ₐ[R] A₂) (x : A₂) : (e.symm : A₂ ≃+ A₁) x = e.symm x := by simp` -> unsolved `(↑e).symm x = e.symm x` (S1b the same for ≃*); S2 `(e.symm : A₂ ≃+ A₁) (x + y) = e.symm x + e.symm y := by simp` -> unsolved `(↑e).symm x + (↑e).symm y = e.symm x + e.symm y`; S1d the RingEquiv analogues compile. batch2/probe3.lean T3 `(e : A₁ ≃+ A₂) x = e x := by simp` -> `simp` made no progress (≃* too); T4 fails. batch2/probe4.lean Fix A adds the four rfl lemmas as @[simp], and all of these goals then compile.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-251b7d","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.image_symm_eq_preimage","line":360,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-companion-lemma","claim":"`AlgEquiv` has `image_symm_eq_preimage` but not its companion `image_eq_preimage_symm : e '' s = e.symm ⁻¹' s`, and `simp` does not prove it. Equiv, RingEquiv, LinearEquiv, ContinuousAlgEquiv, OrderIso, Homeomorph, MeasurableEquiv and others all provide both.","fix":"Add `lemma image_eq_preimage_symm (e : A₁ ≃ₐ[R] A₂) (s : Set A₁) : e '' s = e.symm ⁻¹' s := e.symm.image_symm_eq_preimage s` (as in Ring/Equiv.lean:304).","ev":"batch2/probe1.lean U3 `#check @AlgEquiv.image_eq_preimage_symm` -> Unknown constant; U4 `example (e) (s : Set A₁) : e '' s = e.symm ⁻¹' s := by simp` -> `simp` made no progress; U2 `:= e.symm.image_symm_eq_preimage s` compiles. grep: Mathlib/Algebra/Ring/Equiv.lean:304, Mathlib/Algebra/Module/Equiv/Defs.lean:559, Mathlib/Topology/Algebra/Algebra/Equiv.lean:322, Mathlib/Logic/Equiv/Set.lean:70 each define `image_eq_preimage_symm`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-25264b","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.trans","line":387,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-groupoid-and-coercion-trans-api","claim":"`AlgEquiv.trans` is missing standard lemmas. There is no `trans_refl`, `refl_trans`, `trans_assoc` or unapplied `symm_trans`. There is also no lemma for the AlgHom coercion of a composite, `((e₁.trans e₂ : A₁ →ₐ[R] A₃) = (↑e₂).comp ↑e₁)`, and none for the RingEquiv coercion, `((e₁.trans e₂ : A₁ ≃+* A₃) = (↑e₁).trans ↑e₂)`. The file does state the corresponding results for other targets: `toRingHom_trans`, `toLinearEquiv_trans` and `trans_toLinearMap`. The siblings have these lemmas: `Equiv.trans_refl`/`refl_trans`/`trans_assoc`/`symm_trans`, `LinearEquiv.trans_refl`/`refl_trans`/`trans_assoc`, `RingEquiv.symm_trans` and `RingEquiv.coe_mulEquiv_trans`. I scanned every theorem in `import Mathlib` for an equation whose LHS has one of these six shapes, under any name, and found none for AlgEquiv. The scan's sanity check found `self_trans_symm`, `toRingHom_trans` and the others that do exist. `simp` closes none of the six goals, and each one holds by `rfl`.","fix":"Add `rfl` lemmas: `@[simp] trans_refl`, `@[simp] refl_trans`, `trans_assoc`, `symm_trans` (not simp, as in `RingEquiv`, so `symm_trans_apply` stays simp-normal), `@[simp, norm_cast] toAlgHom_trans` and `@[simp] toRingEquiv_trans` (not norm_cast, because `toRingEquiv` has no `@[coe]` attribute).","ev":"hunts/algequiv/batch3/probe1.lean section (3): six examples `by fail_if_success (simp; done); rfl` (e.g. `example (e : A₁ ≃ₐ[R] A₂) : e.trans AlgEquiv.refl = e := by fail_if_success (simp; done); rfl`). All compile, and `done` is reported as never executed, so `simp` itself fails. hunts/algequiv/batch3/probe2_src.lean is a copy of src.lean with the six lemmas added after `toRingHom_trans`; it compiles, and `#lint only simpNF` passes (the full `#lint` reports only the existing `defsWithUnderscore` on `ofLinearEquiv_symm.aux`). hunts/algequiv/batch3/probe3.lean (`import Mathlib`) scans every theorem's type: no LHS `_.trans refl`, `refl.trans _`, `(_.trans _).trans _`, `(_.trans _).symm`, `toAlgHom (_.trans _)` or `toRingEquiv (_.trans _)`; the projections of `_.trans _` that do occur are `toRingHom_trans`, `toLinearEquiv_trans`, `trans_toLinearMap` and `coe_trans`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-071fa9","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.toAlgHom_ofAlgHom","line":499,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`toAlgHom_ofAlgHom : ↑(ofAlgHom f g h₁ h₂) = f` is an `rfl` projection lemma, but it lacks `@[simp]`. As a result, `simp` cannot rewrite `(ofAlgHom f g h₁ h₂ : A₁ →ₐ[R] A₂)` to `f`. For example, `k.comp ↑(ofAlgHom f g h₁ h₂) = k.comp f` is not closed by `simp`, but is closed by `simp [toAlgHom_ofAlgHom]`. The `@[simps]` lemmas `ofAlgHom_apply` and `ofAlgHom_symm_apply` only cover the coercion to functions. The analogous lemmas are all `@[simp]`: `toAlgHom_ofBijective`, `toLinearMap_ofBijective`, `toLinearEquiv_ofLinearEquiv`, and `ofAlgHom_toAlgHom` just below. No Mathlib file uses `toAlgHom_ofAlgHom` (`git grep` shows only this file).","fix":"Tag `toAlgHom_ofAlgHom` with `@[simp]`; the simpNF linter accepts it.","ev":"hunts/algequiv/batch3/probe1.lean section (4): `example … : (ofAlgHom f g h₁ h₂ : A₁ →ₐ[R] A₂) = f := by fail_if_success (simp; done); exact toAlgHom_ofAlgHom f g h₁ h₂` and `example … : k.comp (ofAlgHom f g h₁ h₂ : A₁ →ₐ[R] A₂) = k.comp f := by fail_if_success (simp; done); simp [toAlgHom_ofAlgHom]` both compile. The run_meta check reports `AlgEquiv.toAlgHom_ofAlgHom: simp = false` and `AlgEquiv.toAlgHom_ofBijective: simp = true`. hunts/algequiv/batch3/probe2_src.lean adds `@[simp]` to it, and `#lint only simpNF` passes.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-241d88","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.toLinearMap","line":538,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"abbrev-missing-simp-api","claim":"`toLinearMap` is an `abbrev` for `↑e.toLinearEquiv`, so `simp` never sees the hidden `toLinearEquiv` subterm. For example, `simp only [toLinearEquiv_trans]` makes no progress on `(f.trans g).toLinearMap`, and `simp only [toLinearEquiv_symm]` makes no progress on `e.symm.toLinearMap`. So every operation needs its own `toLinearMap` simp lemma. `trans_toLinearMap` and `one_toLinearMap` exist, but no `refl` lemma does: `simp` cannot prove `(AlgEquiv.refl : A₁ ≃ₐ[R] A₁).toLinearMap = LinearMap.id`, which is `rfl`. The analogues `LinearEquiv.refl_toLinearMap` (Mathlib/Algebra/Module/Equiv/Defs.lean:494) and `Representation.Equiv.toLinearMap_refl` (RepresentationTheory/Intertwining.lean:388) both exist.","fix":"Add `@[simp] theorem refl_toLinearMap : (refl : A₁ ≃ₐ[R] A₁).toLinearMap = LinearMap.id := rfl` next to `trans_toLinearMap`; it passes simpNF.","ev":"hunts/algequiv/batch4/probe2.lean (Q3): `example : (AlgEquiv.refl : A₁ ≃ₐ[R] A₁).toLinearMap = LinearMap.id := by simp?` -> error: `simp` made no progress (and `:= rfl` compiles). hunts/algequiv/batch4/probe1.lean P2h': `simp only [toLinearEquiv_trans, LinearEquiv.coe_trans]` on `(f.trans g).toLinearMap = ...` -> no progress. hunts/algequiv/batch4/probe2.lean: `simp only [toLinearEquiv_symm]` on `e.symm.toLinearMap = ...` -> no progress. hunts/algequiv/batch4/copy.lean adds `@[simp] theorem refl_toLinearMap ... := rfl` -> `#lint only simpNF` clean.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-5ea632","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.toLinearMap_ofAlgHom","line":544,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`toLinearMap_ofAlgHom : (ofAlgHom f g h₁ h₂).toLinearMap = f.toLinearMap` is not `@[simp]`, although the matching `toLinearMap_ofBijective` and `toAlgHom_ofBijective` are. `simp` cannot prove it, and nothing else in Mathlib uses it (0 uses outside this file). With `@[simp]` added, the file copy passes `#lint only simpNF`.","fix":"Tag `toLinearMap_ofAlgHom` `@[simp]`, matching `toLinearMap_ofBijective`.","ev":"hunts/algequiv/batch4/probe1.lean (P3b): `example (ψ : A₂ →ₐ[R] A₁) (h₁ h₂) : (ofAlgHom φ ψ h₁ h₂).toLinearMap = φ.toLinearMap := by simp` -> error: `simp` made no progress. hunts/algequiv/batch4/copy.lean with `@[simp]` added -> simpNF clean.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-feae3c","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.ofBijective_apply_symm_apply","line":594,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`ofBijective_apply_symm_apply : f ((ofBijective f hf).symm x) = x` is missing `@[simp]`. Its sibling `ofBijective_symm_apply_apply` (line 598) is simp, and so are `MulEquiv.ofBijective_apply_symm_apply` (Mathlib/Algebra/Group/Equiv/Defs.lean:515, `@[to_additive (attr := simp)]`) and `LinearEquiv.apply_ofBijective_symm_apply` (Mathlib/Algebra/Module/Submodule/Equiv.lean, `@[simp]`). `simp` cannot prove the statement, because `apply_symm_apply` needs `⇑(ofBijective f hf)`, which `coe_ofBijective` rewrites away. With `@[simp]` added, the file copy passes `#lint only simpNF`.","fix":"Tag `AlgEquiv.ofBijective_apply_symm_apply` `@[simp]`, as for its sibling `ofBijective_symm_apply_apply` and the `MulEquiv`/`LinearEquiv` analogues.","ev":"hunts/algequiv/batch4/probe1.lean (P3a): `example (φ : A₁ →ₐ[R] A₂) (hφ : Function.Bijective φ) (y : A₂) : φ ((ofBijective φ hφ).symm y) = y := by simp` -> error: `simp` made no progress. hunts/algequiv/batch4/copy.lean (src.lean with `@[simp]` added to this lemma, plus `#lint only simpNF synTaut unusedArguments docBlame`) -> 'All linting checks passed'.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-964d6f","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.ofLinearEquiv","line":612,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-map-one-for-bijective-multiplicative-map","claim":"The hypothesis `map_one : l 1 = 1` is redundant. It follows from `map_mul` and the bijectivity of `l`, because a bijective multiplicative map preserves 1; `map_one (MulEquiv.mk' l.toEquiv map_mul)` supplies it. `RingEquiv` and `MulEquiv.mk'` ask for no such field. All 17 Mathlib call sites still prove it by hand, some non-trivially (e.g. `by simp [Algebra.TensorProduct.one_def]` in RingTheory/TensorProduct/Maps.lean:446, Pi.lean:82).","fix":"Drop `map_one` from `ofLinearEquiv`, deriving it internally as `map_one (MulEquiv.mk' l.toEquiv map_mul)`, and keep the old signature as a deprecated wrapper.","ev":"hunts/algequiv/batch5/probe1.lean (P2): def ofLinearEquiv' (l : A ≃ₗ[R] B) (map_mul : ∀ x y : A, l (x * y) = l x * l y) : A ≃ₐ[R] B := AlgEquiv.ofLinearEquiv l (_root_.map_one (MulEquiv.mk' l.toEquiv map_mul)) map_mul\nexample (l : A ≃ₗ[R] B) (h1 : l 1 = 1) (hm : ∀ x y : A, l (x * y) = l x * l y) : ofLinearEquiv' l hm = AlgEquiv.ofLinearEquiv l h1 hm := rfl","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-14af5a","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.ofLinearEquiv_symm","line":623,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"simp-rhs-proof-args-block-further-rewriting","claim":"This `@[simp]` lemma's right-hand side is a dead end for simp. Its proof arguments have types mentioning `ofLinearEquiv_symm.aux`, so after it fires neither `ofLinearEquiv_apply` nor `ofLinearEquiv_symm` itself can match the result. As a result `simp` and `dsimp` cannot prove `(ofLinearEquiv l h1 hm).symm x = l.symm x`, and `simp` cannot prove `(ofLinearEquiv l h1 hm).symm.symm = ofLinearEquiv l h1 hm`, an instance of the simp lemma `AlgEquiv.symm_symm`. After `simp only [ofLinearEquiv_symm]`, `simp only [ofLinearEquiv_apply]` makes no progress. Without the lemma, simp cannot do it either: there is no `ofLinearEquiv_symm_apply`.","fix":"Restate the right-hand side as `ofLinearEquiv l.symm (l.symm_apply_eq.mpr map_one.symm) (fun x y => l.symm_apply_eq.mpr (by rw [map_mul, l.apply_symm_apply, l.apply_symm_apply]))` (still `rfl`). With that, `simp` closes both goals.","ev":"hunts/algequiv/batch5/probe3.lean (P12): example (l : A ≃ₗ[R] B) (h1 : l 1 = 1) (hm : ∀ x y : A, l (x * y) = l x * l y) (x : B) : (ofLinearEquiv l h1 hm).symm x = l.symm x := by fail_if_success (simp; done); fail_if_success (dsimp; done); rfl\nexample ... : (ofLinearEquiv l h1 hm).symm.symm = ofLinearEquiv l h1 hm := by fail_if_success (simp; done); exact symm_symm _\nexample ... := by simp only [ofLinearEquiv_symm]; fail_if_success simp only [ofLinearEquiv_apply]; rfl","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-f94699","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.ofRingEquiv","line":645,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"implicit-data-argument-inferred-from-proof","claim":"The ring equivalence `f` is an implicit argument, inferable only from `hf`'s type. 18 of the 20 Mathlib call sites have to supply it by hand: 16 with `(f := …)` (e.g. Algebra/Algebra/Pi.lean:247, RingTheory/Ideal/Quotient/Operations.lean:1064, three `@AlgEquiv.ofRingEquiv (f := RingEquiv.refl _)` in AlgCat/Basic.lean) and 2 with a `show ∀ x, f … = …` ascription (RingTheory/AdjoinRoot.lean:1068, 1144). `AlgEquiv.ofRingEquiv (fun _ => rfl)` does not elaborate. There is also no `toRingEquiv_ofRingEquiv`: `simp` cannot prove `(ofRingEquiv hf : A₁ ≃+* A₂) = f`, although `rfl` does.","fix":"Make `f` explicit (deprecating the old form) and add `@[simp] toRingEquiv_ofRingEquiv : (ofRingEquiv f hf : A₁ ≃+* A₂) = f := rfl`.","ev":"hunts/algequiv/batch5/probe3.lean (P6c): example : A ≃ₐ[R] A := by fail_if_success exact AlgEquiv.ofRingEquiv (fun _ => rfl); exact AlgEquiv.ofRingEquiv (f := RingEquiv.refl A) (fun _ => rfl)\nhunts/algequiv/batch5/probe1.lean: example (e : A ≃+* B) (h : ∀ x, e (algebraMap R A x) = algebraMap R B x) : (AlgEquiv.ofRingEquiv h : A ≃+* B) = e := by fail_if_success simp; rfl\nCall-site count: git grep 'ofRingEquiv' origin/master -- Mathlib (20 AlgEquiv sites; 16 contain 'ofRingEquiv (f :=')","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-37a829","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.aut","line":655,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-coe-one-coe-mul-for-aut-group","claim":"The automorphism group has no `coe_one : ⇑(1 : A₁ ≃ₐ[R] A₁) = id` or `coe_mul : ⇑(e₁ * e₂) = e₁ ∘ e₂`, and `simp` proves neither (both are `rfl`). The sibling groups have them: `coe_one` exists for `Equiv.Perm`, `MulAut`, `RingAut` and `LinearEquiv`, and `coe_mul` for `Equiv.Perm` and `MulAut`. The file already has the matching `coe_inv` and `coe_pow`. `git grep 'AlgEquiv\\.coe_one\\|AlgEquiv\\.coe_mul'` finds nothing in Mathlib.","fix":"Add `@[simp, norm_cast] lemma coe_one : ⇑(1 : A₁ ≃ₐ[R] A₁) = id := rfl` and `@[simp, norm_cast] lemma coe_mul (e₁ e₂ : A₁ ≃ₐ[R] A₁) : ⇑(e₁ * e₂) = e₁ ∘ e₂ := rfl`.","ev":"hunts/algequiv/batch5/probe1.lean (P7): example : ⇑(1 : A ≃ₐ[R] A) = id := by fail_if_success simp; rfl\nexample (e₁ e₂ : A ≃ₐ[R] A) : ⇑(e₁ * e₂) = e₁ ∘ e₂ := by fail_if_success simp; rfl","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7dc599","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.apply_smulCommClass","line":722,"sev":"MINOR","status":"suspected","cat":"generality","pattern":"too-strong-typeclass","claim":"`apply_smulCommClass` and `apply_smulCommClass'` assume an action on the scalar semiring plus a scalar tower, but the proof only uses `LinearMap.CompatibleSMul A A S R` (which scalar towers already imply via an existing instance). Not compiled here.","fix":"State them under `[SMul S A] [LinearMap.CompatibleSMul A A S R]`.","ev":"Astra A1 sketch: `smul_comm s e a := (e.toLinearEquiv.toLinearMap.map_smul_of_tower s a).symm`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b6a167","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.algebraMap_eq_apply","line":746,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-symmetric-simp-lemma","claim":"The simp lemma covers only the orientation `algebraMap R A₂ y = e x`. On the equally common `e x = algebraMap R A₂ y ↔ x = algebraMap R A₁ y`, `simp` makes no progress. Both orientations, including the existing lemma, follow in one line from `rw [← e.commutes, EquivLike.apply_eq_iff_eq]`, which is shorter than the current 2-line `simpa` proof.","fix":"Add `@[simp] theorem apply_eq_algebraMap (e : A₁ ≃ₐ[R] A₂) : e x = algebraMap R A₂ y ↔ x = algebraMap R A₁ y := by rw [← e.commutes, EquivLike.apply_eq_iff_eq]`, and use the same one-line proof for this lemma.","ev":"probe1.lean L45-46: example (e : A ≃ₐ[R] A₂) {y : R} {x : A} : e x = algebraMap R A₂ y ↔ x = algebraMap R A y := by simp  -- error: simp made no progress; L47-49: the same goal by `rw [← e.commutes, EquivLike.apply_eq_iff_eq]` compiles; Equiv_fix.lean adds `apply_eq_algebraMap` and compiles (hunts/algequiv/batch6/","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c7586b","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.toLinearMapHom","line":760,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"simps-bang-overprojects","claim":"`@[simps!]` unfolds the `MonoidHom.comp` body and projects into `Module.End`, so it generates only `toLinearMapHom_apply_apply : ((toLinearMapHom R A) x) a = x a`. There is no lemma `toLinearMapHom R A σ = σ.toLinearMap`, and `simp` makes no progress on that goal, unlike `AlgHom.toEnd_apply : AlgHom.toEnd φ = φ.toLinearMap`. So `simp` cannot rewrite an unapplied `toLinearMapHom R A σ` (under `ker`, `det`, `^`, and so on). Nothing in Mathlib uses `toLinearMapHom_apply_apply`.","fix":"Define it with `toFun := AlgEquiv.toLinearMap; map_one' := rfl; map_mul' _ _ := rfl` and plain `@[simps]`, which generates `toLinearMapHom_apply : (toLinearMapHom R A) e = e.toLinearMap` (checked in Equiv_fix.lean).","ev":"probe1.lean L64: example (σ : A ≃ₐ[R] A) : AlgEquiv.toLinearMapHom R A σ = σ.toLinearMap := by simp?  -- error: simp made no progress (L65 `rfl` works); probe3.lean lists the only generated lemma as `AlgEquiv.toLinearMapHom_apply_apply`; Equiv_fix.lean with the fix compiles, `#check @AlgEquiv.toLinearMapHom_apply` gives `(toLinearMapHom R A) e = e.toLinearMap`, and `by simp` closes both the unapplied and applied goals (hunts/algequiv/batch6/","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2a7239","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.pow_toLinearMap","line":764,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-monoid-hom-companion-lemma","claim":"`one_toLinearMap` (simp) and `pow_toLinearMap` (not simp) exist, but there is no `mul` companion. `simp` makes no progress on `(σ * τ).toLinearMap = σ.toLinearMap * τ.toLinearMap`, or on `(σ ^ n).toLinearMap = σ.toLinearMap ^ n`. The `mul` statement is reachable only through `map_mul (toLinearMapHom R A) σ τ`, although the statement is `rfl`. `LinearEquiv` has the matching `coe_toLinearMap_one` and `coe_toLinearMap_mul` (Mathlib/Algebra/Module/Equiv/Basic.lean:95-98).","fix":"Add `@[simp] lemma mul_toLinearMap (σ τ : A₁ ≃ₐ[R] A₁) : (σ * τ).toLinearMap = σ.toLinearMap * τ.toLinearMap := rfl`, and consider making `pow_toLinearMap` `@[simp]` so it matches `one_toLinearMap`.","ev":"probe1.lean L59: example (σ τ : A ≃ₐ[R] A) : (σ * τ).toLinearMap = σ.toLinearMap * τ.toLinearMap := by simp  -- error: simp made no progress; L62 the pow version by simp also fails; L60-61 `map_mul (AlgEquiv.toLinearMapHom R A) σ τ` compiles; Equiv_fix.lean adds `mul_toLinearMap := rfl` and compiles (hunts/algequiv/batch6/","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ef6352","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.algHomUnitsEquiv","line":775,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"simps-rhs-not-simp-normal","claim":"`@[simps]` generates the simp lemma `algHomUnitsEquiv_apply_apply : ((algHomUnitsEquiv R S) f) a = (↑↑(↑f).toRingHom).toFun a`, whose right side is not in simp normal form. After `simp only [algHomUnitsEquiv_apply_apply]` the goal is left as `(↑↑(↑f).toRingHom).toFun x = ↑f x`. Full `simp` needs 6 more lemmas to clean it up (AlgHom.toRingHom_eq_coe, RingHom.toMonoidHom_eq_coe, AlgHom.toRingHom_toMonoidHom, OneHom.toFun_eq_coe, MonoidHom.toOneHom_coe, MonoidHom.coe_ofClass). The one consumer that computes with it (FieldTheory/KummerExtension.lean:231) unfolds the def with `dsimp [..., AlgEquiv.algHomUnitsEquiv]` instead.","fix":"Use `@[simps +simpRhs]`, which turns the generated lemma into `((algHomUnitsEquiv R S) f) a = ↑f a` (checked in Equiv_fix.lean).","ev":"probe2.lean/probe3.lean list `AlgEquiv.algHomUnitsEquiv_apply_apply [simp=true] : ((AlgEquiv.algHomUnitsEquiv R S) f) a = (↑↑(↑f).toRingHom).toFun a`; probe3.lean: after `simp only [AlgEquiv.algHomUnitsEquiv_apply_apply]` the state is `⊢ (↑↑(↑f).toRingHom).toFun x = ↑f x`; in Equiv_fix.lean with `@[simps +simpRhs]`, `#check @AlgEquiv.algHomUnitsEquiv_apply_apply` gives `... = ↑f a` and `simp only [AlgEquiv.algHomUnitsEquiv_apply_apply]` closes the goal (hunts/algequiv/batch6/","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7e5859","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"RingEquiv.toNatAlgEquiv","line":804,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-roundtrip-simp-lemmas","claim":"The round-trip lemmas that the ℚ analogue has (`RingEquiv.toRingEquiv_toRatAlgEquiv : (f.toRatAlgEquiv : R ≃+* S) = f` and `AlgEquiv.toRatAlgEquiv_toRingEquiv : (f : R ≃+* S).toRatAlgEquiv = f`, both `@[simp]`, Mathlib/Algebra/Algebra/Hom/Rat.lean:62-80) are missing for ℕ. `simp` makes no progress on `(f.toNatAlgEquiv : R ≃+* S) = f` or on `(e : R ≃+* S).toNatAlgEquiv = e`, although both hold by `rfl`.","fix":"Add `@[simp] lemma toRingEquiv_toNatAlgEquiv : (f.toNatAlgEquiv : R ≃+* S) = f := rfl` and `@[simp] lemma AlgEquiv.toNatAlgEquiv_toRingEquiv (f : R ≃ₐ[ℕ] S) : (f : R ≃+* S).toNatAlgEquiv = f := rfl`.","ev":"probe1.lean L83: example [Semiring R] [Semiring S] (f : R ≃+* S) : (f.toNatAlgEquiv : R ≃+* S) = f := by simp  -- error: simp made no progress; L85: example (e : R ≃ₐ[ℕ] S) : (e : R ≃+* S).toNatAlgEquiv = e := by simp  -- error: simp made no progress; L84/L86 `rfl` versions compile; Equiv_fix.lean adds both lemmas and compiles (hunts/algequiv/batch6/","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-fedd03","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"RingEquiv.toIntAlgEquiv","line":832,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-roundtrip-simp-lemmas","claim":"The same gap exists for ℤ. The round-trip simp lemmas of the ℚ analogue (Hom/Rat.lean:62-80) are missing. `simp` makes no progress on `(f.toIntAlgEquiv : R ≃+* S) = f` or on `(e : R ≃+* S).toIntAlgEquiv = e`, although both hold by `rfl`.","fix":"Add `@[simp] lemma toRingEquiv_toIntAlgEquiv : (f.toIntAlgEquiv : R ≃+* S) = f := rfl` and `@[simp] lemma AlgEquiv.toIntAlgEquiv_toRingEquiv (f : R ≃ₐ[ℤ] S) : (f : R ≃+* S).toIntAlgEquiv = f := rfl`.","ev":"probe1.lean L87: example [Ring R] [Ring S] (f : R ≃+* S) : (f.toIntAlgEquiv : R ≃+* S) = f := by simp  -- error: simp made no progress; L89: example (e : R ≃ₐ[ℤ] S) : (e : R ≃+* S).toIntAlgEquiv = e := by simp  -- error: simp made no progress; L88/L90 `rfl` versions compile; Equiv_fix.lean adds both lemmas and compiles (hunts/algequiv/batch6/","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c642af","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgHom.ulift","line":934,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"unused-api-wrong-base","claim":"`AlgHom.ulift` is stated over the base ring `ULift R` through the non-instance `ULift.algebra'`, so its type cannot be elaborated unless `attribute [local instance] ULift.algebra'` is active. It has no consumers in Mathlib. Meanwhile, `CommAlgCat.uliftFunctor` (Algebra/Category/CommAlgCat/Basic.lean:195,200) and `FGAlgCat.uliftFunctor` (CommAlgCat/FiniteType.lean:61,66) build the `R`-linear lift `ULift.algEquiv.symm.toAlgHom.comp (f.comp ULift.algEquiv.toAlgHom)` by hand. The docstring calls it functorial, yet there are no `ulift_id`/`ulift_comp` lemmas (both hold by `rfl`).","fix":"Add an `R`-linear `ULift S →ₐ[R] ULift T` lift with `id`/`comp` lemmas and use it in the two `uliftFunctor`s, or else drop or justify the `ULift R`-based version.","ev":"hunts/algequiv/batch7/probe1.lean section (e): `example (f : S →ₐ[R] T) := (AlgHom.ulift.{u₁, u₂, u₃} f : ULift.{u₁} S →ₐ[ULift.{u₂} R] ULift.{u₃} T)` fails with `failed to synthesize Algebra (ULift R) (ULift S)`. Sections (f) and (g) compile: `AlgHom.ulift (AlgHom.id R S) = AlgHom.id (ULift R) (ULift S) := rfl`, `AlgHom.ulift (g.comp f) = (AlgHom.ulift g).comp (AlgHom.ulift f) := rfl`, and the `R`-linear lift typechecks. `git grep -n 'AlgHom\\.ulift\\|down_ulift_apply' origin/master -- Mathlib` finds only the definitions.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d54b34","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"LinearEquiv.algEquivOfRing","line":955,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"commutative-typeclass-not-needed","claim":"`[CommSemiring A]` is stronger than needed: the statement and a proof hold for `[Semiring A]`, because the image of `algebraMap` is central, so `Algebra.commutes` can replace the `mul_comm`/`mul_left_comm` steps. The over-`Semiring` case is already rebuilt by hand in `nonempty_algEquiv_iff_finrank_eq_one` (Mathlib/LinearAlgebra/Dimension/Free.lean:329, `[Semiring S]`) as `.ofBijective (Algebra.ofId R S) (bijective_algebraMap_of_linearEquiv e)`, and `bijective_algebraMap_of_linearEquiv` (Algebra/Basic.lean:554) is itself stated for `[Semiring E]`. Mathlib has no other consumers of `algEquivOfRing`.","fix":"Weaken `[CommSemiring A]` to `[Semiring A]` and use the `Algebra.commutes`-based proof from batch7/EquivCopy.lean.","ev":"hunts/algequiv/batch7/EquivCopy.lean (copy of src.lean: `LinearEquiv.algEquivOfRing` restated with `[Semiring A]`, left_inv via `rw [← Algebra.commutes, Algebra.smul_def]`, right_inv via `key y : algebraMap R A (e.symm y) * e 1 = y`; it also checks `example ... [Semiring S] (e : R ≃ₗ[R] S) : AlgEquiv.ofBijective (Algebra.ofId R S) (bijective_algebraMap_of_linearEquiv e) = e.algEquivOfRing := AlgEquiv.ext fun _ ↦ rfl`). The whole copy compiles with no warnings, and `#lint only simpNF` passes.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-28f90a","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"LinearEquiv.algEquivOfRing","line":955,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"simps-rhs-exposes-tofun","claim":"`@[simps]` combined with `__ := Algebra.ofId R A` generates the simp lemma `LinearEquiv.algEquivOfRing_apply : e.algEquivOfRing a = (↑↑(Algebra.ofId R A).toRingHom).toFun a`. Its right-hand side exposes a raw `.toFun`, so `simp` needs six more lemmas (`AlgHom.toRingHom_eq_coe, Algebra.toRingHom_ofId, RingHom.toMonoidHom_eq_coe, OneHom.toFun_eq_coe, MonoidHom.toOneHom_coe, MonoidHom.coe_ofClass`) to reach `algebraMap R A a`. The sibling `Module.Invertible.algEquivOfRing_apply` states `= algebraMap R A x`.","fix":"Add `toFun := algebraMap R A` to the structure instance, so that `simps` generates `e.algEquivOfRing a = (algebraMap R A) a`.","ev":"hunts/algequiv/batch7/probe1b.lean section (n): `simp only [LinearEquiv.algEquivOfRing_apply]` traces `e.algEquivOfRing a ==> (↑↑(Algebra.ofId R A).toRingHom).toFun a`, and the `simp?` suggestion lists the six extra lemmas. In hunts/algequiv/batch7/EquivCopy.lean, with `toFun := algebraMap R A`, `#check @LinearEquiv.algEquivOfRing_apply` prints `e.algEquivOfRing a = (algebraMap R A) a` and simpNF passes.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-83e47f","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"LinearEquiv.conjAlgEquiv","line":981,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-refl-trans-lemmas","claim":"`conjAlgEquiv_refl` and `conjAlgEquiv_trans` are missing, although both hold by `rfl`. The sibling conjugation equivalences have them (`conjContinuousAlgEquiv_refl/_trans`, `conjStarAlgEquiv_refl/_trans`), and `LinearEquiv.conj` has `conj_refl`/`conj_trans`.","fix":"Add `@[simp] conjAlgEquiv_refl : (refl S M₁).conjAlgEquiv R = .refl := rfl` and `conjAlgEquiv_trans : (e.trans f).conjAlgEquiv R = (e.conjAlgEquiv R).trans (f.conjAlgEquiv R) := rfl`.","ev":"hunts/algequiv/batch7/probe1.lean section (i): `example : (LinearEquiv.refl S M₁).conjAlgEquiv R = AlgEquiv.refl := rfl` and `example (e : M₁ ≃ₗ[S] M₂) (f : M₂ ≃ₗ[S] M₃) : (e.trans f).conjAlgEquiv R = (e.conjAlgEquiv R).trans (f.conjAlgEquiv R) := rfl` both compile. They are also added to hunts/algequiv/batch7/EquivCopy.lean, and simpNF passes there. `git grep conjAlgEquiv origin/master -- Mathlib` shows no refl/trans lemma.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-e4737a","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"LinearEquiv.symm_conjAlgEquiv","line":988,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-on-symm-lemma","claim":"`symm_conjAlgEquiv` is not `@[simp]`, unlike its siblings `ContinuousLinearEquiv.symm_conjContinuousAlgEquiv`, `LinearIsometryEquiv.symm_conjStarAlgEquiv` and `Equiv.conj_symm`, so `simp` cannot rewrite `(e.conjAlgEquiv R).symm`. Making it simp requires `@[simps!]` to stop marking `conjAlgEquiv_symm_apply_apply` as simp; otherwise simpNF reports that simp can prove it. This matches the `conjContinuousAlgEquiv` design, where `symm_..._apply_apply` is not simp.","fix":"Mark `symm_conjAlgEquiv` `@[simp]` and change `@[simps!]` on `conjAlgEquiv` to `@[simps! apply_apply, simps! -isSimp symm_apply_apply]`.","ev":"hunts/algequiv/batch7/probe1.lean section (j): `example (e : M₁ ≃ₗ[S] M₂) (P : _ → Prop) (h : P (e.symm.conjAlgEquiv R)) : P (e.conjAlgEquiv R).symm := by simp; exact h` fails with `simp made no progress`. Section (k) succeeds with `attribute [local simp] LinearEquiv.symm_conjAlgEquiv`. In hunts/algequiv/batch7/EquivCopy.lean, `@[simp]` alone makes `#lint only simpNF` flag `conjAlgEquiv_symm_apply_apply`, and with the `simps!` change the lint passes on all 232 declarations.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-f1fd5b","file":"Mathlib/Algebra/Algebra/Operations.lean","decl":"Submodule.mul_def","line":445,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Submodule.mul_eq_span_mul_set` (Algebra.Algebra.Operations), `Submodule.mul_def` (Algebra.Algebra.Operations) state exactly the same thing (Lean-checked). Reviewer: Same file: `s * t = span R (s * t : Set A)` is proved twice (mul_eq_map₂ plus map₂_eq_span_image2, and simp with span_mul_span). The only difference is whether the arguments are explicit. Keep the older mathlib3 name, used in FractionalIdeal/Extended. Deprecate `mul_def`, which is unused by full name.","fix":"Deprecate `Submodule.mul_def` in favour of `Submodule.mul_eq_span_mul_set`.","ev":"dupscan/Check.lean: `example := (@Submodule.mul_def : type_of% @Submodule.mul_eq_span_mul_set)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 3, rating MAJOR): Neither theorem has a distinct attribute or mathematical role. The explicit scalar-ring argument of `mul_def` does not justify maintaining a second multiplication characterization.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the two declarations differ in which arguments are explicit, which Mathlib sometimes keeps deliberately for rewriting.","at":"2026-10-07","commit":""},{"id":"RT-20261007-a5af4f","file":"Mathlib/Algebra/Algebra/Pi.lean","decl":"AlgEquiv.piMulOpposite","line":200,"sev":"MINOR","status":"suspected","cat":"api","pattern":"missing-characteristic-api","claim":"Astra A1 items 5-9 (not compiled): `AlgEquiv.piMulOpposite` has no `_apply`/`_symm_apply` lemmas; the `Algebra (Π i, S i) (Π i, A i)` instance has no named API; `AlgHom.pi`/`Pi.evalAlgHom` lack bundled product identities (e.g. `(evalAlgHom R A i).comp (AlgHom.pi g) = g i`); `AlgEquiv.funUnique` has no dependent version (`piUnique`); the `ofRingEquiv` proofs of `funUnique`/`sumArrowEquivProdArrow` use `simp`/`ext` where `rfl` should do.","fix":"Add the apply lemmas, the composition identities and `AlgEquiv.piUnique`.","ev":"Suspected: Astra A1 items 5-9 (probes not run).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-71dff3","file":"Mathlib/Algebra/Algebra/Pi.lean","decl":"AlgEquiv.sumArrowEquivProdArrow_symm_apply_inr","line":270,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"name-describes-other-statement","claim":"`AlgEquiv.sumArrowEquivProdArrow_symm_apply_inr` states the general `(sumArrowEquivProdArrow α β R S).symm x = (Equiv.sumArrowEquivProdArrow α β S).symm x` for any `x : (α → S) × (β → S)`; nothing in it is about `inr`. The name describes a different (evaluated-at-`inr`) lemma; the matching forward lemma is `sumArrowEquivProdArrow_apply`, so this should be `sumArrowEquivProdArrow_symm_apply` (the `Equiv` lemma `Equiv.sumArrowEquivProdArrow_symm_apply_inr`, Logic/Equiv/Prod.lean:392, genuinely evaluates at `Sum.inr b`; the name was copied without the statement).","fix":"Rename to `sumArrowEquivProdArrow_symm_apply` with a deprecated alias.","ev":"Measured: source (statement has no `Sum.inr`).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-68343d","file":"Mathlib/Algebra/BigOperators/Fin.lean","decl":"finFunctionFinEquiv_apply","line":607,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `finFunctionFinEquiv_apply_val` (Algebra.BigOperators.Fin), `finFunctionFinEquiv_apply` (Algebra.BigOperators.Fin) state exactly the same thing (Lean-checked). Reviewer: `@[simps!] def finFunctionFinEquiv` generates the simp lemma finFunctionFinEquiv_apply_val. The manual finFunctionFinEquiv_apply (line 607, rfl, no comment) states the same value formula. Keep the generated simp lemma and deprecate the manual one (1 use, at line 613).","fix":"Deprecate `finFunctionFinEquiv_apply` in favour of `finFunctionFinEquiv_apply_val`.","ev":"dupscan/Check.lean: `example := (@finFunctionFinEquiv_apply : type_of% @finFunctionFinEquiv_apply_val)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 5, rating MAJOR): The manual `_apply` theorem also describes the coerced natural-number value; it does not complement `_apply_val` with an equality in `Fin`.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-7b6014","file":"Mathlib/Algebra/BigOperators/Finprod.lean","decl":"finsum_eq_finsetSum_of_support_subset","line":350,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `finsum_eq_sum_of_support_subset` (Algebra.BigOperators.Finprod), `finsum_eq_finsetSum_of_support_subset` (Algebra.BigOperators.Finprod) state exactly the same thing (Lean-checked). Reviewer: Additive images of `finprod_eq_prod_of_mulSupport_subset` (350) and `finprod_eq_finsetProd_of_mulSupport_subset` (373): same file, same hypotheses (`mulSupport f ⊆ ↑s`), different proofs. Keep the `prod`/`sum` names (~30/~24 uses), deprecate the `finsetProd`/`finsetSum` pair (few uses).","fix":"Deprecate `finsum_eq_finsetSum_of_support_subset` in favour of `finsum_eq_sum_of_support_subset`.","ev":"dupscan/Check.lean: `example := (@finsum_eq_finsetSum_of_support_subset : type_of% @finsum_eq_sum_of_support_subset)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 6, rating MAJOR): The additive duplication introduces neither different hypotheses nor a separate automation interface. Consolidating the multiplicative source and additive counterpart together is appropriate.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: both names are in active use (drop side 4 uses), so the pair looks like intended API.","at":"2026-10-07","commit":""},{"id":"RT-20261007-0b0072","file":"Mathlib/Algebra/BigOperators/Finprod.lean","decl":"finprod_eq_finsetProd_of_mulSupport_subset","line":373,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `finprod_eq_finsetProd_of_mulSupport_subset` (Algebra.BigOperators.Finprod), `finprod_eq_prod_of_mulSupport_subset` (Algebra.BigOperators.Finprod) state exactly the same thing (Lean-checked). Reviewer: Same file: finprod_eq_prod_of_mulSupport_subset (l.350, about 36 uses) and finprod_eq_finsetProd_of_mulSupport_subset (l.373, renamed 2026-04-08 from finset_prod) state the same thing ((h : mulSupport f ⊆ ↑s) is identical after coercion). Deprecate the finsetProd copy and its finsum twin.","fix":"Deprecate `finprod_eq_finsetProd_of_mulSupport_subset` in favour of `finprod_eq_prod_of_mulSupport_subset`.","ev":"dupscan/Check.lean: `example := (@finprod_eq_prod_of_mulSupport_subset : type_of% @finprod_eq_finsetProd_of_mulSupport_subset)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 4, rating MAJOR): There is no support/coercion distinction here, and the retained multiplicative/additive pair already supplies the necessary `to_additive` correspondence. Preserve compatibility for the previously deprecated spellings.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: both names are in active use (drop side 7 uses), so the pair looks like intended API.","at":"2026-10-07","commit":""},{"id":"RT-20261013-ef0716","file":"Mathlib/Algebra/Category/ModuleCat/Biproducts.lean","decl":"lift","line":85,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-docstring","claim":"Docstrings copied from the abelian-group file were not adapted: `HasLimit.lift` speaks of 'an indexed family of abelian groups' and 'the Cartesian product of those groups' (these are `R`-modules and linear maps); `productLimitCone` says 'using `ModuleCat.of R (∀ j, F.obj j)`' but there is no `F` (it is `∀ j, f j`); `biproductIsoPi` says 'the biproduct we've just defined', but the file defines a product cone, not a biproduct.","fix":"Say 'family of `R`-modules … product module', '`ModuleCat.of R (∀ j, f j)`', and 'the biproduct `⨁ f` is isomorphic to …'.","ev":"Measured: src L85-87, L99-100, L117-119 against the signatures at L89, L102, L120.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f93fe19494d"},{"id":"RT-20261013-70b142","file":"Mathlib/Algebra/Category/ModuleCat/Biproducts.lean","decl":"lift","line":89,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reinvents-existing-constructor","claim":"`ModuleCat.HasLimit.lift` builds `x ↦ fun j ↦ s.π.app ⟨j⟩ x` as a linear map by hand (two `simp only …; rfl` proofs under `set_option backward.defeqAttrib.useBackward true`); it is `LinearMap.pi fun j ↦ (s.π.app ⟨j⟩).hom`.","fix":"`ofHom <| LinearMap.pi fun j => (s.π.app ⟨j⟩).hom`, and drop the `set_option`.","ev":"hunts/modulecat-biprod/copyP.lean: the file with this body and without the `set_option` compiles (including `productLimitCone`'s `fac := rfl`) with the Mathlib linter set, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f93fe19494d"},{"id":"RT-20261013-8aeb43","file":"Mathlib/Algebra/Category/ModuleCat/Biproducts.lean","decl":"biproductIsoPi","line":115,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"universe-restricted-index","claim":"`biproductIsoPi` and `biproductIsoPi_inv_comp_π` take the index from `variable {J : Type}`, i.e. universe 0 only (`ULift.{1} (Fin 2)` is excluded), although the product cone they use already allows `J : Type w`; and `[Finite J]` is used only to get `[HasBiproduct f]`.","fix":"Use `{J : Type w} (f : J → ModuleCat.{max w v} R) [HasBiproduct f]` (or keep `[Finite J]`).","ev":"hunts/modulecat-biprod/copyG.lean: with `J : Type w` and `ModuleCat.{max w v}` the file compiles; `J : Type` uses still elaborate unannotated and a `J : Type 3` use compiles with `biproductIsoPi.{3, 3}`, exit 0. hunts/modulecat-biprod/copyH.lean: with `[HasBiproduct f]` instead of `[Finite J]` the file compiles with the Mathlib linter set, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f93fe19494d"},{"id":"RT-20261013-7360e5","file":"Mathlib/Algebra/Category/ModuleCat/Biproducts.lean","decl":"lequivProdOfRightSplitExact","line":165,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"The split-exact equivalences assume `[Ring R]`, but `[Semiring R]` (with the given additive groups) suffices; the `Ring` comes only from routing through `ModuleCat R`.","fix":"State them over `[Semiring R]` (free with the s-0 rewrite).","ev":"hunts/modulecat-biprod/copyX.lean: both definitions and their value examples compile under `[Semiring R]`, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f93fe19494d"},{"id":"RT-20261013-e6df21","file":"Mathlib/Algebra/Category/ModuleCat/Biproducts.lean","decl":"lequivProdOfRightSplitExact","line":174,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"second-construction-not-defeq","claim":"`lequivProdOfRightSplitExact` / `lequivProdOfLeftSplitExact` (with private helpers `…'`) build the isomorphism `A × B ≃ₗ[R] M` of a split short exact sequence through `ShortComplex.Splitting`, `isoBinaryBiproduct`, `biprodIsoProd` and a `ULift` round trip; Mathlib already constructs the same splitting directly as `Function.Exact.splitSurjectiveEquiv` / `splitInjectiveEquiv` (Algebra/Exact/Basic.lean), universe-polymorphic and with its compatibility equations. The two are not `ext; rfl`-equal (the categorical one goes through `conePointUniqueUpToIso`; its inverse is `biprod.desc (ofHom j) (ofHom f)`), and no lemma bridges them, so by the lane calibration this is MINOR reuse rather than a MAJOR duplicate.","fix":"Define both as `((LinearMap.exact_iff.mpr exac.symm).splitSurjectiveEquiv hj ⟨f, h⟩).1.symm` (resp. `splitInjectiveEquiv hg ⟨f, h⟩`), deleting the private helpers and their `backward.privateInPublic` options.","ev":"hunts/modulecat-biprod/probe_rfl.lean: `ext x <;> rfl` against `(Function.Exact.splitSurjectiveEquiv …).1.symm` fails for both ('not definitionally equal'). hunts/modulecat-biprod/copyX.lean: the file with both definitions rebuilt from `Function.Exact.split*Equiv` (helpers and all four `privateInPublic` options deleted) compiles with the Mathlib linter set, and proves `e (a, b) = j a + f b` and `e.symm m = (f m, g m)`, exit 0. Consumers: Mathlib/Algebra/Module/PID.lean L198, L264 use only the equivalence, not its formula (not rebuilt).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f93fe19494d"},{"id":"RT-20261013-dfda86","file":"Mathlib/Algebra/Category/ModuleCat/Biproducts.lean","decl":"lequivProdOfLeftSplitExact","line":190,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"Neither split-exact equivalence has any lemma (no `_apply`, `_symm_apply`, nor compatibility with `j`, `g`), and outside this file their values cannot even be computed: `simp [lequivProdOfRightSplitExact]` stops at the inaccessible private helper `lequivProdOfRightSplitExact'✝`. So `(a, b) ↦ j a + f b` is unprovable by unfolding for downstream users.","fix":"Add `@[simp] lequivProdOfRightSplitExact_apply : e (a, b) = j a + f b` and `lequivProdOfLeftSplitExact_symm_apply : e.symm m = (f m, g m)` (one-liners once the definitions use `Function.Exact.split*Equiv`).","ev":"hunts/modulecat-biprod/probe_val.lean: `simp [lequivProdOfRightSplitExact]` leaves `((lequivProdOfRightSplitExact'✝ ⋯ ⋯ ⋯) ({ down := a }, { down := b })).down = j a + f b`, exit 1. hunts/modulecat-biprod/copyX.lean proves both formulas after the s-0 rewrite, exit 0.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f93fe19494d"},{"id":"RT-20261007-437090","file":"Mathlib/Algebra/Category/ModuleCat/Presheaf/Pushforward.lean","decl":"PresheafOfModules.pushforward₀OfCommRingCat","line":71,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"duplicate-abbrev","claim":"`PresheafOfModules.pushforward₀OfCommRingCat` (Pushforward.lean:71) and `PresheafOfModulesOfCommRing.pushforward₀` (OfCommRing.lean:102) are two abbreviations with the same body `pushforward₀ F (R ⋙ forget₂ _ _)`, equal by `rfl`. Astra disagrees that this is a defect (the OfCommRing namespace is a deliberate naming layer); the residual point is that the newer abbreviation could delegate to the older one.","fix":"Define `PresheafOfModulesOfCommRing.pushforward₀` as `PresheafOfModules.pushforward₀OfCommRingCat F R`.","ev":"dupscan/body/probe.lean: `PresheafOfModulesOfCommRing.pushforward₀ F R = PresheafOfModules.pushforward₀OfCommRingCat F R := rfl` compiles.","evr":"compiles","astraV":"disagrees","astraS":"Astra item 3: deliberate API layer (introducing commit discusses it); OfCommRing imports Pushforward so the newer name can delegate; MINOR at most.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-8b5a4e","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"(file)","line":12,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-module-docstring","claim":"The module docstring covers only `pushforward` and its pseudofunctor-style compatibility with composition, so it is stale for the current file. It leaves out most of what the file now contains: the restrictions to `Over` (`overFunctor`, `over`, `overMap`, `overPullback`, `overFunctorMap`), functoriality in natural transformations (`pushforwardNatTrans`, `pushforwardNatIso`, `pushforwardCongr₂`), the adjunctions (`pushforwardPushforwardAdj`, `overPushforwardOverAdj`, `overMapPushforwardAdj`, `isLeftAdjoint_pushforward_of_isIso`), the equivalence `pushforwardPushforwardEquivalence`, and `pushforwardCompForgetToSheafModuleCat`.","fix":"Extend the module docstring with a `## Main definitions` list covering the `Over` restrictions, the natural-transformation functoriality, the adjunctions and the equivalence.","ev":"src.lean L12-22 (module docstring) versus the declarations at L57-L415.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ccc29c","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforward","line":44,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-additive-instance","claim":"`SheafOfModules.pushforward φ` has no `Functor.Additive` instance, although its action on morphisms is pointwise restriction of scalars and so is additive on the nose. `(pushforward.{v} φ).Additive` fails `infer_instance` even with `Mathlib.Algebra.Category.ModuleCat.Sheaf.Abelian` imported. The only downstream user re-derives it the long way: `Mathlib/AlgebraicGeometry/Modules/Sheaf.lean:199` proves `(pushforward f).Additive := Functor.additive_of_preservesBinaryBiproducts _`.","fix":"Add `instance : (pushforward.{v} φ).Additive where map_add := by intros; ext; rfl` (or analogous) in this file, then drop or simplify the instance at `AlgebraicGeometry/Modules/Sheaf.lean:199`.","ev":"probe_astra.lean L17 `example : (pushforward.{v} φ).Additive := by infer_instance` → failed to synthesize `(pushforward φ).Additive`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-0bc774","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.overFunctor","line":57,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"instance-on-unfolded-spelling","claim":"Instance search cannot see through `overFunctor R X`, so the restriction functor has no left-adjoint instance. The file's adjunction and instance for it are stated for the unfolded spelling `pushforward.{w} (𝟙 (R.over x))`: `overPushforwardOverAdj` (L340) and the anonymous instance at L348. As a result, `inferInstance : (overFunctor R X).IsLeftAdjoint` fails, while `by unfold overFunctor; infer_instance` and `(overPushforwardOverAdj X).isLeftAdjoint` both succeed. The same holds for the colimit preservation that `GeneratingSections.map` needs: `PreservesColimitsOfSize.{u,u} (pushforward (𝟙 (R.over X)))` is found and `PreservesColimitsOfSize.{u,u} (overFunctor R X)` is not. Consumers therefore bypass the named functor: Generators.lean:200 (`G.map (pushforward (𝟙 (R.over x)))`) and Quasicoherent.lean:385 (`P.map (pushforward (𝟙 (R.over x)))`). Meanwhile AlgebraicGeometry/Modules/{Sheaf,Tilde}.lean use `overFunctor`, so the same functor has two spellings and the instances work for only one. (The defect lives at L340/L348, which are in another batch; it is recorded here as overFunctor's missing API.)","fix":"State `overPushforwardOverAdj` as `overFunctor R x ⊣ pushforward (pushforwardOver x)`, give the L348 instance for `overFunctor R x`, and repoint Generators.lean:200 and Quasicoherent.lean:385 to `overFunctor`.","ev":"batch0/Probe1.lean P3 (L53: `example [HasBinaryProducts D] (X : D) : (overFunctor.{v} R X).IsLeftAdjoint := inferInstance` -> 'failed to synthesize (overFunctor R X).IsLeftAdjoint'; L55-59: `by unfold overFunctor; infer_instance` and `(overPushforwardOverAdj (R := R) X).isLeftAdjoint` compile) and Probe5.lean (T1 `PreservesColimitsOfSize.{u, u} (pushforward.{u} (𝟙 (R.over X))) := inferInstance` compiles; T2 the same for `overFunctor.{u} R X` -> 'failed to synthesize'). Outputs in Probe1.out / Probe5.out.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-029fd8","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.overFunctorMap","line":79,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-wrong-direction-verb","claim":"The docstring reads 'First restricting to `Over Y` and then extending to `Over X` is the same as restricting to `Over X`'. The second step is `overMap R f` for `f : X ⟶ Y`, which is the pushforward along `Over.map f : Over X ⥤ Over Y`. That functor sends `R.over Y`-modules to `R.over X`-modules by precomposition, so it restricts further from `Y` to `X`. It does not extend. Extension, meaning a left adjoint or extension by zero, would go in the opposite direction, from `Over X` to `Over Y`. The statement `overFunctor R Y ⋙ overMap R f ≅ overFunctor R X` is fine; only the docstring describes the second functor wrongly.","fix":"Reword to 'Restricting to `Over Y` and then along `Over.map f` to `Over X` is the same as restricting directly to `Over X`.'","ev":"src.lean L79-82: docstring text versus signature `overFunctor.{v} R Y ⋙ overMap.{v} R f ≅ overFunctor.{v} R X`, where `overMap R f : SheafOfModules (R.over Y) ⥤ SheafOfModules (R.over X)` (`#check @overMap` in Probe1.out).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-1467fd","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.overFunctorMap","line":81,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-component-lemmas","claim":"`overFunctorMap` has no `@[simps]` and no component lemma, so `simp` cannot compute `((overFunctorMap R f).hom.app M).val.app U x`; it gets stuck at `(ConcreteCategory.hom (((overFunctorMap R f).hom.app M).val.app U)) x = x`, while `rfl` proves the equation. The iso is built from `NatIso.ofComponents`, `fullyFaithfulForget.preimageIso` and `isoMk (fun U ↦ Iso.refl _)`. This construction is not even cheaply defeq to `Iso.refl _`: `overFunctorMap R f = Iso.refl _ := rfl` times out at whnf. Yet `Iso.refl _` typechecks at its type, and it is how the analogous `pushforwardComp` and `pushforwardId` are written. `pushforwardComp` also gets `_hom_app_val_app` lemmas, and `overFunctorMap` has none. It has 0 uses in Mathlib.","fix":"Define it as `Iso.refl _`, as `pushforwardComp` is, and add `overFunctorMap_hom_app_val_app`/`_inv_app_val_app` (`... x = x := rfl`), mirroring `pushforwardComp`.","ev":"batch0/Probe1.lean P2b (L41 `overFunctorMap.{v} R f = Iso.refl _ := rfl` -> '(deterministic) timeout at whnf'), P2c (L44-46 `... = x := by simp` -> unsolved goals; L48-50 same statement `:= rfl` compiles); Probe2.lean Q1 (`noncomputable example ... : overFunctor.{v} R Y ⋙ overMap.{v} R f ≅ overFunctor.{v} R X := Iso.refl _` compiles). `git grep overFunctorMap origin/master -- Mathlib` finds only the definition.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b927eb","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.overPullback","line":95,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"typeclass-stronger-than-needed","claim":"`overPullback` assumes `[HasPullbacks D]`, but it only uses pullbacks along `f`. `Over.pullback f` and `Over.mapPullbackAdj f` need only `[HasPullbacksAlong f]`. The stronger class comes from `CategoryTheory/Sites/Over.lean`: `coverPreserving_overPullback`, the `(Over.pullback f).IsContinuous` instance and `Sheaf.toPushforwardOverPullback` all ask for `[HasPullbacks C]`, although their proofs go through verbatim under `[HasPullbacksAlong f]`. A probe restates those three under `HasPullbacksAlong f` with the same proofs and defines `overPullback'` under `[HasPullbacksAlong f]`. It compiles, and it is `rfl`-equal to `overPullback` when `HasPullbacks D` holds. The needless assumption reaches `overMapPushforwardAdj` (L355) and the instance at L363.","fix":"Weaken `[HasPullbacks C]` to `[HasPullbacksAlong f]` in Sites/Over.lean's `coverPreserving_overPullback`, its `IsContinuous` instance and `Sheaf.toPushforwardOverPullback`, then in `overPullback`, `overMapPushforwardAdj` and the L363 instance.","ev":"batch0/Probe1.lean section Pullback (L96-126): `coverPreserving_overPullback'`, `instance ... [HasPullbacksAlong f] : (Over.pullback f).IsContinuous (K.over Y) (K.over X)`, `toPushforwardOverPullback'` and `noncomputable def overPullback' (R) {X Y} (f) [HasPullbacksAlong f] := pushforward (F := Over.pullback f) (toPushforwardOverPullback' R f)` all compile, and so does `example [HasPullbacks D] ... : overPullback'.{v} R f = overPullback.{v} R f := rfl` (no errors after L90 in Probe1.out).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-193972","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardId","line":104,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-component-lemmas","claim":"`pushforwardId` (`Iso.refl _`) has no `@[simps]` and no component lemma, unlike its siblings `pushforwardComp` and `pushforwardCongr`, which have `_hom_app_val_app`/`_inv_app_val_app`. `simp` cannot prove `((pushforwardId R).hom.app M).val.app U x = x`, while `rfl` can. The gap is filled downstream: AlgebraicGeometry/Modules/Sheaf.lean:210-211 adds `@[simp] Scheme.Modules.pushforwardId_hom_app_app`/`_inv_app_app := rfl` for its wrapper.","fix":"Add `pushforwardId_hom_app_val_app` and `pushforwardId_inv_app_val_app` (`... x = x := rfl`), as for `pushforwardComp`.","ev":"batch0/Probe1.lean P4: `((pushforwardId.{v} R).hom.app M).val.app U x = x := by simp` -> unsolved goals `(ConcreteCategory.hom (((pushforwardId R).hom.app M).val.app U)) x = x`; the same statement `:= rfl` compiles. Probe3 lists the declarations with prefix `SheafOfModules.pushforwardId`: only `[SheafOfModules.pushforwardId]`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-add0cf","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardCongr","line":110,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-trans-lemma","claim":"`pushforwardCongr` gets `_symm` as a simp lemma, but it has no `_trans` (or `_refl`) lemma, and the simp set cannot derive `_trans`. After `ext`, `simp` rewrites the inner component with `pushforwardCongr_hom_app_val_app` to `x`, but that `x` is typed by `φ`. The outer lemma is stated for `x` typed by `ψ`, so it no longer matches. The goal is left at `(ModuleCat.Hom.hom (((pushforwardCongr e').hom.app M).val.app U)) x = x`. `pushforwardCongr e ≪≫ pushforwardCongr e' = pushforwardCongr (e.trans e')` itself holds by `ext; rfl`. Such composites occur in this file, via `pushforwardNatIso.inv` and `pushforwardCongr₂ = pushforwardNatIso _ e ≪≫ pushforwardCongr he`.","fix":"Add `@[simp] lemma pushforwardCongr_trans (e : φ = ψ) (e' : ψ = χ) : pushforwardCongr e ≪≫ pushforwardCongr e' = pushforwardCongr (e.trans e') := by ext; rfl` (and `pushforwardCongr_refl`).","ev":"batch0/Probe1.lean P8 (L88-91, `ext; simp` -> unsolved goals `(ModuleCat.Hom.hom (((pushforwardCongr e').hom.app x✝¹).val.app X✝)) x✝ = x✝` with `x✝ : ↑(((pushforward φ).obj x✝¹).val.obj X✝)`); Probe2.lean Q3 (the same statement `by ext; rfl` compiles) and Q4 (`((pushforwardCongr e ≪≫ pushforwardCongr e').hom.app M).val.app U x = x := by simp` -> unsolved goals). The refl case `pushforwardCongr.{v} (rfl : φ = φ) = Iso.refl _ := by ext; simp` does compile.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-131918","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforward_assoc","line":157,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"derivable-instance-binder","claim":"`pushforward_assoc` takes `[Functor.IsContinuous (G ⋙ G') K K'']` and `[(F ⋙ G).IsContinuous J K']` as instance binders, although both follow from the individual continuity instances by `Functor.isContinuous_comp`. Its sibling `pushforwardComp` installs that derived instance in its statement with `haveI`, as `pushforward_assoc` can. The restatement with only `F`, `G`, `G'` continuous and the two `haveI`s compiles with the same `by ext; rfl` proof. Its consumer `SheafOfModules.pullback_assoc` (`PullbackContinuous.lean:185–187`) carries the composite instances too.","fix":"Drop the two composite-continuity binders from the section `variable` and put `haveI : … := Functor.isContinuous_comp …` in the statement, as `pushforwardComp` does.","ev":"probe_assoc.lean: `pushforward_assoc'` with only `[F.IsContinuous J K] [G.IsContinuous K K'] [G'.IsContinuous K' K'']` and two `haveI`s in the statement, proof `by ext; rfl`, compiles with no messages.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-aaa26d","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardNatTrans_app_val_app_apply","line":219,"sev":"MINOR","status":"pr-open","cat":"reuse","pattern":"duplicate-simp-lemma-same-file","claim":"`pushforwardNatTrans_app_val_app_apply` (L219) is an exact duplicate of `pushforwardNatTrans_app_val_app` (L205) in the same file: `((pushforwardNatTrans φ α).app X).val.app U x = X.val.map (α.app U.unop).op x`, proved by `rfl`. The two statements differ only in the bound name `X`/`M`. Their types are alpha-equivalent (`Expr ==` is true after matching the universe names), and both carry `@[simp]`, so the simp set holds the same rewrite twice. Neither is used by name anywhere in Mathlib (`git grep` on origin/master). (Graded MINOR, not MAJOR, under the user's calibration: an exact duplicate, but a harmless twin `@[simp]` lemma 14 lines from the original with no external users.)","fix":"Delete `pushforwardNatTrans_app_val_app_apply`, or make it a `@[deprecated]` alias of `pushforwardNatTrans_app_val_app`.","ev":"hunts/modsheaf-pushfwd/batch1/probe1.lean P1 (run_cmd: `a.type == b.type` -> true; both `isLemma` in the simp set -> true / true); hunts/modsheaf-pushfwd/batch1/probe3.lean P7 (each lemma's statement proved by the other one, applied to the same arguments); hunts/modsheaf-pushfwd/batch1/copy4.lean = src.lean with L218-221 deleted (together with the L269 change below): the whole file compiles, exit 0, no warnings.","evr":"compiles","astraV":"agrees","astraS":"Agrees (A2 claim 2): same assumptions, rewrite direction and simp role; the `_apply` suffix does not distinguish them (both already apply to `x`); only the bound name differs. Rated MAJOR.","pr":44580,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-6cfdcd","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardCongr₂","line":248,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"simps-bang-raw-field-rhs","claim":"`@[simps!]` on `pushforwardCongr₂` (an `Iso.trans`) unfolds all the way to element level. It generates two simp lemmas, `pushforwardCongr₂_hom_app_val_app_hom_apply` and `pushforwardCongr₂_inv_app_val_app_hom_apply`, whose right-hand sides use the raw structure field `ModuleCat.Hom.hom'`. ModuleCat declares `initialize_simps_projections Hom (hom' → hom)`, so the normal form should be `ConcreteCategory.hom`. The `inv` lemma also leaves an unsplit composite `(f ≫ g).hom'`. In practice, `simp` on the expected component formula `((pushforwardCongr₂ φ e he).hom.app X).val.app U x = X.val.map (e.hom.app U.unop).op x` stops at `(((pushforwardCongr he).hom.app X).val.app U).hom' ((((pushforwardNatTrans φ e.hom).app X).val.app U).hom' x) = …`. Neither `pushforwardCongr_hom_app_val_app` nor `pushforwardNatTrans_app_val_app` can fire on that form, since both are stated with `ConcreteCategory.hom`. The inverse gets stuck the same way. The simpNF linter does not see this, because it only checks left-hand sides.","fix":"Use `@[simps! hom inv]`, which generates `pushforwardCongr₂_hom : (pushforwardCongr₂ φ e he).hom = pushforwardNatTrans φ e.hom ≫ (pushforwardCongr he).hom` and the matching `_inv`, both simpNF-clean; or add hand-written `_app_val_app` lemmas like those of `pushforwardCongr`. Check downstream simp calls (AlgebraicGeometry/Modules/Sheaf.lean) when changing it.","ev":"hunts/modsheaf-pushfwd/batch1/probe3.lean P6: `example … : ((pushforwardCongr₂ φ e he).hom.app X).val.app U x = X.val.map (e.hom.app U.unop).op x := by simp` fails with the residual `.hom'` goal quoted in the claim, and likewise for `.inv`; probe2.lean lists the generated statements. hunts/modsheaf-pushfwd/batch1/copy3.lean = src.lean with `@[simps! hom inv]` at L246: the file compiles (the only errors are the two appended `by simp` component examples, which simp now leaves in standard `ConcreteCategory.hom` form, because of the dsimp-able-type issue the file already notes), and `simpNF.test` returns none for both new lemmas.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-35b817","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardPushforwardAdj","line":272,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-omits-hypotheses","claim":"The docstring \"If `F ⊣ G`, then the pushforwards along `F` and `G` are also adjoint.\" is copied in spirit from `Adjunction.sheafPushforwardContinuous`, which has no ring data. It omits that the pushforwards here also depend on the ring maps `φ : S ⟶ F_* R` and `ψ : R ⟶ G_* S`, and that the adjunction needs the compatibility hypotheses `H₁` (ψ followed by G^*φ is restriction along the counit) and `H₂` (φ, then F^*ψ, then restriction along the unit is the identity). These are real constraints. For example, for `F = G = 𝟭` with the identity adjunction, they say that `φ` and `ψ` are mutually inverse. Read literally, the docstring claims an adjunction for arbitrary `φ`, `ψ`.","fix":"Say: \"If `adj : F ⊣ G` and the ring maps `φ` and `ψ` are compatible with the unit and counit of `adj` (`H₁`, `H₂`), then `pushforward φ` is left adjoint to `pushforward ψ`.\"","ev":"measured: src.lean L270 docstring vs the signature printed by probe1.lean P2 (`#check @SheafOfModules.pushforwardPushforwardAdj` shows explicit `φ ψ` and the two equations H₁ H₂).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2342b6","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.isLeftAdjoint_pushforward_of_isIso","line":307,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"universe-pinned-instance","claim":"The instance is stated for `pushforward.{u} φ`, which pins the module universe to the ring universe `u`. Its proof (via `pushforwardPushforwardAdj`, which works in every module universe) goes through unchanged for `pushforward.{v} φ`. As stated, `(pushforward.{w} φ).IsLeftAdjoint` is not found when w ≠ u.","fix":"Replace `(pushforward.{u} φ).IsLeftAdjoint` with `(pushforward.{v} φ).IsLeftAdjoint`. The only consumer (Quasicoherent.lean:357, at `.{u}`) still elaborates.","ev":"hunts/modsheaf-pushfwd/batch2/probe2.lean: a copy of src.lean with L308 changed to `pushforward.{v} φ`. The whole file compiles clean (exit 0) and includes test T1 `example (x : C) : (pushforward.{w} (𝟙 (R.over x))).IsLeftAdjoint := isLeftAdjoint_pushforward_of_isIso _`. Against the built module, hunts/modsheaf-pushfwd/batch2/probe4.lean P2 `example : (pushforward.{w} φ).IsLeftAdjoint := inferInstance` fails with synthInstanceFailed, while P1 at `.{u}` succeeds.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ba321e","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardOver","line":332,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"hand-rolled-adjunction-unit","claim":"`pushforwardOver x` is the unit at `R` of the existing sheaf-level adjunction `(Over.forgetAdjStar x).sheafPushforwardContinuous (E := RingCat) (J.over x) J` (Mathlib/CategoryTheory/Sites/Continuous.lean:433, `Adjunction.sheafPushforwardContinuous`). The same file already uses exactly this pattern (`shAdj.unit.app R`) in `isLeftAdjoint_pushforward_of_isIso`.","fix":"Define it as `((Over.forgetAdjStar x).sheafPushforwardContinuous (E := RingCat) (J.over x) J).unit.app R`, or record this equality as a lemma.","ev":"hunts/modsheaf-pushfwd/batch2/probe1c.lean C1b: `example (x : C) : pushforwardOver (R := R) x = ((Over.forgetAdjStar x).sheafPushforwardContinuous (E := RingCat.{u}) (J.over x) J).unit.app R := by ext U : 3; simp [pushforwardOver]; rfl` compiles. So does C1c, which is `ext U : 3; simp [pushforwardOver]` under the file's backward options. Plain `rfl` (C1a) is rejected by the unifier.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-45107a","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardOver","line":332,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"specialised-general-construction","claim":"`pushforwardOver` is a morphism of sheaves of rings `R ⟶ (Over.star x)_* (R.over x)`, specialised to `RingCat` and placed in the `SheafOfModules` namespace of a module file. The construction works verbatim for `F : Sheaf J A` with any category `A`. Its sibling for `Over.pullback` is the general `Sheaf.toPushforwardOverPullback` (Mathlib/CategoryTheory/Sites/Over.lean:518), which carries `@[simps]`.","fix":"Move it to CategoryTheory/Sites/Over.lean as `Sheaf.toPushforwardOverStar (F : Sheaf J A) (x : C)` next to `Sheaf.toPushforwardOverPullback`, and use it here at `A := RingCat`.","ev":"hunts/modsheaf-pushfwd/batch2/probe4.lean G1: `noncomputable def probeToPushforwardOverStar {A : Type*} [Category A] (F : Sheaf J A) (x : C) : F ⟶ ((Over.star x).sheafPushforwardContinuous A J (J.over x)).obj (F.over x) := ⟨{app U := F.obj.map Limits.prod.snd.op, naturality U V f := by simp [← Functor.map_comp, ← op_comp]; rfl}⟩` compiles. G2: `example (x : C) : pushforwardOver (R := R) x = probeToPushforwardOverStar R x := rfl` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-3242cc","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.overPushforwardOverAdj","line":337,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-right-adjoint-instance","claim":"`overPushforwardOverAdj` and `overMapPushforwardAdj` each register only the left-adjoint instance; the right adjoints `pushforward (pushforwardOver x)` and `overPullback R f` get no `IsRightAdjoint` instance. Both `infer_instance` calls fail, while `(overPushforwardOverAdj x).isRightAdjoint` and `(overMapPushforwardAdj R f).isRightAdjoint` close them, so limit-preservation instances are unreachable.","fix":"Add `instance : (pushforward.{w} (pushforwardOver (R := R) x)).IsRightAdjoint := (overPushforwardOverAdj x).isRightAdjoint` and `instance [HasPullbacks C] : (overPullback R f).IsRightAdjoint := (overMapPushforwardAdj R f).isRightAdjoint`.","ev":"probe_astra.lean L25, L27: `infer_instance` fails for `(pushforward (pushforwardOver x)).IsRightAdjoint` and `(overPullback R f).IsRightAdjoint`; the explicit `.isRightAdjoint` terms at L29–33 compile.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-649280","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.instIsLeftAdjointOverOverRingCatPushforwardIdSheafOver","line":348,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"instance-on-unfolded-def","claim":"The instance is stated on the unfolded functor `pushforward.{w} (𝟙 (R.over x))` rather than on the file's named restriction functor `overFunctor R x` (L57), which is defined to be that functor. Instance search does not unfold `overFunctor`, so `(overFunctor R x).IsLeftAdjoint` is not found.","fix":"State it as `instance (x : C) : (overFunctor.{w} R x).IsLeftAdjoint := (overPushforwardOverAdj x).isLeftAdjoint`. The unfolded form is then covered by the generalised `isLeftAdjoint_pushforward_of_isIso`.","ev":"hunts/modsheaf-pushfwd/batch2/probe1.lean: B2 `example (x : C) : overFunctor.{w} R x = pushforward.{w} (𝟙 (R.over x)) := rfl` compiles. B3 `example (x : C) : (overFunctor.{w} R x).IsLeftAdjoint := inferInstance` fails with 'failed to synthesize (overFunctor R x).IsLeftAdjoint'. In hunts/modsheaf-pushfwd/batch2/probe2.lean, the restated instance fires on `overFunctor` (T2), with the whole file compiling.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-82eb29","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.instIsLeftAdjointOverOverRingCatPushforwardIdSheafOver","line":348,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"instance-special-case-of-general-instance","claim":"When w = u, this instance is a special case of `isLeftAdjoint_pushforward_of_isIso` from the same file: `Over.forget x` is cocontinuous, it is a left adjoint (Mathlib instance from `Over.forgetAdjStar`), and `𝟙` is an iso. Its only extra content is the module universe w ≠ u, and that goes away once finding 0 is fixed.","fix":"Drop it in favour of the universe-generalised `isLeftAdjoint_pushforward_of_isIso`, or keep it only as the `overFunctor` restatement (finding 1).","ev":"hunts/modsheaf-pushfwd/batch2/probe1.lean B4: `example (x : C) : (pushforward.{u} (𝟙 (R.over x))).IsLeftAdjoint := isLeftAdjoint_pushforward_of_isIso _` compiles. In hunts/modsheaf-pushfwd/batch2/probe2.lean T1 (after generalising), the same holds at every universe w, both explicitly and by `inferInstance`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-1d8b32","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardPushforwardEquivalence","line":386,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simps","claim":"The equivalence has no `@[simps functor inverse]`, so `simp`/`dsimp` cannot rewrite `(pushforwardPushforwardEquivalence eqv φ ψ H₁ H₂).functor` to `pushforward φ` (or `.inverse` to `pushforward ψ`), although both hold by `rfl`. Only the unit/counit component lemmas are provided.","fix":"Add `@[simps functor inverse]`.","ev":"hunts/modsheaf-pushfwd/batch2/probe1.lean D1: `example : (pushforwardPushforwardEquivalence.{v} eqv φ ψ H₁ H₂).functor = pushforward φ := rfl` compiles. D2 (the same statement and the `.inverse` one `:= by simp`) fails with '`simp` made no progress'. In hunts/modsheaf-pushfwd/batch2/probe2.lean T4, with `@[simps functor inverse]` added, both close by `simp` and the whole file compiles.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-f0a05f","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardCompForgetToSheafModuleCat","line":415,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-component-simp-lemma","claim":"The iso is built by tactics with no `@[simps]` and no component lemma. Its components are definitionally the identity on elements, but `simp` cannot see this. The other canonical isos in the file (`pushforwardCongr`, `pushforwardComp`) each come with a `_hom_app_val_app … = x` lemma.","fix":"Add `pushforwardCompForgetToSheafModuleCat_hom_app_hom_app` / `_inv_app_hom_app` lemmas (`… x = x := rfl`), or `@[simps!]`.","ev":"hunts/modsheaf-pushfwd/batch2/probe1b.lean: `example … (M : SheafOfModules.{max u₂ v₂ w} R) (U x) : ((pushforwardCompForgetToSheafModuleCat φ X hX hX').hom.app M).hom.app U x = x := rfl` compiles. The same goal `:= by simp` fails with unsolved goal `(ConcreteCategory.hom (((pushforwardCompForgetToSheafModuleCat φ X hX hX').hom.app M).hom.app U)) x = x`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-83ae28","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.Presentation","line":46,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-basic-constructor","claim":"Two basic constructions are missing: a presentation with no relations (generators whose `π` is an iso), and a presentation (finite when `I` is) of the free sheaf `free I`. LocallyFree.lean builds the first inline inside `LocalGeneratorsData.quasiCoherentData` (`relations.I := ULift Empty`, `relations.epi := IsZero.epi …`). Outside this file, `Presentation` is used only in AlgebraicGeometry/Modules/Tilde.lean. A 5-line constructor compiles, and with it a presentation of `free I`, finite for finite `I`.","fix":"Add `Presentation.ofIsIsoπ`/`GeneratingSections.presentation` (no relations, given `[IsIso G.π]`), a `Presentation` of `free I` with an `IsFinite` instance for finite `I`, and use the constructor in `LocalGeneratorsData.quasiCoherentData`.","ev":"hunts/modsheaf-quasicoherent/batch0/Probe2.lean (exit 0): `noncomputable def probePresentationOfIsIsoπ (G : M.GeneratingSections) [IsIso G.π] : M.Presentation where generators := G; relations := { I := PEmpty, s := PEmpty.elim, epi := (isZero_kernel_of_mono G.π).epi _ }`, `noncomputable example (I : Type u) : (free (R := R) I).Presentation := probePresentationOfIsIsoπ (free.generatingSections I)`, and an `IsFinite` instance for `[Finite I]`. `git grep -n Presentation origin/master -- Mathlib/Algebra/Category/ModuleCat Mathlib/AlgebraicGeometry` shows no such declaration. The inline copy is at LocallyFree.lean L117–122.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-fbe5f0","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.generatorsOfIsCokernelFree","line":77,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"hypotheses-only-used-for-epi","claim":"The construction uses `f`, `H` and `H'` only to get `Epi g` (via `epi_of_isColimit_cofork H'`), and it needs only `HasWeakSheafify`, not `HasSheafify`. The same structure for an arbitrary `[Epi g]` elaborates under `[HasWeakSheafify J AddCommGrpCat.{u}]`, and `generatorsOfIsCokernelFree f g H H'` is `rfl`-equal to it.","fix":"Add a constructor `(g : free σ ⟶ M) [Epi g] : M.GeneratingSections` under `HasWeakSheafify` (in Generators.lean), and define `generatorsOfIsCokernelFree` as its instance at `epi_of_isColimit_cofork H'`.","ev":"hunts/modsheaf-quasicoherent/batch0/Probe.lean, blocks (G1) and (G1'): `noncomputable def probeGeneratorsOfEpi {σ : Type u} {M : SheafOfModules.{u} R} (g : free σ ⟶ M) [Epi g] : M.GeneratingSections where I := σ; s := M.freeHomEquiv g; epi := by simpa` under `[HasWeakSheafify J AddCommGrpCat.{u}]`, and `example ... : haveI : Epi g := epi_of_isColimit_cofork H'; generatorsOfIsCokernelFree f g H H' = probeGeneratorsOfEpi g := rfl`. The file compiles (exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-1235bf","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.generatorsOfIsCokernelFree","line":77,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"semireducible-def-index-type-mismatch","claim":"`generatorsOfIsCokernelFree` is a semireducible `def`, so `(generatorsOfIsCokernelFree f g H H').I` reduces to `σ` only if the def is unfolded. As a result, the API around it type-checks only by unfolding a semireducible def. In `generatorsOfIsCokernelFree_π : (…).π = g` the left side has type `free (…).I ⟶ M` and the right side `free σ ⟶ M`, and `kernel.lift (…).π f _` has the same mismatch. `simp` on these goals fails with \"`simp` made no progress … The target expression is not type-correct under the `implicit` transparency level\". `simp [H]` rewrites `(…).π` to `g` but then cannot use `H : f ≫ g = 0`, because the middle object is `free (…).I`. This is why `relationsOfIsCokernelFree` needs `set_option backward.isDefEq.respectTransparency false`: removing it gives 4 errors. Declaring the def `abbrev` makes the whole file compile without that option.","fix":"Make `generatorsOfIsCokernelFree` an `abbrev` (or `@[reducible]`) and drop the `set_option backward.isDefEq.respectTransparency false in` on `relationsOfIsCokernelFree`.","ev":"hunts/modsheaf-quasicoherent/batch0/Probe3.lean (S2) `example … : (relationsOfIsCokernelFree f g H H').π = kernel.lift (generatorsOfIsCokernelFree f g H H').π f _ := by simp` and (S3) `example … : (generatorsOfIsCokernelFree f g H H').π = g := by simp [-generatorsOfIsCokernelFree_π]` both fail with \"`simp` made no progress … not type-correct under the `implicit` transparency level … `f` has type `free ι ⟶ free σ` but is expected to have type `free ι ⟶ free (generatorsOfIsCokernelFree f g H H').I`\". hunts/modsheaf-quasicoherent/batch0/NoSetOpt.lean (src with the L90 set_option removed) fails at 4 places in `relationsOfIsCokernelFree`, including `simp [H]` leaving `⊢ f ≫ g = 0` with `H` unused. hunts/modsheaf-quasicoherent/batch0/Fix1.lean (src with `def` changed to `abbrev` on L77 and the L90 set_option deleted) compiles with exit 0 and no warnings.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-68c8e7","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.relationsOfIsCokernelFree","line":95,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"hand-rolled-exactness","claim":"The 10-line `epi` proof rebuilds exactness by hand (`Abelian.image`, `kernel.mapIso`, `equalizer.hom_ext`). Its content is `ShortComplex.Exact.epi_kernelLift` applied to `ShortComplex.exact_of_g_is_cokernel`. A 3-line replacement compiles in the full file. It needs `import Mathlib.Algebra.Homology.ShortComplex.Exact`, which adds 15 modules to the import closure (3772 → 3787).","fix":"Replace the proof with `rw [Equiv.symm_apply_apply]; exact (ShortComplex.exact_of_g_is_cokernel (.mk f (generatorsOfIsCokernelFree f g H H').π (by simp [H])) (H'.ofIsoColimit (Cofork.ext (Iso.refl _) (by simp)))).epi_kernelLift` and add the (non-public) import.","ev":"hunts/modsheaf-quasicoherent/batch0/Fix2.lean: src with that epi proof and `import Mathlib.Algebra.Homology.ShortComplex.Exact` compiles with exit 0 and no warnings. Fix3.lean, which also has the `abbrev` fix and no set_option, compiles too. Core fact (Probe.lean R0): `example … : Epi (kernel.lift g f H) := (ShortComplex.exact_of_g_is_cokernel (.mk f g H) H').epi_kernelLift`. Import counts measured in hunts/modsheaf-quasicoherent/batch0/Imports1.lean and Imports2.lean.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-ee3a21","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.Presentation.ofIsIso","line":135,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-sheafify-assumption","claim":"`Presentation.ofIsIso` needs no abelian structure, yet it sits in the `[HasSheafify J AddCommGrpCat]` section. Its body elaborates verbatim under `[HasWeakSheafify J AddCommGrpCat.{u}]`, the assumption `Presentation` itself uses.","fix":"Move `Presentation.ofIsIso` (and its `IsFinite` instance, after checking it) into the first section, which assumes `HasWeakSheafify`.","ev":"hunts/modsheaf-quasicoherent/batch0/Probe.lean (G2), section `weak` with only `[HasWeakSheafify J AddCommGrpCat.{u}] [J.WEqualsLocallyBijective AddCommGrpCat.{u}]`: `noncomputable def probeOfIsIso {M N} (f : M ⟶ N) [IsIso f] (σ : M.Presentation) : N.Presentation where generators := σ.generators.ofEpi f; relations := σ.relations.ofEpi ((kernelCompMono _ f).symm.trans <| eqToIso (by simp)).hom` compiles (exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-cb98f2","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.Presentation.map","line":183,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-finiteness-instance-for-map","claim":"There is no instance saying that `P.map F η` is finite when `P` is. Instance search fails on `[P.IsFinite] : (P.map F η).IsFinite`, although the generators and relations of `P.map F η` have the same index types as those of `P` (`map_generators_I`/`map_relations_I`), so the instance has a 3-line proof. Because of this gap, nothing in the file carries finiteness through `map`, so `Presentation.quasicoherentData` and `QuasicoherentData.pushforward` (both built from `map`) never produce `IsFinitePresentation` data. Compare `GeneratingSections.map`, which has the matching `instance [G.IsFiniteType] : (G.map F η).IsFiniteType` in Generators.lean:178.","fix":"Add `instance [P.IsFinite] : (P.map F η).IsFinite where isFiniteType_generators := ⟨inferInstanceAs (Finite P.generators.I)⟩; isFiniteType_relations := ⟨inferInstanceAs (Finite P.relations.I)⟩` after `Presentation.map`.","ev":"hunts/modsheaf-quasicoherent/batch1/probe1.lean (B1) `example [P.IsFinite] : (P.map F η).IsFinite := by infer_instance` -> failed to synthesize (fails as expected); (B2) `example [P.IsFinite] : (P.map F η).IsFinite where isFiniteType_generators := ⟨inferInstanceAs (Finite P.generators.I)⟩ isFiniteType_relations := ⟨inferInstanceAs (Finite P.relations.I)⟩` compiles. In-file check: hunts/modsheaf-quasicoherent/batch1/v6_api.lean (src.lean plus this instance and the other proposed additions) gives EXIT=0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-238f98","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.Presentation.map_π_eq","line":192,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"duplicate-of-sibling-lemma","claim":"`(P.map F η).generators = P.generators.map F η` holds by `rfl`, so `Presentation.map_π_eq` is exactly `GeneratingSections.map_π_eq` (Generators.lean:181: `lemma GeneratingSections.map_π_eq : (G.map F η).π = (mapFreeIso F G.I η).hom ≫ F.map G.π`) applied to `P.generators`. It has no consumer in Mathlib. The underlying equation `(P.map F η).generators = P.generators.map F η` is stated nowhere and `map_π_eq` is not `@[simp]`, so `simp [Presentation.map]` cannot simplify `(P.map F η).generators.π`. (`@[simps!]` only generates the `_I` lemmas, and the `presentationOfIsCokernelFree` simps lemmas do not fire under `π`.)","fix":"Add `@[simp] lemma Presentation.map_generators : (P.map F η).generators = P.generators.map F η := rfl`, and prove `map_π_eq` as `P.generators.map_π_eq F η` (or deprecate it in favour of the new lemma).","ev":"hunts/modsheaf-quasicoherent/batch1/probe1.lean (A1) `example : (P.map F η).generators = P.generators.map F η := rfl` compiles; (A2) `example : (P.map F η).generators.π = (mapFreeIso F _ η).hom ≫ F.map (P.generators.π) := P.generators.map_π_eq F η` compiles. hunts/modsheaf-quasicoherent/batch1/probe2.lean (A6) `example : (P.map F η).generators.π = P.mapGenerators F η := by simp [Presentation.map]` leaves an unsolved goal (fails as expected). `git grep map_π_eq origin/master -- Mathlib` finds no use of `Presentation.map_π_eq`. In-file: hunts/modsheaf-quasicoherent/batch1/v6_api.lean (with `map_π_eq := P.generators.map_π_eq F η` and `map_generators := rfl`) gives EXIT=0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-ba5ff9","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.QuasicoherentData.shrink","line":218,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-shrink-instance","claim":"There is no instance saying that `shrink` preserves finite presentation: `[q.IsFinitePresentation] : q.shrink.IsFinitePresentation` is not found, although it is a one-liner. The sibling `LocalGeneratorsData.IsLocallyFreeData.shrink` (LocallyFree.lean:52) does provide the analogue. As a result, `QuasicoherentData.IsFinitePresentation` data indexed by a universe other than `u₁` cannot be turned into `M.IsFinitePresentation` by instance search.","fix":"Add `instance IsFinitePresentation.shrink (q : M.QuasicoherentData) [q.IsFinitePresentation] : q.shrink.IsFinitePresentation where isFinite_presentation i := inferInstanceAs (q.presentation i.2.choose).IsFinite`.","ev":"hunts/modsheaf-quasicoherent/batch1/probe1.lean (C1) `example (q : QuasicoherentData.{w} M) [q.IsFinitePresentation] : q.shrink.IsFinitePresentation := by infer_instance` -> failed to synthesize (fails as expected); (C2) the same with `where isFinite_presentation i := inferInstanceAs (q.presentation i.2.choose).IsFinite` compiles. In-file: hunts/modsheaf-quasicoherent/batch1/v6_api.lean gives EXIT=0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-7aba72","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.QuasicoherentData.shrink","line":222,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"duplicated-proof","claim":"The `coversTop` proof of `QuasicoherentData.shrink` (L222-225) is a verbatim copy of the one in `LocalGeneratorsData.shrink` (Generators.lean:128-131). Since `q.shrink.X` and `q.localGeneratorsData.shrink.X` are definitionally equal, the field is simply `q.localGeneratorsData.shrink.coversTop`.","fix":"Move `shrink` below `localGeneratorsData` and set `coversTop := q.localGeneratorsData.shrink.coversTop`, or extract the shared argument as a `GrothendieckTopology.CoversTop` lemma and use it in both `shrink`s.","ev":"hunts/modsheaf-quasicoherent/batch1/probe1.lean (D1) `example {M : SheafOfModules.{u} R} (q : QuasicoherentData.{w} M) : J.CoversTop q.shrink.X := q.localGeneratorsData.shrink.coversTop` compiles. In-file: hunts/modsheaf-quasicoherent/batch1/v6_api.lean (with `shrink` moved after `localGeneratorsData` and `coversTop := q.localGeneratorsData.shrink.coversTop`) gives EXIT=0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-6e70a1","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.IsFinitePresentation","line":270,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"unexercised-predicate-no-witness","claim":"`IsFinitePresentation` is not used anywhere in Mathlib outside this file, and nothing provides an instance of it. No instance covers `free I` with `[Finite I]` or `unit R`, and no introduction lemma builds it from finite-presentation `QuasicoherentData` in an arbitrary universe (the analogue of `QuasicoherentData.isQuasicoherent`) or from a finite global `Presentation`. `exact?` cannot prove `M.IsFinitePresentation` from `q : QuasicoherentData.{w} M` with `[q.IsFinitePresentation]`. The definition is not vacuous: a witness for `free I` with `[Finite I]` compiles in a few lines from existing API. So this is missing API, not a wrong definition.","fix":"Add `lemma QuasicoherentData.isFinitePresentation (q : M.QuasicoherentData) [q.IsFinitePresentation] : M.IsFinitePresentation := ⟨q.shrink, inferInstance⟩` (with the shrink instance), and instances for `free I` with `[Finite I]` and `unit R`, alongside the `IsLocallyFree` instances.","ev":"hunts/modsheaf-quasicoherent/batch1/probe1.lean: (W0) `example (I : Type u) [Finite I] : (free (R := R) I).IsFinitePresentation := by infer_instance` and `example : (unit R).IsFinitePresentation := by infer_instance` fail to synthesize (fail as expected); (C3) `example (q : QuasicoherentData.{w} M) [q.IsFinitePresentation] : M.IsFinitePresentation := by exact?` fails; (C4) `⟨q.shrink, ⟨fun i ↦ inferInstanceAs (q.presentation i.2.choose).IsFinite⟩⟩` compiles; (W1) witness `example (I : Type u) [Finite I] : (free (R := R) I).IsFinitePresentation where exists_quasicoherentData := ⟨(free.generatingSections I).localGeneratorsData.quasiCoherentData, ⟨fun i ↦ { isFiniteType_generators := ⟨inferInstanceAs (Finite I)⟩, isFiniteType_relations := ⟨inferInstanceAs (Finite (ULift.{u} Empty))⟩ }⟩⟩` compiles. `git grep -n -w -E 'IsFinitePresentation|isFinitePresentation' origin/master -- Mathlib` gives 14 lines, all in Quasicoherent.lean.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-01af48","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.isFinitePresentation","line":276,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-fullsubcategory-instance","claim":"`isQuasicoherent` comes with the instance `(M : (isQuasicoherent R).FullSubcategory) : M.obj.IsQuasicoherent` (L265), but `isFinitePresentation` has no analogue, so `M.obj.IsFinitePresentation` is not found for an object of the full subcategory.","fix":"Add `instance (M : (isFinitePresentation R).FullSubcategory) : M.obj.IsFinitePresentation := M.property` after the abbrev.","ev":"hunts/modsheaf-quasicoherent/batch1/probe1.lean (F1) `example (M : (isFinitePresentation R).FullSubcategory) : M.obj.IsFinitePresentation := by infer_instance` -> failed to synthesize (fails as expected); (F2) the `isQuasicoherent` version compiles. In-file: hunts/modsheaf-quasicoherent/batch1/v6_api.lean with `instance (M : (isFinitePresentation R).FullSubcategory) : M.obj.IsFinitePresentation := M.property` gives EXIT=0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-379b13","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.QuasicoherentData.pushforward","line":305,"sev":"MINOR","status":"suspected","cat":"generality","pattern":"technical-hypothesis-automatic","claim":"The hypothesis `h` (every `pushforward` along `Over.post G ⋙ Over.map f` preserves colimits) should be automatic for a continuous and cocontinuous `G`: restriction along such a functor is a left adjoint on abelian sheaves (`Functor.sheafAdjunctionCocontinuous`), and colimits of sheaves of modules are computed on the underlying abelian sheaves. Mathlib has no module-level colimit-preservation instance for `SheafOfModules.pushforward` (Sheaf/Colimits.lean only provides `HasColimits`), so every caller must discharge `h` by hand. Only `isQuasicoherent_pushforward_of_isLeftAdjoint` does so, and it needs extra left-adjoint and pullback hypotheses. The same applies to `isQuasicoherent_pushforward`.","fix":"Prove that `SheafOfModules.pushforward` along a continuous and cocontinuous functor preserves colimits (the module analogue of `Functor.sheafAdjunctionCocontinuous`), then drop `h`.","ev":"Pointer: Mathlib/CategoryTheory/Sites/CoverLifting.lean:319 `def sheafAdjunctionCocontinuous : G.sheafPushforwardContinuous A J K ⊣ G.sheafPushforwardCocontinuous A J K` exists for sheaves valued in A. `git grep -E 'PreservesColimit.*toSheaf|toSheaf.*PreservesColimit' origin/master -- Mathlib` finds nothing, and Mathlib/Algebra/Category/ModuleCat/Sheaf/Colimits.lean contains only two `HasColimits` instances. The Lean removal of `h` was not attempted.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-9446f1","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.QuasicoherentData.pushforward","line":305,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"slow-definition-elaboration","claim":"Elaborating the definition takes about 3 s: `letI e : … := overS.mapIso η` takes 1.23 s and the final `exact (P.presentation i.2.1).map (SheafOfModules.pushforward ψ) e.symm` takes 1.62 s, presumably from expensive defeq checks between the restricted and pushed-forward unit sheaves. This is the slowest declaration in the file.","fix":"Replace the defeq-heavy `letI e` ascription and the final `exact` with explicit isomorphisms (or `dsimp only` / `show` the expected type) so the unifier does not have to unfold `pushforward`/`over`.","ev":"lake env lean -Dtrace.profiler=true -Dtrace.profiler.threshold=150 hunts/modsheaf-quasicoherent/batch2/QcProfile.lean (verbatim copy of src.lean): `[Elab.definition.value] [2.927137] SheafOfModules.QuasicoherentData.pushforward`; children `letI e : [1.229208]`, `exact (P.presentation i.2.1).map … [1.615543]`. The plain profiler gives `tactic execution of exact took 1.52s`. Every other declaration in the batch takes under 0.15 s, except `bind`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-6e508b","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.isQuasicoherent_pushforward_of_isLeftAdjoint","line":343,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-hypothesis-derivable","claim":"Given `[IsIso φ]`, the explicit `η : (pushforward φ).obj (unit R) ≅ unit S` is redundant: the canonical `unitToPushforwardObjUnit φ : unit S ⟶ (pushforward φ).obj (unit R)` (Sheaf/PullbackFree.lean) is an isomorphism whenever `φ` is. Callers such as `Scheme.Modules.isQuasicoherent_restrictFunctor` in Tilde.lean must still construct `η` by hand.","fix":"Add `instance [IsIso φ] : IsIso (unitToPushforwardObjUnit φ)` and drop `η`, using `(asIso (unitToPushforwardObjUnit φ)).symm` (this needs `Sheaf.PullbackFree` imported, which open PR #39989 already adds to this file).","ev":"hunts/modsheaf-quasicoherent/batch2/ProbeB2.lean (imports Quasicoherent + PullbackFree; section variables are exactly the lemma's context):\nlemma probeB2_isIso [IsIso φ] : IsIso (unitToPushforwardObjUnit φ) := by\n  rw [← isIso_iff_of_reflects_iso _ (SheafOfModules.forget _ ⋙ PresheafOfModules.toPresheaf _),\n    NatTrans.isIso_iff_isIso_app]\n  intro X\n  have : IsIso φ.hom := (inferInstance : IsIso ((sheafToPresheaf K RingCat).map φ))\n  rw [ConcreteCategory.isIso_iff_bijective]\n  exact ConcreteCategory.bijective_of_isIso (φ.hom.app X)\n\nlemma probeB2 [G.IsLeftAdjoint] [IsIso φ]\n    [∀ X, Functor.IsContinuous (Over.post (X := X) G) (K.over _) (J.over _)]\n    [HasPullbacks C] [HasPullbacks D] {M : SheafOfModules.{u} R} [IsQuasicoherent M] :\n    IsQuasicoherent ((pushforward φ).obj M) :=\n  haveI := probeB2_isIso G φ\n  isQuasicoherent_pushforward_of_isLeftAdjoint G φ (asIso (unitToPushforwardObjUnit φ)).symm","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-8c0cbd","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.Presentation.quasicoherentData","line":377,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-finite-counterpart","claim":"Nothing turns a finite global presentation into finite presentation: there is no instance `[P.IsFinite] → P.quasicoherentData.IsFinitePresentation` and no `Presentation.isFinitePresentation` analogue of `Presentation.isQuasicoherent`. `inferInstance` fails on the instance. Nothing anywhere in Mathlib produces an `IsFinitePresentation` witness (`git grep IsFinitePresentation` hits only this file), although the instance takes three lines.","fix":"Add `instance [P.IsFinite] : P.quasicoherentData.IsFinitePresentation` and `theorem Presentation.isFinitePresentation [P.IsFinite] : M.IsFinitePresentation`.","ev":"Fails (hunts/modsheaf-quasicoherent/batch2/ProbeB.lean B3e): `example (M : SheafOfModules.{u} R) (P : M.Presentation) [P.IsFinite] : P.quasicoherentData.IsFinitePresentation := inferInstance` -> failed to synthesize. Compiles (hunts/modsheaf-quasicoherent/batch2/QcCopy.lean, file context L364-372):\ninstance probeA2_qcd_fp {M : SheafOfModules.{u} R} (P : Presentation M) [P.IsFinite] :\n    P.quasicoherentData.IsFinitePresentation where\n  isFinite_presentation _ :=\n    { isFiniteType_generators := ⟨inferInstanceAs (Finite P.generators.I)⟩\n      isFiniteType_relations := ⟨inferInstanceAs (Finite P.relations.I)⟩ }\ntheorem Presentation.isFinitePresentation' {M : SheafOfModules.{u} R} (P : Presentation M)\n    [P.IsFinite] : M.IsFinitePresentation := ⟨⟨P.quasicoherentData, inferInstance⟩⟩","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-bce240","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.QuasicoherentData.ofIsIso","line":394,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-sheafify-assumption","claim":"`QuasicoherentData.ofIsIso` and the instances at L401, L408 and L414 (isomorphism closure of `isQuasicoherent R` and `isFinitePresentation R`) require `[∀ X, HasSheafify (J.over X) AddCommGrpCat]`, but `QuasicoherentData`, `isQuasicoherent R` and `isFinitePresentation R` need only `HasWeakSheafify`. The stronger assumption comes from `Presentation.ofIsIso` being stated in a `HasSheafify` section, although it works under `HasWeakSheafify`.","fix":"Move `Presentation.ofIsIso` (and its `IsFinite` instance) into the `HasWeakSheafify` section at L39, then state `QuasicoherentData.ofIsIso` and the three instances under `[∀ X, HasWeakSheafify (J.over X) _]`.","ev":"hunts/modsheaf-quasicoherent/batch2/QcCopy2.lean (compiles cleanly): `Presentation.ofIsIsoW` (same body as `Presentation.ofIsIso`) under `[HasWeakSheafify J AddCommGrpCat.{u}] [J.WEqualsLocallyBijective AddCommGrpCat.{u}]`; then `QuasicoherentData.ofIsIsoW`, `instance probeW_closed : (isQuasicoherent R).IsClosedUnderIsomorphisms`, `probeW_fp` and `instance probeW_closedFP : (isFinitePresentation R).IsClosedUnderIsomorphisms` under `[∀ X, HasWeakSheafify (J.over X) AddCommGrpCat.{u}] [∀ X, (J.over X).WEqualsLocallyBijective AddCommGrpCat.{u}]`, with the original proofs. The original signatures (ProbeB.out) carry `[inst_1 : ∀ (X : C), HasSheafify (J.over X) AddCommGrpCat]`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-82f8a1","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.QuasicoherentData.bind","line":430,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"universe-restricted-index","claim":"`bind` takes `{I : Type u}`, tying the cover's index type to the universe `u` of the sheaf of rings. Nothing requires this: `QuasicoherentData` allows `I : Type w`, and `GrothendieckTopology.CoversTop.over` is universe-polymorphic in `I`. Covers indexed in other universes, such as the cover of `C` by all its objects when `u₁ ≠ u`, are excluded although the docstring covers any cover. Open upstream PRs #39553 and #39989 (Brian Nugent) both change this binder to `{I : Type w}`. (Graded MINOR, not MAJOR, consistently with the lane's earlier universe-pinning findings: a one-binder generalisation, not a wrong statement. Astra's blind pass raised the same point (P2, item 1). ALREADY BEING FIXED UPSTREAM: open PRs #39553 and #39989 (Brian-Nugent) change `bind` to `{I : Type w}`.)","fix":"Change `{I : Type u}` to `{I : Type*}` (as open PRs #39553/#39989 do); the body compiles unchanged.","ev":"hunts/modsheaf-quasicoherent/batch2/QcCopy.lean `QuasicoherentData.bind'`: the verbatim body with `{I : Type*}` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-6d5070","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.QuasicoherentData.bind","line":430,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"slow-definition-elaboration","claim":"Elaborating the definition takes about 2.3 s: the term `(by exact e.counitIso.app ((M.over (X i.1)).over ((D i.1).X i.2)))` takes 1.1 s and the structure instance 0.95 s. The `by exact` hides an expensive defeq check between `e.functor.obj (e.inverse.obj _)` and the restricted module.","fix":"Give the `preimageIso` argument an explicit, cheaply checked type (or factor the iterated-slice comparison iso into a separate lemma or def) so the defeq check is not repeated inside `by exact`.","ev":"lake env lean -Dtrace.profiler=true -Dtrace.profiler.threshold=150 hunts/modsheaf-quasicoherent/batch2/QcProfile.lean: `[Elab.definition.value] [2.273277] SheafOfModules.QuasicoherentData.bind`; children `structure instance elaboration [0.950384]` and `exact e.counitIso.app ((M.over (X i.1)).over ((D i.1).X i.2)) [1.114241]`. The plain profiler gives `tactic execution of Lean.Parser.Tactic.exact took 1s`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-00a945","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.IsQuasicoherent.of_coversTop","line":445,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"universe-restricted-index","claim":"The locality lemma `IsQuasicoherent.of_coversTop` also takes `{I : Type u}`, the universe of the sheaf of rings. So it cannot be applied to covers indexed in any other universe. For example, it fails on the cover of `C` by all its objects when `C : Type (u+1)`. `IsQuasicoherent` itself shrinks to `QuasicoherentData.{u₁}`, so nothing needs the restriction. Open PRs #39553 and #39989 generalise only `bind` and leave this lemma at `{I : Type u}`. (Graded MINOR, not MAJOR, consistently with the lane's earlier universe-pinning findings; Astra raised the same point (P2, item 1). Unlike `bind`, NOT changed by the open upstream PRs #39553/#39989; flagged to the user as a possible escalation.)","fix":"Change `{I : Type u}` to `{I : Type*}` (after generalising `bind`); the proof is unchanged.","ev":"Fails (hunts/modsheaf-quasicoherent/batch2/ProbeB.lean B1, C : Type (u + 1), [Category.{u} C], R : Sheaf J RingCat.{u}): `example (M : SheafOfModules.{u} R) [∀ X, IsQuasicoherent (M.over X)] : IsQuasicoherent M := IsQuasicoherent.of_coversTop M (id : C → C) (fun _ ↦ GrothendieckTopology.covering_of_eq_top J <| by simp)` -> `Application type mismatch: id has type C → C but is expected to have type ?m.71 → C`. Compiles (hunts/modsheaf-quasicoherent/batch2/QcCopy.lean probeA4): `IsQuasicoherent.of_coversTop'` with `{I : Type*}` (same proof via `bind'`), and the same `id`-cover example proved by `IsQuasicoherent.of_coversTop' M (id : C → C) …`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-5355a5","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.isQuasicoherent_over","line":452,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-instance-attribute","claim":"`isQuasicoherent_over` is a plain lemma, so instance search cannot find `(M.over X).IsQuasicoherent` from `[M.IsQuasicoherent]`, for example when feeding the instance arguments of `IsQuasicoherent.of_coversTop`. It is safe as an instance: its premise is about `M`, so there is no loop. The analogous `Scheme.Modules.isQuasicoherent_restrictFunctor` in Tilde.lean is an instance.","fix":"Make it an `instance` (named `SheafOfModules.isQuasicoherent_over`).","ev":"Fails (hunts/modsheaf-quasicoherent/batch2/ProbeB.lean B3f): `example [HasPullbacks C] (M : SheafOfModules.{u} R) (X : C) [∀ X Y, HasSheafify ((J.over X).over Y) AddCommGrpCat.{u}] [∀ X Y, ((J.over X).over Y).WEqualsLocallyBijective AddCommGrpCat.{u}] [M.IsQuasicoherent] : (M.over X).IsQuasicoherent := inferInstance` -> failed to synthesize. Compiles (hunts/modsheaf-quasicoherent/batch2/QcCopy2.lean probeL): the same example under `attribute [local instance] isQuasicoherent_over in`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-6eebf0","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.isQuasicoherent_over","line":453,"sev":"MINOR","status":"suspected","cat":"generality","pattern":"proof-artifact-hypotheses","claim":"`[HasPullbacks C] [HasBinaryProducts C]` are artifacts of the proof through `isQuasicoherent_pushforward_of_isLeftAdjoint` (`Over.forget X ⊣ Over.star X` needs binary products and `Over.map f ⊣ Over.pullback f` needs pullbacks). Mathematically, restricting a quasi-coherent module to `C/X` gives a quasi-coherent module on any ringed site, because `j_X^*` has both adjoints and so preserves cokernels and direct sums. The `[HasBinaryProducts C]` on `Presentation.quasicoherentData` and `Presentation.isQuasicoherent` has the same root cause: Mathlib has no colimit preservation for `pushforward (𝟙 (R.over x))` without binary products.","fix":"Once restriction along `Over.forget X` and `Over.map f` is known to preserve colimits for any site (see the finding on `QuasicoherentData.pushforward`), prove the lemma via `isQuasicoherent_pushforward` and drop both hypotheses.","ev":"Measured: Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean:326-363 derives `IsLeftAdjoint (pushforward (𝟙 (R.over x)))` only under `[HasBinaryProducts C]` (via `Over.forgetAdjStar`) and `(overMap R f).IsLeftAdjoint` only under `[HasPullbacks C]`. No other colimit-preservation instance for these functors exists. Lean removal not attempted.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-e69185","file":"Mathlib/Algebra/Category/MonCat/Colimits.lean","decl":"Prequotient","line":73,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"universe-coupling","claim":"The section variable `{J : Type v} [Category.{u} J] (F : J ⥤ MonCat.{v})` ties the object universe of the index category to the carrier universe, so colimits of small diagrams of large monoids are not available: `HasColimitsOfShape J MonCat.{u+1}` for `J : Type u` is not found by instance search, although it is valid (the neighbouring `MonCat/Limits.lean` separates the universes with `hasLimitsOfSize`) (Astra A1 item 2; complements the hom-universe finding on `hasColimits_monCat`).","fix":"Separate the universes (or add a `Small.{v} J` transport) and state `HasColimitsOfSize.{w, w'} MonCat.{v}` for all `w, w' ≤ v`-compatible sizes.","ev":"hunts/moncat-colimits/probe2.lean L6: `infer_instance` fails for `HasColimitsOfShape J MonCat.{u+1}` with `J : Type u`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-496308","file":"Mathlib/Algebra/Category/MonCat/Colimits.lean","decl":"Prequotient","line":73,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"rebuilds-existing-machinery","claim":"The construction re-implements existing algebra machinery by hand: the term algebra + `Relation` closure + quotient monoid + `descFun` re-do `FreeMonoid (Σ j, F.obj j)`, `conGen`/`Con.Quotient`/`Con.monoid` and `FreeMonoid.lift`/`Con.lift`/`Con.hom_ext`; only the three generating families (component `one`, component `mul`, diagram maps) are specific. The discrete-diagram case duplicates `Monoid.CoprodI` (GroupTheory/CoprodI.lean). The file's docstring frames this as deliberate ('knowing nothing about monoids'), so it is a reuse cost, not a second definition of an existing object (Astra A1 item 6).","fix":"Rebuild on `FreeMonoid` + `conGen` (a much shorter file), or document why the generic route is avoided.","ev":"Measured: source L72-213 vs `FreeMonoid.lift` (Algebra/FreeMonoid/Basic.lean), `conGen` (GroupTheory/Congruence/Defs.lean), `Con.lift` (GroupTheory/Congruence/Hom.lean), `Monoid.CoprodI` (GroupTheory/CoprodI.lean).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-d040c7","file":"Mathlib/Algebra/Category/MonCat/Colimits.lean","decl":"descFunLift","line":175,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-describes-other-object","claim":"`descFunLift`'s docstring ('The function from the free monoid on the diagram …') and the construction overview ('the free monoid on the disjoint union of all the monoids … then taking the quotient') misdescribe `Prequotient F`: it is the raw term algebra on `of`, `one`, `mul` (e.g. `mul one one ≠ one` in `Prequotient F`), not a free monoid; the monoid laws only hold after the quotient. The module docstring's 'current' `#print Monoid` output is also stale (Monoid now extends `NPow` and `npow_succ` is `x ^ (n + 1) = x ^ n * x`) (Astra A1 items 3-4).","fix":"Describe `Prequotient` as the term algebra quotiented by the monoid laws and diagram relations; drop the printer dump.","ev":"Measured: source L56-60 (overview), L175 (docstring), L68-74 (`Prequotient` constructors), L30-46 (printer output).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-cbb880","file":"Mathlib/Algebra/Category/MonCat/Colimits.lean","decl":"hasColimits_monCat","line":227,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"universe-specialised-instance","claim":"`hasColimits_monCat : HasColimits MonCat` only gives `HasColimitsOfSize.{v, v} MonCat.{v}`, although the construction never uses the index category's hom-universe (the relations are `Prop`s): the same cocone and `colimitIsColimit` give `HasColimitsOfSize.{u, v} MonCat.{v}` for every `u`. As stated, instance search fails e.g. for `HasColimitsOfSize.{0, 1} MonCat.{1}`.","fix":"State the instance as `HasColimitsOfSize.{u, v} MonCat.{v}`.","ev":"hunts/moncat-colimits/probe1.lean: the `HasColimitsOfSize.{u, v} MonCat.{v}` instance compiles from the file's construction; `infer_instance` for `HasColimitsOfSize.{0, 1} MonCat.{1}` fails.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-cca868","file":"Mathlib/Algebra/Category/MonCat/Colimits.lean","decl":"hasColimits_monCat","line":227,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-additive-companion","claim":"There is no `HasColimits AddMonCat` instance anywhere in Mathlib (the additive companion of this file's instance), although `AddMonCat.equivalence` transports it in one line (Astra A1 item 5).","fix":"Add `instance : HasColimits AddMonCat := Adjunction.has_colimits_of_equivalence AddMonCat.equivalence.functor` (in a file importing `Adjunction.Limits`).","ev":"hunts/moncat-colimits/probe2.lean L8: `infer_instance` fails for `HasColimits AddMonCat`; L9-10: the transport via `AddMonCat.equivalence` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-038f15","file":"Mathlib/Algebra/CharP/Basic.lean","decl":"CharP.natCast_eq_natCast_mod","line":48,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CharP.natCast_eq_natCast_mod` (Algebra.CharP.Basic), `CharP.cast_eq_mod` (Algebra.CharP.Defs) state exactly the same thing (Lean-checked). Reviewer: Same `[AddMonoidWithOne R] [CharP R p]` statement `(a : R) = ((a % p : ℕ) : R)`. cast_eq_mod lives in CharP/Defs, lower in the import graph; natCast_eq_natCast_mod in CharP/Basic re-proves it (1 use, Tactic/ReduceModChar.lean:62).","fix":"Deprecate `CharP.natCast_eq_natCast_mod` in favour of `CharP.cast_eq_mod`.","ev":"dupscan/Check.lean: `example := (@CharP.cast_eq_mod : type_of% @CharP.natCast_eq_natCast_mod)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 8, rating MAJOR): The tactic occurrence is an ordinary rewrite inside a supporting proof, not a mechanism requiring that declaration name. It can use the lower-import theorem directly. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Tactic/ReduceModChar.lean#L58)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-67e130","file":"Mathlib/Algebra/Exact/Basic.lean","decl":"Function.MulExact.of_comp_eq_one_of_ker_in_range","line":73,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Function.MulExact.of_comp_eq_one_of_ker_in_range` (Algebra.Exact.Basic), `Function.MulExact.of_comp_of_mem_range` (Algebra.Exact.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file, both @[to_additive], `g ∘ f = 1` vs `g.comp f = 1` (same term), proved separately. `of_comp_of_mem_range` is used (lines 130, 253), while `of_comp_eq_one_of_ker_in_range` and its additive version have no uses. Keep the former, deprecate the latter.","fix":"Deprecate `Function.MulExact.of_comp_eq_one_of_ker_in_range` in favour of `Function.MulExact.of_comp_of_mem_range`.","ev":"dupscan/Check.lean: `example := (@Function.MulExact.of_comp_of_mem_range : type_of% @Function.MulExact.of_comp_eq_one_of_ker_in_range)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 10, rating MAJOR): Neither `to_additive` annotation requires preserving both source declarations. Keep one constructor and its additive image.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-a08695","file":"Mathlib/Algebra/Field/Subfield/Basic.lean","decl":"Subfield.closure_preimage_le","line":546,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Subfield.closure_preimage_le` (Algebra.Field.Subfield.Basic), `RingHom.field_closure_preimage_le` (Algebra.Field.Subfield.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file, identical statement and identical proof term. Precedent: `Subring.closure_preimage_le` was deprecated on 2026-09-10 in favour of `RingHom.closure_preimage_le` (Subring/Basic.lean:1058), and this fits the `RingHom.*_field_closure` family, so keep the RingHom one and deprecate `Subfield.closure_preimage_le`.","fix":"Deprecate `Subfield.closure_preimage_le` in favour of `RingHom.field_closure_preimage_le`.","ev":"dupscan/Check.lean: `example := (@RingHom.field_closure_preimage_le : type_of% @Subfield.closure_preimage_le)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 11, rating MAJOR): The `RingHom` theorem retains useful receiver notation and matches the existing closure API; the `Subfield` copy supplies no additional receiver-based interface.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the names live in different namespaces, plausibly deliberate for discoverability/dot notation.","at":"2026-10-07","commit":""},{"id":"RT-20261007-d4d8ae","file":"Mathlib/Algebra/Group/Basic.lean","decl":"mul_div_assoc'","line":337,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `mul_div` (Algebra.Group.Basic), `mul_div_assoc'` (Algebra.Group.Basic) state exactly the same thing (Lean-checked). Reviewer: Adjacent @[to_additive] lemmas, both `a * (b / c) = a * b / c`, proved separately. Keep `mul_div`/`add_sub`, deprecate the Lean-3-core `mul_div_assoc'`/`add_sub_assoc'` (~17 uses to migrate).","fix":"Deprecate `mul_div_assoc'` in favour of `mul_div`.","ev":"dupscan/Check.lean: `example := (@mul_div_assoc' : type_of% @mul_div)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 24, rating MINOR): There is no functional distinction to preserve, although `mul_div_assoc'` is an established name for the reverse associativity rewrite. Treat this as low-priority synonym cleanup.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-0223f5","file":"Mathlib/Algebra/Group/Basic.lean","decl":"add_sub_assoc'","line":341,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `add_sub` (Algebra.Group.Basic), `add_sub_assoc'` (Algebra.Group.Basic) state exactly the same thing (Lean-checked). Reviewer: to_additive images of mul_div (l.341) and mul_div_assoc' (l.337), adjacent with identical statement `a * (b / c) = a * b / c`. mul_div/add_sub are used about 90 times in total and the primed Lean-3 names about 19. Deprecate mul_div_assoc'/add_sub_assoc'.","fix":"Deprecate `add_sub_assoc'` in favour of `add_sub`.","ev":"dupscan/Check.lean: `example := (@add_sub_assoc' : type_of% @add_sub)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 16, rating MINOR): No attribute or argument convention distinguishes them, but `add_sub_assoc'` is a familiar reverse-associativity name. Consolidation is reasonable, with limited benefit relative to foundational API churn.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-22a006","file":"Mathlib/Algebra/Group/Commute/Defs.lean","decl":"Commute.inv","line":165,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Commute.mul_inv` (Algebra.Group.Commute.Defs), `Commute.inv` (Algebra.Group.Commute.Defs) state exactly the same thing (Lean-checked). Reviewer: These are adjacent, with identical statement `(a * b)⁻¹ = a⁻¹ * b⁻¹` and identical proof `by rw [hab.eq, mul_inv_rev]`. Keep the descriptive `Commute.mul_inv`. Deprecate `Commute.inv`, a name that suggests `Commute a⁻¹ b⁻¹`.","fix":"Deprecate `Commute.inv` in favour of `Commute.mul_inv`.","ev":"dupscan/Check.lean: `example := (@Commute.inv : type_of% @Commute.mul_inv)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 27, rating MAJOR): `hab.mul_inv` provides the same witness-based application as `hab.inv`, with a more informative name. There is no distinct commutation-preservation theorem here.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-306208","file":"Mathlib/Algebra/Group/Int/Units.lean","decl":"Int.IsUnit.natAbs_eq","line":34,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Int.natAbs_of_isUnit` (Algebra.Group.Int.Units), `Int.IsUnit.natAbs_eq` (Algebra.Group.Int.Units) state exactly the same thing (Lean-checked). Reviewer: @[simp] natAbs_of_isUnit (3 uses) and `alias ⟨IsUnit.natAbs_eq, _⟩ := isUnit_iff_natAbs_eq` (unused) state the same thing. The alias lands in namespace Int as Int.IsUnit.natAbs_eq, so it does not even provide `hu.natAbs_eq` dot notation.","fix":"Deprecate `Int.IsUnit.natAbs_eq` in favour of `Int.natAbs_of_isUnit`.","ev":"dupscan/Check.lean: `example := (@Int.IsUnit.natAbs_eq : type_of% @Int.natAbs_of_isUnit)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup0 item 12, rating MINOR): This is explicitly a forward `alias`, contrary to the stated exclusion, rather than an independently rediscovered proof. Its apparent purpose is an `IsUnit` method; correcting the namespace deserves consideration before removing that interface. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Algebra/Group/Int/Units.lean#L76)","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-cef9ad","file":"Mathlib/Algebra/Group/Pointwise/Set/Lattice.lean","decl":"Set.iUnion_smul_set","line":254,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Set.iUnion_smul_left_image` (Algebra.Group.Pointwise.Set.Lattice), `Set.iUnion_smul_set` (Algebra.Group.Pointwise.Set.Lattice) state exactly the same thing (Lean-checked). Reviewer: Same section and same proof (`iUnion_image_left _`): iUnion_smul_left_image (pairs with iUnion_smul_right_image) and @[simp] iUnion_smul_set (about 13 uses) state `⋃ a ∈ s, a • t = s • t`. Keep one; the left_image name fits the family. Either way move @[simp] and deprecate the other.","fix":"Deprecate `Set.iUnion_smul_set` in favour of `Set.iUnion_smul_left_image`.","ev":"dupscan/Check.lean: `example := (@Set.iUnion_smul_set : type_of% @Set.iUnion_smul_left_image)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 15, rating MAJOR): Both produce exactly the same simp normal form. Moving `[simp]` to the retained theorem and its additive counterpart preserves the relevant automation.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the two declarations differ in which arguments are explicit, which Mathlib sometimes keeps deliberately for rewriting.","at":"2026-10-07","commit":""},{"id":"RT-20261007-0fe1a8","file":"Mathlib/Algebra/Group/Pointwise/Set/Lattice.lean","decl":"Set.iUnion_vadd_set","line":254,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Set.iUnion_vadd_set` (Algebra.Group.Pointwise.Set.Lattice), `Set.iUnion_vadd_left_image` (Algebra.Group.Pointwise.Set.Lattice) state exactly the same thing (Lean-checked). Reviewer: to_additive images of the iUnion_smul_set / iUnion_smul_left_image pair (same section, same proof). Fixed together with that group.","fix":"Deprecate `Set.iUnion_vadd_set` in favour of `Set.iUnion_vadd_left_image`.","ev":"dupscan/Check.lean: `example := (@Set.iUnion_vadd_left_image : type_of% @Set.iUnion_vadd_set)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 17, rating MAJOR): There is no separate additive normal form or translation requirement; retaining one theorem with the existing simp behavior suffices.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the two declarations differ in which arguments are explicit, which Mathlib sometimes keeps deliberately for rewriting.","at":"2026-10-07","commit":""},{"id":"RT-20261007-798b56","file":"Mathlib/Algebra/Group/Semigroup.lean","decl":"IsLeftRegular.all","line":76,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `IsLeftCancelMul.mul_left_cancel` (Algebra.Group.Semigroup), `IsLeftRegular.all` (Algebra.Group.Semigroup) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: The class field is now `protected mul_left_cancel (a : G) : IsLeftRegular a`. IsLeftRegular.all is the intended user-facing name (used as `.all g` in IsRegular.all) but is re-proved via isLeftCancelMul_iff instead of being an alias of the field.","fix":"Declare `IsLeftRegular.all` as an `alias` of `IsLeftCancelMul.mul_left_cancel`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-58d899","file":"Mathlib/Algebra/Group/Semigroup.lean","decl":"IsAddLeftRegular.all","line":76,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `IsAddLeftRegular.all` (Algebra.Group.Semigroup), `IsLeftCancelAdd.add_left_cancel` (Algebra.Group.Semigroup) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: `IsLeftRegular.all`/`IsAddLeftRegular.all` is an intended `.all` name for the class field `IsLeftCancelMul.mul_left_cancel`/`IsLeftCancelAdd.add_left_cancel`, with identical binders, but it is re-proved via `(isLeftCancelMul_iff R).mp ‹_› _`. It can be `@[to_additive] alias IsLeftRegular.all := IsLeftCancelMul.mul_left_cancel`.","fix":"Declare `IsAddLeftRegular.all` as an `alias` of `IsLeftCancelAdd.add_left_cancel`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-b1b742","file":"Mathlib/Algebra/Group/Semigroup.lean","decl":"IsAddRightRegular.all","line":76,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `IsRightCancelAdd.add_right_cancel` (Algebra.Group.Semigroup), `IsAddRightRegular.all` (Algebra.Group.Semigroup) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: Same pattern as the left version: `IsRightRegular.all`/`IsAddRightRegular.all` is the intended `.all` name for the class field `IsRightCancelMul.mul_right_cancel`, with identical binders, but is re-proved via `isRightCancelMul_iff`. It can be `@[to_additive] alias IsRightRegular.all := IsRightCancelMul.mul_right_cancel`.","fix":"Declare `IsAddRightRegular.all` as an `alias` of `IsRightCancelAdd.add_right_cancel`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-e4ac07","file":"Mathlib/Algebra/Group/Semigroup.lean","decl":"mul_left_cancel_iff","line":99,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `mul_left_cancel_iff` (Algebra.Group.Semigroup), `mul_right_inj` (Algebra.Group.Semigroup) state exactly the same thing (Lean-checked). Reviewer: Adjacent: mul_left_cancel_iff ({a} implicit) and @[simp] mul_right_inj (a explicit) both state `a * b = a * c ↔ b = c`. This is a long-standing pair (Lean 3 core name vs mathlib name). mul_right_inj has about 190 uses and mul_left_cancel_iff about 30, so deprecating the latter is real but sizeable churn (also add_*).","fix":"Deprecate `mul_left_cancel_iff` in favour of `mul_right_inj`.","ev":"dupscan/Check.lean: `example := (@mul_right_inj : type_of% @mul_left_cancel_iff)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup0 item 14, rating MINOR): The implicit theorem supports `mul_left_cancel_iff.mp h` without supplying the cancelled factor, while `mul_right_inj` exposes that factor explicitly. These established cancellation and injectivity interfaces justify retaining both names. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Algebra/Group/Semigroup.lean#L94)","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-7f6ab3","file":"Mathlib/Algebra/Group/Semigroup.lean","decl":"add_left_cancel_iff","line":106,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `add_right_inj` (Algebra.Group.Semigroup), `add_left_cancel_iff` (Algebra.Group.Semigroup) state exactly the same thing (Lean-checked). Reviewer: These are to_additive of `mul_right_inj (a)` and `mul_left_cancel_iff`, which sit 7 lines apart, state the same `a * b = a * c ↔ b = c`, are proved separately, and differ only in whether `a` is explicit. This is a long-standing pair. Keep `_inj` (about 290 uses, part of the _injective family). Deprecating `_cancel_iff` (about 50 uses) is low priority.","fix":"Deprecate `add_left_cancel_iff` in favour of `add_right_inj`.","ev":"dupscan/Check.lean: `example := (@add_left_cancel_iff : type_of% @add_right_inj)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup0 item 28, rating MINOR): The implicit `add_left_cancel_iff` supports inference from an equality hypothesis and belongs to the established cancellation family. The explicit `add_right_inj a` remains useful alongside it. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Algebra/Group/Semigroup.lean#L94)","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-29b20b","file":"Mathlib/Algebra/Group/Semigroup.lean","decl":"mul_right_cancel_iff","line":124,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `mul_left_inj` (Algebra.Group.Semigroup), `mul_right_cancel_iff` (Algebra.Group.Semigroup) state exactly the same thing (Lean-checked). Reviewer: Same file and section (IsRightCancelMul): `b * a = c * a ↔ b = c` appears as @[simp] mul_left_inj (explicit a) and as mul_right_cancel_iff (implicit a), both with to_additive. This is a long-standing Lean 3 core/Mathlib pair with no comment. Keep mul_left_inj (simp, far more uses) and deprecate mul_right_cancel_iff. The deprecation is high-churn (add_right_cancel_iff has about 30 uses).","fix":"Deprecate `mul_right_cancel_iff` in favour of `mul_left_inj`.","ev":"dupscan/Check.lean: `example := (@mul_right_cancel_iff : type_of% @mul_left_inj)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup0 item 20, rating MINOR): `mul_right_cancel_iff.mp h` is an established interface with all elements inferred, whereas `mul_left_inj` requires the common right factor explicitly. Removing it sacrifices useful calling syntax for little benefit. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Algebra/Group/Semigroup.lean#L119)","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-65884d","file":"Mathlib/Algebra/Group/Semigroup.lean","decl":"add_right_cancel_iff","line":131,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `add_left_inj` (Algebra.Group.Semigroup), `add_right_cancel_iff` (Algebra.Group.Semigroup) state exactly the same thing (Lean-checked). Reviewer: Additive images of `mul_left_inj` (@[simp], `a` explicit) and `mul_right_cancel_iff` (all implicit), adjacent in one file, both `b + a = c + a ↔ b = c`, proved separately, no comment; the only difference is the explicitness of `a`. Keep `add_left_inj`/`mul_left_inj` (simp, ~100 uses each), deprecate `add_right_cancel_iff`/`mul_right_cancel_iff` (~32/12 uses). These are core-era names, so expect review discussion.","fix":"Deprecate `add_right_cancel_iff` in favour of `add_left_inj`.","ev":"dupscan/Check.lean: `example := (@add_right_cancel_iff : type_of% @add_left_inj)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup0 item 22, rating MINOR): The implicit cancellation form supports direct `.mp`/`.mpr` use and matches `add_right_cancel`; the explicit `_inj` form serves another convenient calling convention. This established pair is worth retaining. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Algebra/Group/Semigroup.lean#L119)","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-be3b55","file":"Mathlib/Algebra/Group/Subgroup/Ker.lean","decl":"AddSubgroup.ker_le_comap","line":287,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `AddMonoidHom.ker_le_comap` (Algebra.Group.Subgroup.Ker), `AddSubgroup.ker_le_comap` (Algebra.Group.Subgroup.Ker) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: to_additive pair of MonoidHom.ker_le_comap (f) (H) and Subgroup.ker_le_comap (f) (H), same argument order, same file. They are namespace twins enabling `f.ker_le_comap H` and `H.ker_le_comap f`, both forms used (Sylow.lean:163, Subgroup/Order.lean:71). Fix: alias.","fix":"Declare `AddSubgroup.ker_le_comap` as an `alias` of `AddMonoidHom.ker_le_comap`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-d82f86","file":"Mathlib/Algebra/Group/Subgroup/Ker.lean","decl":"Subgroup.ker_le_comap","line":287,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `MonoidHom.ker_le_comap` (Algebra.Group.Subgroup.Ker), `Subgroup.ker_le_comap` (Algebra.Group.Subgroup.Ker) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: MonoidHom.ker_le_comap (f) (H) and Subgroup.ker_le_comap (f) (H) are namespace twins in the same file for `f.ker_le_comap H` and `H.ker_le_comap f`, and both dot forms are used. The Subgroup one should be an alias, not a second proof.","fix":"Declare `Subgroup.ker_le_comap` as an `alias` of `MonoidHom.ker_le_comap`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-ef8136","file":"Mathlib/Algebra/Group/Subgroup/Map.lean","decl":"Subgroup.map_inf_eq","line":247,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Subgroup.map_inf` (Algebra.Group.Subgroup.Map), `Subgroup.map_inf_eq` (Algebra.Group.Subgroup.Map) state exactly the same thing (Lean-checked). Reviewer: Same file, same statement for injective f, proved separately (coe_injective plus image_inter versus a simp proof). Keep `map_inf`: it matches Submonoid, Subring, Subalgebra and the other map_inf lemmas, and it is used at l.259. Deprecate `map_inf_eq`, which is unused.","fix":"Deprecate `Subgroup.map_inf_eq` in favour of `Subgroup.map_inf`.","ev":"dupscan/Check.lean: `example := (@Subgroup.map_inf_eq : type_of% @Subgroup.map_inf)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 26, rating MAJOR): The arguments, orientation, and translation attributes match; both also permit the same subgroup receiver syntax. `map_inf_eq` provides no separate interface.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-ec1fb6","file":"Mathlib/Algebra/Group/Submonoid/Operations.lean","decl":"Submonoid.map_comap_eq_self_of_surjective","line":1196,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Submonoid.map_comap_eq_self_of_surjective` (Algebra.Group.Submonoid.Operations), `Submonoid.map_comap_eq_of_surjective` (Algebra.Group.Submonoid.Operations) state exactly the same thing (Lean-checked). Reviewer: Same file: `map f (comap f S) = S` for surjective f is proved via giMapComap at line 393 and again via map_comap_eq_self at the end of the file (line 1196). Submonoid is the only substructure with both names. Keep the earlier `_of_surjective` (Subsemigroup/Submodule naming; used in Etale/Kaehler and RingHom/Surjective) and deprecate map_comap_eq_self_of_surjective.","fix":"Deprecate `Submonoid.map_comap_eq_self_of_surjective` in favour of `Submonoid.map_comap_eq_of_surjective`.","ev":"dupscan/Check.lean: `example := (@Submonoid.map_comap_eq_of_surjective : type_of% @Submonoid.map_comap_eq_self_of_surjective)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 19, rating MAJOR): The `_self_` copy adds only an implicit submonoid argument; the retained theorem already provides the result, additive translation, and an explicit submonoid receiver.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the two declarations differ in which arguments are explicit, which Mathlib sometimes keeps deliberately for rewriting.","at":"2026-10-07","commit":""},{"id":"RT-20261007-99a74e","file":"Mathlib/Algebra/Group/Submonoid/Operations.lean","decl":"AddSubmonoid.map_comap_eq_self_of_surjective","line":1196,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `AddSubmonoid.map_comap_eq_self_of_surjective` (Algebra.Group.Submonoid.Operations), `AddSubmonoid.map_comap_eq_of_surjective` (Algebra.Group.Submonoid.Operations) state exactly the same thing (Lean-checked). Reviewer: Additive images of `Submonoid.map_comap_eq_of_surjective` (393, from `giMapComap`) and `Submonoid.map_comap_eq_self_of_surjective` (1196): same file, both @[to_additive], same statement, different proofs and binders. Keep `map_comap_eq_of_surjective` (shared with Subsemigroup/Submodule, earlier in the file), deprecate the `_self_` copy. Mathlib uses both names across structures (Subgroup/Subring use `_self_`).","fix":"Deprecate `AddSubmonoid.map_comap_eq_self_of_surjective` in favour of `AddSubmonoid.map_comap_eq_of_surjective`.","ev":"dupscan/Check.lean: `example := (@AddSubmonoid.map_comap_eq_of_surjective : type_of% @AddSubmonoid.map_comap_eq_self_of_surjective)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 25, rating MAJOR): Cross-structure naming offers some justification for `_self_`, but neither attributes nor additive translation require both declarations in this namespace.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the two declarations differ in which arguments are explicit, which Mathlib sometimes keeps deliberately for rewriting.","at":"2026-10-07","commit":""},{"id":"RT-20261006-97bb0a","file":"Mathlib/Algebra/Group/TypeTags/Hom.lean","decl":"AddMonoidHom.toMultiplicative","line":25,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-comp-lemma","claim":"The transports have `_id` simp lemmas but no composition or zero/one lemmas: `(g.comp f).toMultiplicative = g.toMultiplicative.comp f.toMultiplicative` and `(0 : M →+ N).toMultiplicative = 1` both hold by `rfl`, but `simp` makes no progress on either (likewise for `MonoidHom.toAdditive` and the Left/Right variants). Because the transports are plain `Equiv`s, `map_add`/`map_zero` do not apply.","fix":"Add `@[simp] toMultiplicative_comp`, `toMultiplicative_zero`, `MonoidHom.toAdditive_comp`, `toAdditive_one` (all `rfl`), and Left/Right analogues.","ev":"probe2.lean L6 (comp, `by simp`) and L12 (zero, `by simp`) → `simp` made no progress; L9 `rfl` compiles.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-f80b65","file":"Mathlib/Algebra/Group/TypeTags/Hom.lean","decl":"AddMonoidHom.toMultiplicative_add","line":146,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-dual-lemma","claim":"`AddMonoidHom.toMultiplicative_add` has no counterpart for the other three transfers: there is no `MonoidHom.toAdditive_mul`, nor `_add`/`_mul` lemmas for `toMultiplicativeLeft/Right`, `toAdditiveLeft/Right`. `(f * g).toAdditive = f.toAdditive + g.toAdditive` holds by `rfl`, but `simp` makes no progress on it.","fix":"Add `@[simp] MonoidHom.toAdditive_mul` (and the Left/Right analogues) next to `toMultiplicative_add`.","ev":"probe1.lean L31 `(f * g).toAdditive = f.toAdditive + g.toAdditive := by simp` → `simp` made no progress; L33 `rfl` compiles.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-864ae6","file":"Mathlib/Algebra/Group/TypeTags/Hom.lean","decl":"AddMonoidHom.toMultiplicativeLeftAddEquiv","line":152,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"Five declarations assume `[AddMonoid M]`/`[Monoid M]` where `[AddZeroClass M]`/`[MulOneClass M]` suffices: `AddMonoidHom.toMultiplicative_add`, `toMultiplicativeLeftAddEquiv`, `toMultiplicativeRightAddEquiv`, `MonoidHom.toAdditiveLeftMulEquiv` and `toAdditiveRightMulEquiv`. The pointwise `+`/`*` on `M →+ N`/`M →* N` only needs the unital-magma class on the domain, and the rest of the file uses exactly that.","fix":"Weaken the domain class in all five to `AddZeroClass`/`MulOneClass`; the `rfl` proofs are unchanged.","ev":"probe1.lean L6–28: all five restated with `[AddZeroClass M]`/`[MulOneClass M]` and the original `rfl` proofs compile with no messages.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-3ab648","file":"Mathlib/Algebra/Group/TypeTags/Hom.lean","decl":"AddMonoidHom.toMultiplicativeLeftAddEquiv","line":152,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"equiv-without-simps","claim":"The four bundled equivalences (`toMultiplicativeLeftAddEquiv`, `toMultiplicativeRightAddEquiv`, `toAdditiveLeftMulEquiv`, `toAdditiveRightMulEquiv`) are plain `def`s with no `@[simps]` and no apply lemma, so `simp` cannot evaluate them: `toMultiplicativeLeftAddEquiv f = Additive.ofMul f.toMultiplicativeLeft` (true by `rfl`) is not closed by `simp`. Nothing in Mathlib uses any of the four.","fix":"Add `@[simps!]` (or `@[simps! apply symm_apply]`) to the four definitions.","ev":"probe1.lean L37 `… := by simp` → `simp` made no progress. `grep -rnw` for the four names outside the file: no hits.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-6bbdb1","file":"Mathlib/Algebra/GroupWithZero/Units/Basic.lean","decl":"IsUnit.mk0","line":210,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `Ne.isUnit` (Algebra.GroupWithZero.Units.Basic), `IsUnit.mk0` (Algebra.GroupWithZero.Units.Basic) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: `Ne.isUnit` is the dot-notation alias of isUnit_iff_ne_zero.mpr. `IsUnit.mk0 (x) (hx : x ≠ 0) : IsUnit x` is the constructor-style twin, named after Units.mk0, and is proved again via `(Units.mk0 x hx).isUnit`. Both are intended, and IsUnit.mk0 could be `hx.isUnit`. A plain alias does not work because the binders differ in explicitness.","fix":"Declare `IsUnit.mk0` as an `alias` of `Ne.isUnit`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-296498","file":"Mathlib/Algebra/Homology/HomotopyCategory/Acyclic.lean","decl":"(file)","line":18,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-docstring","claim":"The module docstring names the main lemma as `HomotopyCategory.quasiIso_eq_subcategoryAcyclic_W`, which is now a deprecated alias (since 2026-05-06) of `quasiIso_eq_trW_subcategoryAcyclic`; the docstring was not updated with the rename. The title also reads 'acyclic complex' for 'acyclic complexes'.","fix":"Cite `HomotopyCategory.quasiIso_eq_trW_subcategoryAcyclic` (and say 'the class `(subcategoryAcyclic C).trW`'), and fix the title's plural.","ev":"src L18 `In the lemma `HomotopyCategory.quasiIso_eq_subcategoryAcyclic_W` we obtain` vs L72 `@[deprecated (since := \"2026-05-06\")] alias quasiIso_eq_subcategoryAcyclic_W := quasiIso_eq_trW_subcategoryAcyclic`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4f42d9","file":"Mathlib/Algebra/Homology/HomotopyCategory/Acyclic.lean","decl":"HomotopyCategory.subcategoryAcyclic","line":37,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`subcategoryAcyclic` and its elementary API (`mem_subcategoryAcyclic_iff`, the two `quotient_obj_mem_*` lemmas, the `IsClosedUnderIsomorphisms` instance) are stated under `[Abelian C]`, but the definition body `(homologyFunctor C (.up ℤ) 0).homologicalKernel`, the membership iff and closure under isomorphisms all elaborate with only `[Preadditive C] [CategoryWithHomology C]`. Only the triangulated instance and the `trW` comparison use abelianness.","fix":"Put the definition and membership API in a section with `[Preadditive C] [CategoryWithHomology C]`; keep `[Abelian C]` for `IsTriangulated` and `quasiIso_eq_trW_subcategoryAcyclic`.","ev":"-- hunts/homotopy-acyclic/P2.lean: with `variable (D) [Category D] [Preadditive D] [CategoryWithHomology D]`, `def weakAcyclic := (HomotopyCategory.homologyFunctor D (.up ℤ) 0).homologicalKernel`, its `mem_homologicalKernel_iff` characterization and `IsClosedUnderIsomorphisms` (by `dsimp; infer_instance`) compile.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-599cb8","file":"Mathlib/Algebra/Homology/HomotopyCategory/Acyclic.lean","decl":"HomotopyCategory.(instance at L75)","line":75,"sev":"MINOR","status":"suspected","cat":"generality","pattern":"too-strong-typeclass","claim":"The instance `(quasiIso C (.up ℤ)).IsCompatibleWithShift ℤ` is proved through `trW` and so needs `[Abelian C]`, but it should hold under `[Preadditive C] [CategoryWithHomology C]` via the homology shift sequence `H^i(f⟦n⟧) ≅ H^{n+i}(f)` (complex-level analogue: `CochainComplex.quasiIso_shift_iff`). Not proved in Lean here.","fix":"Prove it from `(homologyFunctor C (.up ℤ) 0).shiftIso` and `NatIso.isIso_map_iff` under the weaker classes.","ev":"Astra A1 sketch; the current proof is `rw [quasiIso_eq_trW_subcategoryAcyclic]; infer_instance`, which needs the abelian triangulated structure.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2fc55d","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain","line":69,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"ring-where-semiring-suffices","claim":"The file-level `[Ring R] [Linear R C]` (L45), under which `deriving instance SMul R, AddCommGroup, Module R` (L74) and `smul_v`/`units_smul_v` are stated, is stronger than needed: `CategoryTheory.Linear` only needs `[Semiring R]`, and the whole file compiles with `[Semiring R]` except `linearHomComplex`, `Cocycle.isKernel'` and `Cocycle.isKernel'_lift_apply_coe_eq_δ` (`ModuleCat` needs a ring). This excludes R = ℕ, although `Linear.preadditiveNatLinear : Linear ℕ C` exists: on master `Cochain.smul_v (R := ℕ)` fails with `failed to synthesize Ring ℕ`, and `simp` cannot rewrite `((k : ℕ) • z).v p q hpq`. With `[Semiring R]`, `simp` proves it, and the new derived `SMul ℕ`/`Module ℕ` agree with `NSMul.toSMul`/`AddCommMonoid.toNatModule` under `with_reducible_and_instances rfl`, so no nsmul diamond appears. The same over-strong `[Ring R]` was reported for `ofHom_smul`, `smul_comp`/`comp_smul`, `δ_hom`/`δ_smul`, and the `Cocycle` `Module` instance; a single `[Semiring R]` copy (only the `ModuleCat` part keeps `Ring`) compiles.","fix":"Weaken the section variable to `{R : Type*} [Semiring R] [Linear R C]` and require `[Ring R]` only for the three `ModuleCat` declarations at the end of the file.","ev":"hunts/homcomplex/batch0/P1.lean section E (master: `fail_if_success simp`; `fail_if_success exact Cochain.smul_v (R := ℕ) k z p q hpq`; `#synth Linear ℕ C` = `Linear.preadditiveNatLinear`) and hunts/homcomplex/batch0/SemiringR.lean (src copy with L45 `[Semiring R]`, a separate `[Ring S] [Linear S C]` for the ModuleCat decls; the file compiles with no errors or warnings, and probes P1–P3 there show `simp` proving `(k • z).v p q hpq = k • z.v p q hpq` for `k : ℕ`, plus the nsmul/zsmul instance agreement)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-5d65b4","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.ofHoms","line":131,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-map-add-api","claim":"`ofHoms` is additive (and `R`-linear) in the family but its only algebraic lemma is `ofHoms_zero`. `simp` makes no progress on `ofHoms (ψ + ψ') = ofHoms ψ + ofHoms ψ'`, on the pointwise form `ofHoms (fun p => ψ p + ψ' p)`, or on `ofHoms (-ψ) = -ofHoms ψ`. Its specialisation `ofHom` has `ofHom_add/sub/neg/smul`, and those are proved separately by `cat_disch` instead of from `ofHoms` lemmas. No current consumer needs these lemmas.","fix":"Add `@[simp] ofHoms_add/sub/neg/smul` (each `by cat_disch`), or bundle `ofHoms` as a linear map, and derive the `ofHom_*` lemmas from them.","ev":"hunts/homcomplex/batch0/P1.lean section L: `example (ψ ψ' : ∀ p, F.X p ⟶ G.X p) : Cochain.ofHoms (ψ + ψ') = Cochain.ofHoms ψ + Cochain.ofHoms ψ' := by fail_if_success simp; cat_disch` (likewise for the pointwise sum and for `-ψ`)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-db0e62","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.ofHoms_v_comp_d","line":143,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-reassoc-simp","claim":"`ofHoms_v_comp_d` is `@[simp]` but has no `@[reassoc]`. In simp normal form (right-associated) `(ofHoms ψ).v p q hpq ≫ G.d q q' ≫ h` never contains its left-hand side, so `simp` makes no progress on the reassociated statement. The file uses `@[reassoc]` on similar lemmas (`v_comp_XIsoOfEq_hom/inv`). The sibling `ofHom_v_comp_d` (batch 1) has the same gap.","fix":"Tag it `@[reassoc (attr := simp)]`.","ev":"hunts/homcomplex/batch0/P1.lean section H: `example (ψ : ∀ p, F.X p ⟶ G.X p) (p q q' : ℤ) (hpq : p + 0 = q) {Z : C} (h : G.X q' ⟶ Z) : (Cochain.ofHoms ψ).v p q hpq ≫ G.d q q' ≫ h = ψ p ≫ G.d p q' ≫ h := by fail_if_success simp; rw [← assoc, Cochain.ofHoms_v_comp_d, assoc]`; hunts/homcomplex/batch0/SemiringR.lean probe P4: with `@[reassoc (attr := simp)]` plain `simp` closes it","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a7f178","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.d_comp_ofHoms_v","line":150,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-reassoc-simp","claim":"`d_comp_ofHoms_v` is `@[simp]` but has no `@[reassoc]`, so `simp` makes no progress on `F.d p' p ≫ (ofHoms ψ).v p q hpq ≫ h = F.d p' q ≫ ψ q ≫ h`. The sibling `d_comp_ofHom_v` (batch 1) has the same gap.","fix":"Tag it `@[reassoc (attr := simp)]`.","ev":"hunts/homcomplex/batch0/P1.lean section H (second example: `fail_if_success simp; rw [← assoc, Cochain.d_comp_ofHoms_v, assoc]`); hunts/homcomplex/batch0/SemiringR.lean probe P4: with `@[reassoc (attr := simp)]` plain `simp` closes it","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-e93011","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.ofHom_v_comp_d","line":172,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"simp-comp-lemma-missing-reassoc","claim":"This is a `@[simp]` composition lemma `(ofHom φ).v p q hpq ≫ G.d q q' = …` without `@[reassoc]`. Simp keeps `≫` right-associated, so the lemma never fires inside a longer chain `(ofHom φ).v p q hpq ≫ G.d q q' ≫ x`. The convention, e.g. `HomologicalComplex.d_comp_XIsoOfEq_hom`, is `@[reassoc (attr := simp)]`.","fix":"Change `@[simp]` to `@[reassoc (attr := simp)]` (likewise `ofHoms_v_comp_d`).","ev":"hunts/homcomplex/batch1/probe1.lean §P3a: `example {Y : C} (φ : F ⟶ G) (p q q' : ℤ) (hpq : p + 0 = q) (x : G.X q' ⟶ Y) : (Cochain.ofHom φ).v p q hpq ≫ G.d q q' ≫ x = φ.f p ≫ G.d p q' ≫ x := by fail_if_success (simp; done); rw [← assoc, Cochain.ofHom_v_comp_d, assoc]` (simp fails). §P3c control: the two-term form closes by `simp`. In hunts/homcomplex/batch1/HomComplexB1.lean with `@[reassoc (attr := simp)]`, §P3a closes by `simp` and simpNF passes.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4a6476","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.d_comp_ofHom_v","line":177,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"simp-comp-lemma-missing-reassoc","claim":"This is a `@[simp]` composition lemma `F.d p' p ≫ (ofHom φ).v p q hpq = …` without `@[reassoc]`, so it never fires on the simp-normal right-associated chain `F.d p' p ≫ (ofHom φ).v p q hpq ≫ x`.","fix":"Change `@[simp]` to `@[reassoc (attr := simp)]` (likewise `d_comp_ofHoms_v`).","ev":"hunts/homcomplex/batch1/probe1.lean §P3b: `example {Y : C} (φ : F ⟶ G) (p' p q : ℤ) (hpq : p + 0 = q) (x : G.X q ⟶ Y) : F.d p' p ≫ (Cochain.ofHom φ).v p q hpq ≫ x = F.d p' q ≫ φ.f q ≫ x := by fail_if_success (simp; done); rw [← assoc, Cochain.d_comp_ofHom_v, assoc]`. In hunts/homcomplex/batch1/HomComplexB1.lean with `@[reassoc (attr := simp)]`, the same goal closes by `simp` and simpNF passes.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-12aef8","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.ofHom_add","line":182,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"unbundled-linear-map","claim":"`Cochain.ofHom` is R-linear but never bundled: `ofHom_zero/add/sub/neg/smul` are five hand-proved `map_*` instances (each `by cat_disch`), and nothing covers finite sums, so simp cannot prove `ofHom (∑ i ∈ s, φ i) = ∑ i ∈ s, ofHom (φ i)`. The bundled map can already be built from existing API: `Cocycle.toCochainAddMonoidHom ∘ Cocycle.equivHom`, after which `map_sum` gives the sum lemma in one line.","fix":"Add `@[simps] def Cochain.ofHomLinearMap : (F ⟶ G) →ₗ[R] Cochain F G 0` and derive `ofHom_zero/add/sub/neg/smul` and a new `ofHom_sum` from `map_*`.","ev":"hunts/homcomplex/batch1/probe1.lean §P2c: `example {ι : Type*} (s : Finset ι) (φ : ι → (F ⟶ G)) : Cochain.ofHom (∑ i ∈ s, φ i) = ∑ i ∈ s, Cochain.ofHom (φ i) := by fail_if_success (simp; done); induction s using Finset.cons_induction <;> simp [*]` (simp fails, induction closes it). §P2d: the same goal by `exact map_sum ((Cocycle.toCochainAddMonoidHom F G 0).comp (Cocycle.equivHom F G).toAddMonoidHom) φ s` (compiles). hunts/homcomplex/batch1/HomComplexB1.lean: `def ofHomLinearMap : (F ⟶ G) →ₗ[R] Cochain F G 0 where toFun := ofHom; map_add' := ofHom_add; map_smul' := ofHom_smul`, then `ofHom_sum` is `map_sum (ofHomLinearMap ℤ F G) φ s` (compiles).","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-9c427c","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.ofHomotopy","line":199,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-value-simp-lemma","claim":"`Cochain.ofHomotopy` has no value lemma, so simp cannot evaluate `(ofHomotopy ho).v p q hpq` even though it is `rfl`. Its own consumers unfold the definition instead: `δ_ofHomotopy` uses `rw [Cochain.ofHomotopy, …]` and `equivHomotopy.right_inv` uses `dsimp [Cochain.ofHomotopy]`. There are also no compatibility lemmas with `Homotopy.symm`/`Homotopy.trans`, both of which are `rfl`.","fix":"Add `@[simp] lemma ofHomotopy_v (ho) (p q hpq) : (ofHomotopy ho).v p q hpq = ho.hom p q := rfl` (plus `ofHomotopy_symm`/`ofHomotopy_trans`, both `rfl`) and use it in `δ_ofHomotopy` and `equivHomotopy`.","ev":"hunts/homcomplex/batch1/probe1.lean §P1a: `example {φ₁ φ₂ : F ⟶ G} (ho : Homotopy φ₁ φ₂) (p q : ℤ) (hpq : p + (-1) = q) : (Cochain.ofHomotopy ho).v p q hpq = ho.hom p q := by fail_if_success (simp; done); rfl`. §P1b/§P1c: `ofHomotopy ho.symm = -ofHomotopy ho` and `ofHomotopy (ho.trans ho') = ofHomotopy ho + ofHomotopy ho'`, where simp fails and `ext; rfl` closes both. hunts/homcomplex/batch1/HomComplexB1.lean adds the three lemmas as `@[simp] … := rfl`. `#lint only simpNF` reports 0 errors in 174 declarations, and plain `simp` then closes §P1a.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-72aaf1","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.v_comp_XIsoOfEq_hom","line":211,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"xisoofeq-lemma-not-simp","claim":"Only `@[reassoc]`, not simp, whereas all its siblings in `HomologicalComplex.lean` (`d_comp_XIsoOfEq_hom`, `XIsoOfEq_hom_comp_d`, …) are `@[reassoc (attr := simp)]`. So simp cannot absorb `(G.XIsoOfEq h).hom` after a cochain component. The lemma and its `_assoc` form are used nowhere in Mathlib, and there is no precomposition analogue `(F.XIsoOfEq h).hom ≫ γ.v p' q hpq = γ.v p q _`.","fix":"Make it `@[reassoc (attr := simp)]` and add `XIsoOfEq_hom_comp_v`/`XIsoOfEq_inv_comp_v` (each `subst hp; simp`).","ev":"hunts/homcomplex/batch1/probe1.lean §P4a: `example (n : ℤ) (γ : Cochain F G n) (p q q' : ℤ) (hpq : p + n = q) (hq' : q = q') : γ.v p q hpq ≫ (G.XIsoOfEq hq').hom = γ.v p q' (by rw [← hq', hpq]) := by fail_if_success (simp; done); simp [Cochain.v_comp_XIsoOfEq_hom]`. §P4c: the precomposition goal, where simp fails and `subst hp; simp` closes it. §P4d control: `G.d p q ≫ (G.XIsoOfEq hq').hom = G.d p q' := by simp`. In hunts/homcomplex/batch1/HomComplexB1.lean with `@[reassoc (attr := simp)]` plus the two precomposition lemmas, `#lint only simpNF` passes (0 errors in 174 declarations) and plain `simp` closes §P4a and §P4c. `git grep -n v_comp_XIsoOfEq origin/master -- Mathlib` matches only HomComplex.lean:211 and :218.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2ac11f","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.v_comp_XIsoOfEq_inv","line":218,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"xisoofeq-lemma-not-simp","claim":"Same as `v_comp_XIsoOfEq_hom`: only `@[reassoc]`, not simp, unlike `HomologicalComplex.d_comp_XIsoOfEq_inv` and its siblings, and used nowhere in Mathlib.","fix":"Make it `@[reassoc (attr := simp)]`.","ev":"hunts/homcomplex/batch1/probe1.lean §P4b: `example (n : ℤ) (γ : Cochain F G n) (p q q' : ℤ) (hpq : p + n = q) (hq' : q' = q) : γ.v p q hpq ≫ (G.XIsoOfEq hq').inv = γ.v p q' (by rw [hq', hpq]) := by fail_if_success (simp; done); simp [Cochain.v_comp_XIsoOfEq_inv]`. simpNF passes with the attribute in hunts/homcomplex/batch1/HomComplexB1.lean.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7c46e1","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.comp_assoc_of_second_is_zero_cochain","line":284,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"rigid-degree-proof-in-simp-lhs","claim":"The simp LHS hard-codes the inner proof `add_zero n₁`, so the inner composite must have degree literally `n₁`. The lemma therefore does not fire on `(z₁.comp z₂ h₁₂).comp z₃ h` with `h₁₂ : n₁ + 0 = m` for a variable `m`. The same one-line proof `comp_assoc _ _ _ _ _ (by lia)` proves the version with an arbitrary `h₁₂ : n₁ + 0 = n₁₂`. That version specialises to the original by `exact` and closes the goal above by `simp only`.","fix":"Take `(h₁₂ : n₁ + 0 = n₁₂) (h₁₃ : n₁₂ + n₃ = n₁₃)` as hypotheses instead of hard-coding `add_zero n₁`; the proof is unchanged.","ev":"hunts/homcomplex/batch2/P1.lean section (A). A1 (L14-17): `example {n₁ n₃ m n : ℤ} (z₁ : Cochain F G n₁) (z₂ : Cochain G K 0) (z₃ : Cochain K L n₃) (h₁₂ : n₁ + 0 = m) (h : m + n₃ = n) : (z₁.comp z₂ h₁₂).comp z₃ h = z₁.comp (z₂.comp z₃ (zero_add n₃)) (by lia) := by simp only [comp_assoc_of_second_is_zero_cochain]` gives error '`simp` made no progress'. A2 (`comp_assoc_of_second_is_zero_cochain'`, the generalised statement, proved by `comp_assoc _ _ _ _ _ (by lia)`), A3 (it specialises to the original) and A4 (`simp only [comp_assoc_of_second_is_zero_cochain']` closes A1) all compile.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6dc5a2","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.comp_assoc_of_third_is_zero_cochain","line":290,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"rigid-degree-proof-in-simp-lhs","claim":"The simp LHS hard-codes the outer proof `add_zero n₁₂`, so the outer composite must have degree literally `n₁₂`. The lemma therefore does not fire on `(z₁.comp z₂ h₁₂).comp z₃ h` with `h : n₁₂ + 0 = n` for a variable `n`. The version with an arbitrary `h : n₁₂ + 0 = n` has the same one-line proof, specialises to the original and closes that goal by `simp only`.","fix":"Take `(h : n₁₂ + 0 = n)` as a hypothesis instead of hard-coding `add_zero n₁₂`, and give the RHS outer composition degree `n` with proof `by lia`.","ev":"hunts/homcomplex/batch2/P1.lean section (B). B1 (L40-43): `example {n₁ n₂ n₁₂ n : ℤ} (z₁ : Cochain F G n₁) (z₂ : Cochain G K n₂) (z₃ : Cochain K L 0) (h₁₂ : n₁ + n₂ = n₁₂) (h : n₁₂ + 0 = n) : (z₁.comp z₂ h₁₂).comp z₃ h = z₁.comp (z₂.comp z₃ (add_zero n₂)) (by lia) := by simp only [comp_assoc_of_third_is_zero_cochain]` gives error '`simp` made no progress'. The generalised `comp_assoc_of_third_is_zero_cochain'` (proved by `comp_assoc _ _ _ _ _ (by lia)`), its specialisation to the original, and `simp only [comp_assoc_of_third_is_zero_cochain']` on B1 all compile.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-608cb6","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.comp_assoc_of_second_degree_eq_neg_third_degree","line":296,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"rigid-degree-proof-in-simp-lhs","claim":"The degrees are fixed in the shape `(-n₂, n₂)`. As a simp lemma it fires on `(-1, 1)` (control C0), and on the literal `(1, -1)` because `-(-1)` reduces to `1` (C1). It makes no progress on the symbolic case `z₂ : Cochain G K n`, `z₃ : Cochain K L (-n)` (C2), although the name ('second degree = neg third degree') covers that case. The version with arbitrary `n₂ n₃`, a hypothesis `h₂₃ : n₂ + n₃ = 0` (which simp discharges) and a free outer degree has the same one-line proof. It specialises to the original and closes C0, C1 and C2.","fix":"Generalise to `z₂ : Cochain G K n₂`, `z₃ : Cochain K L n₃`, `(h₂₃ : n₂ + n₃ = 0)`, or add the `(n₂, -n₂)` companion lemma.","ev":"hunts/homcomplex/batch2/P1.lean section (C). C2 (L76-79): `example {n₁ n n₁₂ : ℤ} (z₁ : Cochain F G n₁) (z₂ : Cochain G K n) (z₃ : Cochain K L (-n)) (h₁₂ : n₁ + n = n₁₂) (h : n₁₂ + (-n) = n₁) : (z₁.comp z₂ h₁₂).comp z₃ h = z₁.comp (z₂.comp z₃ (add_neg_cancel n)) (add_zero n₁) := by simp only [comp_assoc_of_second_degree_eq_neg_third_degree]` gives error '`simp` made no progress'. C0 and C1 succeed. `theorem comp_assoc_of_add_eq_zero ... (h₂₃ : n₂ + n₃ = 0) (h₁₂ : n₁ + n₂ = n₁₂) (h : n₁₂ + n₃ = n) : (z₁.comp z₂ h₁₂).comp z₃ h = z₁.comp (z₂.comp z₃ h₂₃) (by lia) := comp_assoc _ _ _ _ _ (by lia)` compiles. So do its specialisation to the original and `simp only [comp_assoc_of_add_eq_zero, add_neg_cancel]` (or `neg_add_cancel`) on C0, C1 and C2.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-f12389","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.add_comp","line":310,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-sum-distributivity","claim":"`Cochain.comp` is bilinear, and the file proves each linearity law by hand (`zero_comp` ... `comp_units_smul`). There is no `sum_comp`/`comp_sum` and no bundled bilinear `comp`, so `simp` cannot distribute `comp` over a `Finset` sum on either side; the identity needs an induction. The analogues exist for morphisms (`Preadditive.sum_comp : (∑ j ∈ s, f j) ≫ g = ∑ j ∈ s, f j ≫ g`, `Preadditive.comp_sum`) and for Ext (`Ext.sum_comp : (∑ i, α i).comp β h = ∑ i, (α i).comp β h`, `Ext.comp_sum`).","fix":"Add `@[simp]` `Cochain.sum_comp`/`Cochain.comp_sum`, or bundle `comp` as a bilinear map and derive the whole `zero_comp`...`comp_sum` family from `map_*` lemmas.","ev":"hunts/homcomplex/batch2/P1.lean section (D). D3 `(∑ i ∈ s, f i).comp z₂ h = ∑ i ∈ s, (f i).comp z₂ h := by simp` (L125-127) and D4 `z₁.comp (∑ i ∈ s, f i) h = ∑ i ∈ s, z₁.comp (f i) h := by simp` (L129-131) both give '`simp` made no progress'. D5 proves D3 by `Finset.induction_on` with `simp [Finset.sum_insert ha, ih]` and compiles. `git grep` over HomotopyCategory finds no `sum_comp`/`comp_sum`/`mk₂` for cochains.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-0f5971","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.diff","line":397,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"def-without-characteristic-api","claim":"`Cochain.diff K` (the differential as a degree-1 cochain) has no API beyond `diff_v`. Its only consumer in Mathlib is `Cocycle.diff` (HomComplex.lean:706-710), which is itself unused. The identity that motivates it, that `δ` is the graded commutator with the differential (`δ n m z = z.comp (diff G) hnm + m.negOnePow • (diff F).comp z _`), is not stated anywhere, though it takes four rewrites.","fix":"Add `δ_eq_comp_diff_add` (proved in the probe), or drop `Cochain.diff`/`Cocycle.diff` if no consumer is planned.","ev":"hunts/homcomplex/batch2/P1.lean section (E): `lemma δ_eq_comp_diff_add {n m : ℤ} (hnm : n + 1 = m) (z : Cochain F G n) : δ n m z = z.comp (diff G) hnm + m.negOnePow • (diff F).comp z (by lia) := by ext p q hpq; rw [δ_v n m hnm z p q hpq (q - 1) (p + 1) rfl rfl, add_v, units_smul_v, comp_v _ _ hnm p (q - 1) q (by lia) (by lia), comp_v _ _ (show 1 + n = m by lia) p (p + 1) q rfl (by lia), diff_v, diff_v]` compiles. `git grep -nw diff origin/master -- Mathlib/Algebra/Homology Mathlib/CategoryTheory/Triangulated Mathlib/CategoryTheory/Shift` finds only HomComplex.lean:397, 400, 706, 707.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-f2a8a1","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.δ_δ","line":474,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`δ_δ : δ n₁ n₂ (δ n₀ n₁ z) = 0` is the defining identity of the complex but is not `@[simp]`; plain `simp` cannot prove `δ (n+1) (n+2) (δ n (n+1) z) = 0`, and every caller passes it by hand (`simp [δ_δ]` at HomComplex.lean:575, :979 and ModelCategory/Lifting.lean:58). Adding `@[simp]` keeps the whole file compiling and `#lint only simpNF simpComm synTaut` passes.","fix":"Tag `δ_δ` with `@[simp]`.","ev":"example (n : ℤ) (z : Cochain F G n) : δ (n + 1) (n + 2) (δ n (n + 1) z) = 0 := by\n  fail_if_success simp\n  simp [δ_δ]\n-- hunts/homcomplex/batch3/Probe1.lean (P1); whole file with @[simp] δ_δ + simpNF lint: hunts/homcomplex/batch3/Copy1lint.lean","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2b2847","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cocycle","line":584,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"type-synonym-coercion-misses-generic-simp-lemmas","claim":"`Cocycle F G n` is a plain (semireducible) `def` for `↥(cocycle F G n)` and its `Coe` instance (L595) is `x.1`, so every coercion is `Subtype.val` applied to a term whose type is only semireducibly a subtype. Mathlib's generic subgroup coercion simp lemmas (`AddMemClass.coe_add`, `AddSubmonoidClass.coe_nsmul`, `AddSubmonoidClass.coe_finsetSum`) therefore never fire (simp reports the term is not type-correct at `implicit` transparency). The file hand-writes `coe_zero/add/neg/sub/smul/units_smul` but not `coe_nsmul` or `coe_sum`, so `simp` cannot push the coercion through `ℕ`-multiples or finite sums of cocycles.","fix":"Add `@[simp]` lemmas `Cocycle.coe_nsmul` and `Cocycle.coe_sum` (e.g. from `map_nsmul`/`map_sum` of `toCochainAddMonoidHom`, which could be moved up next to the `coe_*` lemmas).","ev":"-- hunts/homcomplex/batch4/P2.lean (B3, B4) and P3.lean (H1-H4)\nexample (k : ℕ) (z : Cocycle F G n) :\n    ((k • z : Cocycle F G n) : Cochain F G n) = k • (z : Cochain F G n) := by simp\n-- error: `simp` made no progress (\"Application type mismatch: k • z has type Cocycle F G n but is expected to have type ↥(cocycle F G n)\" at implicit transparency)\nexample (z₁ z₂ : Cocycle F G n) :\n    ((z₁ + z₂ : Cocycle F G n) : Cochain F G n) = (z₁ : Cochain F G n) + z₂ := by simp [-Cocycle.coe_add]\n-- error: `simp` made no progress\nexample {ι : Type*} (s : Finset ι) (z : ι → Cocycle F G n) :\n    ((∑ i ∈ s, z i : Cocycle F G n) : Cochain F G n) = ∑ i ∈ s, (z i : Cochain F G n) := by simp\n-- error: `simp` made no progress\n-- whereas these compile:\nexample {ι : Type*} (s : Finset ι) (z : ι → Cocycle F G n) :\n    ((∑ i ∈ s, z i : Cocycle F G n) : Cochain F G n) = ∑ i ∈ s, (z i : Cochain F G n) :=\n  map_sum (Cocycle.toCochainAddMonoidHom F G n) z s\nexample (k : ℕ) (z : Cocycle F G n) :\n    ((k • z : Cocycle F G n) : Cochain F G n) = k • (z : Cochain F G n) := rfl","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-1215ee","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cocycle.coe_zero","line":614,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"by-rfl-not-dsimp-lemma","claim":"`coe_zero` is proved `by rfl` while its siblings `coe_add`/`coe_neg`/`coe_sub`/`coe_smul` use the term `rfl`. As a result it is not registered as an rfl-lemma: `dsimp only [Cocycle.coe_zero]` (and plain `dsimp` on `(↑(0 : Cocycle F G n)).v p q h`) makes no progress, while `dsimp only [Cocycle.coe_add]` works. The term-mode `rfl` proof compiles.","fix":"Replace `:= by rfl` with `:= rfl`.","ev":"-- hunts/homcomplex/batch4/P5.lean, P6.lean\nexample : (↑(0 : Cocycle F G n) : Cochain F G n) = 0 := by dsimp only [Cocycle.coe_zero]\n-- error: `dsimp` made no progress\nexample (p q : ℤ) (h : p + n = q) : (↑(0 : Cocycle F G n) : Cochain F G n).v p q h = 0 := by dsimp\n-- error: `dsimp` made no progress\ntheorem coe_zero_term : (↑(0 : Cocycle F G n) : Cochain F G n) = 0 := rfl\nexample : (↑(0 : Cocycle F G n) : Cochain F G n) = 0 := by dsimp only [coe_zero_term]   -- compiles\nexample (z₁ z₂ : Cocycle F G n) : ((z₁ + z₂ : Cocycle F G n) : Cochain F G n) = (z₁ : Cochain F G n) + z₂ := by\n  dsimp only [Cocycle.coe_add]   -- compiles\n-- and in HomComplexB.lean (copy of src.lean) `lemma coe_zero_term : (↑(0 : Cocycle F G n) : Cochain F G n) = 0 := rfl` compiles in place","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c9f888","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cocycle.ofHom","line":661,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-additive-simp-api","claim":"`Cocycle.ofHom` has `ofHom_smul` but no `ofHom_add`/`ofHom_neg`/`ofHom_sub`, and `Cocycle.homOf` has no additive lemmas at all, although `Cochain.ofHom_add/sub/neg` exist (L182-190). `simp` cannot prove `ofHom (φ₁ + φ₂) = ofHom φ₁ + ofHom φ₂`, `ofHom (-φ) = -ofHom φ` or `homOf (z₁ + z₂) = homOf z₁ + homOf z₂`. Each is a one-liner (`ext : 1; simp`, or `(Cocycle.equivHom F G).map_add`).","fix":"Add `@[simp]` `Cocycle.ofHom_add/neg/sub` and `Cocycle.homOf_add/neg/sub/zero` (or `homOf_smul`), each proved by `ext; simp` or via `equivHom`.","ev":"-- hunts/homcomplex/batch4/P2.lean (C1, C2, C4, C5, C6, C8)\nexample (φ₁ φ₂ : F ⟶ G) : Cocycle.ofHom (φ₁ + φ₂) = Cocycle.ofHom φ₁ + Cocycle.ofHom φ₂ := by simp\n-- error: `simp` made no progress\nexample (φ : F ⟶ G) : Cocycle.ofHom (-φ) = -Cocycle.ofHom φ := by simp\n-- error: `simp` made no progress\nexample (z₁ z₂ : Cocycle F G 0) : Cocycle.homOf (z₁ + z₂) = Cocycle.homOf z₁ + Cocycle.homOf z₂ := by simp\n-- error: `simp` made no progress\n-- these compile:\nexample (φ₁ φ₂ : F ⟶ G) : Cocycle.ofHom (φ₁ + φ₂) = Cocycle.ofHom φ₁ + Cocycle.ofHom φ₂ := by ext : 1; simp\nexample (z₁ z₂ : Cocycle F G 0) : Cocycle.homOf (z₁ + z₂) = Cocycle.homOf z₁ + Cocycle.homOf z₂ := by ext; simp\n-- `git grep -n \"ofHom_add\\|ofHom_neg\\|ofHom_sub\\|homOf_add\\|homOf_zero\" origin/master -- Mathlib/Algebra/Homology/HomotopyCategory/` finds only the Cochain versions at HomComplex.lean:182,186,190","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4b5b43","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cocycle.equivHom","line":695,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"addequiv-without-linearequiv","claim":"`equivHom` is only an AddEquiv. In the file's `[Linear R C]` setting both sides are `R`-modules, and `Cocycle.ofHom_smul` (L664) already proves `R`-linearity, so `(Cocycle.equivHom F G).toLinearEquiv (fun r φ => Cocycle.ofHom_smul r φ) : (F ⟶ G) ≃ₗ[R] Cocycle F G 0` is one line. No `≃ₗ[R]` version exists. The shift API does have linear versions (`rightShiftLinearEquiv`, `leftShiftLinearEquiv` in HomComplexShift.lean L298/L305). `equivHomShift_smul` and `equivHomShift_symm_smul` there prove the `R`-compatibility of the shifted equivalence as separate lemmas.","fix":"Add `Cocycle.linearEquivHom R F G : (F ⟶ G) ≃ₗ[R] Cocycle F G 0 := (equivHom F G).toLinearEquiv (fun r φ => ofHom_smul r φ)` with `@[simps]`.","ev":"hunts/homcomplex/batch5/p1.lean (P3): example : (F ⟶ G) ≃ₗ[R] Cocycle F G 0 := (Cocycle.equivHom F G).toLinearEquiv (fun r φ => Cocycle.ofHom_smul r φ)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-1a92f8","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cocycle.toCochainAddMonoidHom","line":715,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reimplements-subtype","claim":"Since `Cocycle K L n` is by definition the subgroup `cocycle K L n`, `toCochainAddMonoidHom` is definitionally `AddSubgroup.subtype`: `Cocycle.toCochainAddMonoidHom K L n = (cocycle K L n).subtype` holds by `rfl`. The definition re-proves `map_zero'` and `map_add'`.","fix":"Define it as `(cocycle K L n).subtype`.","ev":"hunts/homcomplex/batch5/p1.lean (P1): example (n : ℤ) : Cocycle.toCochainAddMonoidHom K L n = (cocycle K L n).subtype := rfl","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a3bbb4","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cocycle.isKernel","line":732,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"hand-rolled-kernel-islimit","claim":"`isKernel` builds the limit by hand: 19 lines (L732-750) under two `backward.*` set_options, with two `#adaptation_note` workarounds (`simp +instances only [...]; rfl`). It is `AddCommGrpCat.kernelIsLimit` (Grp/Kernels.lean L31) transported along the evident AddEquiv `ker ((HomComplex K L).d n m).hom ≃+ Cocycle K L n`. That 6-line term compiles at the same type with no set_options. Its `lift` stays definitional: the `rfl` that `leftHomologyData'_f'_apply_coe` (HomComplexCohomology.lean L255) relies on still goes through. The shorter `subst hm; exact AddCommGrpCat.kernelIsLimit _` also compiles but loses that `rfl`.","fix":"Define it as `(AddCommGrpCat.kernelIsLimit _).ofIsoLimit (Fork.ext (AddEquiv.toAddCommGrpIso { toFun x := ⟨x.1, (mem_iff n m hm x.1).2 x.2⟩, invFun x := ⟨x.1, (mem_iff n m hm x.1).1 x.2⟩, map_add' _ _ := rfl }) rfl)` and drop the set_options and adaptation notes.","ev":"hunts/homcomplex/batch5/p2.lean: def isKernelIso (n m : ℤ) (hm : n + 1 = m) : type_of% (Cocycle.isKernel K L n m hm) := (AddCommGrpCat.kernelIsLimit ((HomComplex K L).d n m)).ofIsoLimit (Fork.ext (AddEquiv.toAddCommGrpIso { toFun x := ⟨x.1, (Cocycle.mem_iff n m hm x.1).2 x.2⟩, invFun x := ⟨x.1, (Cocycle.mem_iff n m hm x.1).1 x.2⟩, map_add' _ _ := rfl }) rfl) -- compiles; and example (n m p : ℤ) (hp : m + 1 = p) (x : Cochain K L n) : (((isKernelIso (K := K) (L := L) m p hp).lift (KernelFork.ofι ((HomComplex K L).d n m) (by simp))) x).1 = δ n m x := rfl -- compiles (the same rfl fails for the `subst` version)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-36eb85","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.equivHomotopy","line":803,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-wrong-degree-and-sign","claim":"The docstring (L799-801) is wrong about the degree and the sign. It says homotopies correspond to 'a `1`-cochain `z` such that `δ (-1) 0 z` is the difference of the zero cochains associated to `φ₂` and `φ₁`', which reads as δ z = ofHom φ₂ - ofHom φ₁. The Lean statement is `{ z : Cochain F G (-1) // Cochain.ofHom φ₁ = δ (-1) 0 z + Cochain.ofHom φ₂ }`, so `z` has degree -1, not 1, and δ z = ofHom φ₁ - ofHom φ₂. That is the opposite order, and it matches Mathlib's `Homotopy f g` convention `f.f i = dNext i hom + prevD i hom + g.f i` (Homotopy.lean L128) and `δ_ofHomotopy` (L541). The two readings agree only when 2 • (ofHom φ₁ - ofHom φ₂) = 0. The Lean statement is correct; only the docstring is wrong. (Graded MINOR, not MAJOR, under the user's calibration: the Lean statement is correct and visible; only the prose degree and the order of the difference are wrong.)","fix":"Change the docstring to '... is equivalent to the datum of a `(-1)`-cochain `z` such that `δ (-1) 0 z = Cochain.ofHom φ₁ - Cochain.ofHom φ₂`'.","ev":"hunts/homcomplex/batch5/p1.lean (P4): example (φ₁ φ₂ : F ⟶ G) (ho : Homotopy φ₁ φ₂) : δ (-1) 0 ((Cochain.equivHomotopy φ₁ φ₂ ho).1 : Cochain F G (-1)) = Cochain.ofHom φ₁ - Cochain.ofHom φ₂ := eq_sub_of_add_eq (Cochain.equivHomotopy φ₁ φ₂ ho).2.symm","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b4dd72","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.map","line":920,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-functor-typeclass","claim":"`Cochain.map` and the lemmas `map_v`, `map_zero`, `map_comp`, `map_ofHom` assume `[Φ.Additive]` (section variable at L912, re-bound in `map_comp`), but only `[Φ.PreservesZeroMorphisms]` is needed (the assumption of `Functor.mapHomologicalComplex` itself); only `map_add`, `map_neg`, `map_sub` and `δ_map` use additivity.","fix":"Make the section variable `[Φ.PreservesZeroMorphisms]`, add `[Φ.Additive]` only to `map_add`/`map_neg`/`map_sub`/`δ_map`, and drop 'additive' from the `map` docstring.","ev":"hunts/homcomplex/batch6/src_gen.lean (copy of src.lean: L912 `[Φ.Additive]` -> `[Φ.PreservesZeroMorphisms]`; `[Φ.Additive]` added to map_add/map_neg/map_sub/δ_map; re-binding of Φ in map_comp removed). Whole file compiles with no errors; `#check @Cochain.map` shows `[inst_4 : Φ.PreservesZeroMorphisms]` (output in src_gen.out).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-953c08","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.map","line":920,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-map-smul-simp-lemma","claim":"`Cochain.map` has `map_add/neg/sub/zero/comp/ofHom` but no compatibility with scalar actions or `diff`: `simp` cannot prove `(k • z).map Φ = k • z.map Φ` for `k : ℤˣ` (the `n.negOnePow` signs produced by `δ`), nor for `k : R` with `[Φ.Linear R]`, nor `(Cochain.diff K).map Φ = Cochain.diff _`; each holds by `ext; simp`.","fix":"Add `@[simp]` lemmas `Cochain.map_units_smul`, `Cochain.map_smul` (for `[Φ.Linear R]`) and `Cochain.map_diff`, each proved by `ext; simp`.","ev":"-- hunts/homcomplex/batch6/probe1.lean, section map, with (Φ : C ⥤ D) [Φ.Additive]\nexample (n : ℤ) (z : Cochain K L n) (k : ℤˣ) : (k • z).map Φ = k • z.map Φ := by\n  fail_if_success (simp; done)\n  ext; simp\nexample {R : Type*} [Ring R] [Linear R C] [Linear R D] [Φ.Linear R]\n    (n : ℤ) (z : Cochain K L n) (k : R) : (k • z).map Φ = k • z.map Φ := by\n  fail_if_success (simp; done)\n  ext; simp\nexample : (Cochain.diff K).map Φ = Cochain.diff ((Φ.mapHomologicalComplex _).obj K) := by\n  fail_if_success (simp; done)\n  ext; simp\n-- all compile; `simp` makes no progress on each goal (the `done` is reported unreachable)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-97bf1c","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.δ_map","line":957,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"simp-lemma-direction-nonconfluent","claim":"`@[simp] δ_map : δ n m (z.map Φ) = (δ n m z).map Φ` pulls `map` outward while the other simp lemmas (`map_comp`, `map_add`, `map_ofHom`) push it inward, so the simp set is not confluent: `simp` fails on the instance `δ n₁₂ m ((z₁.comp z₂ h).map Φ) = (δ n₁₂ m (z₁.comp z₂ h)).map Φ` of `δ_map` itself; with the reversed orientation `(δ n m z).map Φ = δ n m (z.map Φ)` simp closes it.","fix":"State it as `map_δ : (δ n m z).map Φ = δ n m (z.map Φ)` (pushing `map` inward like the other `map_*` lemmas) and deprecate `δ_map`.","ev":"-- hunts/homcomplex/batch6/probe1.lean\nexample {n₁ n₂ n₁₂ m : ℤ} (z₁ : Cochain F G n₁) (z₂ : Cochain G K n₂) (h : n₁ + n₂ = n₁₂) :\n    δ n₁₂ m ((z₁.comp z₂ h).map Φ) = (δ n₁₂ m (z₁.comp z₂ h)).map Φ := by\n  fail_if_success (simp; done)\n  exact δ_map ..\ntheorem map_δ' (n m : ℤ) (z : Cochain K L n) : (δ n m z).map Φ = δ n m (z.map Φ) := (δ_map ..).symm\nexample {n₁ n₂ n₁₂ m : ℤ} (z₁ : Cochain F G n₁) (z₂ : Cochain G K n₂) (h : n₁ + n₂ = n₁₂) :\n    δ n₁₂ m ((z₁.comp z₂ h).map Φ) = (δ n₁₂ m (z₁.comp z₂ h)).map Φ := by\n  simp [-δ_map, map_δ']\n-- all compile","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-5f1936","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cocycle.isKernel'_lift_apply_coe_eq_δ","line":992,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"special-case-of-easy-general-lemma","claim":"The lemma computes `lift` only for the particular fork `KernelFork.ofι ((linearHomComplex R K L).d n m) _`; the characteristic lemma for an arbitrary fork `s`, `((isKernel' R K L m p hp).lift s x).1 = s.ι x`, has the same one-line proof and gives this lemma as an instance.","fix":"Add `isKernel'_lift_apply_coe` for an arbitrary `s : KernelFork ((linearHomComplex R K L).d m p)` and derive the `δ` version from it.","ev":"-- hunts/homcomplex/batch6/probe2.lean\ntheorem isKernel'_lift_apply_coe (m p : ℤ) (hp : m + 1 = p)\n    (s : KernelFork ((linearHomComplex R K L).d m p)) (x : s.pt) :\n    dsimp% (((Cocycle.isKernel' R K L m p hp).lift s) x).1 = s.ι x :=\n  congr($((Cocycle.isKernel' R K L m p hp).fac s .zero).1 x)\nexample (n m p : ℤ) (hp : m + 1 = p) (x : Cochain K L n) :\n    dsimp% (((Cocycle.isKernel' R K L m p hp).lift\n      (KernelFork.ofι ((linearHomComplex R K L).d n m) (by simp))) x).1 = δ n m x :=\n  isKernel'_lift_apply_coe (K := K) (L := L) R m p hp\n    (KernelFork.ofι ((linearHomComplex R K L).d n m) (by simp)) x\n-- compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ab450d","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean","decl":"CochainComplex.HomComplex.CohomologyClass.descAddMonoidHom","line":128,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`descAddMonoidHom` (and `descAddMonoidHom_cohomologyClass`) require the target `[AddCommGroup G]`, but the body `QuotientAddGroup.lift _ f hf` needs only `[AddMonoid G]`.","fix":"Use `{G : Type*} [AddMonoid G]` in that section.","ev":"-- hunts/homcomplex-cohom/P.lean: `example [AddMonoid G] (f : Cocycle K L n →+ G) (hf : coboundaries K L n ≤ f.ker) : CohomologyClass K L n →+ G := QuotientAddGroup.lift _ f hf` compiles; the same with `CohomologyClass.descAddMonoidHom f hf` fails (elaboration cannot find `AddCommGroup G`, timing out in whnf).","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-37e915","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean","decl":"CochainComplex.HomComplex.CohomologyClass.homAddEquiv","line":181,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"The file gives `CohomologyClass K L n` an `R`-module structure and proves `homologyLinearEquiv`, but the main identification with homotopy-category morphisms exists only additively (`toHom`, `homAddEquiv`). `toHom` is `R`-linear, a 4-line proof, so the linear equivalence `homLinearEquiv` is missing for no reason.","fix":"Add `toHom_smul` and `homLinearEquiv : CohomologyClass K L n ≃ₗ[R] (... ⟶ ...)` via `AddEquiv.toLinearEquiv`.","ev":"-- hunts/homcomplex-cohom/P.lean: `example [Linear R C] (r : R) (z) : toHom (r • z) = r • toHom z := by obtain ⟨x, rfl⟩ := mk_surjective z; simp only [← mk_smul, toHom_mk, Cocycle.equivHomShift_symm_smul, Functor.map_smul]` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-054db3","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean","decl":"CochainComplex.HomComplex.CohomologyClass.instModule","line":204,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reprovable-from-existing-api","claim":"The `Module R (CohomologyClass K L n)` instance proves six module laws by hand (with `induction` and a positional `nth_rw 1`), but it is `Function.Surjective.module R (mkAddMonoidHom K L n) mk_surjective (fun _ _ ↦ rfl)`, transporting from `Cocycle`.","fix":"Define the instance by `Function.Surjective.module`.","ev":"-- hunts/homcomplex-cohom/P.lean: `example [Linear R C] : Module R (CohomologyClass K L n) := Function.Surjective.module R (CohomologyClass.mkAddMonoidHom K L n) CohomologyClass.mk_surjective (fun _ _ ↦ rfl)` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-ef5de4","file":"Mathlib/Algebra/Homology/HomotopyCategory/ShortExact.lean","decl":"CochainComplex.mappingCone.descShortComplex_naturality","line":172,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CochainComplex.mappingCone.map_descShortComplex` (Algebra.Homology.HomotopyCategory.ShortExact), `CochainComplex.mappingCone.descShortComplex_naturality` (Algebra.Homology.HomotopyCategory.ShortExact) state exactly the same thing (Lean-checked). Reviewer: Same file, ~100 lines apart, identical naturality square proved twice by different `ext` proofs, no comment (S₁ S₂ explicit vs implicit). Keep `map_descShortComplex` (carries `@[map (attr := reassoc)]`, whose `_map_assoc` variant is used in DerivedCategory/ShortExact.lean:117), deprecate `descShortComplex_naturality` (one use, DerivedCategory/ShortExact.lean:63).","fix":"Deprecate `CochainComplex.mappingCone.descShortComplex_naturality` in favour of `CochainComplex.mappingCone.map_descShortComplex`.","ev":"dupscan/Check.lean: `example := (@CochainComplex.mappingCone.descShortComplex_naturality : type_of% @CochainComplex.mappingCone.map_descShortComplex)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 30, rating MAJOR): The second proof supplies no additional naturality or automation behavior. Preserve the surviving theorem’s generated `map` and `reassoc` family when deprecating the duplicate.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the two declarations differ in which arguments are explicit, which Mathlib sometimes keeps deliberately for rewriting.","at":"2026-10-07","commit":""},{"id":"RT-20261007-ca5b4e","file":"Mathlib/Algebra/Homology/HomotopyCategory/ShortExact.lean","decl":"CochainComplex.mappingCone.descShortComplex_naturality_assoc","line":172,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CochainComplex.mappingCone.descShortComplex_naturality_assoc` (Algebra.Homology.HomotopyCategory.ShortExact), `CochainComplex.mappingCone.map_descShortComplex_assoc` (Algebra.Homology.HomotopyCategory.ShortExact) state exactly the same thing (Lean-checked). Reviewer: Both _assoc lemmas are @[reassoc] output of two separately proved base lemmas, `map_descShortComplex` (l.73, @[map (attr := reassoc)]) and `descShortComplex_naturality` (l.172, @[reassoc]). These state the same square and differ only in whether S₁ and S₂ are explicit. Keep map_descShortComplex, whose @[map] variants are used in DerivedCategory. Deprecate descShortComplex_naturality, which has 1 use in DerivedCategory/ShortExact.","fix":"Deprecate `CochainComplex.mappingCone.descShortComplex_naturality_assoc` in favour of `CochainComplex.mappingCone.map_descShortComplex_assoc`.","ev":"dupscan/Check.lean: `example := (@CochainComplex.mappingCone.map_descShortComplex_assoc : type_of% @CochainComplex.mappingCone.descShortComplex_naturality_assoc)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 31, rating MAJOR): These are duplicate reassociation consequences of duplicate base theorems, not two different reassociation interfaces. Consolidate at the bases and preserve the surviving generated family.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the two declarations differ in which arguments are explicit, which Mathlib sometimes keeps deliberately for rewriting.","at":"2026-10-07","commit":""},{"id":"RT-20261007-aba89a","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"HomologicalComplexUpToQuasiIso.Q","line":52,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"api-only-in-specialisation","claim":"For a general complex shape there is no instance `IsIso (HomologicalComplexUpToQuasiIso.Q.map f)` from `[QuasiIso f]`; `inferInstance` fails. Only the `up ℤ` specialisation has it (`DerivedCategory/Basic.lean:102`, `instance ... [QuasiIso f] : IsIso (Q.map f)`), so users of other shapes must call `Localization.inverts` by hand.","fix":"Add `instance {K L : HomologicalComplex C c} (f : K ⟶ L) [QuasiIso f] : IsIso (Q.map f) := Localization.inverts _ (HomologicalComplex.quasiIso C c) _ (by simpa)` to this file.","ev":"hunts/homology-localization/batch0/Probe1.lean (P1a, lines 15-21): `example {K L : HomologicalComplex C c} (f : K ⟶ L) [QuasiIso f] : IsIso (HomologicalComplexUpToQuasiIso.Q.map f) := inferInstance` -> error: failed to synthesize IsIso (HomologicalComplexUpToQuasiIso.Q.map f); the same goal compiles as `Localization.inverts _ (HomologicalComplex.quasiIso C c) _ (by simpa)`","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-72c16f","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"HomologicalComplexUpToQuasiIso.homologyFunctorFactors","line":64,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-natiso-component-simp-lemma","claim":"No naturality lemma for the components of `homologyFunctorFactors`, so `simp` cannot close `(homologyFunctor C c i).map (Q.map f) ≫ (homologyFunctorFactors C c i).hom.app L = (homologyFunctorFactors C c i).hom.app K ≫ homologyMap f i`. Only the `up ℤ` copy `DerivedCategory.homologyFunctorFactors_hom_naturality` (`DerivedCategory/HomologySequence.lean:44`, `@[reassoc (attr := simp)]`) exists. The general lemma is `(homologyFunctorFactors C c i).hom.naturality f`.","fix":"Add `@[reassoc (attr := simp)] lemma homologyFunctorFactors_hom_naturality` (and an `inv` version) here and have the DerivedCategory lemma reuse it.","ev":"hunts/homology-localization/batch0/Probe1.lean (P1b, lines 23-29): `example ... : (HomologicalComplexUpToQuasiIso.homologyFunctor C c i).map (HomologicalComplexUpToQuasiIso.Q.map f) ≫ (HomologicalComplexUpToQuasiIso.homologyFunctorFactors C c i).hom.app L = (HomologicalComplexUpToQuasiIso.homologyFunctorFactors C c i).hom.app K ≫ HomologicalComplex.homologyMap f i := by simp` -> error: unsolved goals; the same statement compiles as the term `(HomologicalComplexUpToQuasiIso.homologyFunctorFactors C c i).hom.naturality f` (P1b'/P1b'', even without the respectTransparency option)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-0eca34","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"HomotopyCategory.quasiIso","line":104,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"definition-in-downstream-file","claim":"The `HomotopyCategory` block (L101-153: `quasiIso`, `mem_quasiIso_iff`, `quotient_map_mem_quasiIso_iff`, `RespectsIso`/`IsMultiplicative`, `homologyFunctor_inverts_quasiIso`, `quasiIso_eq_quasiIso_map_quotient`) uses no localization theory, yet it lives in the localization file. As a result `HomotopyCategory/Acyclic.lean` imports `Mathlib.Algebra.Homology.Localization` only to name `HomotopyCategory.quasiIso`. It uses no other declaration from this file, and its other imports do not already bring in this file or `CategoryTheory.Localization.Composition`.","fix":"Move the `HomotopyCategory.quasiIso` block to a file importing only `HomotopyCategory` and `QuasiIso` (e.g. a new `HomotopyCategory/QuasiIso.lean`) and import that from `Acyclic.lean`.","ev":"git grep in Acyclic.lean finds no use of UpToQuasiIso/Qh/QFactors/quotient_isLocalization/inverts_quasiIso/quotient_map_mem_quasiIso_iff; hunts/homology-localization/batch0/Probe3.lean (imports HomotopyCategory.HomologicalFunctor + ShiftSequence, Acyclic's other imports) prints `Mathlib.Algebra.Homology.Localization: false`, `Mathlib.CategoryTheory.Localization.Composition: false`, `Mathlib.Algebra.Homology.QuasiIso: true`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-49dd8e","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"HomotopyCategory.quotient_map_mem_quasiIso_iff","line":114,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"This lemma is not `@[simp]`, so `simp` makes no progress on `HomotopyCategory.quasiIso C c ((quotient C c).map f) ↔ QuasiIso f`. With the lemma as a local simp lemma, `simp` closes the goal. Two consumers already pass it to `simp` by hand: `HomotopyCategory/Plus.lean:251` and `DerivedCategory/DerivabilityStructureInjectives.lean:270`, both `simpa [quasiIso, quotient_map_mem_quasiIso_iff]`. The sibling `HomologicalComplex.mem_quasiIso_iff` is `@[simp]`.","fix":"Tag `HomotopyCategory.quotient_map_mem_quasiIso_iff` with `@[simp]`.","ev":"hunts/homology-localization/batch0/Probe1.lean (P1d, lines 73-81): `example {K L : HomologicalComplex C c} (f : K ⟶ L) : HomotopyCategory.quasiIso C c ((HomotopyCategory.quotient C c).map f) ↔ QuasiIso f := by simp` -> error: `simp` made no progress; with `attribute [local simp] HomotopyCategory.quotient_map_mem_quasiIso_iff in`, the same `by simp` compiles","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-e64594","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"HomotopyCategory.instIsMultiplicativeQuasiIso","line":129,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-morphism-property-instances","claim":"`HomotopyCategory.quasiIso C c` gets only `RespectsIso` and `IsMultiplicative`. It lacks `HasTwoOutOfThreeProperty` and `IsStableUnderRetracts`, which its sibling `HomologicalComplex.quasiIso` has (`QuasiIso.lean:308`, `:316`). `inferInstance` fails for both, even for `up ℤ` over an abelian category with `DerivedCategory.Basic` imported. Two-out-of-three is an 8-line proof, because the class is an intersection of inverse images of isomorphisms.","fix":"Add `HasTwoOutOfThreeProperty` and `IsStableUnderRetracts` instances for `HomotopyCategory.quasiIso C c` next to the `IsMultiplicative` instance.","ev":"hunts/homology-localization/batch0/Probe1.lean (P1c, lines 58-70) and hunts/homology-localization/batch0/Probe2.lean: `example : (HomotopyCategory.quasiIso C c).HasTwoOutOfThreeProperty := inferInstance` -> failed to synthesize (likewise IsStableUnderRetracts; likewise for `up ℤ` + `[Abelian C]` importing DerivedCategory.Basic). Compiles: `example : (HomotopyCategory.quasiIso C c).HasTwoOutOfThreeProperty where of_postcomp f g hg hfg i := by have := hg i; have := hfg i; simp only [Functor.map_comp] at this; exact IsIso.of_isIso_comp_right _ ((HomotopyCategory.homologyFunctor C c i).map g)  of_precomp f g hf hfg i := by have := hf i; have := hfg i; simp only [Functor.map_comp] at this; exact IsIso.of_isIso_comp_left ((HomotopyCategory.homologyFunctor C c i).map f) _`","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-f65a0f","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"HomologicalComplexUpToQuasiIso.quotientCompQhIso","line":184,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-naturality-simp-lemma","claim":"`quotientCompQhIso` is `@[no_expose]` and has no API lemmas. In particular, nothing states its naturality in the form simp normalises to: `Qh.map ((quotient C c).map f) ≫ (quotientCompQhIso C c).hom.app L = (quotientCompQhIso C c).hom.app K ≫ Q.map f`. `simp` cannot prove this, because `NatTrans.naturality` is keyed on `(quotient ⋙ Qh).map f`, which simp rewrites away (probe P6 leaves the goal unsolved). The `up ℤ` specialisation adds exactly these lemmas: `DerivedCategory.quotientCompQhIso_hom_naturality` (`@[reassoc (attr := simp)]`) and `_inv_naturality` (DerivedCategory/Basic.lean:118-129, with an adaptation note about the same simp-normal-form issue). The general iso has neither.","fix":"Add `@[reassoc (attr := simp)] quotientCompQhIso_hom_naturality` and `@[reassoc] quotientCompQhIso_inv_naturality` in general, both proved by `(quotientCompQhIso C c).hom.naturality f` / `.inv.naturality f`.","ev":"hunts/homology-localization/batch1/probe1.lean:67-70 `example {K L : HomologicalComplex C c} (f : K ⟶ L) : Qh.map ((HomotopyCategory.quotient C c).map f) ≫ (quotientCompQhIso C c).hom.app L = (quotientCompQhIso C c).hom.app K ≫ Q.map f := by simp` gives 'unsolved goals' with the goal unchanged (probe1.out). The same statement compiles as `(quotientCompQhIso C c).hom.naturality f` (probe2.lean theorem p6; axioms standard).","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-c1375e","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"HomologicalComplexUpToQuasiIso.Qh_inverts_quasiIso","line":187,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-iff-characterisation","claim":"For `Q` the file provides the characterisation `isIso_Q_map_iff_mem_quasiIso` (line 71). For `Qh` it provides only the one-way `Qh_inverts_quasiIso`, which nothing in Mathlib uses: git grep finds no consumer, inside or outside the file. The missing iff is proved by hand for the `up ℤ` specialisation, as `DerivedCategory.isIso_Qh_map_iff : IsIso (Qh.map f) ↔ HomotopyCategory.quasiIso C _ f` (DerivedCategory/HomologySequence.lean:76, 10 lines), and used in DerivedCategory/Fractions.lean:58,83. Probe P3 proves the general statement `IsIso (Qh.map f) ↔ HomotopyCategory.quasiIso C c f` from this file's own API (`Qh_inverts_quasiIso`, `homologyFunctorFactorsh`).","fix":"Add `HomologicalComplexUpToQuasiIso.isIso_Qh_map_iff_mem_quasiIso` in general, with `Qh_inverts_quasiIso` as one direction, and make `DerivedCategory.isIso_Qh_map_iff` a one-line specialisation.","ev":"hunts/homology-localization/batch1/probe2.lean theorem p3: `theorem p3 {X Y : HomotopyCategory C c} (f : X ⟶ Y) : IsIso (Qh.map f) ↔ HomotopyCategory.quasiIso C c f := by refine ⟨fun hf => ?_, fun hf => Qh_inverts_quasiIso C c _ hf⟩; rw [HomotopyCategory.mem_quasiIso_iff]; intro n; rw [← NatIso.isIso_map_iff (homologyFunctorFactorsh C c n) f]; dsimp; infer_instance`; 'Probe.p3' depends on axioms: [propext, Classical.choice, Quot.sound]. `git -C mathlib4 grep -n Qh_inverts_quasiIso origin/master -- Mathlib` returns only Localization.lean:187.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-4febef","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"HomologicalComplexUpToQuasiIso.instIsLocalizationHomotopyCategoryQhQuasiIso","line":234,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-localization-hypothesis","claim":"The instance `Qh.IsLocalization (HomotopyCategory.quasiIso C c)` assumes `[(HomotopyCategory.quotient C c).IsLocalization (HomologicalComplex.homotopyEquivalences C c)]` on top of `[c.QFactorsThroughHomotopy C]`, but the statement does not need it. Once `Qh` exists, Q factors through the quotient functor. That functor is the identity on objects and surjective on morphisms, so a factorisation through it is unique, and no localization at homotopy equivalences is needed. In Lean, `HomRel.FactorsThroughLocalization.strictUniversalPropertyFixedTarget'` makes `quotient ⋙ (HomotopyCategory.quasiIso C c).Q` a localization for `quasiIso`, and `Functor.IsLocalization.of_equivalence_target` with `Localization.uniq` and `Quotient.natIsoLift` transfers this to `Qh`. Probe P2 proves the instance under only `[HasLocalization] [QFactorsThroughHomotopy]`. The control P2b shows `inferInstance` currently fails in that context. Excluded cases: any shape with a `QFactorsThroughHomotopy` instance but no quotient-localization instance. For example, a user-supplied instance for `ComplexShape.up ℕ` is excluded, because `hc : ∀ j, ∃ i, c.Rel i j` fails at 0 and `quotient_isLocalization` does not apply there. Every Mathlib consumer today (down ι, up ℤ) has both instances, so nothing in Mathlib breaks. Not checked: the same hypothesis in the `mapHomologicalComplexUpToQuasiIsoFactorsh` variable block (line 382, batch 2).","fix":"Drop the `[(HomotopyCategory.quotient C c).IsLocalization (homotopyEquivalences C c)]` hypothesis, and prove the instance through `HomRel.FactorsThroughLocalization` (import Mathlib.CategoryTheory.Localization.Quotient, +1 module) as in probe P2.","ev":"hunts/homology-localization/batch1/probe2.lean theorem p2 (section variables only `[CategoryWithHomology C] [(HomologicalComplex.quasiIso C c).HasLocalization] [c.QFactorsThroughHomotopy C]`): `theorem p2 : Qh.IsLocalization (HomotopyCategory.quasiIso C c) := by have hW : HomologicalComplex.quasiIso C c = (HomotopyCategory.quasiIso C c).inverseImage (HomotopyCategory.quotient C c) := by ext K L f; exact (HomotopyCategory.quotient_map_mem_quasiIso_iff f).symm; have h : (homotopic C c).FactorsThroughLocalization (HomologicalComplex.quasiIso C c) := fun _ _ _ _ ⟨h⟩ => ComplexShape.QFactorsThroughHomotopy.areEqualizedByLocalization h; have : (HomotopyCategory.quotient C c ⋙ (HomotopyCategory.quasiIso C c).Q).IsLocalization (HomologicalComplex.quasiIso C c) := Functor.IsLocalization.mk' _ _ (h.strictUniversalPropertyFixedTarget' hW _) (h.strictUniversalPropertyFixedTarget' hW _); [two restatements of the instances in `Quotient.functor (homotopic C c)` form]; exact Functor.IsLocalization.of_equivalence_target (HomotopyCategory.quasiIso C c).Q (HomotopyCategory.quasiIso C c) Qh (Localization.uniq (HomotopyCategory.quotient C c ⋙ (HomotopyCategory.quasiIso C c).Q) (HomotopyCategory.quotient C c ⋙ Qh) (HomologicalComplex.quasiIso C c)) (Quotient.natIsoLift _ ((Functor.associator _ _ _).symm ≪≫ Localization.compUniqFunctor _ _ (HomologicalComplex.quasiIso C c)))`; 'Probe.p2' depends on axioms: [propext, Classical.choice, Quot.sound]. Control probe1.lean:48 `example : Qh.IsLocalization (HomotopyCategory.quasiIso C c) := inferInstance` fails with 'failed to synthesize instance' (probe1.out).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-16af0b","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"ComplexShape.strictUniversalPropertyFixedTargetQuotient","line":255,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"special-case-of-general-quotient-localization","claim":"This public def has a single consumer, `ComplexShape.quotient_isLocalization` (line 270); git grep finds no other use in Mathlib. It repeats the construction of the private `Quotient.isLocalization_functor.strictUniversalPropertyFixedTarget` (Localization/OfQuotient.lean:44: `inverts := hW`, `lift F hF := Quotient.lift r F …`, `fac := rfl`, `uniq` by `Functor.ext`), specialised to the homotopy relation, with the cylinder argument packaged as `Homotopy.map_eq_of_inverts_homotopyEquivalences`. Once `quotient_isLocalization` is derived from `Quotient.isLocalization_functor` (probe P5, see that finding), this def is dead.","fix":"Delete it after reproving `quotient_isLocalization` from `Quotient.isLocalization_functor`. If the import cost is unacceptable, at least make it private or an auxiliary declaration.","ev":"hunts/homology-localization/batch1/probe2.lean theorem p5 (the localization statement proved without this def); `git -C mathlib4 grep -n strictUniversalPropertyFixedTargetQuotient origin/master -- Mathlib` returns only Localization.lean:255 and :270.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-6212b0","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"ComplexShape.quotient_isLocalization","line":266,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"special-case-of-general-quotient-localization","claim":"This is a special case of the general `CategoryTheory.Quotient.isLocalization_functor` (Mathlib/CategoryTheory/Localization/OfQuotient.lean:68, same author, 2026). That lemma says: if W is inverted by `Quotient.functor r`, and every r-related pair `f₀ f₁` has a `Precylinder` P with `P.LeftHomotopy f₀ f₁` and `W P.π`, then `(functor r).IsLocalization W`. Probe P5 reproves `quotient_isLocalization` (same hypotheses `hc`, `[HasBinaryBiproducts C]`) as a single term, with `HomologicalComplex.cylinder` (`ι₀`, `ι₁`, `π`, `desc`, `homotopyEquiv K hc`) as the precylinder. Neither the 9-line auxiliary `strictUniversalPropertyFixedTargetQuotient` nor `Homotopy.map_eq_of_inverts_homotopyEquivalences` is needed. Caveat: OfQuotient.lean imports AlgebraicTopology.ModelCategory.RightHomotopy, which would add 19 modules (model-category files) to this file's import closure (measured). The refactor therefore costs imports; moving this section next to the cylinder construction is an alternative.","fix":"Prove `quotient_isLocalization` as `Quotient.isLocalization_functor _ _ (HomotopyCategory.quotient_inverts_homotopyEquivalences C c) (fun K _ f₀ f₁ ⟨h⟩ => ⟨⟨K.cylinder, cylinder.ι₀ K, cylinder.ι₁ K, cylinder.π K, _, _⟩, {h := cylinder.desc f₀ f₁ h}, ⟨cylinder.homotopyEquiv K hc, rfl⟩⟩)` in a file that may import Localization.OfQuotient, and delete the auxiliary def.","ev":"hunts/homology-localization/batch1/probe2.lean theorem p5: `open HomotopicalAlgebra in theorem p5 (hc : ∀ j, ∃ i, c.Rel i j) [HasBinaryBiproducts C] : (HomotopyCategory.quotient C c).IsLocalization (HomologicalComplex.homotopyEquivalences C c) := by classical; exact Quotient.isLocalization_functor _ _ (HomotopyCategory.quotient_inverts_homotopyEquivalences C c) (fun K _ f₀ f₁ ⟨h⟩ => ⟨{ I := K.cylinder, i₀ := HomologicalComplex.cylinder.ι₀ K, i₁ := HomologicalComplex.cylinder.ι₁ K, π := HomologicalComplex.cylinder.π K }, { h := HomologicalComplex.cylinder.desc f₀ f₁ h }, ⟨HomologicalComplex.cylinder.homotopyEquiv K hc, rfl⟩⟩)`; 'Probe.p5' depends on axioms: [propext, Classical.choice, Quot.sound]. The import-closure difference was measured with a script walking `import` lines from the source tree (OfQuotient: +19 modules; Localization.Quotient: +1).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-094a4b","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"instIsLocalizationHomologicalComplexDownHomotopyCategoryQuotientHomotopyEquivalences","line":287,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-index-typeclass","claim":"The `ChainComplex` section (L284-285) assumes `[AddRightCancelSemigroup ι] [One ι]` for its two instances, the L287 instance `(HomotopyCategory.quotient C (ComplexShape.down ι)).IsLocalization (homotopyEquivalences _ _)` and the L293 instance `(ComplexShape.down ι).QFactorsThroughHomotopy C`. Associativity is never used. `ComplexShape.down` only needs `[Add ι] [IsRightCancelAdd ι] [One ι]` (ComplexShape.lean:186), and the witness `fun _ => ⟨_, rfl⟩` uses no cancellation at all. With the section variable weakened to `[Add ι] [IsRightCancelAdd ι] [One ι]`, the whole file still compiles, including the L296 example, and instance search still finds both instances at `down ℕ` and `down ℤ`. In practice the impact is small: every index type in use (ℕ, ℤ) is a semigroup, and `AddRightCancelSemigroup` is the usual idiom for `ComplexShape.down` lemmas across the homology library.","fix":"Replace `[AddRightCancelSemigroup ι]` by `[Add ι] [IsRightCancelAdd ι]` in the `ChainComplex` section variables (L285).","ev":"hunts/homology-localization/batch2/probe1.lean P3_down, P3_down' (theorems under `[Add ι] [IsRightCancelAdd ι] [One ι]`, proved by the instances' own terms) compile; hunts/homology-localization/batch2/LocCopy.lean (copy of src.lean with L285 weakened) compiles with exit 0, and its appended tests `example : (HomotopyCategory.quotient C (ComplexShape.down ℕ)).IsLocalization (HomologicalComplex.homotopyEquivalences _ _) := inferInstance`, `example : (ComplexShape.down ℕ).QFactorsThroughHomotopy C := inferInstance`, and the same for `down ℤ`, all compile (hunts/homology-localization/batch2/LocCopy.out).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-9d1390","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"instIsLocalizationHomologicalComplexIntUpHomotopyCategoryQuotientHomotopyEquivalences","line":312,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"instance-specialised-to-int","claim":"The two cochain-complex instances, L312 `(HomotopyCategory.quotient C (ComplexShape.up ℤ)).IsLocalization (homotopyEquivalences _ _)` and L318 `(ComplexShape.up ℤ).QFactorsThroughHomotopy C`, are stated only for `ℤ`. Their proofs, `fun n => ⟨n - 1, by simp⟩`, work verbatim for `ComplexShape.up ι` with any `[AddGroup ι] [One ι]`, for example `ZMod n` (periodic complexes). Today instance search fails for `up G` with `G` an additive group. With the instances generalised in a copy of the file, the file compiles, the ℤ instances are still found by `inferInstance`, and the L325 example `Qh.IsLocalization (HomotopyCategory.quasiIso C (ComplexShape.up ℤ))` still elaborates. The comment at L301-304 explains why the ℤ case is done directly instead of by duality; the direct argument just was not stated at its natural generality.","fix":"State the L312 and L318 instances for `{ι : Type*} [AddGroup ι] [One ι]` and `ComplexShape.up ι`, keeping the same proof terms.","ev":"hunts/homology-localization/batch2/probe1.lean L53-56: `example {G : Type*} [AddCommGroup G] [One G] : (HomotopyCategory.quotient C (ComplexShape.up G)).IsLocalization (HomologicalComplex.homotopyEquivalences _ _) := inferInstance` fails on master with 'failed to synthesize'; P3_up and P3_up' (the general statements under `[AddGroup ι] [One ι]`) compile. hunts/homology-localization/batch2/LocCopy.lean (instances generalised) compiles with exit 0; its tests at `up ℤ` and at a general `AddCommGroup G`, and the original L325 example, all compile.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-1b5eaa","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"CategoryTheory.Functor.mapHomologicalComplexUpToQuasiIsoLocalizerMorphism","line":347,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"preadditive-where-zero-morphisms-suffice","claim":"The functoriality section (L339-342) assumes `[Preadditive C] [Preadditive D] [F.Additive]`. The localizer morphism and everything built only from it need just `[HasZeroMorphisms C] [HasZeroMorphisms D] [F.PreservesZeroMorphisms] [F.PreservesHomology]`. That covers the inverts lemma (L352), `mapHomologicalComplexUpToQuasiIso` (L361), the `Lifting` instance (L366) and `mapHomologicalComplexUpToQuasiIsoFactors` (L375). `Functor.PreservesHomology`, `Functor.mapHomologicalComplex` and `HomologicalComplexUpToQuasiIso` itself (L35) are all set up for zero morphisms. The `Preadditive` requirement comes only from `HomologicalComplex.quasiIso_map_of_preservesHomology` (QuasiIso.lean:248, section `PreservesHomology`), whose proof goes through `ShortComplex.quasiIso_map_of_preservesLeftHomology`, which needs only zero morphisms. With the `map` field reproved directly from that ShortComplex lemma, the localizer morphism, the induced functor, the `Lifting` instance, the `Factors` iso and the inverts lemma all compile without `Preadditive`/`Additive`. For preadditive `C`, `D` the generalised morphism is `rfl`-equal to Mathlib's. Only `Factorsh` and later declarations (through `mapHomotopyCategory`) genuinely need `Preadditive`/`Additive`. All current consumers (DerivedCategory/ExactFunctor.lean, Ext/Map.lean) are abelian, so nothing downstream gains today.","fix":"Generalise the `PreservesHomology` section of QuasiIso.lean to `[HasZeroMorphisms]` and `[F.PreservesZeroMorphisms]`, then split this file's functoriality section so that L347-379 assume only zero morphisms and `F.PreservesZeroMorphisms`.","ev":"hunts/homology-localization/batch2/probe1.lean P5 (`LocalizerMorphism (quasiIso C c) (quasiIso D c)` under `[HasZeroMorphisms C] [HasZeroMorphisms D] [F.PreservesZeroMorphisms] [F.PreservesHomology]`, with `map` proved by `change QuasiIso ((F.mapHomologicalComplex c).map f); rw [quasiIso_iff]; intro i; ... rw [quasiIsoAt_iff] at this ⊢; exact ShortComplex.quasiIso_map_of_preservesLeftHomology F ((HomologicalComplex.shortComplexFunctor C c i).map f)`), P5_functor, the `Lifting` instance, P5_factors and P5_inverts all compile; P8 `example : P5 F c = F.mapHomologicalComplexUpToQuasiIsoLocalizerMorphism c := rfl` compiles in the preadditive setting.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-a64296","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"CategoryTheory.Functor.mapHomologicalComplex_upToQuasiIso_Q_inverts_quasiIso","line":352,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"unused-one-line-specialisation","claim":"The lemma is `LocalizerMorphism.inverts` (LocalizerMorphism.lean:88) applied to the file's own localizer morphism: `(F.mapHomologicalComplexUpToQuasiIsoLocalizerMorphism c).inverts _` proves it as a term. The current proof is the same thing behind `by apply`. It has no consumer: `git grep` over origin/master finds it only at its own declaration, and `localizedFunctor` already uses `Φ.inverts` internally. The name does not follow the convention either: there is no `upToQuasiIso` constant, and the `⋙` is not rendered as `comp`.","fix":"Deprecate the lemma in favour of `(F.mapHomologicalComplexUpToQuasiIsoLocalizerMorphism c).inverts _`, or at least make the proof that term.","ev":"hunts/homology-localization/batch2/probe1.lean P4: `example : (HomologicalComplex.quasiIso C c).IsInvertedBy (F.mapHomologicalComplex c ⋙ HomologicalComplexUpToQuasiIso.Q) := (F.mapHomologicalComplexUpToQuasiIsoLocalizerMorphism c).inverts _` compiles. `git -C mathlib4 grep -n mapHomologicalComplex_upToQuasiIso_Q_inverts_quasiIso origin/master -- Mathlib` gives only Localization.lean:352.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-f77007","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"CategoryTheory.Functor.mapHomologicalComplexUpToQuasiIsoFactorsh","line":388,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"unneeded-localization-hypothesis","claim":"`mapHomologicalComplexUpToQuasiIsoFactorsh` carries `[(HomotopyCategory.quotient C c).IsLocalization (HomologicalComplex.homotopyEquivalences C c)]` (L382-383) only because it is built with `Localization.liftNatIso` along the quotient functor. `HomotopyCategory C c` is a `CategoryTheory.Quotient`, so `Quotient.natIsoLift` lifts the same iso with no localization hypothesis, exactly as `homologyFunctorFactorsh` (L200) does in this file. The hypothesis is then inherited by the `Lifting` instance (L399) and by `mapHomologicalComplexUpToQuasiIsoFactorsh_hom_app` (L410), three declarations in all. Rebuilt with `natIsoLift`, the definition, the instance and the `hom_app` lemma (now a one-line proof) compile without the hypothesis. No current instance is lost: at the shapes Mathlib supports (`down ι`, `up ℤ`) the hypothesis is an instance anyway. The downstream file DerivedCategory/ExactFunctor.lean was not rebuilt (no `lake build`), but it uses only the declaration's type, the `Lifting` instance and the `hom_app` lemma, whose statements are unchanged.","fix":"Define `mapHomologicalComplexUpToQuasiIsoFactorsh` as `Quotient.natIsoLift _ (...)` from `quotientCompQhIso` and `mapHomologicalComplexUpToQuasiIsoFactors`, and drop the `IsLocalization` variable from L382-383.","ev":"hunts/homology-localization/batch2/probe1.lean P6 (`Quotient.natIsoLift _ ((Functor.associator _ _ _).symm ≪≫ Functor.isoWhiskerRight (quotientCompQhIso C c) _ ≪≫ F.mapHomologicalComplexUpToQuasiIsoFactors c ≪≫ Functor.isoWhiskerLeft _ (quotientCompQhIso D c).symm ≪≫ (Functor.associator _ _ _).symm ≪≫ Functor.isoWhiskerRight (F.mapHomotopyCategoryFactors c).symm _ ≪≫ Functor.associator _ _ _)`), P6_hom_app (the original `hom_app` statement, proved by `(Quotient.natTransLift_app ..).trans (by simp)`) and the `Lifting` example all compile with no `IsLocalization` instance in scope. hunts/homology-localization/batch2/LocCopy.lean (L382-383 deleted, definition replaced) compiles with exit 0; there `#check @mapHomologicalComplexUpToQuasiIsoFactorsh` shows no `IsLocalization` binder, while probe1 P1 shows binder `inst_12` on master.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-3e98cc","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"CategoryTheory.Functor.mapHomologicalComplexUpToQuasiIsoFactorsh_hom_app","line":410,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"brittle-change-proof","claim":"The proof (L419-425) is brittle. It needs two `backward.*` compatibility options and runs `dsimp` on the `@[no_expose]` definition `mapHomologicalComplexUpToQuasiIsoFactorsh`. It then has an uncommented `change` that relies on `(quotientCompQhIso C c).hom.app K`, `(quotientCompQhIso D c).inv.app _` and `(F.mapHomotopyCategoryFactors c).inv.app K` being definitionally `𝟙 _`, which they are because both isos are `Quotient.lift.isLift`. The sibling lemmas `homologyFunctorFactorsh_hom_app_quotient_obj` and `_inv_app_quotient_obj` (L208, L218) are one-liners. With the `natIsoLift` definition from the generality finding, this lemma has the same one-line proof `(Quotient.natTransLift_app ..).trans (by simp)` under a single `set_option backward.isDefEq.respectTransparency false in`, the same option those siblings use. Without that option, `simp` leaves goals.","fix":"After redefining `Factorsh` with `Quotient.natIsoLift`, prove the lemma by `(Quotient.natTransLift_app ..).trans (by simp)`; otherwise at least comment the `change`.","ev":"Measured: src.lean L407-408 have two `set_option backward.*` lines, L419-425 are 7 tactic lines including `dsimp [mapHomologicalComplexUpToQuasiIsoFactorsh]` and an uncommented `change _ = (F.mapHomologicalComplexUpToQuasiIso c).map (𝟙 _) ≫ _ ≫ 𝟙 _ ≫ HomologicalComplexUpToQuasiIso.Qh.map (𝟙 _)`. hunts/homology-localization/batch2/LocCopy.lean: the one-line proof compiles (exit 0). hunts/homology-localization/batch2/LocCopy2.lean: the same proof without the set_option gives 'unsolved goals' (LocCopy2.out).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-316efa","file":"Mathlib/Algebra/Lie/Basic.lean","decl":"LieEquiv.coe_toLieHom","line":539,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `LieEquiv.coe_toLieHom` (Algebra.Lie.Basic), `LieEquiv.coe_coe` (Algebra.Lie.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file, `⇑(e : L₁ →ₗ⁅R⁆ L₂) = e` and `⇑e.toLieHom = e` are the same term (the Coe instance is `⟨toLieHom⟩`), both rfl; Lean-3 `coe_coe`/`coe_toX` port artefact. Keep the @[simp] `coe_coe`, deprecate `coe_toLieHom` (one use, Lie/Nilpotent.lean:684).","fix":"Deprecate `LieEquiv.coe_toLieHom` in favour of `LieEquiv.coe_coe`.","ev":"dupscan/Check.lean: `example := (@LieEquiv.coe_coe : type_of% @LieEquiv.coe_toLieHom)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 34, rating MINOR): The coercion is the projection, and the retained simp theorem handles both source spellings. Removing the little-used descriptive synonym is reasonable, but remains modest compatibility cleanup.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-45853d","file":"Mathlib/Algebra/Lie/Basic.lean","decl":"LieModuleEquiv.coe_toLieModuleHom","line":924,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `LieModuleEquiv.coe_coe` (Algebra.Lie.Basic), `LieModuleEquiv.coe_toLieModuleHom` (Algebra.Lie.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file, both `⇑(e : M →ₗ⁅R,L⁆ N) = e` by rfl; the Lean-3 `coe_coe` vs `coe_toX` distinction collapsed in Lean 4 (the same pattern recurs for LieEquiv, LinearEquiv, AffineEquiv, BialgEquiv). Keep the @[simp] `coe_coe` (Mathlib-wide name), deprecate `coe_toLieModuleHom` (no uses).","fix":"Deprecate `LieModuleEquiv.coe_toLieModuleHom` in favour of `LieModuleEquiv.coe_coe`.","ev":"dupscan/Check.lean: `example := (@LieModuleEquiv.coe_toLieModuleHom : type_of% @LieModuleEquiv.coe_coe)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 33, rating MINOR): The retained theorem supplies the same coercion normalization, and the other name contributes no additional attribute or calling convention. This is legacy API-name redundancy rather than a substantial defect.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-93ca99","file":"Mathlib/Algebra/Lie/Derivation/Basic.lean","decl":"LieDerivation.lie_apply","line":323,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `LieDerivation.commutator_apply` (Algebra.Lie.Derivation.Basic), `LieDerivation.lie_apply` (Algebra.Lie.Derivation.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file, both rfl: `⁅D1, D2⁆ a = D1 (D2 a) - D2 (D1 a)` appears as commutator_apply (line 306, used in the LieRing/LieAlgebra instance proofs; mirrors Derivation.commutator_apply) and as @[simp] lie_apply (line 323). Keep commutator_apply, give it @[simp], and deprecate lie_apply.","fix":"Deprecate `LieDerivation.lie_apply` in favour of `LieDerivation.commutator_apply`.","ev":"dupscan/Check.lean: `example := (@LieDerivation.lie_apply : type_of% @LieDerivation.commutator_apply)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup0 item 32, rating MINOR): `lie_apply` makes both derivations explicit, enabling `D₁.lie_apply D₂ x`; `commutator_apply` leaves them implicit. Moving `[simp]` alone does not preserve that receiver-based API or the conventional operation-application name. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Algebra/Lie/Derivation/Basic.lean#L300)","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-7438ac","file":"Mathlib/Algebra/Lie/Subalgebra.lean","decl":"LieSubalgebra.map_top","line":548,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `LieSubalgebra.map_top` (Algebra.Lie.Subalgebra), `LieHom.range_eq_map` (Algebra.Lie.Subalgebra) state exactly the same thing (Lean-checked). Reviewer: Same file, both `f.range = map f ⊤ := by ext; simp`. `LieSubalgebra.map_top` has the opposite orientation to Submodule.map_top and LieModuleHom.map_top (`map f ⊤ = range`). Keep `LieHom.range_eq_map`. Deprecate LieSubalgebra.map_top, whose 2 uses are in Lie/Basis/Prod, or flip it into the conventional direction.","fix":"Deprecate `LieSubalgebra.map_top` in favour of `LieHom.range_eq_map`.","ev":"dupscan/Check.lean: `example := (@LieHom.range_eq_map : type_of% @LieSubalgebra.map_top)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 35, rating MAJOR): The existing `map_top` has an orientation inconsistent with its name and duplicates the hom-facing theorem. Reversing its statement would give it a useful conventional role; otherwise deprecate it.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the two declarations differ in which arguments are explicit, which Mathlib sometimes keeps deliberately for rewriting.","at":"2026-10-07","commit":""},{"id":"RT-20261007-28a858","file":"Mathlib/Algebra/Module/Equiv/Defs.lean","decl":"LinearEquiv.coe_toLinearMap","line":213,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `LinearEquiv.coe_coe` (Algebra.Module.Equiv.Defs), `LinearEquiv.coe_toLinearMap` (Algebra.Module.Equiv.Defs) state exactly the same thing (Lean-checked). Reviewer: Same file, both rfl: `⇑(e : M →ₛₗ M₂) = e` and `⇑e.toLinearMap = e` elaborate identically because the coercion is toLinearMap. This is a Lean 3 coe-vs-projection artifact, with no comment. Keep @[simp, norm_cast] coe_coe (181 uses) and deprecate coe_toLinearMap (31 uses).","fix":"Deprecate `LinearEquiv.coe_toLinearMap` in favour of `LinearEquiv.coe_coe`.","ev":"dupscan/Check.lean: `example := (@LinearEquiv.coe_toLinearMap : type_of% @LinearEquiv.coe_coe)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup0 item 38, rating MINOR): `coe_toLinearMap` is an established, descriptive projection-facing name with substantial reported use. Sharing the proof or simplifying registrations is reasonable, but deprecating that public name offers little benefit; this does not require claiming a separate `norm_cast` behavior. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Algebra/Module/Equiv/Defs.lean#L204)","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-a634c3","file":"Mathlib/Algebra/Module/Hom.lean","decl":"AddMonoidHom.smul","line":115,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"convenience-interface-defined-twice","claim":"`AddMonoidHom.smul` (Algebra/Module/Hom.lean:115) and `smulAddHom` (Algebra/Module/End.lean:49) are the same bundled hom `R →+ M →+ M`, both defined as `(Module.toAddMonoidEnd R M).toAddMonoidHom` with separate simp lemmas; they differ in argument explicitness (Astra: two convenience interfaces; the later one could delegate to `smulAddHom R M`).","fix":"Define `AddMonoidHom.smul := smulAddHom _ _` (Hom.lean already imports End.lean).","ev":"dupscan/defs/probe.lean: `smulAddHom R M = (AddMonoidHom.smul : R →+ M →+ M) := rfl` compiles, exit 0.","evr":"compiles","astraV":"agrees","astraS":"ITEM 3: VERDICT: agrees RATING 3: MINOR This is much better defended as two convenience interfaces. [`smulAddHom`](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Algebra/Module/End.lean#L47) takes explicit `R M` arguments and documents its use with `flip`. [`AddMonoidHom.smul`](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Algebra/Module/Hom.lean#L113) infers those types and supports expected-type `.smul` notation. Their simp lemmas also expose different application levels. Thus the specialized `rfl` test overlooks meaningful differences in ","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-4f78ed","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End","line":32,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-docstring-reference","claim":"The `Module.End` docstring cites `Module.End.semiring` and `Module.End.algebra`, which do not exist; the instances are `Module.End.instSemiring` (this file, L74) and `Module.End.instAlgebra` (Mathlib/Algebra/Algebra/Basic.lean:204). The module docstring is similarly stale: 'formed by taking the additive structure above' points at nothing in this file (`LinearMap.addCommMonoid` lives in Mathlib/Algebra/Module/LinearMap/Defs.lean:845).","fix":"Replace the cited names with `Module.End.instSemiring` and `Module.End.instAlgebra`, and make the module docstring say the additive structure comes from `LinearMap.addCommMonoid`.","ev":"probe hunts/linearmap-end/batch0/probe1.lean (imports Mathlib.Algebra.Module.LinearMap.End and Mathlib.Algebra.Algebra.Basic): `#check @Module.End.semiring` -> error: Unknown constant `Module.End.semiring`; `#check @Module.End.algebra` -> error: Unknown constant `Module.End.algebra`; `#check @Module.End.instSemiring` and `#check @Module.End.instAlgebra` succeed.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-f5b9e5","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.instOne","line":47,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-isapply-instance","claim":"The `One`/`Mul` instances on `Module.End R M` (L47, L49) are not paired with `IsOneApplyEqSelf (Module.End R M) M` / `IsMulApplyEqComp (Module.End R M) M` (Mathlib/Algebra/Group/IsApply.lean, which is not even imported here), although `M₁ →L[R₁] M₁` (ContinuousLinearMap/Basic.lean:376,569), `α →o α` (Order/Group/End.lean:107-108) and the Lie homs register them. So the generic simp/norm_cast endomorphism API (`FunLike.coe_one_eq_id`, `FunLike.coe_mul_eq_comp`, `FunLike.coe_pow_eq_iterate`, `pow_apply_eq_iterate`, `FunLike.compMonoidWithZero/compSemiring/compRing`) does not apply to the most basic endomorphism type, and `one_apply`/`mul_apply`/`coe_one`/`coe_mul` (and `coe_pow`/`pow_apply`) stay bespoke.","fix":"Add `public import Mathlib.Algebra.Group.IsApply` (new to the closure: only it and Mathlib.Data.Int.Cast.Pi) and `instance : IsOneApplyEqSelf (Module.End R M) M where` / `instance : IsMulApplyEqComp (Module.End R M) M where` after L49 (both close by the default `rfl`).","ev":"probe hunts/linearmap-end/batch0/probe1.lean section (E): `inferInstance : IsOneApplyEqSelf (Module.End R M) M` and `... IsMulApplyEqComp ...` -> failed to synthesize; `FunLike.coe_one_eq_id` at `⇑(1 : Module.End R M) = id` -> failed to synthesize. Section (F): after `instance : IsOneApplyEqSelf (Module.End R M) M where` and `instance : IsMulApplyEqComp (Module.End R M) M where`, `FunLike.coe_one_eq_id`, `FunLike.coe_mul_eq_comp f g`, `one_apply_eq_self x`, `mul_apply_eq_comp f g x`, `FunLike.coe_pow_eq_iterate f n`, `pow_apply_eq_iterate f n x` all typecheck and `simp` closes `⇑1 = id`, `⇑(f * g) = ⇑f ∘ ⇑g`, `⇑(f ^ n) = (⇑f)^[n]`. hunts/linearmap-end/batch0/End_copyA.lean (src.lean + the import + the two instances) compiles with the brief's flags and `#lint only simpNF` passes. probe2.lean: Mathlib.Algebra.Group.IsApply and Mathlib.Data.Int.Cast.Pi are the only IsApply imports not already in End's closure.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-160457","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.coe_one","line":61,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`Module.End.coe_one` (`⇑1 = id`) and `Module.End.coe_mul` (`⇑(f * g) = f ∘ g`) are not `@[simp]`, unlike their siblings `Monoid.End.coe_one`/`coe_mul` and `AddMonoid.End.coe_one`/`coe_mul` (Algebra/Group/Hom/Defs.lean:1012-1016, `@[to_additive (attr := simp)]`), `LinearEquiv.coe_one` (Module/Equiv/Basic.lean:89) and the generic `FunLike.coe_one_eq_id`/`coe_mul_eq_comp` (`@[simp, norm_cast]`); `simp` makes no progress on either coercion equation.","fix":"Tag both `@[simp]` (simpNF-clean), or after registering the IsApply instances deprecate them to `FunLike.coe_one_eq_id`/`FunLike.coe_mul_eq_comp` as Lie/Basic.lean:397 did.","ev":"probe hunts/linearmap-end/batch0/probe1.lean section (D): `example : ⇑(1 : Module.End R M) = _root_.id := by simp` -> error: `simp` made no progress; `example (f g : Module.End R M) : ⇑(f * g) = ⇑f ∘ ⇑g := by simp` -> error: `simp` made no progress. hunts/linearmap-end/batch0/End_copyB.lean (src.lean with `@[simp]` on coe_one and coe_mul) compiles, the same `by simp` example then succeeds, and `#lint only simpNF` reports 0 errors.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-2f8171","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.instSemiring","line":74,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-isapply-instance","claim":"`instSemiring` defines `NatCast (Module.End R M)` as `n • 1`, but Mathlib has no `IsNatCastApplyEqSMul (Module.End R M) M` instance. `M₁ →L[R₁] M₁` has one (`instIsNatCastApply`, Topology/Algebra/Module/ContinuousLinearMap/Basic.lean:599) and builds its semiring as `fast_instance% FunLike.compSemiring`. So the generic `@[simp]` lemma `natCast_apply_eq_smul` and `FunLike.natCast_eq_nsmul_one` do not apply to `Module.End`, and `natCast_apply`/`ofNat_apply` stay bespoke. This complements batch 0's finding (results-0 F:1) about `IsOneApplyEqSelf`/`IsMulApplyEqComp`. Each of these instances closes by its default `rfl` field. Once they are added, together with `IsZeroApply`/`IsAddApply`/`IsSMulApply ℕ`, the generic lemmas reprove `natCast_apply`, `ofNat_apply`, `coe_pow` and `pow_apply`. `FunLike.compSemiring` then equals `Module.End.instSemiring` by `with_reducible_and_instances rfl`.","fix":"Import `Mathlib.Algebra.Group.IsApply` (see results-0 F:1) and add `instance : IsNatCastApplyEqSMul (Module.End R M) M where` after `instSemiring`. Once the `LinearMap` Is*Apply instances exist, consider defining `instSemiring` as `fast_instance% FunLike.compSemiring`, as for continuous linear maps.","ev":"hunts/linearmap-end/batch1/probe1.lean P7 (fails-as-expected): `example : IsNatCastApplyEqSMul (Module.End R M) M := inferInstance` -> failed to synthesize; `example (n : ℕ) (x : M) : (n : Module.End R M) x = n • x := natCast_apply_eq_smul n x` -> failed to synthesize IsNatCastApplyEqSMul. hunts/linearmap-end/batch1/probe2.lean Q3-Q5 (compiles): `instance : IsNatCastApplyEqSMul (Module.End R M) M where` (plus IsOneApplyEqSelf, IsMulApplyEqComp, IsZeroApply, IsAddApply, IsSMulApply ℕ, all with empty `where`); then `natCast_apply_eq_smul n x`, `FunLike.coe_pow_eq_iterate f n`, `by simp` for `(f ^ n) x = f^[n] x`, and `ofNat_apply` via `simp only [← Nat.cast_ofNat (R := Module.End R M), natCast_apply_eq_smul]` all check, and `example : (FunLike.compSemiring : Semiring (Module.End R M)) = Module.End.instSemiring := by with_reducible_and_instances rfl` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-4c4708","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.instRing","line":94,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-isapply-instance","claim":"`instRing` defines `IntCast (Module.End R N₁)` as `z • 1`, but Mathlib has no `IsIntCastApplyEqSMul (Module.End R N₁) N₁` instance. `M →L[R] M` has one (`instIsIntCastApply`, ContinuousLinearMap/Basic.lean:893), deprecated its own `intCast_apply` in favour of `_root_.intCast_apply_eq_smul` (since 2026-05-20, L895), and builds its ring as `fast_instance% FunLike.compRing`. Here `intCast_apply` stays bespoke and the generic `@[simp]` `intCast_apply_eq_smul` does not fire. With the instance, which closes by its default `rfl`, plus the Neg/Sub/SMul ℤ apply classes, `FunLike.compRing` equals `Module.End.instRing` by `rfl`.","fix":"Add `instance : IsIntCastApplyEqSMul (Module.End R N₁) N₁ where` after `instRing`. Consider `fast_instance% FunLike.compRing` once the `LinearMap` Is*Apply instances exist.","ev":"hunts/linearmap-end/batch1/probe1.lean P7: `example : IsIntCastApplyEqSMul (Module.End R N) N := inferInstance` -> failed to synthesize. hunts/linearmap-end/batch1/probe2.lean (compiles): `instance : IsIntCastApplyEqSMul (Module.End R N) N where` plus IsZeroApply/IsAddApply/IsNegApply/IsSubApply/IsSMulApply ℕ/IsSMulApply ℤ (all empty `where`); then `example (z : ℤ) (x : N) : (z : Module.End R N) x = z • x := intCast_apply_eq_smul z x` and `example : (FunLike.compRing : Ring (Module.End R N)) = Module.End.instRing := rfl` compile.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-60a634","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.instIsScalarTower","line":108,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"The section hypotheses `[Monoid S] [DistribMulAction S M] [SMulCommClass R S M]` are stronger than needed. The action it is about, `SMul S (M →ₛₗ[σ] M₂)` (LinearMap/Defs.lean:736), needs only `[DistribSMul S M₂] [SMulCommClass R₂ S M₂]`, and `(s • f) * g = s • (f * g)` holds by `rfl`. Under `[DistribSMul S M] [SMulCommClass R S M]`, the SMul exists but `inferInstance` cannot find the tower, while `⟨fun _ _ _ ↦ rfl⟩` proves it. No current consumer needs a non-monoid `S`, so the impact is small.","fix":"Change the section variable to `[DistribSMul S M] [SMulCommClass R S M]` and prove the instance by `⟨fun _ _ _ ↦ rfl⟩`.","ev":"hunts/linearmap-end/batch1/probe1.lean P4: `example [DistribSMul S M] [SMulCommClass R S M] : IsScalarTower S (Module.End R M) (Module.End R M) := ⟨fun _ _ _ ↦ rfl⟩` compiles; P4b the same with `:= inferInstance` -> failed to synthesize. hunts/linearmap-end/batch1/End_general.lean (src.lean with `variable [DistribSMul S M] [SMulCommClass R S M]` at L106) compiles cleanly.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-4cffb4","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.instSMulCommClass","line":112,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`SMulCommClass S (Module.End R M) (Module.End R M)` says exactly that every R-linear endomorphism commutes with `s • ·`, which is `LinearMap.CompatibleSMul M M S R`. That is the hypothesis of `LinearMap.comp_smul`, the lemma this proof uses, and of `compRight` in this file (L359). The instance asks instead for `[SMul S R] [IsScalarTower S R M]` (plus `[Monoid S] [DistribMulAction S M]`), which is strictly stronger. Example: for a comm ring `A`, `T : Submonoid A` and `N` a module over both `A` and `Localization T` with the tower, Lean finds both `SMul (Localization T) (Module.End A N)` and `CompatibleSMul N N (Localization T) A` (RingTheory/Localization/Basic.lean:141). Yet `SMulCommClass (Localization T) (Module.End A N) (Module.End A N)` fails to synthesize, since there is no `SMul (Localization T) A`, and the CompatibleSMul form proves it in one line. The CompatibleSMul form still covers the old hypotheses through `IsScalarTower.compatibleSMul`. The same holds for the symmetric `instSMulCommClass'`.","fix":"State both instances with `[DistribSMul S M] [SMulCommClass R S M] [LinearMap.CompatibleSMul M M S R]` and prove the first by `⟨fun s f g ↦ LinearMap.ext fun x ↦ (f.map_smul_of_tower s (g x)).symm⟩`.","ev":"hunts/linearmap-end/batch1/probe1.lean P5/P5b (import Mathlib.RingTheory.Localization.Basic; `variable {A} [CommRing A] (T : Submonoid A) (N) [AddCommGroup N] [Module A N] [Module (Localization T) N] [IsScalarTower A (Localization T) N]`): `SMul (Localization T) (Module.End A N)` and `LinearMap.CompatibleSMul N N (Localization T) A` by inferInstance compile; `SMulCommClass (Localization T) (Module.End A N) (Module.End A N) := inferInstance` and the primed `SMulCommClass (Module.End A N) (Localization T) (Module.End A N) := inferInstance` -> failed to synthesize; `⟨fun s f g ↦ LinearMap.ext fun x ↦ (f.map_smul_of_tower s (g x)).symm⟩` proves the first. hunts/linearmap-end/batch1/End_general.lean (both instances restated with `[LinearMap.CompatibleSMul M M S R]`) compiles; hunts/linearmap-end/batch1/probe5.lean: with the library instances erased, `genSMulCommClass` applies at `[SMul R S] [IsScalarTower R S M]` and `Algebra.ofModule smul_mul_assoc fun r f g => (smul_comm r f g).symm` still elaborates.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-5c07ad","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.isUnit_apply_inv_apply_of_isUnit","line":120,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"statement-not-in-simp-normal-form","claim":"This lemma and its twin `isUnit_inv_apply_apply_of_isUnit` (L124) are stated with the raw field `h.unit.inv` (`Units.inv`), not the simp-normal `↑h.unit⁻¹` (`Units.inv_eq_val_inv` is `@[simp]`), which is how consumers write their goals (Algebra/Algebra/Basic.lean:226-242, Module/FinitePresentation.lean:577). So `rw` and `simp only` with them fail on normal-form goals. Consumers rely on defeq or a `simpa using` round-trip (Basic.lean:233, 242). No simp lemma closes `f (↑h.unit⁻¹ x) = x` or `↑h.unit⁻¹ (f x) = x` (`simp` makes no progress). Restated with `(↑h.unit⁻¹ : End R M)`, the lemmas work with `rw`/`simp`, accept `@[simp]`, and stay defeq to the old form, so term-mode consumers are unaffected.","fix":"Restate both lemmas with `(↑h.unit⁻¹ : End R M)` in place of `h.unit.inv` and tag them `@[simp]`.","ev":"hunts/linearmap-end/batch1/probe1.lean P6 (fails-as-expected): `example : f ((↑h.unit⁻¹ : Module.End R M) x) = x := by rw [Module.End.isUnit_apply_inv_apply_of_isUnit h]` -> `Did not find an occurrence of the pattern f (h.unit.inv ?x)`; the same with `simp only [...]` -> `simp made no progress`; `rw [Module.End.isUnit_inv_apply_apply_of_isUnit h]` on `↑h.unit⁻¹ (f x) = x` -> pattern not found; `by simp` -> no progress. hunts/linearmap-end/batch1/probe4.lean (compiles): `theorem apply_inv_apply_of_isUnit' {f : Module.End R M} (h : IsUnit f) (x : M) : f ((↑h.unit⁻¹ : Module.End R M) x) = x := DFunLike.congr_fun h.mul_val_inv x`, then `rw [apply_inv_apply_of_isUnit' h]` and `simp only [apply_inv_apply_of_isUnit']` close the normal-form goal, and `example : f (h.unit.inv x) = x := apply_inv_apply_of_isUnit' h x`. hunts/linearmap-end/batch1/End_general.lean (both restated, `@[simp]`) compiles.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-613971","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.isUnit_apply_inv_apply_of_isUnit","line":120,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reprovable-in-one-line","claim":"Both lemmas are one-liners from general API. `isUnit_apply_inv_apply_of_isUnit h x` is `DFunLike.congr_fun h.mul_val_inv x`, and also `smul_inv_smul h.unit x` through the tautological action. `isUnit_inv_apply_apply_of_isUnit h x` is `DFunLike.congr_fun h.val_inv_mul x`, and also `inv_smul_smul h.unit x`. The current proofs instead go through `show (f * h.unit.inv) x = x by simp` and a `(by simp : ...)` ascription, which rely on defeq. `isUnit_apply_inv_apply_of_isUnit` has 6 uses in Mathlib and `isUnit_inv_apply_apply_of_isUnit` has 1.","fix":"Prove them by `DFunLike.congr_fun h.mul_val_inv x` and `DFunLike.congr_fun h.val_inv_mul x`, keeping them as named `Module.End` conveniences (restated as in the api finding).","ev":"hunts/linearmap-end/batch1/probe1.lean P6c: `example : f (h.unit.inv x) = x := DFunLike.congr_fun h.mul_val_inv x`, `example : h.unit.inv (f x) = x := DFunLike.congr_fun h.val_inv_mul x`, `example : f (h.unit.inv x) = x := smul_inv_smul h.unit x`, `example : h.unit.inv (f x) = x := inv_smul_smul h.unit x` all compile; hunts/linearmap-end/batch1/End_general.lean uses the `DFunLike.congr_fun` proofs at L120 position and compiles. Use counts: `git grep -n isUnit_apply_inv_apply_of_isUnit origin/master -- Mathlib` = 6 outside End.lean, `isUnit_inv_apply_apply_of_isUnit` = 1.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-461115","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.iterate_surjective","line":154,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"rederives-function-iterate-lemma","claim":"This can be proved in one line from existing API: it is `Function.Surjective.iterate` transported along `Module.End.coe_pow`. The file instead re-derives that lemma with a 4-line structural recursion on `n` through `iterate_succ` (0 consumers in Mathlib).","fix":"Keep the statement and prove it as `coe_pow f' n ▸ h.iterate n`, taking `(n : ℕ)` as a binder.","ev":"hunts/linearmap-end/batch2/SrcEdited.lean (copy of src.lean with `theorem iterate_surjective (h : Surjective f') (n : ℕ) : Surjective (f' ^ n) := coe_pow f' n ▸ h.iterate n`) compiles with no errors or warnings under the brief's flags; also hunts/linearmap-end/batch2/Probe1.lean (2)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-d42f1a","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.iterate_injective","line":160,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"rederives-function-iterate-lemma","claim":"This can be proved in one line from existing API: it is `Function.Injective.iterate` transported along `Module.End.coe_pow`. The file instead re-derives that lemma with a 4-line structural recursion on `n` through `iterate_succ` (2 consumers: RingTheory/Artinian/Module.lean:160 and Analysis/Normed/Operator/Compact/FredholmAlternative.lean:147).","fix":"Keep the statement and prove it as `coe_pow f' n ▸ h.iterate n`, taking `(n : ℕ)` as a binder.","ev":"hunts/linearmap-end/batch2/SrcEdited.lean (copy of src.lean with `theorem iterate_injective (h : Injective f') (n : ℕ) : Injective (f' ^ n) := coe_pow f' n ▸ h.iterate n`) compiles with no errors or warnings under the brief's flags; also hunts/linearmap-end/batch2/Probe1.lean (2)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-5a7f18","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.iterate_bijective","line":166,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"rederives-function-iterate-lemma","claim":"This can be proved in one line from existing API: it is `Function.Bijective.iterate` transported along `Module.End.coe_pow`. The file instead re-derives that lemma with a 4-line structural recursion on `n` through `iterate_succ` (0 consumers in Mathlib).","fix":"Keep the statement and prove it as `coe_pow f' n ▸ h.iterate n`, taking `(n : ℕ)` as a binder.","ev":"hunts/linearmap-end/batch2/SrcEdited.lean (copy of src.lean with `theorem iterate_bijective (h : Bijective f') (n : ℕ) : Bijective (f' ^ n) := coe_pow f' n ▸ h.iterate n`) compiles with no errors or warnings under the brief's flags; also hunts/linearmap-end/batch2/Probe1.lean (2)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-c7a55c","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.smulLeft","line":183,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"special-case-of-existing-def","claim":"`smulLeft α hα` rebuilds `DistribSMul.toLinearMap R M (⟨α, hα⟩ : Submonoid.center R)` (this file, line 241) and is rfl-equal to it, to `DistribMulAction.toModuleEnd R M ⟨α, hα⟩`, `Module.toModuleEnd R M (⟨α, hα⟩ : Subsemiring.center R)`, `(⟨α, hα⟩ : Subsemiring.center R) • LinearMap.id` and `algebraMap (Subsemiring.center R) (End R M) ⟨α, hα⟩`. Its `map_smul'` proof re-proves the existing instance `Submonoid.instSMulCommClassSubtypeMemCenter : SMulCommClass (Submonoid.center M) M α` (GroupTheory/Submonoid/Center.lean:52). The only obstacle is that End.lean does not import `Submonoid.center`, but `smulLeft` has no consumer in End.lean. Every consumer has the replacement in scope: FreeModule/Basic `mem_center_iff` restates verbatim with `DistribSMul.toLinearMap R M α`, `α : Submonoid.center R`, and Central/End imports FreeModule/Basic. Lie/Graded uses it only over a `CommRing`, where it is `φ i • .id = LinearMap.lsmul R M (φ i)` by rfl. [Graded MINOR after Astra A2 item 1 (hunts/linearmap-end/A2.answer.md): `smulLeft` takes a raw central element with a proof, a convenience interface, and End.lean cannot import `Submonoid.center` for the replacement.]","fix":"Deprecate `Module.End.smulLeft` in favour of `DistribSMul.toLinearMap R M (⟨α, hα⟩ : Submonoid.center R)` (or `algebraMap (Subsemiring.center R) (End R M)`), and restate `mem_center_iff` and its two corollaries with an `α : Submonoid.center R`.","ev":"probe2.lean (imports End + Algebra.Basic + Submonoid.Center + Subsemiring.Basic): `example (α : R) (hα : α ∈ Set.center R) : End.smulLeft (M := M) α hα = DistribSMul.toLinearMap R M (⟨α, hα⟩ : Submonoid.center R) := rfl`, likewise `= DistribMulAction.toModuleEnd R M ⟨α, hα⟩ := rfl`, `= Module.toModuleEnd R M (⟨α, hα⟩ : Subsemiring.center R) := rfl`, `= (⟨α, hα⟩ : Subsemiring.center R) • LinearMap.id := rfl`, `= algebraMap (Subsemiring.center R) (End R M) ⟨α, hα⟩ := rfl`, all compile. probe3.lean (imports only FreeModule.Basic): `example [Free R M] {f : Module.End R M} : f ∈ Set.center (Module.End R M) ↔ ∃ α : Submonoid.center R, f = DistribSMul.toLinearMap R M α := by rw [Module.End.mem_center_iff]; exact ⟨fun ⟨α, hα, h⟩ ↦ ⟨⟨α, hα⟩, h⟩, fun ⟨α, h⟩ ↦ ⟨α, α.2, h⟩⟩` compiles. probe3b.lean (imports Lie.Graded, CommRing R): `Module.End.smulLeft (M := M) a (by simp) = LinearMap.lsmul R M a := rfl` compiles. Files: hunts/linearmap-end/batch3/probe2.lean, probe3.lean, probe3b.lean; probe1.lean shows `Submonoid.center` is unknown with only End.lean imported.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-5ccbdf","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.smulLeft_eq","line":188,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"commsemiring-where-smulcommclass-suffices","claim":"`smulLeft_eq` assumes `[CommSemiring R]`, but its statement `smulLeft α hα = α • LinearMap.id` only needs the `R`-action on `End R M`, i.e. `[SMulCommClass R R M]` over a `Semiring R`, and the same `rfl` proves it there.","fix":"State it for the section's `[Semiring R]` with `[SMulCommClass R R M]` (keeping `hα` explicit or `by simp` only where it discharges).","ev":"probe2.lean: `variable {R S M : Type*} [Semiring R] [AddCommMonoid M] [Module R M]` ... `example [SMulCommClass R R M] (α : R) (hα : α ∈ Set.center R) : End.smulLeft (M := M) α hα = α • LinearMap.id := rfl` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-fa71df","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.apply_faithfulSMul","line":212,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-dangling-name","claim":"The docstring '`LinearMap.applyModule` is faithful.' names a declaration that does not exist; the instance is `Module.End.applyModule`. The same stale name appears in the module docstring of Mathlib/Algebra/Group/Action/End.lean:48.","fix":"Write '`Module.End.applyModule` is faithful.' (and fix the list in Algebra/Group/Action/End.lean).","ev":"probe2.lean: `#check @LinearMap.applyModule` gives `Unknown constant LinearMap.applyModule`; `#check @Module.End.applyModule` succeeds. `git grep -n applyModule origin/master -- Mathlib` finds no `LinearMap.applyModule` declaration or alias.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-2c9b36","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.apply_isScalarTower","line":224,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"typeclass-stronger-than-underlying-instance","claim":"`apply_isScalarTower` assumes `[Monoid S] [DistribMulAction S M]`, but the action `SMul S (M →ₗ[R] M)` it is about (`LinearMap.instSMul`, LinearMap/Defs.lean:733-736) only needs `[DistribSMul S M] [SMulCommClass R S M]`. The instance holds by `rfl` under those classes and the current one does not fire there. The sibling `instIsScalarTower` (line 108, batch 1) carries the same too-strong `[Monoid S] [DistribMulAction S M]`.","fix":"Replace `[Monoid S] [DistribMulAction S M]` by `[DistribSMul S M]` in `apply_isScalarTower`.","ev":"probe1.lean: `example [DistribSMul S M] [SMulCommClass R S M] : IsScalarTower S (Module.End R M) M := ⟨fun _ _ _ ↦ rfl⟩` compiles, while `example [DistribSMul S M] [SMulCommClass R S M] : IsScalarTower S (Module.End R M) M := inferInstance` fails with `failed to synthesize instance of type class IsScalarTower S (End R M) M`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-4fe25e","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"LinearMap.smulRight","line":314,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-basic-api","claim":"`LinearMap.smulRight` (for a general scalar semiring `S`) has only `coe_smulRight`, `smulRight_apply`, `smulRight_zero`, `zero_smulRight` and `smulRight_apply_eq_zero_iff`. Nothing in Mathlib states additivity in either argument (`f.smulRight (x + y) = f.smulRight x + f.smulRight y`, `(f + g).smulRight x = f.smulRight x + g.smulRight x`) or the two composition rules (`(f.smulRight x).comp g = (f.comp g).smulRight x`, `(g.restrictScalars R).comp (f.smulRight x) = f.smulRight (g x)`). The search covered every `smulRight` lemma name in Mathlib; the only composition lemma is `ContinuousLinearMap.smulRight_comp_smulRight`. `simp` makes no progress on any of the four statements, and each has a one-line proof (`ext; simp [smul_add]`, `ext; simp [add_smul]`, `rfl`). The bilinear `smulRightₗ` gives additivity only when `R` is commutative and `S = R`.","fix":"Add `smulRight_add`, `add_smulRight`, `smulRight_comp` and `comp_smulRight` (simp where the RHS is normal) next to `smulRight_zero`/`zero_smulRight`.","ev":"hunts/linearmap-end/batch4/probe1.lean section P4: `example (f : M₁ →ₗ[R] S) (x y : M) : f.smulRight (x + y) = f.smulRight x + f.smulRight y := by simp`, likewise `(f + g).smulRight x = …`, `(f.smulRight x).comp g = (f.comp g).smulRight x` and `(g.restrictScalars R).comp (f.smulRight x) = f.smulRight (g x)`, all give error `simp made no progress` (probe1.out lines for 59/62/66/70). In the same file, `by ext; simp [smul_add]`, `by ext; simp [add_smul]` and `rfl` prove the first three. `git grep -nE '(theorem|lemma) [A-Za-z_.]*smulRight' HEAD -- Mathlib` lists no add or comp lemma for `LinearMap.smulRight`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-7b0d92","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"LinearMap.smulRight_apply_eq_zero_iff","line":333,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"isdomain-where-iscancelmulzero-suffices","claim":"`smulRight_apply_eq_zero_iff` assumes `[IsDomain S]`, but its proof only uses `smul_eq_zero` (Mathlib/Algebra/Module/Torsion/Free.lean), which needs `[IsCancelMulZero S] [Module.IsTorsionFree S M]`. The same proof compiles under `[IsCancelMulZero S]`. The gain is small: `IsCancelMulZero` with `Nontrivial` already gives `IsDomain`, so the only new case is the zero ring. The `IsDomain` + `IsTorsionFree` pairing is common in Mathlib (124 lines), so this is a pattern rather than a one-off.","fix":"Replace `[IsDomain S]` by `[IsCancelMulZero S]` in `smulRight_apply_eq_zero_iff`.","ev":"hunts/linearmap-end/batch4/probe1.lean P3a: `example [IsCancelMulZero S] [Module.IsTorsionFree S M] {f : M₁ →ₗ[R] S} {x : M} : f.smulRight x = 0 ↔ f = 0 ∨ x = 0 := by simp [DFunLike.ext_iff, forall_or_right]` compiles. hunts/linearmap-end/batch4/copy_gen.lean (src.lean with the lemma's `[IsDomain S]` changed to `[IsCancelMulZero S]`) compiles, and `#lint` reports all checks passed. hunts/linearmap-end/batch4/probe2.lean P7: `example (S) [Semiring S] [IsCancelMulZero S] [Nontrivial S] : IsDomain S := {}` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-89ab05","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"LinearMap.smulRight_apply_eq_zero_iff","line":333,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"apply-suffix-on-unapplied-statement","claim":"The name contains `_apply`, which by Mathlib convention means the map is applied to a point (`f.smulRight x c = 0 ↔ …`). The statement is about the unapplied map: `f.smulRight x = 0 ↔ f = 0 ∨ x = 0`. The neighbouring lemmas about the unapplied map, `smulRight_zero` and `zero_smulRight`, have no `_apply`. There is precedent for the same usage in `LinearMap.range_smulRight_apply` and `ContinuousLinearMap.range_smulRight_apply`. Nothing in Mathlib uses the lemma, so a rename is cheap.","fix":"Rename to `LinearMap.smulRight_eq_zero_iff`, keeping a deprecated alias.","ev":"hunts/linearmap-end/batch4/probe1.lean P3b: `example [IsDomain S] [Module.IsTorsionFree S M] {f : M₁ →ₗ[R] S} {x : M} (c : M₁) : f.smulRight x c = 0 ↔ f c = 0 ∨ x = 0 := smulRight_apply_eq_zero_iff` fails with a type mismatch (`smulRight ?f ?x = 0 ↔ …` against `(f.smulRight x) c = 0 ↔ …`). `git grep -n smulRight_apply_eq_zero_iff HEAD -- Mathlib` finds only the declaration.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-6695c6","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"LinearMap.applyₗ'","line":351,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"additive-where-linear-available","claim":"`applyₗ' : M →+ (M →ₗ[R] M₂) →ₗ[S] M₂` keeps only additivity in `v`, although under exactly its hypotheses (`Semiring R`, which may be noncommutative, and `SMulCommClass R S M₂`) the map is `R`-linear in `v`. Library note [bundled maps over different rings] recommends that form, `M →ₗ[R] N →ₗ[S] P`. `LinearMap.flip` (BilinearMap.lean) builds that form by declaring `SMulCommClass.symm` a local instance, and `(LinearMap.id : (M →ₗ[R] M₂) →ₗ[S] _).flip.toAddMonoidHom = applyₗ' S` holds by `rfl`. A copy of the file in which `applyₗ'` is stated as `M →ₗ[R] (M →ₗ[R] M₂) →ₗ[S] M₂` compiles, along with the rest of the file and a replica of its downstream user `ringLmapEquivSelf`, and passes `#lint`. In that copy `applyₗ = applyₗ' R` holds by `rfl`, so the CommSemiring `applyₗ` becomes a plain specialisation. This is not a MAJOR duplicate of `flip`: `flip` lives downstream of this file, and `applyₗ'` is needed upstream by `LinearMap.ringLmapEquivSelf`.","fix":"State `applyₗ'` as `M →ₗ[R] (M →ₗ[R] M₂) →ₗ[S] M₂` (with `attribute [local instance] SMulCommClass.symm in`, as for `LinearMap.flip`) and define `applyₗ` as `applyₗ' R`.","ev":"hunts/linearmap-end/batch4/probe1.lean P5: under `[Semiring R] [Semiring S] … [SMulCommClass R S M₂]`, `example : (LinearMap.id : (M →ₗ[R] M₂) →ₗ[S] _).flip.toAddMonoidHom = applyₗ' S := rfl` compiles. The R-linear `applyₗ''` built from `applyₗ'` plus `map_smul' c v := LinearMap.ext fun f => f.map_smul c v` compiles; `applyₗ'' S = LinearMap.id.flip := rfl` and, for CommSemiring R, `applyₗ'' R = applyₗ := rfl`. hunts/linearmap-end/batch4/copy_gen.lean: src.lean with `applyₗ'` restated R-linearly compiles together with a `ringLmapEquivSelf` replica, `example : applyₗ = applyₗ' R := rfl`, and `#lint` (all checks passed).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-16f143","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"LinearMap.compRight","line":363,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-docstring-variable-names","claim":"The docstring (L361-362) reads 'Composition by `f : M₂ → M₃` is a linear map from the space of linear maps `M → M₂` to the space of linear maps `M → M₃`', but the signature is `(f : M₁ →ₗ[R] M₂) : (M →ₗ[R] M₁) →ₗ[S] M →ₗ[R] M₂`: the module names are shifted (stale from an older signature, so `M₂` names the wrong space) and it does not say the map is `S`-linear.","fix":"Reword to 'Composition by `f : M₁ →ₗ[R] M₂` is an `S`-linear map from `M →ₗ[R] M₁` to `M →ₗ[R] M₂`.'","ev":"src.lean L361-363: docstring mentions `f : M₂ → M₃`, `M → M₂`, `M → M₃`; declaration is `def compRight (f : M₁ →ₗ[R] M₂) : (M →ₗ[R] M₁) →ₗ[S] M →ₗ[R] M₂`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-8921d9","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"LinearMap.applyₗ","line":385,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-cites-nonexistent-name","claim":"The docstring says 'This is the `LinearMap` version of `toAddMonoidHom.eval`', but no declaration `toAddMonoidHom.eval` exists (nor `AddMonoidHom.toAddMonoidHom.eval`); the intended name is `AddMonoidHom.eval : M →+ (M →+ N) →+ N` (Mathlib/Algebra/Group/Hom/Instances.lean:226, via to_additive of `MonoidHom.eval`). `git grep toAddMonoidHom.eval` hits only this docstring.","fix":"Replace `toAddMonoidHom.eval` by `AddMonoidHom.eval` in the docstring.","ev":"hunts/linearmap-end/batch5/probe2_fail.lean: `#check @toAddMonoidHom.eval` -> error: Unknown identifier `toAddMonoidHom.eval`; `#check @AddMonoidHom.toAddMonoidHom.eval` -> Unknown constant. hunts/linearmap-end/batch5/probe1.lean: `#check @AddMonoidHom.eval` -> `M →+ (M →+ N) →+ N`","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-b87f5c","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"LinearMap.applyₗ","line":385,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"parallel-spelling-without-bridge-lemma","claim":"The evaluation map `applyₗ` is rebuilt downstream under the spelling `LinearMap.id.flip` / `LinearMap.flip LinearMap.id` (definition of `Module.Dual.eval` at LinearAlgebra/Dual/Defs.lean:79-80, `Contraction.lean:57`, `ModuleCat/Monoidal/Closed.lean:73`, `RepresentationTheory/Rep/Basic.lean:832`), and no lemma relates the two spellings (no `flip_id`/`id_flip` lemma; `git grep 'flip.*applyₗ'` finds only an unrelated QuadraticForm use). Both are equal by `rfl`.","fix":"Add `@[simp] lemma LinearMap.id_flip : (LinearMap.id : (M →ₗ[R] M₂) →ₗ[R] _).flip = applyₗ := rfl` in BilinearMap.lean and define `Module.Dual.eval` as `LinearMap.applyₗ`.","ev":"hunts/linearmap-end/batch5/probe1.lean: `example : (applyₗ : M →ₗ[R] (M →ₗ[R] M₂) →ₗ[R] M₂) = (LinearMap.id).flip := rfl` and `example : Module.Dual.eval R M = applyₗ := rfl` (CommSemiring R, AddCommMonoid M M₂) both compile","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-653637","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.commute_id_left","line":428,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"Stated under `[Ring R] [AddCommGroup M]` (section variables at L426) although it holds verbatim, with the same proof, for `[Semiring R] [AddCommMonoid M]`.","fix":"Change the section variables to `{R M : Type*} [Semiring R] [AddCommMonoid M] [Module R M]` (or move the lemmas into the earlier `Semiring` section).","ev":"hunts/linearmap-end/batch5/probe1.lean: `variable {R M : Type*} [Semiring R] [AddCommMonoid M] [Module R M] (f : Module.End R M)` `example : Commute LinearMap.id f := by ext; simp`; hunts/linearmap-end/batch5/srccopy.lean with L426 weakened to Semiring/AddCommMonoid compiles (consumer Lie/Semisimple/Lemmas.lean only needs the weaker form)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-643fc8","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.commute_id_left","line":428,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"restated-general-lemma","claim":"This is `Commute.one_left f` restated with the `LinearMap.id` spelling of `1` (`Module.End.one_eq_id` is `rfl`); it is reproved by `ext; simp` instead of from the general lemma. The `LinearMap.id` spelling is worth keeping (Lie/Semisimple/Lemmas.lean rewrites with it), but the proof should be the one-liner.","fix":"Prove it as `Commute.one_left f` (`lemma commute_id_left : Commute LinearMap.id f := .one_left f`).","ev":"hunts/linearmap-end/batch5/probe1.lean: `example : Commute LinearMap.id f := Commute.one_left f` (Semiring R, AddCommMonoid M); srccopy.lean uses `.one_left f` and compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-512263","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.commute_id_right","line":430,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"Stated under `[Ring R] [AddCommGroup M]` (section variables at L426) although it holds verbatim, with the same proof, for `[Semiring R] [AddCommMonoid M]`.","fix":"Change the section variables to `{R M : Type*} [Semiring R] [AddCommMonoid M] [Module R M]`.","ev":"hunts/linearmap-end/batch5/probe1.lean: `example : Commute f LinearMap.id := by ext; simp` under `[Semiring R] [AddCommMonoid M] [Module R M]`; hunts/linearmap-end/batch5/srccopy.lean with L426 weakened compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-c814a8","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.commute_id_right","line":430,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"restated-general-lemma","claim":"This is `Commute.one_right f` restated with the `LinearMap.id` spelling of `1`; it is reproved by `ext; simp`. Keep the spelling (used by `(toEnd k L M y).commute_id_right.lie_eq` in Lie/Semisimple/Lemmas.lean:59,65) but derive it from the general lemma.","fix":"Prove it as `Commute.one_right f`.","ev":"hunts/linearmap-end/batch5/probe1.lean: `example : Commute f LinearMap.id := Commute.one_right f`; srccopy.lean uses `.one_right f` and compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261006-0ea2d3","file":"Mathlib/Algebra/Module/LinearMap/Index.lean","decl":"LinearMap.index_of_surjective","line":67,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"Several index lemmas assume more than they use: `index_of_surjective`, `index_mkQ` and `index_projectionOnto` need only `[Nontrivial R]`, not `[StrongRankCondition R]` (the sibling `index_of_injective` already uses `Nontrivial`); `index_of_bijective`, `index_id` and `LinearEquiv.index_eq_zero` hold over every ring (the zero ring is handled by `index_of_subsingleton`); `index_neg` holds over every `Ring`, not just a `DivisionRing`.","fix":"Replace `variable [StrongRankCondition R]` by `[Nontrivial R]` on the surjective lemmas, drop it from the bijective/id/equiv lemmas (prove by `nontriviality R`), and move `index_neg` to the `Ring` section.","ev":"example (hf : Bijective f) : f.index = 0 := by\n  nontriviality R\n  rw [index_eq_finrank_sub, ker_eq_bot.mpr hf.injective, range_eq_top.mpr hf.surjective, finrank_bot,\n    finrank_zero_of_subsingleton]\n  simp\n\nexample [Nontrivial R] (hf : Surjective f) : f.index = finrank R f.ker := by\n  rw [index_eq_finrank_sub, range_eq_top.mpr hf, finrank_zero_of_subsingleton (M := N ⧸ ⊤)]\n  simp\n\n-- [Ring R]\nexample : (-f).index = f.index := by\n  rw [index_eq_finrank_sub, index_eq_finrank_sub, ker_neg, range_neg]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-e972e5","file":"Mathlib/Algebra/Module/LinearMap/Index.lean","decl":"LinearMap.index_eq_of_finiteDimensional","line":102,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`index_eq_of_finiteDimensional` is stated over a division ring, but its proof works verbatim over any ring with `[StrongRankCondition R] [HasRankNullity R]` and `[Module.Finite R M] [Module.Finite R N]` (e.g. every commutative domain, so ℤ-linear maps ℤ² → ℤ³).","fix":"Restate under `[StrongRankCondition R] [HasRankNullity R] [Module.Finite R M] [Module.Finite R N]`.","ev":"example {R : Type*} [Ring R] [StrongRankCondition R] [HasRankNullity.{u} R]\n    {M N : Type u} [AddCommGroup M] [AddCommGroup N] [Module R M] [Module R N]\n    [Module.Finite R M] [Module.Finite R N] {f : M →ₗ[R] N} :\n    f.index = finrank R M - finrank R N := by\n  rw [index_eq_finrank_sub]\n  have h₁ := f.range.finrank_quotient_add_finrank\n  have h₂ := f.quotKerEquivRange.finrank_eq\n  have h₃ := f.ker.finrank_quotient_add_finrank\n  lia","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-a90a03","file":"Mathlib/Algebra/Module/LinearMap/Index.lean","decl":"LinearMap.index_comp","line":113,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-drops-hypothesis","claim":"The module docstring says '`index_comp`: the index is additive under composition' without its hypotheses (division ring; finite-dimensional kernels and cokernels of f and g), and `index_comp` itself has no docstring. With the junk value the unqualified claim is false: f = inl : H → H × ℚ, g = 0 : H × ℚ → 0 (H infinite-dimensional) give index f = -1, index g = 0, index (g ∘ f) = 0.","fix":"Qualify the summary ('…when the kernels and cokernels are finite-dimensional') and give `index_comp` a docstring.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-a18148","file":"Mathlib/Algebra/Module/LinearMap/Index.lean","decl":"LinearMap.index_comp","line":113,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"There is no invariance of the index under composition with linear equivalences (`(e.toLinearMap ∘ₗ f).index = f.index`, `(f ∘ₗ e.toLinearMap).index = f.index`), which hold over any ring with no finiteness hypotheses; the only route is `index_comp`, which needs a division ring and four finiteness instances.","fix":"Add `LinearEquiv.index_comp` / `index_comp_linearEquiv` over `Ring` via `LinearEquiv.finrank_eq` on kernels and cokernels.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-115fbe","file":"Mathlib/Algebra/Module/LinearMap/Index.lean","decl":"LinearMap.index_smul","line":141,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"special-case-of-general","claim":"`index_smul` (field, `t ≠ 0`) is a special case of the statement for a unit of any commutative ring: `((u : R) • f).index = f.index` for `u : Rˣ`, with no nontriviality or finiteness hypothesis.","fix":"Prove the `Rˣ` version over `CommRing` and derive the field version from it (`Units.mk0 t ht`).","ev":"example {R M N : Type*} [CommRing R] [AddCommGroup M] [AddCommGroup N] [Module R M] [Module R N]\n    (f : M →ₗ[R] N) (u : Rˣ) : ((u : R) • f).index = f.index := by\n  have hk : ((u : R) • f).ker = f.ker := by ext x; simp\n  have hr : ((u : R) • f).range = f.range := by\n    ext y; constructor\n    · rintro ⟨x, rfl⟩; exact ⟨(u : R) • x, by simp⟩\n    · rintro ⟨x, rfl⟩; exact ⟨(↑u⁻¹ : R) • x, by simp [smul_smul]⟩\n  rw [index_eq_finrank_sub, index_eq_finrank_sub, hk, hr]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261007-ac16d9","file":"Mathlib/Algebra/Module/PointwisePi.lean","decl":"vadd_univ_pi","line":37,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Set.vadd_set_univ_pi` (Algebra.Group.Pointwise.Set.Scalar), `vadd_univ_pi` (Algebra.Module.PointwisePi) state exactly the same thing (Lean-checked). Reviewer: to_additive images of Set.smul_set_univ_pi (Pointwise/Set/Scalar) and root smul_univ_pi (Algebra/Module/PointwisePi, which imports Scalar). The root copy is unused; deprecate it.","fix":"Deprecate `vadd_univ_pi` in favour of `Set.vadd_set_univ_pi`.","ev":"dupscan/Check.lean: `example := (@vadd_univ_pi : type_of% @Set.vadd_set_univ_pi)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 18, rating MAJOR): The imported `Set` theorem already supplies this entire additive statement under the same assumptions. The root declaration adds no specialization or automation role.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the names live in different namespaces, plausibly deliberate for discoverability/dot notation.","at":"2026-10-07","commit":""},{"id":"RT-20261007-24f512","file":"Mathlib/Algebra/Module/PointwisePi.lean","decl":"smul_univ_pi","line":37,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `smul_univ_pi` (Algebra.Module.PointwisePi), `Set.smul_set_univ_pi` (Algebra.Group.Pointwise.Set.Scalar) state exactly the same thing (Lean-checked). Reviewer: Root smul_univ_pi (PointwisePi, 2021) re-proves Set.smul_set_univ_pi from the imported Pointwise/Set/Scalar with the same `[∀ i, SMul K (R i)]` statement and proof (piMap_image_univ_pi). Unused; deprecate the root smul_pi family.","fix":"Deprecate `smul_univ_pi` in favour of `Set.smul_set_univ_pi`.","ev":"dupscan/Check.lean: `example := (@Set.smul_set_univ_pi : type_of% @smul_univ_pi)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 37, rating MAJOR): The imported `Set` theorem already states the result under arbitrary pointwise scalar actions; the root copy adds no capability.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the names live in different namespaces, plausibly deliberate for discoverability/dot notation.","at":"2026-10-07","commit":""},{"id":"RT-20261007-98f435","file":"Mathlib/Algebra/Module/PointwisePi.lean","decl":"smul_pi","line":42,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Set.smul_set_pi` (Algebra.Group.Action.Pointwise.Set.Basic), `smul_pi` (Algebra.Module.PointwisePi) state exactly the same thing (Lean-checked). Reviewer: Both state `c • I.pi s = I.pi (c • s)` for a group action and are proved separately. Root-namespace `smul_pi` is about Set.pi but lives outside `Set`, and it is used only by smul_pi₀, which in turn duplicates Set.smul_set_pi₀. Keep the Set.smul_set_* family and deprecate `smul_pi`/`smul_pi₀`.","fix":"Deprecate `smul_pi` in favour of `Set.smul_set_pi`.","ev":"dupscan/Check.lean: `example := (@smul_pi : type_of% @Set.smul_set_pi)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 29, rating MAJOR): The root theorem supplies neither weaker assumptions nor a different action. Consolidating into the `Set.smul_set_*` family is appropriate, with imports adjusted so existing importing files retain access.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the names live in different namespaces, plausibly deliberate for discoverability/dot notation.","at":"2026-10-07","commit":""},{"id":"RT-20261007-f7ec68","file":"Mathlib/Algebra/Module/PointwisePi.lean","decl":"vadd_pi","line":42,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `vadd_pi` (Algebra.Module.PointwisePi), `Set.vadd_set_pi` (Algebra.Group.Action.Pointwise.Set.Basic) state exactly the same thing (Lean-checked). Reviewer: to_additive images of root smul_pi (Algebra/Module/PointwisePi, 2021) and Set.smul_set_pi, with the same `[Group K] [∀ i, MulAction K (R i)]` statement. The root-namespace smul_pi/vadd_pi family is unused and duplicates the Set.smul_set_* family. Deprecate the root ones.","fix":"Deprecate `vadd_pi` in favour of `Set.vadd_set_pi`.","ev":"dupscan/Check.lean: `example := (@Set.vadd_set_pi : type_of% @vadd_pi)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 36, rating MAJOR): The root additive theorem adds no assumptions, specialization, or attributes beyond the `Set` version. Consolidating the source multiplicative family handles this duplication too.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the names live in different namespaces, plausibly deliberate for discoverability/dot notation.","at":"2026-10-07","commit":""},{"id":"RT-20261007-e52057","file":"Mathlib/Algebra/Module/Submodule/LinearMap.lean","decl":"Submodule.injective_subtype","line":100,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Submodule.subtype_injective` (Algebra.Module.Submodule.LinearMap), `Submodule.injective_subtype` (Algebra.Module.Submodule.LinearMap) state exactly the same thing (Lean-checked). Reviewer: Eight lines apart in the same section, both `Injective p.subtype := Subtype.coe_injective`. `subtype_injective` is the name used by Subgroup/Submonoid/Subring/SMulMemClass (line 58), so keep it and deprecate `Submodule.injective_subtype`, which has ~60 uses to migrate.","fix":"Deprecate `Submodule.injective_subtype` in favour of `Submodule.subtype_injective`.","ev":"dupscan/Check.lean: `example := (@Submodule.injective_subtype : type_of% @Submodule.subtype_injective)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 40, rating MINOR): Both have the same explicit submodule receiver, statement, and proof, so this is purely competing word order. The reported migration size makes it low-priority naming cleanup.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-09e770","file":"Mathlib/Algebra/Module/Submodule/Range.lean","decl":"Submodule.map_comap_eq_of_le","line":130,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Submodule.map_comap_eq_self` (Algebra.Module.Submodule.Range), `Submodule.map_comap_eq_of_le` (Algebra.Module.Submodule.Range) state exactly the same thing (Lean-checked). Reviewer: Same file: `p ≤ range f → (p.comap f).map f = p` is proved at line 130 (map_comap_eq_of_le) and at line 176 (map_comap_eq_self). Keep map_comap_eq_self (the Subgroup/Submonoid/Subring family name, several uses) and deprecate map_comap_eq_of_le (1 use).","fix":"Deprecate `Submodule.map_comap_eq_of_le` in favour of `Submodule.map_comap_eq_self`.","ev":"dupscan/Check.lean: `example := (@Submodule.map_comap_eq_of_le : type_of% @Submodule.map_comap_eq_self)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 39, rating MAJOR): Both infer the map and submodule from the same range-containment hypothesis, with no attribute distinction. The two proofs do not support different APIs.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-6603f9","file":"Mathlib/Algebra/Order/Nonneg/Basic.lean","decl":"Nonneg.nsmul_coe","line":156,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Nonneg.coe_nsmul` (Algebra.Order.Nonneg.Basic), `Nonneg.nsmul_coe` (Algebra.Order.Nonneg.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file, `↑(n • a) = n • ↑a` proved twice (rfl with @[simp, norm_cast] vs `coeAddMonoidHom.map_nsmul` with @[norm_cast]). Keep `coe_nsmul` (standard `coe_nsmul` name, simp), deprecate `nsmul_coe` (essentially unused).","fix":"Deprecate `Nonneg.nsmul_coe` in favour of `Nonneg.coe_nsmul`.","ev":"dupscan/Check.lean: `example := (@Nonneg.nsmul_coe : type_of% @Nonneg.coe_nsmul)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 41, rating MAJOR): The retained theorem already has both `[simp]` and `[norm_cast]`; the second theorem contributes no missing cast-normalization role.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-279dce","file":"Mathlib/Algebra/Order/Ring/Ordering/Defs.lean","decl":"RingPreordering.copy_eq","line":122,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `RingPreordering.copy_eq` (Algebra.Order.Ring.Ordering.Defs), `RingPreordering.coe_copy` (Algebra.Order.Ring.Ordering.Defs) have exactly the same statement (Lean-checked), so `RingPreordering.copy_eq` does not state what its name promises and the intended lemma is missing. Reviewer: copy_eq is mis-stated: `P.copy S hS = S` coerces to `↑(P.copy S hS) = S`, which is exactly the @[simps]-generated coe_copy. Every other copy_eq in Mathlib (Subgroup, Submonoid, Subalgebra, ...) states `P.copy S hS = P`. It is unused; restate as `= P` (via SetLike.coe_injective hS). Astra rates it CRITICAL (a lemma weaker than or unrelated to its name).","fix":"Restate `RingPreordering.copy_eq` as its name says (keep `RingPreordering.coe_copy`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@RingPreordering.coe_copy : type_of% @RingPreordering.copy_eq)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 4, rating CRITICAL): Equality with the replacement carrier is meaningful, but that is precisely `coe_copy`’s job. The conventional `copy_eq` statement concerns the bundled object. Correct: `P.copy S hS = P`, proved by `SetLike.coe_injective hS`. The accidental coercion changes which equality is exposed. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Algebra/Order/Ring/Ordering/Defs.lean#L108-L122)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-d2abcf","file":"Mathlib/Algebra/Order/Ring/Unbundled/Basic.lean","decl":"mul_le_mul_of_nonpos_of_nonneg'","line":104,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `mul_le_mul_of_nonpos_of_nonneg'` (Algebra.Order.Ring.Unbundled.Basic), `mul_le_mul_of_nonneg_of_nonpos'` (Algebra.Order.Ring.Unbundled.Basic) have exactly the same statement (Lean-checked), so `mul_le_mul_of_nonpos_of_nonneg'` does not state what its name promises and the intended lemma is missing. Reviewer: This is a copy-paste mis-statement. mul_le_mul_of_nonpos_of_nonneg' has exactly the hypotheses (hca hbd ha:0≤a hd:d≤0) and the proof of mul_le_mul_of_nonneg_of_nonpos'. The intended primed form is the one `mul_le_mul_of_nonpos_of_nonneg''` states (a ≤ c, d ≤ b, a ≤ 0, 0 ≤ d). Deprecate the bad lemma (unused) and later rename `''` to `'`. Astra rates it CRITICAL (a lemma weaker than or unrelated to its name).","fix":"Restate `mul_le_mul_of_nonpos_of_nonneg'` as its name says (keep `mul_le_mul_of_nonneg_of_nonpos'`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@mul_le_mul_of_nonneg_of_nonpos' : type_of% @mul_le_mul_of_nonpos_of_nonneg')` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 10, rating CRITICAL): The neighboring sign-pattern family makes the intended interpretation clear. Correct hypotheses are `(hac : a ≤ c) (hdb : d ≤ b) (ha : a ≤ 0) (hd : 0 ≤ d)`, concluding `a * b ≤ c * d`. **That exact lemma already exists as `mul_le_mul_of_nonpos_of_nonneg''`**, so the missing-lemma assertion is false even though the name/statement mismatch is real. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Algebra/Order/Ring/Unbundled/Basic.lean#L89-L113)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261006-f2ccda","file":"Mathlib/Algebra/Order/Sub/Unbundled/Hom.lean","decl":"le_tsub_mul","line":35,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`le_tsub_mul` assumes `[NonUnitalCommSemiring R] [MulLeftMono R]` and gets the right-multiplication inequality by commuting. It holds for any `[Distrib R] [Preorder R] [Sub R] [OrderedSub R] [MulRightMono R]` (the mirror of `le_mul_tsub`, via `AddHom.mulRight`), so it does not apply to noncommutative ordered semirings.","fix":"State it with `[Distrib R] [MulRightMono R]` and prove it by `(AddHom.mulRight c).le_map_tsub (monotone_id.mul_const' c) _ _`.","ev":"-- hunts/ordsub-hom/P.lean: `theorem le_tsub_mul' [Distrib R] [Preorder R] [Sub R] [OrderedSub R] [MulRightMono R] : a * c - b * c ≤ (a - b) * c := (AddHom.mulRight c).le_map_tsub (monotone_id.mul_const' c) _ _` compiles; `le_tsub_mul` at a noncommutative `[Semiring R] [MulRightMono R]` fails (cannot synthesize `NonUnitalCommSemiring`).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-399c06","file":"Mathlib/Algebra/Order/Sub/Unbundled/Hom.lean","decl":"map_tsub_of_le","line":41,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`map_tsub_of_le` assumes a global `[AddLeftReflectLE β]`, but the proof needs cancellation only at `f b` (`AddLECancellable (f b)`). This excludes targets like `ℝ≥0∞`, where finite values are cancellable but `∞` is not (e.g. `Nat.cast : ℕ →+ ℝ≥0∞`). Astra also notes that `[AddLeftMono α]` follows from `OrderedSub α` plus commutativity.","fix":"Take `(hfb : AddLECancellable (f b))` (keep the instance version as a corollary) and derive `AddLeftMono α` locally.","ev":"-- hunts/ordsub-hom/P2.lean: `theorem map_tsub_of_le' ... (h : b ≤ a) (hfb : AddLECancellable (f b)) : f a - f b = f (a - b)` without `[AddLeftReflectLE β]`, by `conv => lhs; rw [← tsub_add_cancel_of_le h]; rw [map_add, hfb.add_tsub_cancel_right]`, compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-0306ff","file":"Mathlib/Algebra/Order/Sub/Unbundled/Hom.lean","decl":"AddMonoidHom.le_map_tsub","line":66,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`AddMonoidHom.le_map_tsub` inherits `[AddCommMonoid α]` from the section, but `f : α →+ β` and the proof (`f.toAddHom.le_map_tsub`) need only `[AddZeroClass α]`.","fix":"Use `[AddZeroClass α]` for this lemma (the section's `AddCommMonoid` is otherwise unused).","ev":"-- hunts/ordsub-hom/P.lean: `AddMonoidHom.le_map_tsub'` with `[Preorder α] [AddZeroClass α] [Sub α] [OrderedSub α]` compiles by the same term.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-55fe0d","file":"Mathlib/Algebra/Polynomial/Degree/Support.lean","decl":"Polynomial.nonempty_support_iff","line":114,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Polynomial.support_nonempty` (Algebra.Polynomial.Basic), `Polynomial.nonempty_support_iff` (Algebra.Polynomial.Degree.Support) state exactly the same thing (Lean-checked). Reviewer: `p.support.Nonempty ↔ p ≠ 0` proved twice. Keep the @[simp] `support_nonempty` in Polynomial/Basic (lower in the import graph), deprecate `nonempty_support_iff` in Degree/Support (2 uses: Degree/Support:128, TrailingDegree:263).","fix":"Deprecate `Polynomial.nonempty_support_iff` in favour of `Polynomial.support_nonempty`.","ev":"dupscan/Check.lean: `example := (@Polynomial.nonempty_support_iff : type_of% @Polynomial.support_nonempty)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 42, rating MAJOR): The higher-import theorem adds no degree-specific hypothesis or interface. The existing lower-import simp theorem supplies everything needed.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: both names are in active use (drop side 5 uses), so the pair looks like intended API.","at":"2026-10-07","commit":""},{"id":"RT-20261007-a9d4ba","file":"Mathlib/Algebra/Polynomial/Smeval.lean","decl":"(file)","line":25,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-name-in-module-doc","claim":"The module docstring is stale: \"Main definitions\" lists `smeval.algebraMap` (\"the `smeval` function as an `R`-algebra map\"), which does not exist anywhere in Mathlib, and the TODO asks for \"`smeval_neg` … for `R` a ring and `S` an `AddCommGroup`\", which the file already proves (L154, together with `smeval_sub`).","fix":"Drop the `smeval.algebraMap` bullet (or add the definition) and remove the `smeval_neg` TODO item.","ev":"`git grep 'smeval.algebraMap\\|smeval_algebraMap' origin/master -- Mathlib`: only the docstring line; `smeval_neg` at L154.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-ab36b1","file":"Mathlib/Algebra/Polynomial/Smeval.lean","decl":"Polynomial.smeval_neg_nat","line":161,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"overly-specific-statement","claim":"`smeval_neg_nat` (evaluating `q : ℕ[X]` at `-(n : S)` versus at `(-n : ℤ)` then casting) holds for every integer point, `q.smeval (z : S) = (q.smeval z : S)`, by the same `simp`; and the signed constant lemma `smeval_intCast : (z : R[X]).smeval x = z • x ^ 0` is missing although its natural-number sibling `smeval_natCast` exists and it is one line from `smeval_C`.","fix":"Add `smeval_at_intCast` (deriving `smeval_neg_nat`) and `smeval_intCast`.","ev":"probe2.lean: the `z : ℤ` version closes by `simp only [smeval_eq_sum, smul_pow, sum_def]` (a trailing `simp` reports no goals); `smeval_intCast` by `simpa only [map_intCast, Int.cast_smul_eq_zsmul] using smeval_C (z : R) x`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-6f4e8f","file":"Mathlib/Algebra/Polynomial/Smeval.lean","decl":"Polynomial.smeval_C_mul","line":182,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"Several lemmas carry stronger hypotheses on `S` than they use. `smeval_C_mul` sits in the `[NonAssocSemiring S]` section but needs no multiplication on `S`: it is `smul_eq_C_mul` + `smeval_smul` under `[AddCommMonoid S] [Module R S]`. `smeval_X_pow_assoc` (and by the same sum argument `smeval_assoc_X_pow`, `smeval_at_zero`, `smeval_commute_left`, `smeval_commute`) needs only `[MulActionWithZero R S]`, not `[Module R S]`, excluding e.g. the non-distributive zero-preserving actions.","fix":"Move `smeval_C_mul` into `section Module` (2-line proof); state the sum-based lemmas under `MulActionWithZero`.","ev":"probe2.lean: `smeval_C_mul` under `[AddCommMonoid S] [Module R S]` by `rw [← smul_eq_C_mul, smeval_smul]`, and `smeval_X_pow_assoc` under `[MulActionWithZero R S]` by `simp only [smeval_eq_sum, sum_def, smul_pow, Finset.mul_sum, mul_smul_comm, npow_mul_assoc]` both compile.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-581b6e","file":"Mathlib/Algebra/Ring/Basic.lean","decl":"div_neg_eq_neg_div","line":266,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `div_neg_eq_neg_div` (Algebra.Ring.Basic), `div_neg` (Algebra.Ring.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file: `div_neg_eq_neg_div (a b) : b / -a = -(b / a)` and `div_neg (a) : a / -b = -(a / b)` are equal up to binder names and explicitness; `div_neg` is even proved by `rw [← div_neg_eq_neg_div]`. Keep `div_neg` (standard name), deprecate the Lean-3-core `div_neg_eq_neg_div` (7 uses).","fix":"Deprecate `div_neg_eq_neg_div` in favour of `div_neg`.","ev":"dupscan/Check.lean: `example := (@div_neg : type_of% @div_neg_eq_neg_div)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 44, rating MAJOR): The denominator can still be specified by a named argument to `div_neg`; the older theorem has no separate normalization role. Move its proof earlier as needed for intervening users.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the two declarations differ in which arguments are explicit, which Mathlib sometimes keeps deliberately for rewriting.","at":"2026-10-07","commit":""},{"id":"RT-20261007-b29b82","file":"Mathlib/Algebra/Ring/Subsemiring/Basic.lean","decl":"RingHom.rangeS_top_iff_surjective","line":791,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `RingHom.rangeS_top_iff_surjective` (Algebra.Ring.Subsemiring.Basic), `RingHom.rangeS_eq_top` (Algebra.Ring.Subsemiring.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file, `f.rangeS = ⊤ ↔ Surjective f` proved twice. `range_eq_top` is the Mathlib-wide name (MonoidHom, Subring, LinearMap, Lie, ModelTheory...), so keep `rangeS_eq_top` and deprecate `rangeS_top_iff_surjective` (used once, in `rangeS_top_of_surjective`).","fix":"Deprecate `RingHom.rangeS_top_iff_surjective` in favour of `RingHom.rangeS_eq_top`.","ev":"dupscan/Check.lean: `example := (@RingHom.rangeS_eq_top : type_of% @RingHom.rangeS_top_iff_surjective)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 43, rating MAJOR): These are the same range-surjectivity characterization, and the later corollary can use `rangeS_eq_top.2` directly. No special attribute depends on the duplicate.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-6091bf","file":"Mathlib/Algebra/Ring/SumsOfSquares.lean","decl":"(file)","line":15,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-names-missing-decl","claim":"The module docstring's Main declarations name `AddMonoid.sumSq R`, which does not exist (the declaration is `AddSubmonoid.sumSq`), omit `NonUnitalSubsemiring.sumSq`, describe `Subsemiring.sumSq` as 'in a semiring' though it needs commutativity (in M₂(ℕ) the product of the idempotents [[1,1],[0,0]] and [[0,0],[0,1]] is not a sum of squares, Astra A1 item 4), and say 'if `S` is a sum of squares, then … `a * a + s`' (the variable is `s`).","fix":"Name `AddSubmonoid.sumSq`, add `NonUnitalSubsemiring.sumSq`, fix `S`→`s`.","ev":"Measured: source L22-27; `grep -rn 'AddMonoid.sumSq' Mathlib` finds only this docstring; probe1 (C) `#check @AddSubmonoid.sumSq` compiles.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-4823d5","file":"Mathlib/Algebra/Ring/SumsOfSquares.lean","decl":"IsSumSq","line":43,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"Missing characteristic API for `IsSumSq`: no `IsSumSq.map` (sums of squares are preserved by ring homomorphisms; a 3-line induction), no single-square `IsSumSq.sq : IsSumSq (a ^ 2)` (only the finite-sum `sum_sq` and `mul_self`), and no bridge to an explicit finite representation (`∃ l : List R, (∀ x ∈ l, IsSquare x) ∧ l.sum = s`, available via `AddSubmonoid.exists_list_of_mem_closure` + `closure_isSquare`) (Astra A1 items 6-8). Astra's item 3 (`natCast` under `[AddMonoidWithOne R] [MulOneClass R]`) fails: the two classes carry unrelated `1`s (hunts/sums-of-squares/probe2.lean (E) does not compile).","fix":"Add `IsSumSq.map`, `IsSumSq.sq` and the list characterisation.","ev":"hunts/sums-of-squares/probe2.lean (F): `IsSumSq (f s)` for `f : R →+* S` by induction compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-2fa495","file":"Mathlib/Algebra/Ring/SumsOfSquares.lean","decl":"IsSumSq.sum_sq","line":139,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`IsSumSq.sum_sq` assumes `[CommSemiring R]`, but `IsSumSq (∑ i ∈ I, a i ^ 2)` holds in any `[AddCommMonoid R] [Monoid R]` (in particular any non-commutative semiring) by `simp [sq]` from `IsSumSq.sum_mul_self`; commutativity is never used.","fix":"Weaken to `[AddCommMonoid R] [Monoid R]` (or `[Semiring R]`).","ev":"hunts/sums-of-squares/probe1.lean (A), (B): both versions compile (only `simpa`→`simp` linter warnings).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-e3d135","file":"Mathlib/Algebra/Ring/SumsOfSquares.lean","decl":"IsSumSq.nonneg","line":223,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`IsSumSq.nonneg` assumes `[IsStrictOrderedRing R]`, but the proof needs only `[PosMulMono R] [AddLeftMono R]` (with `[Semiring R] [LinearOrder R] [ExistsAddOfLE R]`): strictness, nontriviality and additive cancellation are unused, so e.g. the Boolean semiring (∨, ∧, false < true) is excluded (Astra A1 item 2).","fix":"Weaken to `[PosMulMono R] [AddLeftMono R]`.","ev":"hunts/sums-of-squares/probe2.lean (D): the original induction compiles under the weaker classes.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-cd83d7","file":"Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean","decl":"SkewMonoidAlgebra.single_zero_right","line":252,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `SkewMonoidAlgebra.single_zero` (Algebra.SkewMonoidAlgebra.Basic), `SkewMonoidAlgebra.single_zero_right` (Algebra.SkewMonoidAlgebra.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file, 8 lines apart: `single a 0 = 0` is proved by `simp [← coeff_inj]` both times. Keep @[simp] single_zero (Finsupp naming) and deprecate single_zero_right (unused).","fix":"Deprecate `SkewMonoidAlgebra.single_zero_right` in favour of `SkewMonoidAlgebra.single_zero`.","ev":"dupscan/Check.lean: `example := (@SkewMonoidAlgebra.single_zero_right : type_of% @SkewMonoidAlgebra.single_zero)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 45, rating MAJOR): Both concern zero in the coefficient slot, and the retained theorem already supplies simplification. `_right` introduces no complementary zero-case result.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-778a22","file":"Mathlib/Algebra/Squarefree/Basic.lean","decl":"squarefree_iff_no_irreducibles","line":129,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `squarefree_iff_no_irreducibles` (Algebra.Squarefree.Basic), `squarefree_iff_irreducible_sq_not_dvd_of_ne_zero` (Algebra.Squarefree.Basic) state exactly the same thing (Lean-checked). Reviewer: Same section ([CommMonoidWithZero R] [WfDvdMonoid R]), same iff under `x ≠ 0`. The `_of_ne_zero` lemma is proved roundabout through a lemma that itself uses `squarefree_iff_no_irreducibles`. Keep the family name (paired with `_of_exists_irreducible`), move the direct proof into it, and deprecate no_irreducibles.","fix":"Deprecate `squarefree_iff_no_irreducibles` in favour of `squarefree_iff_irreducible_sq_not_dvd_of_ne_zero`.","ev":"dupscan/Check.lean: `example := (@squarefree_iff_irreducible_sq_not_dvd_of_ne_zero : type_of% @squarefree_iff_no_irreducibles)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 46, rating MAJOR): The longer name accurately describes the irreducible-square condition and fits the adjacent family. Moving the direct proof before its consumers removes the duplication without creating a dependency cycle.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-f452b1","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"NonUnitalStarRingHom","line":42,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"copied-notation-docstring-omits-star","claim":"The notation docstring at L47 says '`α →⋆ₙ+* β` denotes the type of non-unital ring homomorphisms', which omits the star condition. It was copied verbatim from `→ₙ+*` (Ring/Hom/Defs.lean:63), whereas the analogue `→⋆ₙₐ` uses `@[inherit_doc NonUnitalStarAlgHom]`. The module docstring also lists only `NonUnitalStarRingHom` under Main definitions and describes only that morphism type, although the file also defines `StarRingEquiv`, `NonUnitalStarRingHomClass` and `StarRingEquivClass`.","fix":"Use `@[inherit_doc NonUnitalStarRingHom]` on the notation (as `→⋆ₙₐ` does) and add `StarRingEquiv` and the two classes to the module docstring's Main definitions.","ev":"git grep (origin/master): StarRingHom.lean:47 `/-- `α →⋆ₙ+* β` denotes the type of non-unital ring homomorphisms from `α` to `β`. -/`; Ring/Hom/Defs.lean:63 `/-- `α →ₙ+* β` denotes the type of non-unital ring homomorphisms from `α` to `β`. -/`; StarAlgHom.lean:59 `@[inherit_doc NonUnitalStarAlgHom] infixr:25 \" →⋆ₙₐ \" => NonUnitalStarAlgHom _`; top-level structures/classes in the file: NonUnitalStarRingHom (L42), NonUnitalStarRingHomClass (L59), StarRingEquiv (L238), StarRingEquivClass (L252), but Main definitions lists only `NonUnitalStarRingHom`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-1fde1b","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"NonUnitalStarRingHom","line":42,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-forgetful-coe-and-injective-api","claim":"Nothing connects the projection `f.toNonUnitalRingHom` to the class coercion `(f : A →ₙ+* B)`. They are equal by `rfl`, but there is no `toNonUnitalRingHom_eq_coe`, so `simp` cannot identify them. The `add_decl_doc` tells users to prefer the coercion, yet `comp`, `DirectLimit.lift` and `CentroidHom` use the projection. There is also no `toNonUnitalRingHom_injective`. The ring-side analogues `RingEquiv.toNonUnitalRingHom_eq_coe`, `RingEquiv.toNonUnitalRingHom_injective`, `AlgHom.toRingHom_eq_coe` and `AlgHom.toRingHom_injective` all exist.","fix":"Add `@[simp] toNonUnitalRingHom_eq_coe : f.toNonUnitalRingHom = ↑f := rfl` and `toNonUnitalRingHom_injective` (one line via `ext`/`DFunLike.congr_fun`).","ev":"hunts/star-ringhom/batch0/probe1.lean section P4: `example (f : A →⋆ₙ+* B) : f.toNonUnitalRingHom = (f : A →ₙ+* B) := rfl` compiles; `example (f : A →⋆ₙ+* B) (g : C →ₙ+* A) : f.toNonUnitalRingHom.comp g = (f : A →ₙ+* B).comp g := by simp` fails with '`simp` made no progress' (L104); `#check @NonUnitalStarRingHom.toNonUnitalRingHom_injective` fails with 'Unknown constant' (L107); `example : Function.Injective (NonUnitalStarRingHom.toNonUnitalRingHom : (A →⋆ₙ+* B) → A →ₙ+* B) := fun _ _ h => NonUnitalStarRingHom.ext fun x => DFunLike.congr_fun h x` compiles.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-2f0622","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"NonUnitalStarRingHomClass","line":59,"sev":"MINOR","status":"pr-open","cat":"reuse","pattern":"mixin-class-duplicating-starhomclass","claim":"`NonUnitalStarRingHomClass F A B` adds no field to `StarHomClass F A B` (it `extends StarHomClass` with the ring-hom structure only as a parameter), so under `[NonUnitalRingHomClass F A B]` the two are equivalent (proved both ways). It survived Mathlib PR #16591, which deprecated `StarAlgHomClass`, `NonUnitalStarAlgHomClass` and `StarAlgEquivClass` for exactly this reason. Downstream cost: Lean never builds it from the standard mixin pair — the only bridge (`StarAlgHom.lean:82`) needs a `NonUnitalAlgHomClass F R A B` instance (it does fire for algebra homs, `R` being an outParam), so for `F` with just `[NonUnitalRingHomClass F A B] [StarHomClass F A B]`, `NonUnitalStarRingHom.ofClass f`, `StarRingEquiv.ofStarRingHom`/`ofBijective` and the instance `StarRingHomClass.instOrderHomClass` (monotonicity) are unavailable; `inferInstance` fails for both `NonUnitalStarRingHomClass F A B` and `OrderHomClass F R S`.","fix":"Deprecate `NonUnitalStarRingHomClass` in favour of `StarHomClass` and use `[NonUnitalRingHomClass F A B] [StarHomClass F A B]` in `ofClass`, `coe_ofClass`, the `Bijective` section and `StarRingHomClass.instOrderHomClass`; give `A →⋆ₙ+* B` a direct `StarHomClass` instance.","ev":"hunts/star-ringhom/batch0/probe1.lean P2a `example : NonUnitalStarRingHomClass F A B ↔ StarHomClass F A B := ⟨fun h => h.toStarHomClass, fun h => { toStarHomClass := h }⟩` compiles; P2b `example [StarHomClass F A B] : NonUnitalStarRingHomClass F A B := inferInstance` fails (synthInstanceFailed, L58, with StarAlgHom imported); P2c `NonUnitalStarRingHom.ofClass f` under `[StarHomClass F A B]` fails (L61); P3a `OrderHomClass F R S := inferInstance` under `[NonUnitalRingHomClass F R S] [StarHomClass F R S]` fails (L84), while P3b `map_rel f := (P2ofClass f).map_le_map_of_map_star` compiles; hunts/star-ringhom/batch0/src_noclass.lean (class deleted, binders → `StarHomClass`, L100 instance → `StarHomClass`, L267 instance removed) compiles with exit 0 and no warnings.","evr":"compiles","astraV":"agrees","astraS":"A2 (targeted refutation): agrees, MAJOR under the stated definition — duplicate content of `StarHomClass`, same rationale as #16591, and the generic instance-search gap is real. Correction adopted: the `StarAlgHom.lean` bridge does fire when a `NonUnitalAlgHomClass` instance exists (R is an outParam), so bundled star-algebra homs keep monotonicity; the gap is maps carrying only the ring-hom + star mixins. A1 blind pass independently raised the same point (P2, item 4).","pr":44575,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a redundant class equal to `StarHomClass` is not MAJOR.","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-4f20a6","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"_root_.NonUnitalStarRingHom.ofClass","line":72,"sev":"MINOR","status":"pr-open","cat":"generality","pattern":"ofclass-stronger-than-starhomclass","claim":"`ofClass` assumes `[NonUnitalStarRingHomClass F A B]` but uses only `map_star`, so `[StarHomClass F A B]` suffices. The analogue `NonUnitalStarAlgHom.ofClass` already takes `[StarHomClass F A B]`. The change is backward compatible, because the class extends `StarHomClass` and the generalised def is `rfl`-equal to the original. Without it, maps carrying the standard mixin pair cannot be bundled.","fix":"Replace `[NonUnitalStarRingHomClass F A B]` by `[StarHomClass F A B]` in `ofClass`.","ev":"hunts/star-ringhom/batch0/src_gen.lean (ofClass and coe_ofClass binders changed to `[StarHomClass F A B]`) compiles with exit 0; probe1.lean P2d `def P2ofClass [StarHomClass F A B] (f : F) : A →⋆ₙ+* B := { (f : A →ₙ+* B) with map_star' := map_star f }` compiles, P2e `P2ofClass f = NonUnitalStarRingHom.ofClass f := rfl` compiles, P2c original `ofClass` under `[StarHomClass F A B]` fails (L61).","evr":"compiles","astraV":"","astraS":"","pr":44575,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-e7ccee","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"coe_ofClass","line":109,"sev":"MINOR","status":"pr-open","cat":"generality","pattern":"ofclass-stronger-than-starhomclass","claim":"`NonUnitalStarRingHom.coe_ofClass` assumes `[NonUnitalStarRingHomClass F A B]`, but the statement and its `rfl` proof hold under `[StarHomClass F A B]`. The analogue `NonUnitalStarAlgHom.coe_ofClass` already uses `[StarHomClass F A B]`.","fix":"Replace `[NonUnitalStarRingHomClass F A B]` by `[StarHomClass F A B]` in `coe_ofClass`, together with `ofClass`.","ev":"hunts/star-ringhom/batch0/src_gen.lean (coe_ofClass with `[StarHomClass F A B]`, proof `rfl` unchanged) compiles with exit 0; probe1.lean P2d `theorem P2coe_ofClass [StarHomClass F A B] (f : F) : ⇑(P2ofClass f) = f := rfl` compiles.","evr":"compiles","astraV":"","astraS":"","pr":44575,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-fe863f","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"NonUnitalStarRingHom.comp","line":163,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-forgetful-comp-lemma","claim":"No lemma relates `comp` to `NonUnitalRingHom.comp` under the forgetful map: neither `(f.comp g).toNonUnitalRingHom = f.toNonUnitalRingHom.comp g.toNonUnitalRingHom` nor its class-coercion form `((f.comp g : A →⋆ₙ+* C) : A →ₙ+* C) = (f : B →ₙ+* C).comp g` exists, and `simp` proves neither. Analogues: `AlgHom.comp_toRingHom` (Mathlib/Algebra/Algebra/Hom.lean:272), `NonUnitalRingHom.toAddMonoidHom_comp`/`coe_comp_mulHom`.","fix":"Add `@[simp] toNonUnitalRingHom_comp` (rfl) relating `(f.comp g).toNonUnitalRingHom` to `NonUnitalRingHom.comp`.","ev":"hunts/star-ringhom/batch1/P1.lean: `example (f : B →⋆ₙ+* C) (g : A →⋆ₙ+* B) : (f.comp g).toNonUnitalRingHom = f.toNonUnitalRingHom.comp g.toNonUnitalRingHom := by fail_if_success (simp; done); rfl` and the coercion form `((f.comp g : A →⋆ₙ+* C) : A →ₙ+* C) = (f : B →ₙ+* C).comp (g : A →ₙ+* B) := by fail_if_success (simp; done); rfl` compile (simp fails outright); `#check @NonUnitalStarRingHom.toNonUnitalRingHom_comp` gives `Unknown constant`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-da3a6d","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"NonUnitalStarRingHom.instMonoid","line":188,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-monoid-end-simp-lemmas","claim":"The `Monoid (A →⋆ₙ+* A)` instance (`mul := comp`, `one := id`) comes with only `coe_one`/`one_apply`: there is no `one_def`, `mul_def`, `@[simp] coe_mul` or `coe_pow`, whereas `NonUnitalRingHom` has `one_def`, `mul_def` and `@[simp] coe_mul : ⇑(f * g) = ⇑f ∘ ⇑g` (Mathlib/Algebra/Ring/Hom/Defs.lean L272-284). Consequently `simp` cannot evaluate `(f * g) x` or `⇑(f ^ n)`. Open upstream PR #36878 ('override `npow` in compositional monoids', blocked-by-other-PR) rewrites this instance but adds none of these lemmas.","fix":"Add `one_def`, `mul_def`, `@[simp] coe_mul` (and `coe_pow : ⇑(f ^ n) = (⇑f)^[n]`) after the instance, mirroring `NonUnitalRingHom`.","ev":"hunts/star-ringhom/batch1/P1.lean + hunts/star-ringhom/batch1/P2.lean: `example (f g : A →⋆ₙ+* A) (x : A) : (f * g) x = f (g x) := by fail_if_success (simp; done); rfl`; `example (f g : A →⋆ₙ+* A) : ⇑(f * g) = f ∘ g := by fail_if_success (simp; done); rfl`; `example (f : A →⋆ₙ+* A) (n : ℕ) : ⇑(f ^ n) = (⇑f)^[n] := by fail_if_success (simp; done); induction n ...` all compile, and the unreachable-tactic linter reports that `done` never ran (simp fails outright); `#check @NonUnitalStarRingHom.coe_mul` / `mul_def` / `one_def` give `Unknown constant`. In hunts/star-ringhom/batch1/Copy.lean, adding `@[simp] theorem coe_mul (f g : A →⋆ₙ+* A) : ⇑(f * g) = f ∘ g := rfl` makes `by simp` close the first example.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-389339","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"NonUnitalStarRingHom.instZero","line":211,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"overstrong-typeclass-on-domain","claim":"`section Zero` (L206-209) assumes `[StarAddMonoid A]` on the domain for `instZero`, `instInhabited`, `coe_zero` and `zero_apply`, but the only star fact used is `star_zero` in the codomain `B` (`map_star'` for the zero map reads `0 = star 0` in `B`); `[Star A]` suffices. The section comment ('the `zero` requires extra type class assumptions because we need `star_zero`') is only true of `B`. Only `MonoidWithZero (A →⋆ₙ+* A)` genuinely needs `[StarAddMonoid A]` (there `A` is also the codomain). The template `NonUnitalStarAlgHom` (StarAlgHom.lean L225) carries the same over-restriction.","fix":"Give `Zero`/`Inhabited`/`coe_zero`/`zero_apply` the binders `[Star A] [StarAddMonoid B]` and keep `[StarAddMonoid A]` only for the `MonoidWithZero (A →⋆ₙ+* A)` instance.","ev":"hunts/star-ringhom/batch1/Copy.lean (copy of src.lean with `section Zero` rewritten to `variable [NonUnitalNonAssocSemiring A] [Star A] [NonUnitalNonAssocSemiring B] [StarAddMonoid B]`; `instance : Zero (A →⋆ₙ+* B) := ⟨{ (0 : NonUnitalRingHom A B) with map_star' := by simp }⟩`, `Inhabited`, `coe_zero`, `zero_apply` unchanged in body; `MonoidWithZero` moved to its own section with `[StarAddMonoid A]`; plus `example : (0 : A →⋆ₙ+* B) = default := rfl` under `[Star A] [StarAddMonoid B]`). Compiled with the batch flags: EXIT 0, no warnings (output hunts/star-ringhom/batch1/Copy.out).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-f9390b","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"NonUnitalStarRingHom.instZero","line":211,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-comp-zero-lemmas","claim":"The zero morphism has no `comp_zero`/`zero_comp` lemmas (`NonUnitalRingHom` has both as `@[simp]`, Mathlib/Algebra/Ring/Hom/Defs.lean L250-258); only the endomorphism special cases exist, inlined as the `zero_mul`/`mul_zero` fields of `MonoidWithZero (A →⋆ₙ+* A)`. `simp` cannot prove `g.comp (0 : A →⋆ₙ+* B) = 0` or `(0 : B →⋆ₙ+* C).comp f = 0`.","fix":"Add `@[simp] comp_zero` and `@[simp] zero_comp` for star ring homs between different types and define `MonoidWithZero`'s `zero_mul`/`mul_zero` from them.","ev":"hunts/star-ringhom/batch1/P1.lean: `example (g : B →⋆ₙ+* C) : g.comp (0 : A →⋆ₙ+* B) = 0 := by fail_if_success (simp; done); ext; simp` and `example (f : A →⋆ₙ+* B) : (0 : B →⋆ₙ+* C).comp f = 0 := by fail_if_success (simp; done); ext; simp` compile (simp fails outright); `#check @NonUnitalStarRingHom.comp_zero` / `zero_comp` give `Unknown constant`. hunts/star-ringhom/batch1/Copy.lean adds `comp_zero := ext fun _ => map_zero g`, `zero_comp := rfl` and `MonoidWithZero` with `zero_mul := zero_comp`, `mul_zero := comp_zero`; compiles.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-3f74b9","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"NonUnitalStarRingHom.zero_apply","line":225,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"domain-typeclass-only-needed-on-codomain","claim":"`zero_apply` (like the `Zero`/`Inhabited` instances and `coe_zero` it rests on) inherits `[StarAddMonoid A]` on the DOMAIN from the `section Zero` variables (L207-209), but only the codomain needs `star_zero` (the section comment at L206 justifies nothing more). With `[NonUnitalNonAssocSemiring A] [Star A] [NonUnitalNonAssocSemiring B] [StarAddMonoid B]` the zero map is an `A →⋆ₙ+* B` and `zero_apply` holds by `rfl`; only `MonoidWithZero (A →⋆ₙ+* A)` needs `StarAddMonoid A`. The existing `Zero` instance does not fire under `[Star A]`. (Same over-restriction in the `NonUnitalStarAlgHom` analogue.)","fix":"Weaken the `section Zero` domain assumption to `[Star A]` and give the `MonoidWithZero (A →⋆ₙ+* A)` instance its own `[StarAddMonoid A]` binder.","ev":"hunts/star-ringhom/batch2/probe1.lean section P2 (`fail_if_success have : Zero (A →⋆ₙ+* B) := inferInstance` under `[Star A]`; `def zeroHom' : A →⋆ₙ+* B := { (0 : A →ₙ+* B) with map_star' := by simp }` and `example (a : A) : zeroHom' (B := B) a = 0 := rfl` compile) and hunts/star-ringhom/batch2/copyA.lean (src.lean with the weakened `section Zero` compiles, including `example (a : A) : (0 : A →⋆ₙ+* B) a = 0 := NonUnitalStarRingHom.zero_apply a` with only `[Star A]` on A)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-99810e","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"StarRingEquiv","line":238,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"module-docstring-omits-main-definitions","claim":"The module docstring (L10-31) is not current: it describes only `NonUnitalStarRingHom` and its 'Main definitions' lists only `NonUnitalStarRingHom`; `StarRingEquiv` (notation `≃⋆+*`), `StarRingEquivClass` and `NonUnitalStarRingHomClass` are never mentioned although L233-478 (half the file) are about star ring equivalences.","fix":"List `StarRingEquiv` (`A ≃⋆+* B`), `StarRingEquivClass` and `NonUnitalStarRingHomClass` under Main definitions and mention equivalences in the summary paragraph.","ev":"src.lean L10-31 (module docstring: 'Main definitions * `NonUnitalStarRingHom`') vs L233 `/-! ### Star ring equivalences -/` through L478","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-b4d3db","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"StarRingEquiv","line":243,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"notation-rhs-precedence-zero","claim":"`notation:25 A \" ≃⋆+* \" B => StarRingEquiv A B` parses its right argument at precedence 0, so `A ≃⋆+* B → B` silently elaborates as `StarRingEquiv A (B → B)` (Pi instances supply `Add`/`Mul`/`Star`), whereas the unstarred `A ≃+* B → B` (`infixl:25`) and this file's own `→⋆ₙ+*` (`infixr:25`) bind tighter than `→`. No Mathlib usage relies on the current parse (`git grep -P '≃⋆\\+\\* [^\\s(),]+ →'` is empty), so the fix is free. The sibling `≃⋆*` (StarMulEquiv) has the same quirk.","fix":"Declare it as `@[inherit_doc] infixl:25 \" ≃⋆+* \" => StarRingEquiv`, matching `≃+*`.","ev":"import Mathlib.Algebra.Star.StarAlgHom\nimport Mathlib.Algebra.Star.Pi\n\n/-! Q3'. `notation:25 A \" ≃⋆+* \" B` takes its right argument at precedence 0, so\n`A ≃⋆+* B → B` silently elaborates as `A ≃⋆+* (B → B)`, whereas `A ≃+* B → B` is\n`(A ≃+* B) → B` (`≃+*` is `infixl:25`). -/\nvariable (A B : Type) [NonUnitalSemiring A] [StarRing A] [NonUnitalSemiring B] [StarRing B]\n\nexample : (A ≃⋆+* B → B) = StarRingEquiv A (B → B) := rfl\nexample : (A ≃+* B → B) = ((A ≃+* B) → B) := rfl\n\n-- with an `infixl:25` declaration (as for `≃+*`) the expected parse is obtained\nlocal infixl:25 \" ≃⋆+*' \" => StarRingEquiv\nexample : (A ≃⋆+*' B → B) = ((A ≃⋆+* B) → B) := rfl\n\n-- also batch2/probe2.lean L47: `example : (A ≃⋆+* B → C) = ((A ≃⋆+* B) → C) := rfl` fails with `failed to synthesize Add (B → C)`, while L45 (same with `≃+*`) compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-a7dd47","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"StarRingEquivClass","line":252,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"bundled-class-duplicates-mixin-pair","claim":"`StarRingEquivClass F A B` is equivalent to the mixin pair `[RingEquivClass F A B] [StarHomClass F A B]` (both directions are one-liners) yet restates `map_star` as its own field instead of reusing `StarHomClass`, which forces the hand-written priority-50 bridge instance at L261. Its siblings use the mixin pair: `StarMulEquiv` just provides `MulEquivClass` + `StarHomClass`, and `StarAlgEquiv.ofClass` takes `[NonUnitalAlgEquivClass F R A B] [StarHomClass F A B]` (`StarAlgEquivClass` no longer exists, only the deprecated alias `StarAlgEquivClass.toStarAlgEquiv`), so `StarAlgEquiv` must supply a separate `StarRingEquivClass` instance and the docstring's advice 'extend this typeclass when you extend `StarRingEquiv`' is not followed by the one structure that extends it.","fix":"Deprecate `StarRingEquivClass` in favour of `[RingEquivClass F A B] [StarHomClass F A B]` (as for `StarAlgEquiv`/`StarMulEquiv`), or at least make it `extends RingEquivClass F A B, StarHomClass F A B` (lowering the parent instance's priority, since `extends` projections get 1000) so L261 disappears.","ev":"hunts/star-ringhom/batch2/probe2.lean section Q1: `example [RingEquivClass F A B] [StarHomClass F A B] : StarRingEquivClass F A B := { map_star := map_star }` and the converse `inferInstance`s compile; `#check @StarAlgEquiv.ofClass` shows `[NonUnitalAlgEquivClass F R A B] → [StarHomClass F A B] → F → A ≃⋆ₐ[R] B`; `getInstancePriority?` gives 1000 for `extends` projections. hunts/star-ringhom/batch2/copyB.lean (class `extends RingEquivClass F A B, StarHomClass F A B`, L261 deleted) compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-e14008","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"StarRingEquiv.ofClass","line":273,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-coe-ofclass-simp-lemma","claim":"No `coe_ofClass` simp lemma: `simp` makes no progress on `⇑(StarRingEquiv.ofClass f) = f` or `StarRingEquiv.ofClass f a = f a` (both `rfl`), whereas the same file has `@[simp] NonUnitalStarRingHom.coe_ofClass` (L109) and StarAlgHom.lean has `NonUnitalStarAlgHom.coe_ofClass`/`StarAlgHom.coe_ofClass`. Since #43393 removed the `@[coe]` attribute from `ofClass`, such a lemma is the only simp route for `ofClass` terms (e.g. in `StarRingEquivClass.instOrderIsoClass`).","fix":"Add `@[simp] protected theorem StarRingEquiv.coe_ofClass (f : F) : ⇑(StarRingEquiv.ofClass f) = f := rfl`.","ev":"batch2/probe1.lean L105-113: `example (f : F) : ⇑(StarRingEquiv.ofClass f) = f := by fail_if_success (simp; done); rfl` (and the applied form) compile, with 'this tactic is never executed' on `done` at 108:25 and 112:25, i.e. simp makes no progress","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-294d98","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"StarRingEquiv.toNonUnitalStarRingHom","line":317,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"typeclass-stronger-than-target-structure","claim":"The section variables at L314 assume `[NonUnitalSemiring A] [StarRing A] [NonUnitalSemiring B] [StarRing B]`, but `toNonUnitalStarRingHom`, the coercion `instCoeOutNonUnitalStarRingHom` (L321), `toNonUnitalRingHom_toNonUnitalStarRingHom` and `coe_toNonUnitalStarRingHom` need only `[NonUnitalNonAssocSemiring _] [Star _]`, exactly what `A →⋆ₙ+* B` itself requires (cf. `RingEquiv.toNonUnitalRingHom` and `StarAlgEquiv.toNonUnitalStarAlgHom`, both stated for `NonUnitalNonAssocSemiring` + `Star`). Under the weaker classes `f.toNonUnitalStarRingHom` and `(f : A →⋆ₙ+* B)` fail to elaborate although `NonUnitalStarRingHom.ofClass f` works. Associativity and the `StarRing` axioms are never used.","fix":"Change the L314 `variable` line to `[NonUnitalNonAssocSemiring A] [Star A] [NonUnitalNonAssocSemiring B] [Star B]`.","ev":"hunts/star-ringhom/batch2/probe1.lean section P3 (`fail_if_success have := f.toNonUnitalStarRingHom` and `fail_if_success have : A →⋆ₙ+* B := f` under `[NonUnitalNonAssocSemiring] [Star]`; the same definition `toNonUnitalStarRingHom'` with its `rfl` lemmas compiles) and hunts/star-ringhom/batch2/copyA.lean (src.lean with L314 weakened compiles; its test `example (f : A ≃⋆+* B) : A →⋆ₙ+* B := f` works with `[NonUnitalNonAssocSemiring A] [Star A]`); only downstream consumer (Algebra/Order/Star/Basic.lean L472) uses stronger classes, so it is unaffected","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-be291a","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"StarRingEquiv.toNonUnitalStarRingHom","line":317,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-forgetful-map-refl-trans-lemmas","claim":"Missing characteristic API for the forgetful map: no `toNonUnitalStarRingHom_refl` (`= NonUnitalStarRingHom.id A`), `toNonUnitalStarRingHom_trans` (`= e₂.toNonUnitalStarRingHom.comp e₁.toNonUnitalStarRingHom`), `toNonUnitalStarRingHom_injective`, nor a lemma relating it to `NonUnitalStarRingHom.ofClass` (they agree by `rfl`). simp makes no progress on the refl/trans equations (both `rfl`). The analogues have them: `RingEquiv.toNonUnitalRingHom_refl`/`_trans`/`_injective`/`_eq_coe`, `StarAlgEquiv.toNonUnitalStarAlgHom_refl`/`_comp`.","fix":"Add `@[simp]` `toNonUnitalStarRingHom_refl` and `toNonUnitalStarRingHom_trans` (both `rfl`) and `toNonUnitalStarRingHom_injective`.","ev":"batch2/probe1.lean L64-79: refl and trans statements proved by `fail_if_success (simp; done); rfl` with 'this tactic is never executed' at 65:25 and 71:25 (simp makes no progress); injectivity via `StarRingEquiv.ext fun a => congr($h a)`; `f.toNonUnitalStarRingHom = NonUnitalStarRingHom.ofClass f := rfl`. `git grep 'StarRingEquiv.toNonUnitalStarRingHom_' origin/master -- Mathlib` finds nothing","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-4c1af6","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"StarRingEquiv.instCoeOutRingEquiv","line":333,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-coe-forgetful-simp-lemma","claim":"The coercion `A ≃⋆+* B → A ≃+* B` (`toRingEquiv`) has no `coe_toRingEquiv` simp lemma and there is no `toRingEquiv_injective`: simp makes no progress on `⇑(e : A ≃+* B) = e` or `(e : A ≃+* B) a = e a` (both `rfl`). As a consequence the simp lemma `toRingEquiv_symm` rewrites `e.symm.toRingEquiv x` to the stuck `e.toRingEquiv.symm x`, and simp cannot prove `e.symm.toRingEquiv x = e.symm x`. Analogues: `AlgEquiv.coe_toRingEquiv`/`AlgEquiv.toRingEquiv_injective`, `OrderRingIso.coe_toRingEquiv` (simp), `RingEquiv.coe_toMulEquiv`/`coe_toAddEquiv` (simp).","fix":"Add `@[simp] theorem coe_toRingEquiv (e : A ≃⋆+* B) : ⇑(e : A ≃+* B) = e := rfl` and `theorem toRingEquiv_injective : Function.Injective (toRingEquiv : (A ≃⋆+* B) → A ≃+* B)`.","ev":"batch2/probe1.lean L94-103 (`fail_if_success (simp; done); rfl` with 'this tactic is never executed' at 95:25 and 99:25; injectivity via `StarRingEquiv.ext fun a => RingEquiv.congr_fun h a`) and batch2/probe2.lean Q2 (`simp only [StarRingEquiv.toRingEquiv_symm]; guard_target =ₛ e.toRingEquiv.symm x = e.symm x; rfl` compiles; plain `simp` does not close it)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-f233bd","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"StarRingEquiv.refl","line":345,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-refl-coercion-api","claim":"`refl` lacks lemmas for its images under the forgetful maps. There is no `toRingEquiv_refl : (refl : A ≃⋆+* A).toRingEquiv = RingEquiv.refl A` and no `toNonUnitalStarRingHom_refl : refl.toNonUnitalStarRingHom = NonUnitalStarRingHom.id A`. Both hold by `rfl`, and `simp` proves neither. The siblings have the corresponding lemmas: `RingEquiv.coe_mulEquiv_refl`/`coe_addEquiv_refl` and `StarAlgEquiv.toAlgEquiv_refl`/`toNonUnitalStarAlgHom_refl`/`toStarAlgHom_refl`. In addition, `A` is implicit (`StarRingEquiv.refl : {A : Type} → … → A ≃⋆+* A`), whereas `RingEquiv.refl` and `StarAlgEquiv.refl` take their types explicitly. Callers therefore write `StarRingEquiv.refl (A := A)` (StarAlgHom.lean:723) or ascriptions such as `(StarRingEquiv.refl : A ≃⋆+* A)` (`refl_symm`, L401). (`refl_apply` is not needed, since simp proves `refl x = x` from `coe_refl`.)","fix":"Add `@[simp] toRingEquiv_refl` and (in the `StarRing` section) `@[simp] toNonUnitalStarRingHom_refl`, both by `rfl`; consider making `A` explicit (`variable (A) in`) to match `RingEquiv.refl R`.","ev":"hunts/star-ringhom/batch3/probe1.lean section reflApi: `example : (StarRingEquiv.refl : A ≃⋆+* A).toRingEquiv = RingEquiv.refl A := by fail_if_success (simp; done); rfl` compiles, with `done` reported as never executed. `#check @StarRingEquiv.refl` prints `{A : Type u_1} → … → A ≃⋆+* A`, while `RingEquiv.refl : (R : Type u_1) → …`. hunts/star-ringhom/batch3/probe3.lean: `example : (StarRingEquiv.refl : A ≃⋆+* A).toNonUnitalStarRingHom = NonUnitalStarRingHom.id A := by fail_if_success (simp; done); rfl` compiles, with `done` never executed. In hunts/star-ringhom/batch3/probe2_src.lean, `@[simp] toRingEquiv_refl` passes `#lint only simpNF`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-59b796","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"StarRingEquiv.symm","line":358,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-symm-apply-eq-api","claim":"`StarRingEquiv.symm` is missing the standard `symm_apply_eq : e.symm x = y ↔ x = e y` and `eq_symm_apply : y = e.symm x ↔ e y = x`. Both siblings have them: `RingEquiv.symm_apply_eq`/`eq_symm_apply` (Ring/Equiv.lean:316,319) and `StarAlgEquiv.symm_apply_eq`/`eq_symm_apply` (StarAlgHom.lean:754,758). `simp` proves neither for `StarRingEquiv`: the generic `EquivLike` lemmas are stated for `EquivLike.inv e`, which `invFun_eq_symm` rewrites away. Each is a one-line reproof via `e.toRingEquiv`. `git grep` finds neither name for StarRingEquiv.","fix":"Add `symm_apply_eq` and `eq_symm_apply`, proved by `e.toRingEquiv.symm_apply_eq` and `e.toRingEquiv.eq_symm_apply`, as in StarAlgEquiv.","ev":"hunts/star-ringhom/batch3/probe1.lean section symmApplyEq: `example (e : A ≃⋆+* B) {x : B} {y : A} : e.symm x = y ↔ x = e y := by fail_if_success (simp; done); exact e.toRingEquiv.symm_apply_eq` and the `eq_symm_apply` analogue. Both compile, and `done` is reported as never executed, so simp fails. The two lemmas also compile in hunts/star-ringhom/batch3/probe2_src.lean.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-c947a9","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"StarRingEquiv.toRingEquiv_symm","line":365,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-coercion-simp-lemmas","claim":"`@[simp] toRingEquiv_symm` rewrites `e.symm.toRingEquiv` to `e.toRingEquiv.symm`, but the file has no lemma that turns `⇑e.toRingEquiv` or `⇑e.toRingEquiv.symm` back into `⇑e` or `⇑e.symm`. Since `StarRingEquiv.toRingEquiv_eq_coe` was deprecated, there is no `coe_toRingEquiv : ⇑(e : A ≃+* B) = e`, no `coe_toRingEquiv_symm`, and no `toRingEquiv_injective`. As a result `simp` fails on several rfl goals: `(e.symm : B ≃+* A) x = e.symm x`, `⇑(e : A ≃+* B).symm = ⇑e.symm`, `⇑(e : A ≃+* B) = ⇑e`, and `(e : A ≃+* B) (x * y) = e x * e y` (simp makes progress with `map_mul` and then gets stuck). The stuck goal is confusing to read: `toRingEquiv` is a parent projection without `@[coe]`, so it prints as `⊢ e.symm x = e.symm x`. RingEquiv pairs its `@[simp] coe_toEquiv_symm` with `coe_toEquiv` and `coe_coe_toEquiv_symm`. StarAlgEquiv has `coe_toAlgEquiv`, `coe_symm_toAlgEquiv` and `toAlgEquiv_injective`. `git grep` on origin/master finds no `StarRingEquiv.coe_toRingEquiv`, `coe_toRingEquiv_symm` or `toRingEquiv_injective`.","fix":"Add `@[simp] coe_toRingEquiv (e) : ⇑(e : A ≃+* B) = e := rfl`, `@[simp] coe_toRingEquiv_symm (e) : ⇑(e : A ≃+* B).symm = e.symm := rfl` and `toRingEquiv_injective` (proved by `fun _ _ h => ext <| RingEquiv.congr_fun h`).","ev":"hunts/star-ringhom/batch3/probe1.lean section coeToRingEquiv: `example (e : A ≃⋆+* B) (x : B) : (e.symm : B ≃+* A) x = e.symm x := by fail_if_success (simp; done); rfl`, and the same pattern for `⇑(e : A ≃+* B) = ⇑e`, `(e : A ≃+* B) x = e x` and `⇑(e : A ≃+* B).symm = ⇑e.symm`. All compile, and for the last three the linter reports `done` as never executed, so simp fails outright. `simp [-StarRingEquiv.toRingEquiv_symm]` reports 'simp made no progress' with `⊢ e.symm x = e.symm x` (see probe1.out). hunts/star-ringhom/batch3/probe3.lean: `(e : A ≃+* B) (x * y) = e x * e y` is not closed by simp but is closed by `simp [coe_toRingEquiv']`, and `toRingEquiv_injective` holds in one line. hunts/star-ringhom/batch3/probe2_src.lean is src.lean with the three lemmas added; it compiles, the simp examples close, and `#lint only simpNF` passes (0 errors in 98 declarations).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-6ed714","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"StarRingEquiv.trans","line":406,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-equiv-trans-api","claim":"`StarRingEquiv.trans` lacks the standard composition API that `RingEquiv`/`Equiv` provide: there is no `symm_trans`, `trans_assoc`, `refl_trans`, `trans_refl`, `self_trans_symm`, `symm_trans_self` or `toRingEquiv_trans`, and no `Group (A ≃⋆+* A)` instance (cf. `StarAlgEquiv.aut`, `RingAut`). All are unknown constants or fail to synthesize, `simp` makes no progress on any of the four normal-form goals, and each is provable by `rfl` or by `ext` in one line. Analogues: `RingEquiv.symm_trans : (e₁.trans e₂).symm = e₂.symm.trans e₁.symm`, `RingEquiv.self_trans_symm : e.trans e.symm = RingEquiv.refl R`, `RingEquiv.symm_trans_self : e.symm.trans e = RingEquiv.refl S` (Mathlib/Algebra/Ring/Equiv.lean:353,902,906), `instance StarAlgEquiv.aut : Group (R ≃⋆ₐ[S] R)` (Mathlib/Algebra/Star/StarAlgHom.lean:1098).","fix":"Add `symm_trans`, `trans_assoc`, `refl_trans`, `trans_refl`, `@[simp] self_trans_symm`/`symm_trans_self`, `@[simp] toRingEquiv_trans` (all `rfl`/`ext`) and an `aut` group instance mirroring `StarAlgEquiv.aut`.","ev":"hunts/star-ringhom/batch4/probe1.lean sections P2-P5: `#check @StarRingEquiv.symm_trans` (likewise trans_assoc, refl_trans, trans_refl, self_trans_symm, symm_trans_self, toRingEquiv_trans, aut) -> Unknown constant; `example (e : A ≃⋆+* B) : e.trans e.symm = StarRingEquiv.refl := by simp` (and symm_trans_self, trans_assoc, toRingEquiv_trans goals) -> `simp` made no progress; `example : Group (A ≃⋆+* A) := inferInstance` -> failed to synthesize; while `example (e : A ≃⋆+* B) : e.trans e.symm = StarRingEquiv.refl := StarRingEquiv.ext e.symm_apply_apply`, `example (e₁ : A ≃⋆+* B) (e₂ : B ≃⋆+* C) (e₃ : C ≃⋆+* D) : (e₁.trans e₂).trans e₃ = e₁.trans (e₂.trans e₃) := rfl`, `(e₁.trans e₂).symm = e₂.symm.trans e₁.symm := rfl`, `(StarRingEquiv.refl : A ≃⋆+* A).trans e = e := rfl`, `(e₁.trans e₂).toRingEquiv = e₁.toRingEquiv.trans e₂.toRingEquiv := rfl` all compile (output in batch4/probe1.out)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-924c6a","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"StarRingEquiv.ofStarRingHom","line":452,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"typeclass-stronger-than-needed","claim":"`ofStarRingHom` assumes `[NonUnitalNonAssocSemiring A/B]`, `[NonUnitalRingHomClass F A B]` and `[NonUnitalStarRingHomClass F A B]`, but uses only `map_add`, `map_mul` and `map_star`, so `[Add] [Mul] [Star]` with `[AddHomClass] [MulHomClass] [StarHomClass]` suffice (exactly the assumptions of `StarRingEquiv` itself); and it takes the inverse as `g : G` with `[FunLike G B A]`, which rejects a plain function inverse (`failed to synthesize FunLike (A → A) A A`), whereas `g : B → A` is strictly more general (a bundled `g` still coerces). The generalized copy compiles cleanly under the Mathlib linters and every old call shape (bundled `g : G`, semiring setting) still elaborates, `simp` included.","fix":"State `ofStarRingHom` over `[Add A] [Mul A] [Star A] [Add B] [Mul B] [Star B]` with `[AddHomClass F A B] [MulHomClass F A B] [StarHomClass F A B]` and `g : B → A`.","ev":"hunts/star-ringhom/batch4/StarRingHomGen.lean (copy of src.lean with the `Bijective` section generalized; `def ofStarRingHom (f : F) (g : B → A) (h₁ : ∀ x, g (f x) = x) (h₂ : ∀ x, f (g x) = x) : A ≃⋆+* B` under `[Add A] [Mul A] [Star A] ... [AddHomClass F A B] [MulHomClass F A B] [StarHomClass F A B]`, plus old-setting call probes) compiles with exit 0 and no warnings; hunts/star-ringhom/batch4/probe1.lean P10 on master: `StarRingEquiv.ofStarRingHom (NonUnitalStarRingHom.id A) (fun x : A => x) (fun _ => rfl) (fun _ => rfl)` -> failed to synthesize `FunLike (A → A) A A`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-f37b7c","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"StarRingEquiv.ofBijective","line":462,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"typeclass-stronger-than-needed","claim":"`ofBijective` requires `[NonUnitalNonAssocSemiring A/B]`, `[NonUnitalRingHomClass F A B]` and `[NonUnitalStarRingHomClass F A B]` only because it is assembled from `RingEquiv.ofBijective`; built from `Equiv.ofBijective` it needs just `[Add] [Mul] [Star]` with `[AddHomClass] [MulHomClass] [StarHomClass]` (the assumptions of `StarRingEquiv`), and `StarAlgEquiv.ofBijective` already asks only `[StarHomClass F A B]` rather than the bundled-class `NonUnitalStarRingHomClass`. `coe_ofBijective`/`ofBijective_apply` stay `rfl` and old call sites still elaborate. (`RingEquiv.ofBijective` shares the semiring restriction.)","fix":"Define `ofBijective` as `{ Equiv.ofBijective f hf with toFun := f, map_add' := map_add f, map_mul' := map_mul f, map_star' := map_star f }` under `[Add] [Mul] [Star]` and `[AddHomClass F A B] [MulHomClass F A B] [StarHomClass F A B]`.","ev":"hunts/star-ringhom/batch4/StarRingHomGen.lean: generalized `noncomputable def ofBijective (f : F) (hf : Function.Bijective f) : A ≃⋆+* B := { Equiv.ofBijective f hf with toFun := f, map_add' := map_add f, map_mul' := map_mul f, map_star' := map_star f }` with unchanged `rfl` proofs of `coe_ofBijective`/`ofBijective_apply`, an old-setting `example (f : F) (hf) : ⇑(StarRingEquiv.ofBijective f hf) = f := by simp`, and a use at `[Add A] [Mul A] [Star A] ...` -> exit 0, no warnings","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-9549ad","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"StarRingEquiv.ofBijective","line":462,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-ofbijective-roundtrip-simp-lemmas","claim":"There are no round-trip lemmas `ofBijective_apply_symm_apply : f ((ofBijective f hf).symm x) = x` / `ofBijective_symm_apply_apply : (ofBijective f hf).symm (f x) = x` (present for `Equiv`, `MulEquiv`, `AlgEquiv`, `LinearEquiv`, e.g. `MulEquiv.ofBijective_apply_symm_apply (f : M →* N) (hf : Bijective f) : f ((ofBijective f hf).symm n) = n`, Mathlib/Algebra/Group/Equiv/Defs.lean:516). Because the `@[simp]` lemma `coe_ofBijective` turns `⇑(ofBijective f hf)` into `⇑f`, the generic `apply_symm_apply` no longer matches and `simp` makes no progress on either goal.","fix":"Add `@[simp] ofBijective_apply_symm_apply` and `@[simp] ofBijective_symm_apply_apply`, each proved by `(ofBijective f hf).apply_symm_apply x` / `.symm_apply_apply x`.","ev":"hunts/star-ringhom/batch4/probe1.lean P8: `example (f : F) (hf : Function.Bijective f) (x : B) : f ((StarRingEquiv.ofBijective f hf).symm x) = x := by simp` and `... (x : A) : (StarRingEquiv.ofBijective f hf).symm (f x) = x := by simp` -> `simp` made no progress; the same goals close by `(StarRingEquiv.ofBijective f hf).apply_symm_apply x` / `.symm_apply_apply x`; P2 `#check @StarRingEquiv.ofBijective_apply_symm_apply` -> Unknown constant","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-008a8d","file":"Mathlib/Algebra/Tropical/Basic.lean","decl":"MaxTropical.injective_trop","line":144,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `MaxTropical.injective_trop` (Algebra.Tropical.Basic), `MaxTropical.trop_injective` (Algebra.Tropical.Basic) state exactly the same thing (Lean-checked). Reviewer: to_dual images of MinTropical.injective_trop (l.144) and trop_injective (l.85), same file, same statement. Keep the f_injective-named one (about 30 uses for the pair family) and deprecate injective_trop.","fix":"Deprecate `MaxTropical.injective_trop` in favour of `MaxTropical.trop_injective`.","ev":"dupscan/Check.lean: `example := (@MaxTropical.trop_injective : type_of% @MaxTropical.injective_trop)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 48, rating MAJOR): `to_dual` requires a corresponding retained dual theorem, not both synonymous names. Consolidation at the `MinTropical` source preserves the necessary correspondence.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-d2fb1b","file":"Mathlib/Algebra/Tropical/Basic.lean","decl":"MinTropical.injective_untrop","line":148,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `MinTropical.injective_untrop` (Algebra.Tropical.Basic), `MinTropical.untrop_injective` (Algebra.Tropical.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file: untrop_injective (l.88, `fun _ _ => id`) and injective_untrop (l.148, `tropEquiv.symm.injective`). untrop_injective follows the f_injective naming convention and has about 30 uses (shared with trop_injective); injective_* has 3. Deprecate injective_untrop/injective_trop and their MaxTropical duals.","fix":"Deprecate `MinTropical.injective_untrop` in favour of `MinTropical.untrop_injective`.","ev":"dupscan/Check.lean: `example := (@MinTropical.untrop_injective : type_of% @MinTropical.injective_untrop)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 47, rating MAJOR): The earlier injectivity theorem already provides the result before the equivalence is built; reproving it from that equivalence adds no interface. Preserve the corresponding dual declarations through the cleanup.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261006-515af2","file":"Mathlib/AlgebraicGeometry/AlgebraicCycle/Basic.lean","decl":"AlgebraicGeometry.AlgebraicCycle.map","line":63,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-claims-more","claim":"`map`'s docstring says the weights `wx wy` are 'used to … make the pushforward operation functorial' and recommends `Order.coheight` (codimension) as a common choice. Neither holds in general. Arbitrary weights break composition: with identity morphisms, weights 0→1 then 1→0 give `mapCoeff = 0` twice, while 0→0 gives 1, so `map ∘ map ≠ map`. Codimension weights give the wrong proper pushforward: a closed point of ℙ¹_k (coheight 1) maps to the point of Spec k (coheight 0), so its pushforward is 0 instead of [Spec k]; Stacks 02R4 uses a dimension function. Also, `map` is defined for quasi-compact (not proper) morphisms, where it does not respect rational equivalence (j : 𝔸¹ ↪ ℙ¹ sends div(t) = [0] to [0], of degree 1), while the Stacks tag cited is proper pushforward.","fix":"Say functoriality needs compatible (dimension-type) weights, drop the codimension recommendation or add the dimension shift, and note that only proper f gives the Stacks pushforward.","ev":"example {X : Scheme} (x : X) :\n    mapCoeff (𝟙 X) (fun _ ↦ (0 : ℕ)) (fun _ ↦ 0) x = 1 ∧\n    mapCoeff (𝟙 X) (fun _ ↦ (0 : ℕ)) (fun _ ↦ 1) x = 0 ∧\n    mapCoeff (𝟙 X) (fun _ ↦ (1 : ℕ)) (fun _ ↦ 0) x = 0 := by\n  simp [mapCoeff]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-e04b3c","file":"Mathlib/AlgebraicGeometry/AlgebraicCycle/Basic.lean","decl":"AlgebraicGeometry.AlgebraicCycle.map","line":63,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"`map` is additive but returned as a bare function (no `map_add`, `map_zero`, `map_single`, `map_apply`, no `→+` bundle), so `degree_eq_map_of_unique` has to unfold `Function.locallyFinsupp.map`; `isWeilDivisor_zero` is not `@[simp]` (`simp` cannot prove `IsWeilDivisor 0`) and there is no `isWeilDivisor_single_iff : IsWeilDivisor (single x r) ↔ r = 0 ∨ coheight x = 1`; `degree` exists only on compact schemes, with no finite-support version.","fix":"Bundle `map` as `→+` with `map_single`/`map_apply`; tag `isWeilDivisor_zero` simp; add the single iff and a finite-support degree.","ev":"example {X : Scheme} {R : Type*} [Zero R] : IsWeilDivisor (0 : AlgebraicCycle X R) := by simp\n-- error: `simp` made no progress","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-34ff26","file":"Mathlib/AlgebraicGeometry/AlgebraicCycle/Basic.lean","decl":"AlgebraicGeometry.AlgebraicCycle.degree","line":90,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"junk-value-presented-as-fact","claim":"`degree` is documented as 'the degree of a zero-cycle' but accepts any cycle: `degree (𝟙 ℙ¹) (single η 1) = 1` for the generic point (the 1-cycle [ℙ¹]), and on non-zero-cycles it is not invariant under rational equivalence (div(t²+1) = [q] - 2[∞] on ℙ¹_ℚ has degree -1). `mapCoeff`, `map` and `degree` inherit `residueDegree`'s junk value 0 for infinite residue extensions (Spec L → Spec ℚ with L/ℚ infinite algebraic gives degree 0) without saying so. The inherited `.support` is the set of generic points, not the geometric support (the union of their closures).","fix":"Document the general operation (and its zero-cycle specialisation), the finrank-0 convention, and point vs geometric support.","ev":"#check @AlgebraicGeometry.AlgebraicCycle.degree\n-- (f : X ⟶ Y) [CompactSpace X] [AddCommMonoid R] : AlgebraicCycle X R →+ R   (no zero-cycle hypothesis)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-9fb056","file":"Mathlib/AlgebraicGeometry/AlgebraicCycle/Basic.lean","decl":"AlgebraicGeometry.AlgebraicCycle.degree_eq_map_of_unique","line":118,"sev":"MINOR","status":"suspected","cat":"generality","pattern":"too-strong-typeclass","claim":"(Astra A1, not formalised) `map` needs only `[AddCommMonoid R]` (multipliers are natural numbers: `mapCoeff … • c x`), but this requires generalising `Function.locallyFinsupp.map`; in `degree_eq_map_of_unique`, `[CompactSpace X]` follows from `[Unique Y]` and `[QuasiCompact f]` (`QuasiCompact.compactSpace_of_compactSpace`), and `hw` can be weakened to `residueDegree x • D x ≠ 0 → wx x = wy (f x)`; the public `[DecidableEq N]` could be classical inside the noncomputable `mapCoeff`.","fix":"Generalise the coefficient class via nsmul; derive compactness; weaken `hw`.","ev":"-- not formalised","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-711515","file":"Mathlib/AlgebraicGeometry/EllipticCurve/Jacobian/Basic.lean","decl":"WeierstrassCurve.Jacobian.fin3_def","line":123,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `WeierstrassCurve.Jacobian.fin3_def` (AlgebraicGeometry.EllipticCurve.Jacobian.Basic), `WeierstrassCurve.Projective.fin3_def` (AlgebraicGeometry.EllipticCurve.Projective.Basic) state exactly the same thing (Lean-checked). Reviewer: Sibling files contain the identical generic helper `![P x, P y, P z] = P`, and `fin3_def_ext` is duplicated the same way. Both files import only Affine.Basic. Hoist one copy into a shared place, the WeierstrassCurve namespace or a Fin lemma (cf. FinVec.etaExpand_eq), and deprecate the per-namespace copies.","fix":"Deprecate `WeierstrassCurve.Jacobian.fin3_def` in favour of `WeierstrassCurve.Projective.fin3_def`.","ev":"dupscan/Check.lean: `example := (@WeierstrassCurve.Projective.fin3_def : type_of% @WeierstrassCurve.Jacobian.fin3_def)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 1, rating MAJOR): These helpers have no coordinate-specific assumptions. Hoisting them into a common dependency removes duplication without making Jacobian depend on Projective. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/AlgebraicGeometry/EllipticCurve/Jacobian/Basic.lean#L123).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the names live in different namespaces, plausibly deliberate for discoverability/dot notation.","at":"2026-10-07","commit":""},{"id":"RT-20261007-4d7ff2","file":"Mathlib/AlgebraicGeometry/EllipticCurve/Jacobian/Basic.lean","decl":"WeierstrassCurve.Jacobian.fin3_def_ext","line":126,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `WeierstrassCurve.Jacobian.fin3_def_ext` (AlgebraicGeometry.EllipticCurve.Jacobian.Basic), `WeierstrassCurve.Projective.fin3_def_ext` (AlgebraicGeometry.EllipticCurve.Projective.Basic) state exactly the same thing (Lean-checked). Reviewer: Identical generic `Fin 3` vector fact `![a, b, c] 0 = a ∧ ...` copied (same line, same proof) into the sibling `WeierstrassCurve.Jacobian` and `WeierstrassCurve.Projective` namespaces, which do not import each other (both import Affine.Basic). Fix: state it once as `WeierstrassCurve.fin3_def_ext` in a shared ancestor (e.g. Affine/Basic), which both namespaces resolve unqualified, and deprecate both copies (same applies to `fin3_def`).","fix":"Keep one copy (in a file both import) and deprecate the other.","ev":"dupscan/Check.lean: `example := (@WeierstrassCurve.Projective.fin3_def_ext : type_of% @WeierstrassCurve.Jacobian.fin3_def_ext)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup0 item 52, rating MINOR): The implementation notes specifically document `fin3_def_ext` as part of each coordinate API and request mirrored naming. Hoisting a common implementation while retaining namespace aliases respects that deliberate interface. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/AlgebraicGeometry/EllipticCurve/Projective/Basic.lean#L41)","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-187753","file":"Mathlib/AlgebraicGeometry/EllipticCurve/Jacobian/Basic.lean","decl":"WeierstrassCurve.Jacobian.comp_fin3","line":129,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `WeierstrassCurve.Jacobian.comp_fin3` (AlgebraicGeometry.EllipticCurve.Jacobian.Basic), `WeierstrassCurve.Projective.comp_fin3` (AlgebraicGeometry.EllipticCurve.Projective.Basic) state exactly the same thing (Lean-checked). Reviewer: Coordinate-system-independent lemma `f ∘ ![a, b, c] = ![f a, f b, f c]` (= (FinVec.map_eq ..).symm) copy-pasted into the sibling Jacobian and Projective files (fin3_def_ext likewise). Neither file imports the other, so hoist one copy to a shared import (e.g. Affine/Basic or a general Fin/Matrix lemma) rather than keep either.","fix":"Keep one copy (in a file both import) and deprecate the other.","ev":"dupscan/Check.lean: `example := (@WeierstrassCurve.Projective.comp_fin3 : type_of% @WeierstrassCurve.Jacobian.comp_fin3)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup0 item 51, rating MINOR): The files explicitly document mirrored coordinate namespaces, making these tiny namespace wrappers defensible. Sharing the underlying generic proof is reasonable, but does not require deprecating both public names. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/AlgebraicGeometry/EllipticCurve/Jacobian/Basic.lean#L41)","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-9835da","file":"Mathlib/AlgebraicGeometry/Morphisms/FlatRank.lean","decl":"(module docstring)","line":15,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-claims-more","claim":"The module docstring says the rank of a finite flat morphism 'is locally constant', but that needs local finite presentation, which `isLocallyConstant_finrank` rightly assumes. Counterexample: R = ∏ₙ 𝔽₂ is absolutely flat, so B = R/(⊕ₙ 𝔽₂) is a finite flat R-algebra. Its rank is 0 at the dense set of coordinate primes and 1 on the nonempty closed set V(I), so it is not locally constant. 'Main definitions' also presents `finrank f y` as the stalk rank of f_* 𝒪_X for any f : X ⟶ Y. For f not finite (e.g. X = Y ⊔ ∐ₙ Spec R/(tⁿ) over Y = Spec 𝔽₂[t]) the value is computed on one chosen affine neighbourhood and is not that stalk rank.","fix":"Say 'finite flat and locally of finite presentation' for local constancy; say the stalk interpretation holds for finite flat f only.","ev":"#check @AlgebraicGeometry.Scheme.Hom.isLocallyConstant_finrank\n-- ∀ {X Y} (f : X ⟶ Y) [Flat f] [IsFinite f] [LocallyOfFinitePresentation f], IsLocallyConstant (Scheme.Hom.finrank f)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-7956ed","file":"Mathlib/AlgebraicGeometry/Morphisms/FlatRank.lean","decl":"AlgebraicGeometry.Scheme.Hom.finrank","line":89,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-drops-hypothesis","claim":"Docstring inaccuracies: `one_le_finrank_iff_surjective` and `isIso_iff_finrank_eq` (and the module's Main results) say 'finite flat locally finitely presented morphism' but neither assumes `LocallyOfFinitePresentation` (only `[Flat f] [IsFinite f]`); cross-references name nonexistent `AlgebraicGeometry.isLocallyConstant_finrank` and `AlgebraicGeometry.finrank` (they are `Scheme.Hom.…`); and `Scheme.Hom.finrank` is documented as 'the rank of a morphism at a point' without saying that for f not finite flat its value depends on the chosen affine open cover and `.choose` (it is junk there).","fix":"Drop 'locally finitely presented' from those two docstrings; fix the names; say the value is meaningful only for finite flat f.","ev":"#check @AlgebraicGeometry.Scheme.Hom.isIso_iff_finrank_eq\n-- ∀ {X Y} (f : X ⟶ Y) [Flat f] [IsFinite f], IsIso f ↔ Scheme.Hom.finrank f = 1\n#check @AlgebraicGeometry.Scheme.Hom.one_le_finrank_iff_surjective\n-- ∀ {X Y} (f : X ⟶ Y) [Flat f] [IsFinite f], 1 ≤ finrank f ↔ Surjective f","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-2da676","file":"Mathlib/AlgebraicGeometry/Morphisms/FlatRank.lean","decl":"AlgebraicGeometry.Scheme.Hom.finrank_eq_of_isAffine","line":108,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"general-material-private","claim":"The basic affine computation `f.finrank s = f.appTop.hom.finrank (S.isoSpec.hom s)` for `[IsAffine S] [Flat f] [IsFinite f]` is only available through the private `finrank_eq_of_isAffine`, whose right-hand side is the private `IsAffine.finrank`. A downstream user with an affine target that is not literally `Spec R` must re-derive it by transporting along `isoSpec`.","fix":"Make it public, stated with the public right-hand side `f.appTop.hom.finrank (S.isoSpec.hom s)`.","ev":"-- FlatRank.lean:108  private lemma Scheme.Hom.finrank_eq_of_isAffine [IsAffine S] [Flat f] [IsFinite f] (s : S) :\n--     f.finrank s = IsAffine.finrank f s   (IsAffine.finrank is a private def)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-23e182","file":"Mathlib/AlgebraicGeometry/Morphisms/FlatRank.lean","decl":"AlgebraicGeometry.Scheme.Hom.finrank_SpecMap_eq_finrank","line":117,"sev":"MINOR","status":"suspected","cat":"generality","pattern":"too-strong-typeclass","claim":"(Astra A1, unverified) `finrank_SpecMap_eq_finrank` (`hf₁ : f.hom.Finite`, `hf₂ : f.hom.Flat`) and `finrank_SpecMap_algebraMap` (`[Module.Finite R S] [Module.Flat R S]`) should hold for every ring map: the definition only base-changes along open immersions of affines, where stalks are unchanged. Not settled: the file's route goes through `rankAtStalk_baseChange`, which needs a flat finite module, so the general proof needs new localisation API.","fix":"If true, add an assumption-free rank comparison for base change along a localisation/open immersion and drop the hypotheses.","ev":"-- no compiled evidence: Module.rankAtStalk_baseChange sits under `variable [Flat R M] [Module.Finite R M]`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-69e1d5","file":"Mathlib/AlgebraicGeometry/Morphisms/FlatRank.lean","decl":"AlgebraicGeometry.Scheme.Hom.finrank_comp_left_of_isIso","line":146,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"The `@[simp]` lemma `finrank_comp_left_of_isIso : finrank (f ≫ g) = finrank g` (f an isomorphism) assumes `[Flat g] [IsFinite g]`, which are not needed. Precomposing with an isomorphism changes `appTop` by a ring isomorphism, and `RingHom.finrank` is invariant under that with no finiteness or flatness (`Module.rankAtStalk_eq_of_equiv`). A copy of the file with both instances dropped from it (and from the private `IsAffine.finrank_comp_left_of_isIso`) compiles in full.","fix":"Drop `[Flat g] [IsFinite g]`; prove the affine helper by `Scheme.Hom.comp_appTop` and a hypothesis-free `RingHom.finrank_comp_left_of_bijective`.","ev":"private lemma IsAffine.finrank_comp_left_of_isIso [IsAffine S]\n    (f : X ⟶ Y) (g : Y ⟶ S) [IsIso f] :\n    IsAffine.finrank (f ≫ g) = IsAffine.finrank g := by\n  ext z\n  simp only [IsAffine.finrank, Scheme.Hom.comp_appTop, CommRingCat.hom_comp]\n  have : IsIso f.appTop := inferInstanceAs (IsIso (f.app ⊤))\n  exact RingHom.finrank_comp_left_of_bijective' _ _ (ConcreteCategory.bijective_of_isIso _) _\n-- and `Scheme.Hom.finrank_comp_left_of_isIso (f : X ⟶ Y) (g : Y ⟶ S) [IsIso f]` with the old proof;\n-- the whole file (hunts/flat-rank/ProbeGenCopy.lean) elaborates","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-28c449","file":"Mathlib/AlgebraicGeometry/Morphisms/FlatRank.lean","decl":"AlgebraicGeometry.Scheme.Hom.one_le_finrank_iff_surjective","line":199,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reprovable-from-existing-api","claim":"The affine case of the forward direction re-derives `PrimeSpectrum.rankAtStalk_pos_iff_comap_surjective` point by point (`constructor; intro x; specialize h x; …; exact (rankAtStalk_pos_iff_mem_range_comap _).mp h`). The imported global equivalence closes it in one step.","fix":"Replace the point-by-point tail by `exact ⟨PrimeSpectrum.rankAtStalk_pos_iff_comap_surjective.mp h⟩`.","ev":"    obtain ⟨φ, rfl⟩ := Spec.map_surjective f\n    simp only [IsFinite.SpecMap_iff, Flat.SpecMap_iff] at *\n    rw [finrank_SpecMap_eq_finrank ‹_› ‹_›] at h\n    algebraize [φ.hom]\n    exact ⟨PrimeSpectrum.rankAtStalk_pos_iff_comap_surjective.mp h⟩\n-- whole file compiles (hunts/flat-rank/ProbeAstra.lean)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-f4eea7","file":"Mathlib/AlgebraicGeometry/Morphisms/FlatRank.lean","decl":"AlgebraicGeometry.Scheme.Hom.finrank_eq_one_of_isIso","line":259,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`finrank_eq_one_of_isIso : finrank f = 1` for `[IsIso f]` is not `@[simp]` and there is no `finrank_id`, so `simp` cannot normalise the rank of an isomorphism. With the attribute added, the whole file still compiles and `by simp` closes the goal.","fix":"Tag it `@[simp]`.","ev":"import Mathlib.AlgebraicGeometry.Morphisms.FlatRank\nopen AlgebraicGeometry CategoryTheory\nexample {X Y : Scheme} (f : X ⟶ Y) [IsIso f] : f.finrank = 1 := by simp\n-- error: `simp` made no progress   (passes once the lemma is @[simp]: hunts/flat-rank/ProbeAstra.lean)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-1023fb","file":"Mathlib/AlgebraicGeometry/Morphisms/FlatRank.lean","decl":"AlgebraicGeometry.Scheme.Hom.isIso_iff_finrank_eq","line":273,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"name-describes-wrong-shape","claim":"`isIso_iff_finrank_eq : IsIso f ↔ finrank f = 1` omits the constant from its name. By Mathlib's naming convention it is `isIso_iff_finrank_eq_one`, matching the sibling `finrank_eq_one_of_isIso`.","fix":"Rename to `isIso_iff_finrank_eq_one` (with a deprecated alias, per Mathlib policy).","ev":"#check @AlgebraicGeometry.Scheme.Hom.isIso_iff_finrank_eq\n-- ∀ {X Y} (f : X ⟶ Y) [Flat f] [IsFinite f], IsIso f ↔ Scheme.Hom.finrank f = 1","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-14a3ec","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"Path.Homotopy.trans_refl_reparam","line":102,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"parallel-reparametrisation-helper","claim":"With the reparametrisation written as qRight (·, 0), trans_refl_reparam is `(Path.delayReflRight_zero p).symm` (HSpaces: `delayReflRight_zero (γ : Path x y) : delayReflRight 0 γ = γ.trans (Path.refl y)`). transRefl can also be rebuilt in five lines from delayReflRight_zero/_one. Mathlib therefore carries two independent constructions of the right-unit homotopy p·refl ≃ p. The HSpaces docstring (L235-238) mentions transRefl but does not unify the two.","fix":"After sharing qRight, derive trans_refl_reparam from delayReflRight_zero (or derive delayReflRight_zero from it) and define one homotopy in terms of the other.","ev":"hunts/fundgroupoid/batch0/probe1.lean (sections R2, R3): `example (p : Path x₀ x₁) : p.trans (Path.refl x₁) = p.reparam (fun t => qRight (t, 0)) (by fun_prop) (qRight_zero_left 0) (qRight_one_left 0) := (delayReflRight_zero p).symm`; `noncomputable example (p : Path x₀ x₁) : Path.Homotopy (p.trans (Path.refl x₁)) p where toFun q := p (qRight (q.2, q.1)); continuous_toFun := by fun_prop; map_zero_left t := congr($(delayReflRight_zero p) t); map_one_left t := congr($(delayReflRight_one p) t); prop' t x hx := by rcases hx with rfl | rfl <;> simp [qRight_zero_left, qRight_one_left]`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-9fa59d","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"Path.Homotopy.transAssoc","line":160,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"general-material-in-specialised-file","claim":"The whole `namespace Path` block (L34-L234: the reparametrisation aux functions, `trans_assoc_reparam`, the homotopies `transAssoc`/`transRefl`/`reflTrans`/`reflTransSymm`/`reflSymmTrans`, the `Path.Homotopic.*` groupoid laws and the `@[simp]` laws of `Path.Homotopic.Quotient`) mentions only path/homotopy notions and does not depend on the fundamental groupoid, yet lives in an AlgebraicTopology file that also imports `CategoryTheory.Groupoid.Grpd.Basic` and `Topology.Category.TopCat.Basic`. It compiles verbatim against `Mathlib.Topology.Homotopy.Path` alone (where `Path.Homotopic.Quotient`, `trans`, `symm`, `refl`, `Homotopy.reparam` are defined), and the misplacement already costs a consumer: `Mathlib/Topology/Subpath.lean` must `public import Mathlib.AlgebraicTopology.FundamentalGroupoid.Basic` (82 extra modules: 3505 vs 3423 in the import closure) only to use `Path.Homotopy.reflTrans`/`transRefl` (L135, L206, L211); it uses nothing groupoid-related.","fix":"Move L34-L234 (the `Path.Homotopy`/`Path.Homotopic`/`Path.Homotopic.Quotient` groupoid laws) to `Mathlib/Topology/Homotopy/Path.lean` (or a new `Mathlib/Topology/Homotopy/PathGroupoidLaws.lean`) and drop `Topology/Subpath.lean`'s import of the fundamental groupoid.","ev":"hunts/fundgroupoid/batch1/probeB.lean = `import Mathlib.Topology.Homotopy.Path` + src.lean L23-L234 verbatim (only `open CategoryTheory` dropped, unused): `lake env lean` EXIT=0, no messages; prints `modules imported by probeB: 3423`. hunts/fundgroupoid/batch1/probeC.lean (`import Mathlib.AlgebraicTopology.FundamentalGroupoid.Basic` only) prints 3505. `git show origin/master:Mathlib/Topology/Subpath.lean`: L8 `public import Mathlib.AlgebraicTopology.FundamentalGroupoid.Basic`; its only uses of this file are `transRefl _` (L135), `Homotopy.reflTrans _` (L206, L211); no FundamentalGroupoid/Groupoid/πₓ/⟶ anywhere in it.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-04b849","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"Path.Homotopic.Quotient.trans_symm","line":208,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-api","claim":"The file gives `Path.Homotopic.Quotient` its groupoid laws as `@[simp]` lemmas (refl_trans, trans_refl, trans_symm, symm_trans, trans_assoc) but not the rest of the characteristic `symm` API: `symm (symm γ) = γ`, `symm (refl x) = refl x` and `symm (trans γ₀ γ₁) = trans (symm γ₁) (symm γ₀)` exist nowhere in Mathlib for the quotient (only `Path.symm_symm`, `Path.refl_symm`, `Path.trans_symm` on paths and `Path.Homotopy.symm_symm`), so `simp` cannot prove any of them; each is a two-line descent of the `Path` lemma.","fix":"Add `@[simp]` `Path.Homotopic.Quotient.symm_symm`, `symm_refl` and the anti-distribution lemma for `symm (trans γ₀ γ₁)` next to the groupoid laws.","ev":"-- hunts/fundgroupoid/batch1/probeA.lean (import Mathlib.AlgebraicTopology.FundamentalGroupoid.Basic), inside `namespace Path.Homotopic.Quotient`:\n-- P7: missing symm API — simp cannot do these (expected failures)\nexample (γ : Path.Homotopic.Quotient x₀ x₁) : γ.symm.symm = γ := by simp\nexample (γ₀ : Path.Homotopic.Quotient x₀ x₁) (γ₁ : Path.Homotopic.Quotient x₁ x₂) :\n    (γ₀.trans γ₁).symm = γ₁.symm.trans γ₀.symm := by simp\nexample (x : X) : (Path.Homotopic.Quotient.refl x).symm = .refl x := by simp\n\n-- P8: ... but each is a two-line lemma from existing `Path` API\ntheorem symm_symm' (γ : Path.Homotopic.Quotient x₀ x₁) : γ.symm.symm = γ := by\n  induction γ with | mk p => rw [← mk_symm, ← mk_symm, Path.symm_symm]\ntheorem symm_trans' (γ₀ : Path.Homotopic.Quotient x₀ x₁) (γ₁ : Path.Homotopic.Quotient x₁ x₂) :\n    (γ₀.trans γ₁).symm = γ₁.symm.trans γ₀.symm := by\n  induction γ₀ with | mk p => induction γ₁ with | mk q =>\n  rw [← mk_trans, ← mk_symm, ← mk_symm, ← mk_symm, ← mk_trans, Path.trans_symm]\ntheorem symm_refl' (x : X) : (Path.Homotopic.Quotient.refl x).symm = .refl x := by\n  rw [← mk_refl, ← mk_symm, Path.refl_symm]\n\n-- result: the three `by simp` examples fail with '`simp` made no progress' (L101, L103, L104); the three theorems compile.\n-- git grep -n -E 'symm_symm|symm_refl|refl_symm' origin/master -- Mathlib/Topology/Homotopy/Path.lean Mathlib/AlgebraicTopology/FundamentalGroupoid/ : only Path.Homotopy.symm_symm (Homotopy/Path.lean:109).","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a2aeaa","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"Path.Homotopic.Quotient.symm_trans","line":214,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-reassoc-simp-companions","claim":"`trans_assoc` (L220) is `@[simp]`, so simp's normal form is right-associated, but there are no right-associated cancellation companions for `symm_trans` (or for `trans_symm`, L208). These would be the quotient-level analogues of the category-level `@[reassoc (attr := simp)]` lemmas. So `simp` makes no progress on `γ.symm.trans (γ.trans δ) = δ` or on `γ.trans (γ.symm.trans δ) = δ`. On `(ε.trans γ).trans (γ.symm.trans δ) = ε.trans δ` it right-associates the chain, which strands the cancelling pair, and the goal stays open. `grind` closes all three, and the category-level `inv f ≫ f ≫ g = g` closes by `simp`.","fix":"Add `@[simp, grind =] symm_trans_trans : γ.symm.trans (γ.trans δ) = δ` and `trans_symm_trans : γ.trans (γ.symm.trans δ) = δ`, each proved by `rw [← trans_assoc, symm_trans/trans_symm, refl_trans]`.","ev":"hunts/fundgroupoid/batch2/Probe2.lean: `example … : γ.symm.trans (γ.trans δ) = δ := by fail_if_success (simp; done); rw [← Quotient.trans_assoc, Quotient.symm_trans, Quotient.refl_trans]` (and the `γ.trans (γ.symm.trans δ)` and `(ε.trans γ).trans (γ.symm.trans δ)` variants). The file compiles. With the two companions tagged `@[simp]`, `simp` closes the middle-of-chain goal.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-507118","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"FundamentalGroupoid.instSubsingleton","line":276,"sev":"MINOR","status":"confirmed","cat":"hygiene","pattern":"stale-todo-blocker-exists","claim":"The TODO right after this instance (L280–281) says '`Equiv.nontrivial_congr` doesn't exist. Once it is added, please add the corresponding lemma and instance.' `Equiv.nontrivial_congr` has existed since #24119 (3c296322c8c, 2025-05-01; Mathlib/Logic/Equiv/Defs.lean:207: `theorem nontrivial_congr {α β} (e : α ≃ β) : Nontrivial α ↔ Nontrivial β`). The TODO is therefore stale, and the `nontrivial_iff` lemma and `Nontrivial` instance it asks for are still missing: `infer_instance` fails for `Nontrivial (FundamentalGroupoid Y)`.","fix":"Replace the TODO with `@[simp] lemma nontrivial_iff (X) : Nontrivial (FundamentalGroupoid X) ↔ Nontrivial X := equiv _ |>.nontrivial_congr` and `instance (X) [Nontrivial X] : Nontrivial (FundamentalGroupoid X) := equiv _ |>.nontrivial`.","ev":"hunts/fundgroupoid/batch2/Probe1.lean (P2): `example (Y) [Nontrivial Y] : Nontrivial (FundamentalGroupoid Y) := by fail_if_success infer_instance; exact (FundamentalGroupoid.equiv Y).nontrivial`. The lemma and instance compile, and `Nontrivial (FundamentalGroupoid Bool)` is then inferred. hunts/fundgroupoid/batch2/Copy.lean makes the same replacement in place and compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-95d226","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"FundamentalGroupoid.instGroupoid","line":286,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"instance-reproves-existing-lemmas","claim":"The `Groupoid` instance re-implements `inv` as `Quotient.lift (fun f ↦ ⟦f.symm⟧) …`, which is exactly `Path.Homotopic.Quotient.symm` (Mathlib/Topology/Homotopy/Path.lean:353). It also re-derives all five laws by `rintro …; exact Quotient.sound ⟨Path.Homotopy.…⟩`, although the same file already states them as `Path.Homotopic.Quotient.refl_trans` / `trans_refl` / `trans_assoc` / `symm_trans` / `trans_symm` (L196–228). `id` is written `⟦Path.refl x.as⟧` instead of the simp-normal `Path.Homotopic.Quotient.refl x.as`.","fix":"Write the instance as `id x := .refl x.as`, `inv := Path.Homotopic.Quotient.symm`, `id_comp := Path.Homotopic.Quotient.refl_trans`, `comp_id := …trans_refl`, `assoc := …trans_assoc`, `inv_comp := …symm_trans`, `comp_inv := …trans_symm`.","ev":"hunts/fundgroupoid/batch2/Copy.lean: src.lean with the instance replaced by exactly those field references. The whole file compiles (exit 0, no messages), including the later `map`, `map_comp`, `eqToHom_eq` and `conj_eqToHom`. Downstream files were not recompiled, but none mention the old `Quotient.lift` (git grep), and `FundamentalGroup.inv_def` is `rfl` against `.symm`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-55050f","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"FundamentalGroupoid.instGroupoid","line":286,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-inv-unfolding-lemma","claim":"`≫` and `𝟙` have unfolding lemmas (`comp_eq`, `id_eq_path_refl`), but the inverse has none. `simp` makes no progress on `inv p = Path.Homotopic.Quotient.symm p` and cannot close `inv (fromPath ⟦p⟧) = fromPath ⟦p.symm⟧`. Downstream relies on defeq instead (`FundamentalGroup.inv_def … := rfl`, FundamentalGroup.lean:42).","fix":"Add `theorem inv_eq_symm {x y : FundamentalGroupoid X} (p : x ⟶ y) : inv p = Path.Homotopic.Quotient.symm p` (proof `by rw [← Groupoid.inv_eq_inv]; rfl`) beside `comp_eq`.","ev":"hunts/fundgroupoid/batch2/Probe2.lean: `example (p : x ⟶ y) : inv p = Path.Homotopic.Quotient.symm p := by fail_if_success (simp; done); rw [← Groupoid.inv_eq_inv]; rfl`, plus the `fromPath ⟦p⟧` variant. hunts/fundgroupoid/batch2/Copy.lean adds `inv_eq_symm` and closes the `fromPath` goal with `simp [inv_eq_symm]`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-50f12d","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"FundamentalGroupoid.id_eq_path_refl","line":299,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"non-normal-form-rhs","claim":"The RHS `⟦Path.refl x.as⟧` is a raw `Quotient.mk`, not the simp-normal `Path.Homotopic.Quotient.refl x.as` (Path.lean:311 declares `Path.Homotopic.Quotient.mk` the simp normal form). Its type is `Quotient (Homotopic.setoid ..)`, which matches `x ⟶ x` only by unfolding the semireducible `Path.Homotopic.Quotient`. After `rw [id_eq_path_refl]`, `simp only [Path.Homotopic.Quotient.mk_refl]` makes no progress, and Lean reports that the target is not type-correct at `implicit` transparency; `mk''_eq_mk` has to be added first. `𝟙 x = Path.Homotopic.Quotient.refl x.as` is also `rfl`.","fix":"State it as `𝟙 x = Path.Homotopic.Quotient.refl x.as` (and use `.refl x.as` for the instance's `id` field).","ev":"hunts/fundgroupoid/batch2/Probe2.lean: `example (x) : 𝟙 x = Path.Homotopic.Quotient.refl x.as := by rw [FundamentalGroupoid.id_eq_path_refl]; fail_if_success simp only [Path.Homotopic.Quotient.mk_refl]; simp only [Path.Homotopic.Quotient.mk''_eq_mk, Path.Homotopic.Quotient.mk_refl]` and `example (x) : 𝟙 x = Path.Homotopic.Quotient.refl x.as := rfl`. Both compile. Probe3.lean shows the 'not type-correct under the `implicit` transparency level' message.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-966c1f","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"FundamentalGroupoid.map","line":302,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"simps-projects-into-wrapper-structure","claim":"`@[simps]` on `map` generates only `map_obj_as : ((map f).obj x).as = f x.as`, because `obj` is a constructor application. So `simp` cannot rewrite `(map f).obj ⟨x⟩` to `⟨f x⟩` (it cannot close `(map f).obj ⟨x⟩ = ⟨f x⟩`, which holds by `rfl`). With `@[simps obj map]` the lemma `map_obj : (map f).obj x = { as := f x.as }` is generated and `simp` closes the same goal. A further measured problem: `simp` cannot close the statement of the generated simp lemma `map_map` itself. It leaves `Path.Homotopic.Quotient.map p f = Path.Homotopic.Quotient.map p f`, because the equation is typed at `(map f).obj x ⟶ (map f).obj y`, which matches `Path.Homotopic.Quotient (f x.as) (f y.as)` only by semireducible defeq. `rw [map_map]` closes it.","fix":"Use `@[simps obj map]` so that `map_obj` is generated; the `map_map` closure failure comes from `Hom x y` being only semireducibly `Path.Homotopic.Quotient x.as y.as` (the `Groupoid` instance at L286), so it should be addressed there.","ev":"hunts/fundgroupoid/batch3/evidence.lean lines 13-30 (E0): `example (f : C(X, Y)) (x : X) : (map f).obj ⟨x⟩ = ⟨f x⟩ := by fail_if_success (simp; done); rfl` and the same goal for `@[simps obj map] def map2` closed by `simp`; `example ... (p : x ⟶ y) : (map f).map p = Path.Homotopic.Quotient.map p f := by fail_if_success (simp; done); rw [map_map]`. The file compiles cleanly.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-21c650","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"FundamentalGroupoid.fundamentalGroupoidFunctor","line":318,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"bundled-functor-missing-simps","claim":"`fundamentalGroupoidFunctor` has no `@[simps]` and no simp lemma relating `πₘ f` to `map f.hom`, so `simp` cannot see through the functor. It does not close `(πₘ f).map p = (map f.hom).map p` or `((πₘ f).obj x).as = f x.as`, though both hold by `rfl`. The only bridge is `map_eq`, which is not `@[simp]` and covers only `TopCat.ofHom f`. Adding the `rfl` lemma `@[simp] πₘ f = map f.hom` (what `@[simps map]` generates) lets `simp` prove the first goal.","fix":"Add `@[simps map]` to `fundamentalGroupoidFunctor`, or a `@[simp]` rfl lemma `fundamentalGroupoidFunctor_map : πₘ f = map f.hom`.","ev":"hunts/fundgroupoid/batch3/evidence.lean lines 32-45 (E1): `example (X Y : TopCat.{u}) (f : X ⟶ Y) {x₀ x₁ : πₓ X} (p : x₀ ⟶ x₁) : (πₘ f).map p = (map f.hom).map p := by fail_if_success (simp; done); rfl`, the same for `((πₘ f).obj x).as = f x.as`, then `@[simp] theorem fundamentalGroupoidFunctor_map' (f : X ⟶ Y) : πₘ f = map f.hom := rfl` after which the first goal is closed by `simp`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d84821","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"FundamentalGroupoid.map_eq","line":332,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"lemma-stated-for-ofhom-only","claim":"`map_eq` is stated only for morphisms of the form `TopCat.ofHom f` with `f : C(X, Y)`. For a general `f : X ⟶ Y` in `TopCat`, `rw [map_eq]` fails (pattern not found) and `simp only [map_eq]` makes no progress, yet `(πₘ f).map p = p.map f.hom` holds by `rfl`.","fix":"State it for `f : X ⟶ Y` with right side `p.map f.hom`; the `ofHom` case then follows by `TopCat.hom_ofHom`.","ev":"hunts/fundgroupoid/batch3/evidence.lean lines 47-55 (E3): `example {X Y : TopCat.{u}} {x₀ x₁ : X} (f : X ⟶ Y) (p : Path.Homotopic.Quotient x₀ x₁) : (πₘ f).map p = p.map f.hom := by fail_if_success rw [map_eq]; fail_if_success simp only [map_eq]; rfl` and `theorem map_eq_general ... (f : X ⟶ Y) ... : (πₘ f).map p = p.map f.hom := rfl`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2b7a2b","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"FundamentalGroupoid.map_eq","line":332,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"simp-lemma-needs-respect-transparency-off","claim":"`map_eq` is not `@[simp]`: plain `simp` does not prove its statement. As a simp rewrite it is fragile. On its own statement, `simp only [map_eq]` rewrites but cannot close the residue `p.map f = p.map f`, because the equation is typed at the groupoid Hom type; it does close with `backward.isDefEq.respectTransparency false`, and `rw [map_eq]` works. Its only consumer, `ContinuousMap.Homotopy.evalAt_eq` (InducedMaps.lean:255, `simp only [map_eq]`), fails with \"`simp` made no progress\" when that file's `set_option backward.isDefEq.respectTransparency false` is removed.","fix":"Provide a general-morphism `map_eq` together with a `@[simp]` bridge `πₘ f = map f.hom`, and check whether `evalAt_eq` then works without the `respectTransparency` override.","ev":"hunts/fundgroupoid/batch3/evidence.lean lines 56-69 (E4): `example ... : (πₘ (TopCat.ofHom f)).map p = p.map f := by fail_if_success (simp; done); rfl`, `by fail_if_success (simp only [map_eq]; done); rw [map_eq]`, and the same goal closed by `simp only [map_eq]` under `set_option backward.isDefEq.respectTransparency false in`. Also hunts/fundgroupoid/batch3/InducedMaps.noRT.lean (a copy of InducedMaps.lean without its 4 respectTransparency overrides): line 255 reports \"`simp` made no progress\".","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c05fd8","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"FundamentalGroupoid.toTop","line":337,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"unused-alias-of-projection","claim":"`toTop x` is literally `x.as`, the structure projection. `FundamentalGroupoid` became a structure in #8257 (2023); before that it was a type synonym and `toTop x := x`, so the \"help the typechecker\" role is gone. `toTop` has zero uses in Mathlib, Archive, Counterexamples and MathlibTest. `x.as` already has type `↑X` for `x : πₓ X`.","fix":"Deprecate `toTop` in favour of `FundamentalGroupoid.as`.","ev":"hunts/fundgroupoid/batch3/evidence.lean lines 71-73 (E5): `example {X : TopCat.{u}} (x : πₓ X) : toTop x = x.as := rfl`. A `git grep -nP '\\btoTop\\b' origin/master -- Mathlib Archive Counterexamples MathlibTest` finds no fundamental-groupoid use outside Basic.lean; `git show 6b362d1e171` shows `-def toTop {X : TopCat} (x : πₓ X) : X := x` changed to `x.as`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-349bca","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"FundamentalGroupoid.toPath","line":345,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"needless-bundled-category-restriction","claim":"`toPath` requires `X : TopCat` and `x₀ x₁ : πₓ X`, whereas its inverse `fromPath` works for any `X : Type*` with a topology. As a result, `toPath p` does not elaborate for `p : x₀ ⟶ x₁` in `FundamentalGroupoid X`, and the round trip `toPath (fromPath p)` does not typecheck for a bare type. A version over `{x₀ x₁ : FundamentalGroupoid X}` compiles, agrees with `toPath` on `TopCat` by `rfl`, and satisfies `toPath' (fromPath p) = p := rfl`. `toPath` has zero uses in Mathlib.","fix":"Generalise `toPath` to `{X : Type*} [TopologicalSpace X] {x₀ x₁ : FundamentalGroupoid X}`, matching `fromPath`, or deprecate it since it is unused.","ev":"hunts/fundgroupoid/batch3/evidence.lean lines 75-85 (E6): `example {x₀ x₁ : X} (p : Path.Homotopic.Quotient x₀ x₁) : Path.Homotopic.Quotient x₀ x₁ := by fail_if_success exact toPath (fromPath p); exact p`, the same for `toPath p` with `p : x₀ ⟶ x₁` in `FundamentalGroupoid X`, `abbrev toPath' {x₀ x₁ : FundamentalGroupoid X} (p : x₀ ⟶ x₁) : Path.Homotopic.Quotient x₀.as x₁.as := p`, `example {X : TopCat.{u}} {x₀ x₁ : πₓ X} (p : x₀ ⟶ x₁) : toPath' p = toPath p := rfl`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-8180e6","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"FundamentalGroupoid.fromPath_eq_iff_homotopic","line":355,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"restates-quotient-eq-through-identity-wrapper","claim":"Because `fromPath` is a reducible identity, this is `Path.Homotopic.Quotient.eq` (Topology/Homotopy/Path.lean:319, `theorem eq {p q : Path x₀ x₁} : mk p = mk q ↔ Homotopic p q`) restated at the groupoid Hom type. The term `Path.Homotopic.Quotient.eq` proves it verbatim, and `rw [Path.Homotopic.Quotient.eq]` closes it. Only `simp` cannot use `Quotient.eq` through the wrapper. It has zero uses in Mathlib, Archive, Counterexamples and MathlibTest.","fix":"Deprecate it in favour of `Path.Homotopic.Quotient.eq`.","ev":"hunts/fundgroupoid/batch3/evidence.lean lines 87-100 (E8): `example {x₀ x₁ : X} (f g : Path x₀ x₁) : fromPath (Path.Homotopic.Quotient.mk f) = fromPath (Path.Homotopic.Quotient.mk g) ↔ f.Homotopic g := Path.Homotopic.Quotient.eq`, the same goal closed by `rw [Path.Homotopic.Quotient.eq]`, and `fail_if_success simpa only [Path.Homotopic.Quotient.eq] using h` and `simpa only [fromPath_eq_iff_homotopic] using h`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-88143c","file":"Mathlib/AlgebraicTopology/SimplicialSet/CompStruct.lean","decl":"SSet.Edge.CompStruct.toSubcomplex_edge","line":156,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `SSet.Edge.CompStruct.toSubcomplex_edge` (AlgebraicTopology.SimplicialSet.CompStruct), `SSet.Edge.toSubcomplex_edge` (AlgebraicTopology.SimplicialSet.CompStruct) state exactly the same thing (Lean-checked). Reviewer: This is a verbatim copy. The lemma at line 295, inside `namespace CompStruct`, repeats Edge.toSubcomplex_edge from line 156 (same `e : Edge x₀ x₁` statement, @[simp], rfl) right after CompStruct.toSubcomplex_simplex. Delete or deprecate the CompStruct copy.","fix":"Deprecate `SSet.Edge.CompStruct.toSubcomplex_edge` in favour of `SSet.Edge.toSubcomplex_edge`.","ev":"dupscan/Check.lean: `example := (@SSet.Edge.toSubcomplex_edge : type_of% @SSet.Edge.CompStruct.toSubcomplex_edge)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (mis item 13, rating MAJOR): The duplicate is real, but no missing `CompStruct` statement is established. A composition structure has a `simplex`, and its appropriate theorem is already immediately above: `(h.toSubcomplex A mem).simplex = ⟨h.simplex, mem⟩`. Keep `Edge.toSubcomplex_edge` with its existing statement and remove the extra namespace copy. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/AlgebraicTopology/SimplicialSet/CompStruct.lean#L277-L300)","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-1744d4","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"ContinuousAlternatingMap.cpolynomialAt_compContinuousLinearMapCLM","line":0,"sev":"MINOR","status":"suspected","cat":"generality","pattern":"too-strong-typeclass","claim":"In the alternating and multilinear precomposition families, the source spaces (`E`, respectively each `Fm i`) appear only as operator-space domains, so `[SeminormedAddCommGroup _]` should suffice (`ContinuousMultilinearMap.normedAddCommGroup` and `ContinuousAlternatingMap.instNormedAddCommGroup` allow seminormed sources). Not compiled here.","fix":"Weaken to seminormed source spaces where they occur only in operator-space domains.","ev":"Astra A1 source analysis; instances cited at Multilinear/Basic.lean L1238-1255 and Alternating/Basic.lean L617-629.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4ca958","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"HasFiniteFPowerSeriesOnBall.add","line":52,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"pi-apply-on-def-type-needs-transparency-shim","claim":"The proof rewrites `(pf + pg) N` with `Pi.add_apply`. But `FormalMultilinearSeries 𝕜 E F` is a semireducible `def`, not a Pi type at reducible transparency, so the rewrite works only under the compatibility shim `set_option backward.isDefEq.respectTransparency false in` on line 51. Without the option, the unchanged proof fails with \"Did not find an occurrence of the pattern (?f + ?g) ?i in the target expression (pf + pg) N = 0\". With the existing `@[simp]` rfl lemma `FormalMultilinearSeries.add_apply` in place of `Pi.add_apply`, or with a plain `simp [hf.finite _ _, hg.finite _ _]`, it compiles without the option.","fix":"Replace `Pi.add_apply` with `FormalMultilinearSeries.add_apply` and delete the `set_option backward.isDefEq.respectTransparency false in` line.","ev":"hunts/cpolynomial/batch0/probe1.lean: theorem B1 (original proof, no set_option) fails at 24:8 with the error quoted. Theorems C1 (`rw [FormalMultilinearSeries.add_apply, ...]`) and C3 (`simp [...]`) compile, and `#print axioms C1` gives [propext, Classical.choice, Quot.sound]. hunts/cpolynomial/batch0/src-fixed.lean, the whole file with both set_options removed and the lemma swapped, compiles cleanly (exit 0, no warnings) under `lake env lean -DmaxSynthPendingDepth=3 -DautoImplicit=false -Dpp.unicode.fun=true -Dlinter.mathlibStandardSet=true -Dlinter.style.longFile=1500`, as does the unmodified copy src-orig.lean.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d4dc9d","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"CPolynomialAt.add","line":66,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-fun-prop-registration","claim":"`fun_prop` does not cover `CPolynomialAt`/`CPolynomialOn`. Neither predicate is marked `@[fun_prop]`, and none of the closure lemmas in this batch (`CPolynomialAt.add`/`neg`/`sub`, `CPolynomialOn.add`/`sub`, `CPolynomialAt_const`, `CPolynomialOn_const`) carries the attribute: git grep finds no `fun_prop` in CPolynomialDef.lean or CPolynomial.lean. Their analytic mirrors do: `AnalyticAt.add`/`neg`/`sub` and `AnalyticOnNhd.add`/`neg`/`sub` are `@[to_fun (attr := fun_prop)]`, and `analyticAt_const`, `analyticOnNhd_const` and the `analyticAt_zero` special case are `@[fun_prop]`. `fun_prop` therefore rejects `CPolynomialAt 𝕜 (fun y ↦ f y + -g y - c) x`. After registering the predicate and tagging the existing `to_fun` lemmas, the same goal closes. Impact is currently low, since nothing outside the file uses these lemmas.","fix":"Mark `CPolynomialAt` and `CPolynomialOn` `@[fun_prop]` in CPolynomialDef, switch the closure lemmas here to `@[to_fun (attr := fun_prop)]`, tag the const lemmas `@[fun_prop]`, and add a `cpolynomialAt_zero` special case as for `analyticAt_zero`.","ev":"hunts/cpolynomial/batch0/probe1.lean (E): `example (hf : CPolynomialAt 𝕜 f x) (hg : CPolynomialAt 𝕜 g x) (c : F) : CPolynomialAt 𝕜 (fun y ↦ f y + -g y - c) x := by fun_prop` fails with \"is not a `fun_prop` goal! Consider marking `CPolynomialAt` with `@[fun_prop]`\". (E') After `attribute [fun_prop] CPolynomialAt` and `attribute [fun_prop] CPolynomialAt.fun_add CPolynomialAt.fun_neg CPolynomialAt.fun_sub CPolynomialAt_const`, the same example compiles.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-29d5ee","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"HasFiniteFPowerSeriesOnBall.neg","line":73,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"pi-apply-on-def-type-needs-transparency-shim","claim":"Same defect as `.add`. `rw [Pi.neg_apply, ...]` on `(-pf) m`, with `pf : FormalMultilinearSeries`, needs `set_option backward.isDefEq.respectTransparency false in` (line 72). Without it, the original proof fails (\"Did not find an occurrence of the pattern (-?f) ?i ... (-pf) m = 0\"). With `FormalMultilinearSeries.neg_apply`, or `simp [hf.finite m hm]`, it compiles without the option.","fix":"Replace `Pi.neg_apply` with `FormalMultilinearSeries.neg_apply` and delete the `set_option backward.isDefEq.respectTransparency false in` line.","ev":"hunts/cpolynomial/batch0/probe1.lean: theorem B2 (original proof, no set_option) fails at 29:31. Theorems C2 (`rw [FormalMultilinearSeries.neg_apply, hf.finite m hm, neg_zero]`) and C4 (`simp [hf.finite m hm]`) compile, and `#print axioms C2` is clean. hunts/cpolynomial/batch0/src-fixed.lean compiles cleanly with the change (exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-5c23be","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"CPolynomialAt.neg","line":83,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-sibling-closure-lemma","claim":"Negation is the only closure operation without a `CPolynomialOn` version. `CPolynomialOn.add` and `CPolynomialOn.sub` exist, but `CPolynomialOn.neg` does not (git grep finds nothing in Mathlib), so `hf.neg` for `hf : CPolynomialOn 𝕜 f s` fails. There is also no `@[simp]` iff `cpolynomialAt_neg : CPolynomialAt 𝕜 (-f) x ↔ CPolynomialAt 𝕜 f x`, although the analytic mirror has both `AnalyticOnNhd.neg` and `@[simp] analyticAt_neg` (Analysis/Analytic/Constructions.lean L161-169). Both are one-liners.","fix":"Add `@[to_fun] theorem CPolynomialOn.neg (hf : CPolynomialOn 𝕜 f s) : CPolynomialOn 𝕜 (-f) s := fun z hz ↦ (hf z hz).neg` and `@[simp] lemma cpolynomialAt_neg` mirroring `analyticAt_neg`.","ev":"hunts/cpolynomial/batch0/probe1.lean (D): `example (hf : CPolynomialOn 𝕜 f s) : CPolynomialOn 𝕜 (-f) s := hf.neg` fails (\"Invalid field `neg`\"), and `cpolynomialAt_neg` gives \"Unknown identifier\". `fun z hz ↦ (hf z hz).neg` and `⟨fun h ↦ by simpa using h.neg, .neg⟩` compile. hunts/cpolynomial/batch0/src-fixed.lean adds both declarations after `CPolynomialAt.neg` and compiles cleanly.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2ed99b","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"CPolynomialAt.smul","line":113,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"scalar-restricted-to-base-field","claim":"CPolynomialAt.smul (and CPolynomialOn.smul, L117) only allow a scalar c : 𝕜. The same one-line proof (compose with the continuous 𝕜-linear map y ↦ c • y) works for any c : R with [Monoid R] [DistribMulAction R F] [SMulCommClass 𝕜 R F] [ContinuousConstSMul R F]; the analytic counterpart AnalyticAt.const_smul (Analytic/Constructions.lean:236) already takes {R : Type*} [NormedRing R] [Module R F] [IsBoundedSMul R F] [SMulCommClass 𝕜 R F] {c : R}. Concretely, for V a complex normed space, f : ℝ → V with CPolynomialAt ℝ f x and c : ℂ, `hf.smul c` is a type error (c : ℂ expected ℝ) while the generalised lemma proves CPolynomialAt ℝ (c • f) x. In-file check: replacing both lemmas by the generalised versions (keeping @[to_fun]) compiles, and the only consumer (cpolynomialAt_compContinuousLinearMapCLM, L262) still compiles.","fix":"Generalise c to c : R under [Monoid R] [DistribMulAction R F] [SMulCommClass 𝕜 R F] [ContinuousConstSMul R F] (at least AnalyticAt.const_smul's [NormedRing R] [Module R F] [IsBoundedSMul R F] [SMulCommClass 𝕜 R F]).","ev":"hunts/cpolynomial/batch1/Probe1.lean (section A: A1-A3 compile, A4 `hf.smul c` fails: 'argument c has type ℂ but is expected to have type ℝ') and hunts/cpolynomial/batch1/CopyA.lean (in-file generalisation, compiles with -DmaxSynthPendingDepth=3). Core:\ntheorem probe_cpolynomialAt_const_smul {R : Type*} [Monoid R] [DistribMulAction R F]\n    [SMulCommClass 𝕜 R F] [ContinuousConstSMul R F]\n    {f : E → F} {x : E} (hf : CPolynomialAt 𝕜 f x) (c : R) : CPolynomialAt 𝕜 (c • f) x :=\n  ContinuousLinearMap.comp_cpolynomialAt\n    { toFun := (c • ·), map_add' := smul_add c,\n      map_smul' := fun a y => by simp only [RingHom.id_apply]; exact (smul_comm a c y).symm,\n      cont := continuous_const_smul c } hf\n\nexample {V : Type*} [NormedAddCommGroup V] [NormedSpace ℂ V] {f : ℝ → V} {x : ℝ}\n    (hf : CPolynomialAt ℝ f x) (c : ℂ) : CPolynomialAt ℝ (c • f) x :=\n  probe_cpolynomialAt_const_smul hf c","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ead0c0","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"CPolynomialAt.smul","line":113,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-finite-series-layer","claim":"add, neg, sub and prodMk each have HasFiniteFPowerSeriesOnBall and HasFiniteFPowerSeriesAt versions in this file (mirroring HasFPowerSeriesOnBall.const_smul / HasFPowerSeriesAt.const_smul in Analytic/Constructions.lean:214,225), but scalar multiplication has only the CPolynomialAt/On layer, so the finite expansion of c • f (namely c • pf, same bound n and radius r) is not available. It is a one-liner.","fix":"Add HasFiniteFPowerSeriesOnBall.const_smul and HasFiniteFPowerSeriesAt.const_smul and derive the CPolynomialAt/On statements from them.","ev":"hunts/cpolynomial/batch1/Probe1.lean section B and hunts/cpolynomial/batch1/CopyA.lean (in-file, compiles):\ntheorem probe_hasFiniteFPowerSeriesOnBall_const_smul {R : Type*} [NormedRing R] [Module R F]\n    [IsBoundedSMul R F] [SMulCommClass 𝕜 R F] {c : R}\n    {f : E → F} {pf : FormalMultilinearSeries 𝕜 E F} {x : E} {n : ℕ} {r : ℝ≥0∞}\n    (hf : HasFiniteFPowerSeriesOnBall f pf x n r) :\n    HasFiniteFPowerSeriesOnBall (c • f) (c • pf) x n r :=\n  ⟨hf.1.const_smul, fun m hm ↦ by change c • pf m = 0; rw [hf.finite m hm, smul_zero]⟩","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-589882","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"HasFiniteFPowerSeriesOnBall.prodMk","line":120,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"equal-radii-hypothesis","claim":"Requires both expansions on the same radius r, while the analytic counterpart HasFPowerSeriesOnBall.prod (Analytic/Constructions.lean:316) takes radii r and s and concludes on min r s. The finite version holds verbatim with different radii and conclusion radius min r s (same proof minus the `simpa` for min r r), recovers the current statement by `simpa`, and makes HasFiniteFPowerSeriesAt.prodMk a term (`let ⟨_, hf⟩ := hf; let ⟨_, hg⟩ := hg; ⟨_, hf.prodMk hg⟩`) instead of the `eventually.and … exists` detour. With differing radii the current lemma does not apply (type mismatch). In-file replacement compiles, including downstream CPolynomialAt.prodMk and ContinuousAlternatingMap.cpolynomialAt_apply.","fix":"State it for (hf : … x n r) (hg : … x m r') with conclusion radius (min r r'), as HasFPowerSeriesOnBall.prod does, and simplify HasFiniteFPowerSeriesAt.prodMk accordingly.","ev":"hunts/cpolynomial/batch1/Probe1.lean section C (probe compiles; C2 `hf.prodMk hg` at min r s fails) and hunts/cpolynomial/batch1/CopyA.lean (in-file):\ntheorem probe_prodMk {f : E → F} {g : E → G} {pf : FormalMultilinearSeries 𝕜 E F}\n    {pg : FormalMultilinearSeries 𝕜 E G} {x : E} {n m : ℕ} {r s : ℝ≥0∞}\n    (hf : HasFiniteFPowerSeriesOnBall f pf x n r) (hg : HasFiniteFPowerSeriesOnBall g pg x m s) :\n    HasFiniteFPowerSeriesOnBall (fun x ↦ (f x, g x)) (pf.prod pg) x (max n m) (min r s) :=\n  ⟨hf.1.prod hg.1, fun N hN ↦ by simp [FormalMultilinearSeries.prod,\n    hf.finite _ ((le_max_left n m).trans hN), hg.finite _ ((le_max_right n m).trans hN)]⟩","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6bdfd3","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"CPolynomialAt.prodMk","line":132,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"predicate-missing-fun-prop","claim":"CPolynomialAt/CPolynomialOn are not registered with fun_prop (no fun_prop attribute in CPolynomialDef.lean or CPolynomial.lean), so none of this file's closure lemmas (prodMk, fun_smul, fun_add/neg/sub) are usable by fun_prop: `fun_prop` on `CPolynomialAt 𝕜 (fun y => (f y, g y)) x` and on `CPolynomialAt 𝕜 (fun y => c • f y) x` fails with 'is not a fun_prop goal! Consider marking CPolynomialAt with @[fun_prop]', whereas the analytic counterparts (AnalyticAt.prod, AnalyticAt.fun_const_smul, AnalyticOnNhd.prod, all @[fun_prop]) close the same goals by fun_prop. Registering CPolynomialAt and tagging prodMk, fun_smul, fun_add/neg/sub, CPolynomialAt_const plus an id and a `fun y ↦ g (f y)` comp lemma (from CPolynomialAt.comp) makes fun_prop prove all of these (Probe2.lean compiles).","fix":"Mark CPolynomialAt (and CPolynomialOn) @[fun_prop] in CPolynomialDef.lean and tag the closure lemmas (prodMk, smul/fun_smul, add/neg/sub, const, id, comp) with fun_prop, as Analytic/Constructions does.","ev":"hunts/cpolynomial/batch1/Probe1.lean section D (D1/D2 fail as expected, D3 analytic versions compile) and hunts/cpolynomial/batch1/Probe2.lean (registration works, compiles):\nexample {f : E → F} {g : E → G} {x : E} (hf : CPolynomialAt 𝕜 f x) (hg : CPolynomialAt 𝕜 g x) :\n    CPolynomialAt 𝕜 (fun y => (f y, g y)) x := by fun_prop\n-- error: `CPolynomialAt 𝕜 (fun y => (f y, g y)) x` is not a `fun_prop` goal! Consider marking `CPolynomialAt` with `@[fun_prop]`.\nexample {f : E → F} {g : E → G} {x : E} (hf : AnalyticAt 𝕜 f x) (hg : AnalyticAt 𝕜 g x) :\n    AnalyticAt 𝕜 (fun y => (f y, g y)) x := by fun_prop  -- compiles","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-848d0f","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"ContinuousAlternatingMap.analyticAt","line":189,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-fun-prop-tag","claim":"`ContinuousAlternatingMap.analyticAt` is not tagged `@[fun_prop]`, although `AnalyticAt` is a fun_prop predicate. As a result, `fun_prop` cannot prove `AnalyticAt 𝕜 (fun z ↦ f (g z)) y` for an alternating map `f` and an analytic `g` (\"No theorems found for `f`\"). With `attribute [local fun_prop] ContinuousAlternatingMap.analyticAt`, `fun_prop` proves it, sums included. The gap is systemic: Probe1 shows that `ContinuousLinearMap.analyticAt` and `ContinuousMultilinearMap.analyticAt` are not fun_prop rules either. Tagging `analyticOnNhd` would not help, because fun_prop has no composition rule for `AnalyticOnNhd`: Probe2 fails even with the tag.","fix":"Tag `ContinuousAlternatingMap.analyticAt` `@[fun_prop]`, together with its `ContinuousMultilinearMap` and `ContinuousLinearMap` analogues.","ev":"-- batch2/Evidence.lean, section FunProp: the first example fails as expected, the tagged one compiles\nvariable {ι : Type*} [Fintype ι]\n\n-- EXPECTED-FAIL: \"No theorems found for `f`\"\nexample (f : E [⋀^ι]→L[𝕜] F) (g : G → ι → E) (y : G) (hg : AnalyticAt 𝕜 g y) :\n    AnalyticAt 𝕜 (fun z ↦ f (g z)) y := by\n  fun_prop\n\nattribute [local fun_prop] ContinuousAlternatingMap.analyticAt in\nexample (f₁ f₂ : E [⋀^ι]→L[𝕜] F) (g : G → ι → E) (y : G) (hg : AnalyticAt 𝕜 g y) :\n    AnalyticAt 𝕜 (fun z ↦ f₁ (g z) + f₂ (g z)) y := by\n  fun_prop","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-fee82d","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"ContinuousAlternatingMap.cpolynomialAt_smul_compContinuousLinearMapCLM","line":195,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"slow-proof","claim":"The proof is slow. `trace.profiler` (threshold 200 ms, Mathlib's leanOptions passed as -D flags, load average under 4) measured elaboration at 1.40 s, 1.45 s and 1.46 s over three runs, plus 0.31-0.32 s of kernel typechecking. Of the elaboration time, 0.70 s is the `have` equation: 0.56 s elaborates its statement, unifying the `compL _ _ _ _` holes through `Function.comp`. The rest is the `rw [this]; apply …` chain, which also needs `maxSynthPendingDepth = 3`: without it, `apply ContinuousLinearMap.comp_cpolynomialAt` fails to unify. Supplying the explicit type arguments of both `compL`s only brings elaboration down to 1.23 s. No other declaration in the batch exceeds 0.45 s.","fix":"Run /buzz on it, for example by stating the `have` as an equality of bundled `∘L` compositions, or by proving the three factor lemmas separately so the `Function.comp` unification never happens.","ev":"lake env lean -D pp.unicode.fun=true -D maxSynthPendingDepth=3 -D autoImplicit=false -Dtrace.profiler=true -Dtrace.profiler.threshold=200 batch2/CPolynomialCopy.lean (verbatim copy of src.lean):\n[Elab.async] [1.450424] elaborating proof of ContinuousAlternatingMap.cpolynomialAt_smul_compContinuousLinearMapCLM\n  [Kernel] [0.322877] typechecking declarations [ContinuousAlternatingMap.cpolynomialAt_smul_compContinuousLinearMapCLM]\n  ... [Elab.step] [0.701372] have : ... ; [Elab.step] [0.563381] expected type: Sort ?u, term (the have's statement)\nbatch2/CPolynomialFast.lean (explicit compL type arguments): [Elab.async] [1.225059] same proof\nnext slowest in the batch: cpolynomialAt_compContinuousLinearMapCLM 0.41 s; the four analytic*_compContinuousLinearMapCLM ~0.21 s each","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b4b65a","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"ContinuousAlternatingMap.cpolynomialAt_compContinuousLinearMapCLM","line":241,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"The section variable `[CharZero 𝕜]` (L237) is used only to invert `((Fintype.card ι)! : 𝕜)`; the lemma holds verbatim under the weaker hypothesis `((Fintype.card ι)! : 𝕜) ≠ 0`, e.g. over a nontrivially normed field of characteristic p > card ι (such fields exist in Mathlib via `Valued.toNontriviallyNormedField`). The five corollaries at L266-289 inherit the assumption. None of the six has a consumer outside this file. The CharZero form follows Bourbaki (as the proof comment says), so this is a weakening opportunity, not an error.","fix":"State the lemma under `(h : ((Fintype.card ι)! : 𝕜) ≠ 0)` and keep the `[CharZero 𝕜]` version (and the On/analytic corollaries) as a one-line specialisation via `Nat.cast_ne_zero.2 (Nat.factorial_ne_zero _)`.","ev":"-- batch2/Evidence.lean, section Generality (compiled, no CharZero in scope)\nopen ContinuousAlternatingMap\n\n/-- No `CharZero` instance in scope. -/\ntheorem cpolynomialAt_compContinuousLinearMapCLM_of_factorial_ne_zero\n    {ι : Type*} [Fintype ι] (h : ((Fintype.card ι)! : 𝕜) ≠ 0) (f₀ : E →L[𝕜] F) :\n    CPolynomialAt 𝕜\n      (compContinuousLinearMapCLM : (E →L[𝕜] F) → (F [⋀^ι]→L[𝕜] G) →L[𝕜] (E [⋀^ι]→L[𝕜] G)) f₀ := by\n  have : (compContinuousLinearMapCLM : (E →L[𝕜] F) → (F [⋀^ι]→L[𝕜] G) →L[𝕜] (E [⋀^ι]→L[𝕜] G)) =\n      ((Fintype.card ι)! : 𝕜)⁻¹ • ((Fintype.card ι)! • compContinuousLinearMapCLM) := by\n    rw [← Nat.cast_smul_eq_nsmul 𝕜, smul_smul, inv_mul_cancel₀ h, one_smul]\n  rw [this]\n  exact (cpolynomialAt_smul_compContinuousLinearMapCLM f₀).smul _\n\n/-- The library's `CharZero` statement is the special case. -/\nexample [CharZero 𝕜] {ι : Type*} [Fintype ι] (f₀ : E →L[𝕜] F) :\n    CPolynomialAt 𝕜\n      (compContinuousLinearMapCLM : (E →L[𝕜] F) → (F [⋀^ι]→L[𝕜] G) →L[𝕜] (E [⋀^ι]→L[𝕜] G)) f₀ :=\n  cpolynomialAt_compContinuousLinearMapCLM_of_factorial_ne_zero\n    (Nat.cast_ne_zero.2 (Nat.factorial_ne_zero _)) f₀","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-66cbac","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"ContinuousLinearMap.toFormalMultilinearSeriesOfMultilinear","line":307,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"rebuilds-composable-construction","claim":"The def copies the `if h : card = n then … domDomCongr (Fintype.equivFinOfCardEq h) else 0` shape of `ContinuousMultilinearMap.toFormalMultilinearSeries` (FormalMultilinearSeries.lean:257), and is provably equal to `f.continuousMultilinearMapOption.toFormalMultilinearSeries.compContinuousLinearMap (ContinuousLinearMap.pi fun _ ↦ .id 𝕜 _)`; the equality goes through by `split_ifs <;> ext <;> rfl`. Its companion `hasFiniteFPowerSeriesOnBall_uncurry_of_multilinear` (L313-323) repeats the proof of `ContinuousMultilinearMap.hasFiniteFPowerSeriesOnBall` (L153-158) step for step (mk', sum_eq_single_of_mem, dite_eq_left/right, rfl). The pair's only consumer, in this file or anywhere in Mathlib, is `cpolynomialAt_uncurry_of_multilinear`, and that lemma follows in two lines from `ContinuousMultilinearMap.cpolynomialAt` and `CPolynomialAt.comp` with the diagonal CLM. This file already uses that composition route at L233-235, and `ContinuousMultilinearMap.hasStrictFDerivAt_uncurry` (FDeriv/Analytic.lean:636-645) uses it too.","fix":"Prove `cpolynomialAt_uncurry_of_multilinear` as `f.continuousMultilinearMapOption.cpolynomialAt.comp` of the diagonal `ContinuousLinearMap.pi fun _ ↦ .id 𝕜 _`. Then either deprecate the def and `hasFiniteFPowerSeriesOnBall_uncurry_of_multilinear`, or redefine the series as `toFormalMultilinearSeries.compContinuousLinearMap` of the diagonal so it is no longer a parallel construction.","ev":"-- batch2/Evidence.lean, section Reuse (compiled)\nvariable {ι : Type*} {Em : ι → Type*} [∀ i, NormedAddCommGroup (Em i)] [∀ i, NormedSpace 𝕜 (Em i)]\n  [Fintype ι] (f : G →L[𝕜] ContinuousMultilinearMap 𝕜 Em F) (x : G × (Π i, Em i))\n\n/-- `cpolynomialAt_uncurry_of_multilinear` from `ContinuousMultilinearMap.cpolynomialAt` and\n`CPolynomialAt.comp`, without `toFormalMultilinearSeriesOfMultilinear`. -/\nexample : CPolynomialAt 𝕜 (fun (p : G × (Π i, Em i)) ↦ f p.1 p.2) x := by\n  show CPolynomialAt 𝕜 (f.continuousMultilinearMapOption ∘\n    (ContinuousLinearMap.pi fun _ : Option ι ↦ ContinuousLinearMap.id 𝕜 (G × (Π i, Em i)))) x\n  exact f.continuousMultilinearMapOption.cpolynomialAt.comp (ContinuousLinearMap.cpolynomialAt _ x)\n\n/-- The custom series is Mathlib's `ContinuousMultilinearMap.toFormalMultilinearSeries` of\n`f.continuousMultilinearMapOption`, precomposed with the diagonal. -/\nexample : f.toFormalMultilinearSeriesOfMultilinear =\n    f.continuousMultilinearMapOption.toFormalMultilinearSeries.compContinuousLinearMap\n      (ContinuousLinearMap.pi fun _ : Option ι ↦ ContinuousLinearMap.id 𝕜 (G × (Π i, Em i))) := by\n  refine FormalMultilinearSeries.ext fun n ↦ ?_\n  simp only [ContinuousLinearMap.toFormalMultilinearSeriesOfMultilinear,\n    ContinuousMultilinearMap.toFormalMultilinearSeries,\n    FormalMultilinearSeries.compContinuousLinearMap]\n  split_ifs <;> ext <;> rfl","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-03f081","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"ContinuousLinearMap.analyticAt_uncurry_of_multilinear","line":342,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-fun-prop-tag","claim":"Not tagged `@[fun_prop]`, although `AnalyticAt` is a `fun_prop` predicate (Analytic/Basic.lean L109) and Mathlib tags the analogous uncurried lemmas `analyticAt_mul : AnalyticAt 𝕜 (fun x : A × A ↦ x.1 * x.2) z` and `analyticAt_smul` (Analytic/Constructions.lean L605-612). So for `f : G →L[𝕜] ContinuousMultilinearMap 𝕜 Em F`, `fun_prop` cannot prove `AnalyticAt 𝕜 (fun x ↦ f (g x) (v x)) x₀` from `AnalyticAt 𝕜 g x₀` and `AnalyticAt 𝕜 v x₀`; once this lemma is a local `fun_prop` lemma it proves it. (Tagging the `AnalyticOnNhd` version does not help, because `fun_prop` has no `AnalyticOnNhd` composition rule: probe2 P3 fails with 'missing composition rule'. Mathlib's `ContinuousLinearMap.analyticAt_bilinear` has the same gap, probe2 P5.)","fix":"Tag `ContinuousLinearMap.analyticAt_uncurry_of_multilinear` with `@[fun_prop]` (and `analyticAt_bilinear` in Analytic/Linear.lean with it).","ev":"hunts/cpolynomial/batch3/probe1.lean section C4: `example (f : G →L[𝕜] ContinuousMultilinearMap 𝕜 Em F) (g : H → G) (v : H → Π i, Em i) (x₀ : H) (hg : AnalyticAt 𝕜 g x₀) (hv : AnalyticAt 𝕜 v x₀) : AnalyticAt 𝕜 (fun x ↦ f (g x) (v x)) x₀ := by fail_if_success fun_prop; exact f.analyticAt_uncurry_of_multilinear.comp₂ hg hv` compiles (fun_prop fails today), and the same goal under `attribute [local fun_prop] ContinuousLinearMap.analyticAt_uncurry_of_multilinear in` is closed by `fun_prop` alone (no error at L75).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-50c024","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"ContinuousMultilinearMap.cpolynomialAt_uncurry_of_linear","line":359,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"module-docstring-incomplete","claim":"The results for continuous multilinear maps into continuous linear maps (`*_uncurry_of_linear`, L359-385) and for the joint evaluation map `(φ, v) ↦ φ v` (`ContinuousMultilinearMap.*_apply`, L387-411) are not documented anywhere. The second `namespace ContinuousMultilinearMap` block (L351) has no section header and no doc comments. It sits under the last header, `### Continuous linear maps into continuous multilinear maps` (L293-298), whose text covers only maps `G →L[𝕜] ContinuousMultilinearMap 𝕜 Em F`. The module docstring (L15-23) mentions neither family. (Theorem docstrings are optional in Mathlib, so the gap is the module docstring and the section header.)","fix":"Add a `/-! ### Continuous multilinear maps into continuous linear maps; evaluation -/` header before L351, and name these results in the module docstring.","ev":"measured on src.lean: `sed -n 351,411p src.lean | grep -c '/-'` = 0 (no doc comment or header in the block); the only `/-!` after L176 is at L293 ('### Continuous linear maps into continuous multilinear maps … a continuous linear map into continuous multilinear maps is continuously polynomial (as a function of two variables, i.e., uncurried)'); module docstring L15-23 mentions only addition/subtraction/negation, continuous multilinear maps, and continuous linear maps into continuous multilinear maps.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c7cb22","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"ContinuousMultilinearMap.analyticAt_uncurry_of_linear","line":380,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-fun-prop-tag","claim":"Not tagged `@[fun_prop]`, unlike the uncurried `analyticAt_mul`/`analyticAt_smul` in Analytic/Constructions.lean. For `f : ContinuousMultilinearMap 𝕜 Em (G →L[𝕜] F)`, `fun_prop` cannot prove `AnalyticAt 𝕜 (fun x ↦ f (v x) (g x)) x₀` from analyticity of `v` and `g`; with this lemma as a local `fun_prop` lemma it proves it.","fix":"Tag `ContinuousMultilinearMap.analyticAt_uncurry_of_linear` with `@[fun_prop]`.","ev":"hunts/cpolynomial/batch3/probe1.lean section C6: `example (f : ContinuousMultilinearMap 𝕜 Em (G →L[𝕜] F)) (v : H → Π i, Em i) (g : H → G) (x₀ : H) (hg : AnalyticAt 𝕜 g x₀) (hv : AnalyticAt 𝕜 v x₀) : AnalyticAt 𝕜 (fun x ↦ f (v x) (g x)) x₀ := by fail_if_success fun_prop; exact f.analyticAt_uncurry_of_linear.comp₂ hv hg` compiles, and the same goal under `attribute [local fun_prop] ContinuousMultilinearMap.analyticAt_uncurry_of_linear in` is closed by `fun_prop` alone (no error at L95).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2d85e4","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"ContinuousMultilinearMap.analyticAt_uncurry_compContinuousLinearMap","line":440,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-composed-fun-prop-form","claim":"The joint analyticity of `(L, c) ↦ c.compContinuousLinearMap L` (L416-L450) exists only in uncurried form; `fun_prop` cannot prove `AnalyticAt 𝕜 (fun z ↦ (c z).compContinuousLinearMap (L · z)) y` from `AnalyticAt 𝕜 c y` and `∀ i, AnalyticAt 𝕜 (L i) y`, though it follows in one line from `analyticAt_uncurry_compContinuousLinearMap`. The derivative side has the composed family `HasStrictFDerivAt/HasFDerivAt/HasFDerivWithinAt/DifferentiableAt/DifferentiableOn/Differentiable.continuousMultilinearMapCompContinuousLinearMap` (Mathlib/Analysis/Calculus/FDeriv/ContinuousMultilinearMap.lean L72-L141); the six lemmas here have no consumer in Mathlib.","fix":"Add `AnalyticAt.continuousMultilinearMapCompContinuousLinearMap` (and `WithinAt`/`On`/`OnNhd` variants) tagged `@[fun_prop]`, proved as `analyticAt_uncurry_compContinuousLinearMap.comp ((AnalyticAt.pi hL).prod hc)`.","ev":"hunts/cpolynomial/batch4/Golf.lean probe P3:\nexample {Em Fm : ι → Type*} [∀ i, NormedAddCommGroup (Em i)] [∀ i, NormedSpace 𝕜 (Em i)]\n    [∀ i, NormedAddCommGroup (Fm i)] [∀ i, NormedSpace 𝕜 (Fm i)]\n    {c : H → ContinuousMultilinearMap 𝕜 Em G} {L : ∀ i, H → Fm i →L[𝕜] Em i} {y : H}\n    (hc : AnalyticAt 𝕜 c y) (hL : ∀ i, AnalyticAt 𝕜 (L i) y) :\n    AnalyticAt 𝕜 (fun z ↦ (c z).compContinuousLinearMap (L · z)) y := by\n  fail_if_success fun_prop\n  exact (ContinuousMultilinearMap.analyticAt_uncurry_compContinuousLinearMap\n    (𝕜 := 𝕜) (Fm := Fm) (Em := Em) (G := G)).comp ((AnalyticAt.pi hL).prod hc)\ncd mathlib4 && lake env lean -D pp.unicode.fun=true -D maxSynthPendingDepth=3 -D autoImplicit=false hunts/cpolynomial/batch4/Golf.lean  -> EXIT=0, no errors (output: batch4/Golf.out, only #check lines)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7abaeb","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"ContinuousAlternatingMap.cpolynomialAt_apply","line":459,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"proof-reprovable-from-file-api","claim":"The 10-line tactic proof (a `have` equating `fun p ↦ p.1 p.2` with `(fun p ↦ p.1 p.2) ∘ (fun p ↦ (toContinuousMultilinearMapCLM 𝕜 p.1, p.2))` closed by `rfl`, then `rw [this]`, `CPolynomialAt.comp`, `CPolynomialAt.prodMk`, `comp_cpolynomialAt`, `fst`/`snd`) re-derives a single instance of this file's own `ContinuousLinearMap.cpolynomialAt_uncurry_of_multilinear` (L325) at `f := toContinuousMultilinearMapCLM 𝕜`: the evaluation map of alternating maps is `fun p ↦ C p.1 p.2` up to defeq. A two-line term proof replaces it, and all five downstream `_apply` lemmas (L472-L490) still compile unchanged.","fix":"Replace the proof by `(toContinuousMultilinearMapCLM 𝕜 : (E [⋀^ι]→L[𝕜] F) →L[𝕜] ContinuousMultilinearMap 𝕜 (fun _ : ι ↦ E) F).cpolynomialAt_uncurry_of_multilinear` (the type ascription is required; without it `exact` fails on the higher-order unification `?f p.1 p.2 =?= p.1 p.2`).","ev":"hunts/cpolynomial/batch4/Golf.lean: a copy of src.lean whose L459-L470 are replaced by\n  lemma cpolynomialAt_apply :\n      CPolynomialAt 𝕜 (fun (p : (E [⋀^ι]→L[𝕜] F) × (ι → E)) ↦ p.1 p.2) f :=\n    (toContinuousMultilinearMapCLM 𝕜 :\n      (E [⋀^ι]→L[𝕜] F) →L[𝕜] ContinuousMultilinearMap 𝕜 (fun _ : ι ↦ E) F).cpolynomialAt_uncurry_of_multilinear\n(probe P1b in the same file gives a second one-liner: `ContinuousMultilinearMap.cpolynomialAt_apply.comp (((toContinuousMultilinearMapCLM 𝕜 : …).prodMap (.id 𝕜 (ι → E))).cpolynomialAt _)`). cd mathlib4 && lake env lean -D pp.unicode.fun=true -D maxSynthPendingDepth=3 -D autoImplicit=false hunts/cpolynomial/batch4/Golf.lean  -> EXIT=0, no errors (output: batch4/Golf.out, only #check lines). The same term without the ascription (`by exact (toContinuousMultilinearMapCLM 𝕜).cpolynomialAt_uncurry_of_multilinear`) fails with `Application type mismatch`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-f4ce51","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"ContinuousAlternatingMap.analyticAt_apply","line":484,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-composed-fun-prop-form","claim":"Analyticity of evaluation is only available in uncurried form (`fun p ↦ p.1 p.2` on a product), for alternating maps (L459-L490) and multilinear maps (L387-L411); there is no composed, dot-notation, `@[fun_prop]` form, so `fun_prop` cannot prove `AnalyticAt 𝕜 (fun z ↦ φ z (v z)) y` from `AnalyticAt 𝕜 φ y` and `AnalyticAt 𝕜 v y`, although it follows in one line from these lemmas. The derivative API has exactly these composed forms (`HasFDerivAt.continuousAlternatingMap_apply`, `DifferentiableAt.continuousAlternatingMap_apply` in Mathlib/Analysis/Calculus/FDeriv/ContinuousAlternatingMap.lean L187/L246; `HasFDerivAt.continuousMultilinearMap_apply`). None of the batch's lemmas has a consumer anywhere in Mathlib (`git grep` of each name outside this file: 0 hits), consistent with the uncurried form being awkward to use.","fix":"Add `AnalyticAt.continuousAlternatingMap_apply` / `AnalyticAt.continuousMultilinearMap_apply` (and `WithinAt`/`On`/`OnNhd` variants) tagged `@[fun_prop]`, each proved as `analyticAt_apply.comp (hφ.prod hv)`.","ev":"hunts/cpolynomial/batch4/Golf.lean probes P2 (alternating) and P6 (multilinear):\nexample {φ : H → (E [⋀^ι]→L[𝕜] F)} {v : H → ι → E} {y : H}\n    (hφ : AnalyticAt 𝕜 φ y) (hv : AnalyticAt 𝕜 v y) :\n    AnalyticAt 𝕜 (fun z ↦ φ z (v z)) y := by\n  fail_if_success fun_prop\n  exact (ContinuousAlternatingMap.analyticAt_apply (𝕜 := 𝕜) (E := E) (F := F) (ι := ι)).comp (hφ.prod hv)\nexample {Em : ι → Type*} [∀ i, NormedAddCommGroup (Em i)] [∀ i, NormedSpace 𝕜 (Em i)]\n    {φ : H → ContinuousMultilinearMap 𝕜 Em F} {v : H → Π i, Em i} {y : H}\n    (hφ : AnalyticAt 𝕜 φ y) (hv : AnalyticAt 𝕜 v y) :\n    AnalyticAt 𝕜 (fun z ↦ φ z (v z)) y := by\n  fail_if_success fun_prop\n  exact (ContinuousMultilinearMap.analyticAt_apply (𝕜 := 𝕜) (Em := Em) (F := F)).comp (hφ.prod hv)\ncd mathlib4 && lake env lean -D pp.unicode.fun=true -D maxSynthPendingDepth=3 -D autoImplicit=false hunts/cpolynomial/batch4/Golf.lean  -> EXIT=0, no errors (output: batch4/Golf.out, only #check lines)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-56307e","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"IsometricContinuousFunctionalCalculus","line":31,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"module-doc-overclaim","claim":"The module docstring (L16–17) says 'with a metric on the algebra and an isometric continuous functional calculus, the algebra must *be* a C⋆-algebra already'. The class is parametric in `p`, and the claim is false in general. In any nontrivial complex Banach *-algebra with ‖1‖ = 1 (and `StarModule ℂ A`), the predicate 'is a scalar' carries an isometric CFC. One example is `Matrix (Fin 2) (Fin 2) ℂ` with the L∞ operator norm. There `‖star x‖ = 1 ≠ 2 = ‖x‖` for x = !![1,1;0,0], so it is not a C⋆-algebra. Two secondary points: the docstring refers to 'the module documentation for that file' without naming the file (Unital.lean), and it has no main-declarations or main-results list (IsGreatest.norm_cfc, norm_cfc_le(_iff), CFC.norm_pow, the ℝ≥0 instances, MonotoneOn.nnnorm_cfc).","fix":"Limit the remark to the intended setting (a norm, with `p = IsStarNormal` or `IsSelfAdjoint`; e.g. 'in practice such instances come from a C⋆-algebra structure'), name Unital.lean, and add a Main declarations section.","ev":"hunts/cfc-isometric/batch0/Probe4.lean: for `[NormedRing A] [StarRing A] [NormedAlgebra ℂ A] [StarModule ℂ A] [CompleteSpace A] [NormOneClass A] [Nontrivial A]` it proves `theorem Probe.scalarIsometricCFC : IsometricContinuousFunctionalCalculus ℂ A (· ∈ Set.range (algebraMap ℂ A))`. Every star-algebra hom out of C({c}, ℂ) is f ↦ algebraMap (f c), hence an isometry. Then, with `attribute [local instance] Matrix.linftyOpNormedRing Matrix.linftyOpNormedAlgebra`, it gives `example : IsometricContinuousFunctionalCalculus ℂ (Matrix (Fin 2) (Fin 2) ℂ) (· ∈ Set.range (algebraMap ℂ _)) := Probe.scalarIsometricCFC` and `example : ‖star !![(1 : ℂ), 1; 0, 0]‖ ≠ ‖!![(1 : ℂ), 1; 0, 0]‖`. Exit 0, no messages.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-6448d1","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"norm_cfcHom","line":62,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"normedalgebra-where-algebra-suffices","claim":"The section variable `[NormedAlgebra 𝕜 A]` (L59) is stronger than needed. No lemma in the unital `NormedRing` section (L54–183: norm_cfcHom, nnnorm_cfcHom, IsGreatest.norm_cfc/nnnorm_cfc, norm_apply_le_norm_cfc, norm_cfc_le(_iff), norm_cfc_lt(_iff), the nnnorm variants, the spectrum lemmas and CFC.norm_pow) uses the compatibility ‖c • x‖ ≤ ‖c‖‖x‖; they need only `[NormedRing A] [Algebra 𝕜 A]` plus the isometric CFC. With `[Algebra 𝕜 A]` the whole file compiles unchanged, and the lemmas still apply in the usual `NormedAlgebra` setting. (In the same compile, `[NormedSpace 𝕜 A]` at L258 in the non-unital section also weakens to `[Module 𝕜 A]`.)","fix":"Replace `[NormedAlgebra 𝕜 A]` with `[Algebra 𝕜 A]` in the variable line at L59, and likewise `[NormedSpace 𝕜 A]` with `[Module 𝕜 A]` at L258.","ev":"hunts/cfc-isometric/batch0/GenAlg.lean: a copy of src.lean with L59 `[NormedAlgebra 𝕜 A]` -> `[Algebra 𝕜 A]` and L258 `[NormedSpace 𝕜 A]` -> `[Module 𝕜 A]` (plus the term-mode norm_cfcHom), followed by a Check section with `variable [NormedRing A] [StarRing A] [NormedAlgebra ℂ A] [IsometricContinuousFunctionalCalculus ℂ A IsStarNormal]`, `example ... : ‖cfc f a‖ ≤ c := norm_cfc_le hc h` and `example [Nontrivial A] ... : IsGreatest ((fun x ↦ ‖f x‖) '' spectrum ℂ a) ‖cfc f a‖ := IsGreatest.norm_cfc f a`. `lake env lean` (with the prompt's -D flags) exits 0 with no messages.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-30bd17","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"SpectrumRestricts.isometric_cfc","line":197,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-complete-space","claim":"`SpectrumRestricts.isometric_cfc` (and by the same argument `QuasispectrumRestricts.isometric_cfc`) assumes `[CompleteSpace R]` and `[ContinuousSMul R S]`, but neither is needed: `h0`/`h` give `SpectrumRestricts 0 f`, whose `left_inv` makes `algebraMap R S` have a continuous left inverse, hence a closed embedding (`Function.LeftInverse.isClosedEmbedding`) without completeness; and `ContinuousSMul R S` follows from continuity of `algebraMap` (`continuousSMul_of_algebraMap`). The existing proof only used completeness through `halg.isClosedEmbedding`.","fix":"Drop both binders; build the closed embedding from the left inverse and install `ContinuousSMul` locally.","ev":"main/probe_restrict.lean: `isometric_cfc'` without `[CompleteSpace R]` and `[ContinuousSMul R S]` (closed embedding via `left_inv.isClosedEmbedding`, `letI := continuousSMul_of_algebraMap …`) compiles with the original proof otherwise unchanged.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-847be9","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"norm_cfcₙHom","line":265,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"normed-space-where-module-suffices","claim":"The non-unital `NormedRing` section (variable line L258) assumes `[NormedSpace 𝕜 A]`, but `[Module 𝕜 A]` suffices: every lemma in the section (in this batch: norm_cfcₙHom, nnnorm_cfcₙHom) and the rest of the file compile with it.","fix":"Replace `[NormedSpace 𝕜 A]` by `[Module 𝕜 A]` in the `variable` line at L258.","ev":"hunts/cfc-isometric/batch1/probe_gen2.lean (L258 `[NormedSpace 𝕜 A]` -> `[Module 𝕜 A]`; whole file compiles, exit 0; `#check @nnnorm_cfcₙHom` shows `[inst_3 : Module 𝕜 A]`)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-5e92db","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"IsGreatest.norm_cfcₙ","line":274,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"brittle-proof-needs-backward-option","claim":"The 11-line proof needs `set_option backward.isDefEq.respectTransparency.types false` (line 273). Without the option, the `(by simp)` at line 287 fails on `‖f x‖ ≤ ‖{ toFun := (σₙ 𝕜 a).domRestrict f, .. } ⟨x, hx'⟩‖`, because it closes the goal by unfolding a `ContinuousMapZero` literal, which is brittle. A 4-tactic proof through `IsCompact.isGreatest_sSup`, `ContinuousMapZero.norm_def` and `ContinuousMap.norm_eq_iSup_norm` compiles without the option. The unital twin `IsGreatest.norm_cfc` (line 70) repeats the same argument line for line.","fix":"Replace the proof with the `isGreatest_sSup` / `norm_eq_iSup_norm` proof below and drop the `set_option backward.isDefEq.respectTransparency.types false in`.","ev":"import Mathlib.Analysis.CStarAlgebra.ContinuousFunctionalCalculus.Isometric\n\n/-! Batch 2: a shorter proof of `IsGreatest.norm_cfcₙ` that needs no\n`set_option backward.isDefEq.respectTransparency.types false`. -/\n\nlocal notation \"σₙ\" => quasispectrum\n\nvariable {𝕜 A : Type*} {p : outParam (A → Prop)}\nvariable [RCLike 𝕜] [NonUnitalNormedRing A] [StarRing A] [NormedSpace 𝕜 A] [IsScalarTower 𝕜 A A]\nvariable [SMulCommClass 𝕜 A A]\nvariable [NonUnitalIsometricContinuousFunctionalCalculus 𝕜 A p]\n\nopen scoped ContinuousMapZero NonUnitalContinuousFunctionalCalculus\n\nlemma IsGreatest.norm_cfcₙ' (f : 𝕜 → 𝕜) (a : A)\n    (hf : ContinuousOn f (σₙ 𝕜 a) := by cfc_cont_tac) (hf₀ : f 0 = 0 := by cfc_zero_tac)\n    (ha : p a := by cfc_tac) : IsGreatest ((fun x ↦ ‖f x‖) '' σₙ 𝕜 a) ‖cfcₙ f a‖ := by\n  convert NonUnitalContinuousFunctionalCalculus.isCompact_quasispectrum a\n    |>.image_of_continuousOn hf.norm |>.isGreatest_sSup <| (quasispectrum.nonempty 𝕜 a).image _\n    using 1\n  rw [cfcₙ_apply f a, norm_cfcₙHom a _, ContinuousMapZero.norm_def,\n    ContinuousMap.norm_eq_iSup_norm, Set.image_eq_range]\n  rfl\n\n-- same statement as Mathlib's\nexample (f : 𝕜 → 𝕜) (a : A) (hf : ContinuousOn f (σₙ 𝕜 a)) (hf₀ : f 0 = 0) (ha : p a) :\n    IsGreatest ((fun x ↦ ‖f x‖) '' σₙ 𝕜 a) ‖cfcₙ f a‖ :=\n  IsGreatest.norm_cfcₙ' f a hf hf₀ ha\n\n#print axioms IsGreatest.norm_cfcₙ'\n\n-- Removing the set_option from the original proof (batch2/CopyB.lean) gives `error: unsolved goals ⊢ ‖f x‖ ≤ ‖{ toFun := (σₙ 𝕜 a).domRestrict f, continuous_toFun := ⋯, map_zero' := ⋯ } ⟨x, hx'⟩‖` at the `(by simp)`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-3cc366","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"Nonneg.instIsometricContinuousFunctionalCalculus","line":450,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"instance-hypotheses-stronger-than-class","claim":"The ℝ≥0 instance assumes `[NormedRing A] [NormedAlgebra ℝ A]`, but the class `IsometricContinuousFunctionalCalculus` asks only for `[Ring A] [MetricSpace A] [Algebra R A]`; the module docstring stresses that a norm is deliberately not required. The plain analogue `Nonneg.instContinuousFunctionalCalculus` (Instances.lean:325) is stated for `[TopologicalSpace A]`. The instance body compiles verbatim under `[Ring A] [MetricSpace A] [IsSemitopologicalRing A] [Algebra ℝ A]` (the last two are needed for `NNReal.instContinuousMap.UniqueHom`). Under the current hypotheses `inferInstance` fails in that setting. Every current consumer lives in a normed algebra, so nothing breaks today.","fix":"Replace `[NormedRing A] [NormedAlgebra ℝ A]` by `[Ring A] [MetricSpace A] [IsSemitopologicalRing A] [Algebra ℝ A]` in the `Instances`/`Unital` variable block.","ev":"batch3/probe2.lean G1: `variable {A : Type*} [Ring A] [PartialOrder A] [StarRing A] [StarOrderedRing A] [MetricSpace A] [IsSemitopologicalRing A] [Algebra ℝ A] [IsometricContinuousFunctionalCalculus ℝ A IsSelfAdjoint] [NonnegSpectrumClass ℝ A]`; `example : IsometricContinuousFunctionalCalculus ℝ≥0 A (0 ≤ ·) := SpectrumRestricts.isometric_cfc (q := IsSelfAdjoint) ContinuousMap.realToNNReal NNReal.isometry_coe le_rfl (fun _ ↦ nonneg_iff_isSelfAdjoint_and_quasispectrumRestricts)` compiles; `example : IsometricContinuousFunctionalCalculus ℝ≥0 A (0 ≤ ·) := inferInstance` fails with 'failed to synthesize' (probe2.out L1).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-db02c1","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"Nonneg.instNonUnitalIsometricContinuousFunctionalCalculus","line":465,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"instance-hypotheses-stronger-than-class","claim":"The non-unital ℝ≥0 instance has the same issue. It assumes `[NonUnitalNormedRing A] [NormedSpace ℝ A]`, although `NonUnitalIsometricContinuousFunctionalCalculus` needs only `[NonUnitalRing A] [MetricSpace A] [Module R A]`, and `Nonneg.instNonUnitalContinuousFunctionalCalculus` (Instances.lean:285) is stated for `[TopologicalSpace A]`. The body compiles verbatim under `[NonUnitalRing A] [MetricSpace A] [IsSemitopologicalRing A] [Module ℝ A]`. With the current hypotheses `inferInstance` fails there. No current consumer is affected.","fix":"Replace `[NonUnitalNormedRing A] [NormedSpace ℝ A]` by `[NonUnitalRing A] [MetricSpace A] [IsSemitopologicalRing A] [Module ℝ A]` in the `Instances`/`NonUnital` variable block.","ev":"batch3/probe2.lean G2: `variable {A : Type*} [NonUnitalRing A] [PartialOrder A] [StarRing A] [StarOrderedRing A] [MetricSpace A] [IsSemitopologicalRing A] [Module ℝ A] [IsScalarTower ℝ A A] [SMulCommClass ℝ A A] [NonUnitalIsometricContinuousFunctionalCalculus ℝ A IsSelfAdjoint] [NonnegSpectrumClass ℝ A]`; `example : NonUnitalIsometricContinuousFunctionalCalculus ℝ≥0 A (0 ≤ ·) := QuasispectrumRestricts.isometric_cfc (q := IsSelfAdjoint) ContinuousMap.realToNNReal NNReal.isometry_coe le_rfl (fun _ ↦ nonneg_iff_isSelfAdjoint_and_quasispectrumRestricts)` compiles; `:= inferInstance` fails (probe2.out L5).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-eb1a3e","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"IsometricContinuousFunctionalCalculus.isGreatest_spectrum","line":536,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"downstream-reproof-of-upstream-lemma","claim":"The membership half of `isGreatest_spectrum` is proved a second time downstream. Order.lean (which imports this file) has `CStarAlgebra.nnnorm_mem_spectrum_of_nonneg : [CStarAlgebra A] [PartialOrder A] [StarOrderedRing A] [Nontrivial A] (a : A) (ha : 0 ≤ a) : ‖a‖₊ ∈ spectrum ℝ≥0 a` (Order.lean:223). It reproves this through `NNReal.spectralRadius_mem_spectrum` and `IsSelfAdjoint.spectralRadius_eq_nnnorm`, although it is just `(IsometricContinuousFunctionalCalculus.isGreatest_spectrum a).1`. Its corollary `CStarAlgebra.norm_mem_spectrum_of_nonneg` (Order.lean:230) is likewise one line from `isGreatest_spectrum`. Outside this file `isGreatest_spectrum` has no consumer at all; inside it, only `MonotoneOn.nnnorm_cfc` uses it.","fix":"Prove `CStarAlgebra.nnnorm_mem_spectrum_of_nonneg` as `(IsometricContinuousFunctionalCalculus.isGreatest_spectrum a).1` (or deprecate it in favour of that), and derive `norm_mem_spectrum_of_nonneg` from it as now.","ev":"batch3/probe1.lean S1d: `variable {A : Type*} [CStarAlgebra A] [PartialOrder A] [StarOrderedRing A]`; `example [Nontrivial A] (a : A) (ha : 0 ≤ a) : ‖a‖₊ ∈ spectrum ℝ≥0 a := (IsometricContinuousFunctionalCalculus.isGreatest_spectrum a).1` and `example [Nontrivial A] (a : A) (ha : 0 ≤ a) : ‖a‖ ∈ spectrum ℝ a := by simpa using spectrum.algebraMap_mem ℝ (IsometricContinuousFunctionalCalculus.isGreatest_spectrum a).1` both compile (probe1.out: no error at these lines). Signatures from `#check` in probe1.out; `git grep isGreatest_spectrum origin/master -- Mathlib` shows no use outside Isometric.lean.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-dcb6c0","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"IsometricContinuousFunctionalCalculus.spectrum_le","line":540,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"near-duplicate-spectrum-norm-bound","claim":"`IsometricContinuousFunctionalCalculus.spectrum_le : x ∈ σ ℝ≥0 a → 0 ≤ a → x ≤ ‖a‖₊` overlaps `spectrum.le_nnnorm_of_mem` (Mathlib/Analysis/Normed/Algebra/Spectrum.lean:246, `[NormedRing A] [NormedAlgebra ℝ A] [CompleteSpace A] [NormOneClass A] {a : A} {r : ℝ≥0} (hr : r ∈ spectrum ℝ≥0 a) : r ≤ ‖a‖₊`). That lemma is already in this file's imports (via Instances → Normed.Algebra.Spectrum) and needs no `0 ≤ a`. It is not a strict replacement, because it needs `CompleteSpace` and `NormOneClass` and the isometric setting does not. But in a C⋆-algebra, which is where every Mathlib instance of the class comes from, it proves the statement for every `a`. The proof is 3 lines, with a `subsingleton_or_nontrivial` split only because `NormOneClass` needs `Nontrivial`. The file's lemma has no consumers anywhere in Mathlib.","fix":"Cross-reference `spectrum.le_nnnorm_of_mem` in a docstring, and keep this lemma only as the completeness-free variant (ideally generalised to `IsSelfAdjoint a`, see the generality finding).","ev":"hunts/cfc-isometric/batch4/probe1.lean section P1 (L10-23): `example [CStarAlgebra A] [PartialOrder A] [StarOrderedRing A] (a : A) ⦃x : ℝ≥0⦄ (hx : x ∈ σ ℝ≥0 a) : x ≤ ‖a‖₊ := by obtain (_ | _) := subsingleton_or_nontrivial A; · simp [spectrum.of_subsingleton] at hx; · exact spectrum.le_nnnorm_of_mem hx` compiles (no `0 ≤ a`); `git grep 'spectrum_le' origin/master -- Mathlib` finds no use of this lemma outside the file.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-8e65d0","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"IsometricContinuousFunctionalCalculus.spectrum_le","line":540,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"nonneg-hypothesis-where-selfadjoint-suffices","claim":"The hypothesis `0 ≤ a` (and with it `[PartialOrder A] [StarOrderedRing A] [NonnegSpectrumClass ℝ A]`) is stronger than needed. With only `[IsometricContinuousFunctionalCalculus ℝ A IsSelfAdjoint]` and `IsSelfAdjoint a`, the bound is a one-liner from the file's own `IsometricContinuousFunctionalCalculus.nnnorm_spectrum_le (𝕜 := ℝ)` and `spectrum.algebraMap_mem ℝ hx`. A caller holding only `0 ≤ a` still gets the hypothesis from the `cfc_tac` autoParam.","fix":"State it with `(ha : IsSelfAdjoint a := by cfc_tac)` under the `ℝ`-isometric class only, proved by `simpa using nnnorm_spectrum_le (𝕜 := ℝ) a (spectrum.algebraMap_mem ℝ hx) ha`.","ev":"hunts/cfc-isometric/batch4/probe1.lean section P3U (L36-46) and probe3.lean section G1: `lemma spectrum_le' [NormedRing A] [StarRing A] [NormedAlgebra ℝ A] [IsometricContinuousFunctionalCalculus ℝ A IsSelfAdjoint] (a : A) ⦃x : ℝ≥0⦄ (hx : x ∈ spectrum ℝ≥0 a) (ha : IsSelfAdjoint a := by cfc_tac) : x ≤ ‖a‖₊ := by simpa using IsometricContinuousFunctionalCalculus.nnnorm_spectrum_le (𝕜 := ℝ) a (spectrum.algebraMap_mem ℝ hx) ha` compiles; `example [PartialOrder A] [StarOrderedRing A] (a) (hx) (ha : 0 ≤ a) : x ≤ ‖a‖₊ := spectrum_le' a hx` compiles (the autoParam fires).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-c13d56","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"MonotoneOn.nnnorm_cfc","line":547,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"nnreal-lemmas-assume-real-cfc-not-nnreal-class","claim":"The unital `ℝ≥0` section (L482-550: `IsGreatest.nnnorm_cfc_nnreal`, the `nnnorm_cfc_nnreal_*` lemmas, `isGreatest_spectrum`, `spectrum_le`, `MonotoneOn.nnnorm_cfc`) assumes `[IsometricContinuousFunctionalCalculus ℝ A IsSelfAdjoint] [StarOrderedRing A] [NonnegSpectrumClass ℝ A]` and transfers from `ℝ` via `cfc_nnreal_eq_real`. It never uses the `ℝ≥0` isometric class, even though the module docstring says that class's purpose is to make the CFC isometric over `ℝ≥0`. `[IsometricContinuousFunctionalCalculus ℝ≥0 A (0 ≤ ·)]` alone suffices, and the file's `Nonneg.instIsometricContinuousFunctionalCalculus` derives it from exactly the three assumptions above. Only the root `IsGreatest.nnnorm_cfc_nnreal` (batch 3) needs a new proof: a direct isometry argument, 16 lines instead of 7. Every other lemma, `MonotoneOn.nnnorm_cfc` included, compiles unchanged. Callers with the old `ℝ`-based assumptions still resolve.","fix":"Replace the section variables by `[IsometricContinuousFunctionalCalculus ℝ≥0 A (0 ≤ ·)]` and prove `IsGreatest.nnnorm_cfc_nnreal` directly from `isometry_cfcHom` over `ℝ≥0`.","ev":"hunts/cfc-isometric/batch4/src_weak.lean: a copy of src.lean in which the L482-484 variables become `[NormedRing A] [StarRing A] [NormedAlgebra ℝ A] [PartialOrder A] [IsometricContinuousFunctionalCalculus ℝ≥0 A (0 ≤ ·)]` and only the proof of `IsGreatest.nnnorm_cfc_nnreal` is replaced (dist-to-zero plus `isometry_cfcHom` plus `ContinuousMap.dist_le`/`dist_apply_le_dist`). The whole file compiles (exit 0), as does section DownstreamU (`hf.nnnorm_cfc _ _` under the old ℝ-based variables). The same proof standalone is in probe1.lean section P7.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-59bea3","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"IsGreatest.nnnorm_cfcₙ_nnreal","line":561,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"nnreal-lemmas-assume-real-cfc-not-nnreal-class","claim":"The non-unital `ℝ≥0` section (L556-619) assumes `[NonUnitalIsometricContinuousFunctionalCalculus ℝ A IsSelfAdjoint] [StarOrderedRing A] [NonnegSpectrumClass ℝ A]` and transfers from `ℝ` via `cfcₙ_nnreal_eq_real`. `[NonUnitalIsometricContinuousFunctionalCalculus ℝ≥0 A (0 ≤ ·)]` alone suffices, and the file's own `Nonneg.instNonUnitalIsometricContinuousFunctionalCalculus` derives it from exactly those three assumptions. Re-proving this root lemma directly (16 lines instead of 6) lets the other 8 lemmas of the section compile unchanged under the weaker class. Callers with the old ℝ-based variables, such as the consumers in Rpow/Isometric.lean and ApproximateUnit.lean, still find the class through that instance. This was checked with a stand-in caller, not by rebuilding those files.","fix":"Replace the section variables by `[NonUnitalIsometricContinuousFunctionalCalculus ℝ≥0 A (0 ≤ ·)]` and prove `IsGreatest.nnnorm_cfcₙ_nnreal` directly from `isometry_cfcₙHom` over `ℝ≥0`.","ev":"hunts/cfc-isometric/batch4/src_weak.lean: the L556-559 variables become `... [PartialOrder A] [NonUnitalIsometricContinuousFunctionalCalculus ℝ≥0 A (0 ≤ ·)]` and only this lemma's proof is replaced. The whole file compiles (exit 0), including `apply_le_nnnorm_cfcₙ_nnreal`, `nnnorm_cfcₙ_nnreal_le(_iff)`, `nnnorm_cfcₙ_nnreal_lt(_iff)`, `isGreatest_quasispectrum`, `quasispectrum_le` and `MonotoneOn.nnnorm_cfcₙ` unchanged. Section Downstream calls `MonotoneOn.nnnorm_cfcₙ` under the old ℝ-based variables and compiles. Standalone copy: probe1.lean section P6.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-1b7dd4","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"NonUnitalIsometricContinuousFunctionalCalculus.quasispectrum_le","line":608,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"near-duplicate-spectrum-norm-bound","claim":"`NonUnitalIsometricContinuousFunctionalCalculus.quasispectrum_le : x ∈ σₙ ℝ≥0 a → 0 ≤ a → x ≤ ‖a‖₊` has the same conclusion as `CStarAlgebra.le_nnnorm_of_mem_quasispectrum` (Mathlib/Analysis/CStarAlgebra/Spectrum.lean:102, `{A : Type*} [NonUnitalCStarAlgebra A] {a : A} {x : ℝ≥0} (hx : x ∈ quasispectrum ℝ≥0 a) : x ≤ ‖a‖₊`). That lemma needs no positivity hypothesis and closes the goal in one term in every non-unital C⋆-algebra. It is used in ApproximateUnit.lean:122 and :128, while this one has zero consumers. It is not a strict replacement, because the C⋆ lemma needs completeness and the isometric class does not.","fix":"Cross-reference `CStarAlgebra.le_nnnorm_of_mem_quasispectrum` and keep this lemma only as the completeness-free variant (generalised to `IsSelfAdjoint a`, see the generality finding).","ev":"hunts/cfc-isometric/batch4/probe1.lean section P2 (L25-34): `example [NonUnitalCStarAlgebra A] [PartialOrder A] [StarOrderedRing A] (a : A) ⦃x : ℝ≥0⦄ (hx : x ∈ σₙ ℝ≥0 a) : x ≤ ‖a‖₊ := CStarAlgebra.le_nnnorm_of_mem_quasispectrum hx` compiles; `git grep 'quasispectrum_le' origin/master -- Mathlib` shows no consumer outside the file.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-ed6acd","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"NonUnitalIsometricContinuousFunctionalCalculus.quasispectrum_le","line":608,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"nonneg-hypothesis-where-selfadjoint-suffices","claim":"`0 ≤ a` (and `[PartialOrder A] [StarOrderedRing A] [NonnegSpectrumClass ℝ A]`) is stronger than needed. Under only `[NonUnitalIsometricContinuousFunctionalCalculus ℝ A IsSelfAdjoint]` with `IsSelfAdjoint a`, the bound follows in one line from the file's `nnnorm_quasispectrum_le (𝕜 := ℝ)` and `quasispectrum.algebraMap_mem ℝ hx`. Callers holding `0 ≤ a` still get the hypothesis from `cfc_tac`.","fix":"State it with `(ha : IsSelfAdjoint a := by cfc_tac)` under the `ℝ`-isometric class only, proved by `simpa using nnnorm_quasispectrum_le (𝕜 := ℝ) a (quasispectrum.algebraMap_mem ℝ hx) ha`.","ev":"hunts/cfc-isometric/batch4/probe1.lean section P3N (L48-56) and probe3.lean section G2: `lemma quasispectrum_le' [NonUnitalNormedRing A] [StarRing A] [NormedSpace ℝ A] [IsScalarTower ℝ A A] [SMulCommClass ℝ A A] [NonUnitalIsometricContinuousFunctionalCalculus ℝ A IsSelfAdjoint] (a : A) ⦃x : ℝ≥0⦄ (hx : x ∈ quasispectrum ℝ≥0 a) (ha : IsSelfAdjoint a := by cfc_tac) : x ≤ ‖a‖₊ := by simpa using NonUnitalIsometricContinuousFunctionalCalculus.nnnorm_quasispectrum_le (𝕜 := ℝ) a (quasispectrum.algebraMap_mem ℝ hx) ha` compiles, and so does a caller with only `ha : 0 ≤ a`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-08e8ef","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"IsometricContinuousFunctionalCalculus.toNonUnital","line":635,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"isometric-instance-restricted-to-rclike","claim":"The instance is stated only for `[RCLike 𝕜] [NormedRing A] [NormedAlgebra 𝕜 A]`, because its proof goes through norms (`AddMonoidHomClass.isometry_of_norm`). Its siblings `ContinuousFunctionalCalculus.toNonUnital` and `ClosedEmbeddingContinuousFunctionalCalculus.toNonUnital` (NonUnital.lean:873, :909) hold for any `[Semifield R] [StarRing R] [MetricSpace R] [IsTopologicalSemiring R] [ContinuousStar R]`, and the class itself needs only `[MetricSpace A]`. The same statement holds and is proved in about 17 lines with `dist` in place of `‖·‖` for any such `R` with `[MetricSpace A] [Algebra R A] [ContinuousMapZero.UniqueHom R A]`, and the `RCLike` instance is a special case of it.","fix":"Generalise the instance to `[Semifield R] … [MetricSpace A] [Algebra R A] [ContinuousMapZero.UniqueHom R A]`, using `Isometry.of_dist_eq` with `ContinuousMap.dist_le`/`dist_apply_le_dist`.","ev":"hunts/cfc-isometric/batch4/probe1.lean section P5 (L58-91): `theorem toNonUnital_general {R A} {p : A → Prop} [Semifield R] [StarRing R] [MetricSpace R] [IsTopologicalSemiring R] [ContinuousStar R] [Ring A] [StarRing A] [MetricSpace A] [Algebra R A] [IsometricContinuousFunctionalCalculus R A p] [ContinuousMapZero.UniqueHom R A] : NonUnitalIsometricContinuousFunctionalCalculus R A p` compiles, and `example [RCLike 𝕜] [NormedRing A] [StarRing A] [NormedAlgebra 𝕜 A] [IsometricContinuousFunctionalCalculus 𝕜 A p] : NonUnitalIsometricContinuousFunctionalCalculus 𝕜 A p := toNonUnital_general` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-e16c0f","file":"Mathlib/Analysis/Complex/BranchLogRoot.lean","decl":"(module docstring)","line":15,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-docstring","claim":"The module and theorem docstrings promise 'a continuous branch of `log (g z)`' / '`log ∘ g`'. With `log` in code font this reads as Mathlib's principal `Complex.log`, whose composite need not be continuous (g t = exp(t i) on ℝ: `log ∘ g` jumps at t = π). The theorem gives a continuous logarithm of g, i.e. a lift through exp. Also `UnitDisc.exists_continuousOn_pow_eq`'s docstring says 'for any `n ≠ 0`' but the theorem takes `n : ℕ+`.","fix":"Say 'a continuous logarithm of `g`' / 'a continuous `n`th root of `g`'; 'for every positive natural number `n`' in the disc version.","ev":"#check @Complex.UnitDisc.exists_continuousOn_pow_eq\n-- … ContinuousOn g U → 0 ∉ g '' U → ∀ (n : ℕ+), ∃ f, ContinuousOn f U ∧ ∀ x, f x ^ n = g x","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-019db2","file":"Mathlib/Analysis/Complex/BranchLogRoot.lean","decl":"Complex.exists_continuousOn_eqOn_exp_comp","line":37,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"All three theorems assume `[LocallyPathConnectedSpace X]` and `hUo : IsOpen U` only to obtain `LocallyPathConnectedSpace U`, which is all the lifting theorem needs. With the variable block `{U : Set X} [LocallyPathConnectedSpace U]` and `hUo` deleted (with `have := hUo.locallyPathConnectedSpace` removed), the whole file still compiles. This admits e.g. `U = Icc 0 1 ⊆ ℝ` (not open) and the left summand of `ℝ ⊕ ℚ` (X not locally path connected).","fix":"State the theorems with `[LocallyPathConnectedSpace U]`; keep the open-set form as a corollary (or let the one consumer, RiemannMapping, supply `hUo.locallyPathConnectedSpace`).","ev":"-- hunts/branch-log/ProbeGen.lean: variable {X} [TopologicalSpace X] {U : Set X} [LocallyPathConnectedSpace U], hUo deleted everywhere — compiles:\n-- exists_continuousOn_eqOn_exp_comp : ∀ {X} [TopologicalSpace X] {U : Set X} [LocallyPathConnectedSpace ↑U], IsSimplyConnected U → ∀ {g : X → ℂ}, ContinuousOn g U → 0 ∉ g '' U → ∃ f, ContinuousOn f U ∧ EqOn (exp ∘ f) g U","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-cc44a0","file":"Mathlib/Analysis/Complex/BranchLogRoot.lean","decl":"Complex.exists_continuousOn_eqOn_exp_comp","line":37,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"The proof obtains, from `IsCoveringMapOn.existsUnique_continuousMap_lifts`, a lift with a prescribed starting value that is unique on U, then discards both. Callers wanting a normalised branch (e.g. `F x₀ = w₀` for given `exp w₀ = g x₀`, or the root with a chosen value at a base point) must redo the lifting argument.","fix":"Add a variant returning the unique `F : C(U, ℂ)` with `F x₀ = w₀` and `exp ∘ F = g ∘ (↑)`; derive the current statements from it.","ev":"-- BranchLogRoot.lean:45: `rcases isCoveringMapOn_exp.existsUnique_continuousMap_lifts … (exp_log hx₀) … with ⟨f, ⟨-, hf⟩, -⟩` drops the start-point equation and uniqueness","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-128c73","file":"Mathlib/Analysis/Complex/BranchLogRoot.lean","decl":"Complex.exists_continuousOn_pow_eq","line":67,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reprovable-from-existing-api","claim":"Three steps rebuild existing API: (a) the dependent `if hz : z ∈ U then f ⟨z, hz⟩ else 0` extension is `Function.extend Subtype.val f 0` with `Subtype.val_injective.extend_apply`; (b) continuity of the piecewise root via a `domRestrict` round trip is `ContinuousOn.congr` with `Set.piecewise_eqOn`; (c) `(g z ^ (1 / n : ℂ)) ^ n = g z` outside U is `Complex.cpow_nat_inv_pow`. A copy with all three replacements compiles.","fix":"Use `Function.extend`, `(…).congr (U.piecewise_eqOn _ _)` and `cpow_nat_inv_pow`.","ev":"  · exact (by fun_prop : ContinuousOn (exp <| f · / n) U).congr (U.piecewise_eqOn _ _)\n  …\n    · simpa [hz, one_div] using cpow_nat_inv_pow (g z) hn\n-- and ⟨Function.extend Subtype.val f 0, Subtype.val_injective.extend_apply _ _⟩; hunts/branch-log/ProbeGen.lean compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-25a0ed","file":"Mathlib/Analysis/Complex/Conformal.lean","decl":"(file)","line":28,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-overstates","claim":"Two module-docstring entries misstate their theorems. (1) '`isConformalMap_complex_linear_conj`: the composition of a nonzero complex linear map with `conj` is complex linear': the theorem proves it is conformal (`IsConformalMap`), and the composition is conjugate-linear, not complex-linear. (2) '`isConformalMap_iff_is_complex_or_conj_linear`: a real linear map ... is conformal iff it's complex linear or ...' omits the `g ≠ 0` conjunct; the zero map is complex-linear but not conformal. A third entry says 'real-differential function' and assumes real-differentiability that the theorem does not take.","fix":"Say 'is conformal' in (1), add 'and nonzero' in (2), and fix (3).","ev":"src L28-29 vs L88-89 (`IsConformalMap ((map.restrictScalars ℝ).comp conjCLE)`); L31-32 vs L117-121 (`... ∧ g ≠ 0`); L38-40 vs L155-157.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-45de20","file":"Mathlib/Analysis/Complex/Conformal.lean","decl":"DifferentiableAt.conformalAt","line":147,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-hypothesis","claim":"`DifferentiableAt.conformalAt (h : DifferentiableAt ℂ f z) (hf' : deriv f z ≠ 0)` takes `h`, which follows from `hf'` via the existing `differentiableAt_of_deriv_ne_zero` (the `deriv` of a non-differentiable function is `0`).","fix":"Add `conformalAt_of_deriv_ne_zero (hf' : deriv f z ≠ 0) : ConformalAt f z` (keeping the dot-notation version as a wrapper).","ev":"-- hunts/complex-conformal/P.lean: `example (h : deriv f x ≠ 0) : ConformalAt f x := (differentiableAt_of_deriv_ne_zero h).conformalAt h` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-3a6b94","file":"Mathlib/Analysis/Complex/Conformal.lean","decl":"complexOfReal_fderivWithin","line":256,"sev":"MINOR","status":"suspected","cat":"generality","pattern":"redundant-hypothesis","claim":"`complexOfReal_fderivWithin`/`derivWithin` (and `complexOfReal_fderiv`/`deriv`) should not need `h₁ : DifferentiableWithinAt ℝ f s x`, nor in the within case `hs`. If `f` is not ℝ-differentiable, both selected derivatives are `0`; if `s` has no accumulation point at `x`, both `fderivWithin`s are `0`. A first proof attempt closed the non-differentiable branch but not the non-accumulation branch, so this stays suspected.","fix":"Drop `h₁` (and `hs` where possible) using `fderivWithin_zero_of_not_differentiableWithinAt` / `fderivWithin_zero_of_not_accPt`.","ev":"-- hunts/complex-conformal/P.lean: the case split compiles except the `¬ AccPt` branch (unsolved goal after the two rewrites).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-a5bd1b","file":"Mathlib/Analysis/Complex/Harmonic/Analytic.lean","decl":"HarmonicAt.differentiableAt_complex_partial","line":32,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"hypothesis-stronger-than-needed","claim":"`HarmonicAt.differentiableAt_complex_partial` assumes `HarmonicAt f x` (C² at `x` and `Δ f = 0` on a neighbourhood) but its proof uses only `ContDiffAt ℝ 2 f x` and the pointwise `Δ f x = 0` (`hf.2.eq_of_nhds`). The version with those two hypotheses compiles with the same proof, and is strictly more general: for `f z = (re z) ^ 3`, `Δ f 0 = 0` while `Δ f = 6 re z` does not vanish near `0` (Astra A1 item 2). The analyticity corollary does need the neighbourhood condition.","fix":"Add `differentiableAt_complex_partial_of_laplacian_eq_zero (hC2 : ContDiffAt ℝ 2 f x) (hΔ : Δ f x = 0)` and derive the `HarmonicAt` version from it.","ev":"hunts/harmonic-analytic/probe2.lean: `differentiableAt_complex_partial_of_laplacian_eq_zero` (the original proof with `hf.1 := hC2`, `hf.2.eq_of_nhds := hΔ`) compiles, exit 0 (only `Pi.zero_apply` reported unused).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-624f9c","file":"Mathlib/Analysis/Complex/Harmonic/Analytic.lean","decl":"InnerProductSpace.HarmonicOnNhd.exists_analyticOnNhd_ball_re_eq","line":67,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-written-as-comment","claim":"The intended docstrings of `InnerProductSpace.HarmonicOnNhd.exists_analyticOnNhd_ball_re_eq` (L67-70) and `HarmonicAt.analyticAt` (L140-143) are written as plain `/- … -/` comments, not `/-- … -/`, so neither public theorem has a docstring (the `docBlame` linter does not cover theorems). The second comment also carries the file's TODO.","fix":"Change both `/-` to `/--` (moving the TODO to the module docstring).","ev":"hunts/harmonic-analytic/probe1.lean: `findDocString?` reports `false` for `HarmonicAt.analyticAt` and `InnerProductSpace.HarmonicOnNhd.exists_analyticOnNhd_ball_re_eq` and `true` for `HarmonicAt.differentiableAt_complex_partial`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-945a31","file":"Mathlib/Analysis/Complex/Harmonic/Analytic.lean","decl":"InnerProductSpace.HarmonicOnNhd.exists_analyticOnNhd_univ_re_eq","line":110,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"duplicated-proof","claim":"The 22-line proof of `exists_analyticOnNhd_univ_re_eq` (L113-134) repeats the 26-line argument of `exists_analyticOnNhd_ball_re_eq` (L74-101): build `g = ∂f/∂1 - I • ∂f/∂I`, take a primitive `F` with `F z₀ = f z₀` via `IsExactOn.with_val_at`, and conclude with `Convex.eqOn_of_fderivWithin_eq` after the same `x = x.re • 1 + x.im • I` computation. One lemma for an open convex set on which `g` is exact would give both; Astra A1 item 5 isolates the shared step (`HasDerivAt F ((L 1 : ℂ) - I * (L I : ℂ)) x → HasFDerivAt (fun z ↦ (F z).re) L x`).","fix":"Factor `HarmonicOnNhd.exists_analyticOnNhd_re_eq_of_isExactOn (hU : IsOpen U) (hc : Convex ℝ U) (hex : IsExactOn g U)` and derive the ball and univ versions from `isExactOn_ball`/`isExactOn_univ`.","ev":"Measured: L76-101 vs L113-134 of the audited file (same `let g`, `with_val_at`, `eqOn_of_fderivWithin_eq`, `a.re • 1 + a.im • I` steps).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261006-555dc7","file":"Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Truncated.lean","decl":"ValueDistribution.truncatedLogCounting","line":61,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"junk-value-presented-as-fact","claim":"The docstrings promise 'counting each zero/pole once, regardless of multiplicity', but by `divisor` conventions: (a) infinite-order zeros count nothing (`truncatedLogCounting (fun _ ↦ 0) 0 = 0`); (b) if f is not meromorphic everywhere the whole divisor, and so the count, is 0, even near points where f is fine; (c) zeros/poles are of meromorphic germs, not of values (z ↦ z⁻¹ has `f 0 = 0` but counts a pole there). Also: `truncatedLogCounting_congr_codiscrete` says 'differ only on a discrete set' but `codiscrete` means a closed discrete set (changing z ↦ z on {1/n} breaks meromorphy at 0); `truncatedLogCounting_monotoneOn` says 'monotonous' without the domain `Ioi 0` (it fails at 0: N̄(z, 0, 0) = 0 > log ½ = N̄(z, 0, ½)); the module docstring describes only poles.","fix":"State the conventions (meromorphic f, germ zeros, infinite-order zeros ignored); say 'closed discrete'; 'monotone on positive radii'; mention a₀-points in the module docstring.","ev":"example : truncatedLogCounting (fun _ : ℂ ↦ (0 : ℂ)) 0 = 0 := by\n  simp [truncatedLogCounting_zero]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6f8b44","file":"Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Truncated.lean","decl":"ValueDistribution.truncatedLogCounting","line":61,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"There is no constant-function lemma: `simp` makes no progress on `truncatedLogCounting (fun _ ↦ c) a = 0`, whereas the untruncated `logCounting` has `logCounting_const`/`logCounting_const_zero`; the `_top`/`_coe` simp attributes are only `local`.","fix":"Add `@[simp] truncatedLogCounting_const` (and `_const_zero`), mirroring Basic.lean.","ev":"example (c : ℂ) (a : WithTop ℂ) : truncatedLogCounting (fun _ : ℂ ↦ c) a = 0 := by simp\n-- error: `simp` made no progress","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7ea2de","file":"Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Truncated.lean","decl":"ValueDistribution.truncatedLogCounting_congr_codiscrete","line":125,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`truncatedLogCounting_congr_codiscrete` is stated for `f g : ℂ → E` with `[NormedSpace ℂ E]`, but the same proof works over the file's general `𝕜` (`divisor_congr_codiscreteWithin` is general); the parent `logCounting_congr_codiscrete` in LogCounting/Basic.lean has the same restriction. `logCounting_truncate_le` and `logCounting_truncate_nonneg` are fixed at `truncate₁` although the proofs work for every `truncate n hn` with `0 ≤ n`.","fix":"State the congruence over `𝕜`; generalise the two divisor lemmas to `truncate n hn`.","ev":"example {f g : 𝕜 → E} (hfg : f =ᶠ[codiscrete 𝕜] g) :\n    truncatedLogCounting f = truncatedLogCounting g := by\n  ext a : 1\n  cases a\n  all_goals\n    simp only [truncatedLogCounting_top, truncatedLogCounting_coe]\n    congr! 3\n    exact divisor_congr_codiscreteWithin (hfg.mono <| by simp) isOpen_univ\nexample (D : locallyFinsupp E ℤ) (n : ℤ) (hn : 0 ≤ n) {r : ℝ} (hr : 1 ≤ r) :\n    logCounting (D.truncate n hn) r ≤ logCounting D r := logCounting_le (D.truncate_le n hn) hr","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-1bec16","file":"Mathlib/Analysis/Complex/ValueDistribution/SecondMainTheorem.lean","decl":"Real.exists_sum_posLog_inv_norm_sub_le","line":56,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"The separation lemma is stated over a `NormedField`, but commutativity is never used: the whole file compiles with `[NormedDivisionRing 𝕜]` (and the private helper needs only an additive normed group).","fix":"Weaken the section variable to `[NormedDivisionRing 𝕜]`.","ev":"-- hunts/smt/ProbeCopy.lean: `variable {𝕜 : Type*} [NormedDivisionRing 𝕜]` — compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-42ee25","file":"Mathlib/Analysis/Complex/ValueDistribution/SecondMainTheorem.lean","decl":"Real.exists_sum_posLog_inv_norm_sub_le","line":56,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"proof-detour","claim":"The proof is 87 lines and carries dead weight: the cap `δ ≤ 1` (`hδ₁`) is never used (`clear hδ₁` compiles), the final `h6` estimate is redundant (`linarith only [hhead, htail, hposA]` closes the goal), and `hcaste` reproves `Finset.cast_card_erase_of_mem` with `grind`. Astra also proposes replacing the whole `hhead` dominance argument (`hlarge`, `hlow`, `hdom`, the pole split) by `Real.posLog_norm_add_le`, which gives the same constant (not yet tested).","fix":"Use `infsep` uncapped, drop `h6`, use `cast_card_erase_of_mem`, and try the `posLog_norm_add_le` route for the head term.","ev":"-- hunts/smt/ProbeCopy.lean: `clear hδ₁`; `hcaste := Finset.cast_card_erase_of_mem (R := ℝ) ha₀`; final step `linarith only [hhead, htail, hposA]` without h6 — compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-57c803","file":"Mathlib/Analysis/Distribution/ContDiffMapSupportedIn.lean","decl":"ContDiffMapSupportedIn.compact_supp","line":161,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `ContDiffMapSupportedIn.hasCompactSupport` (Analysis.Distribution.ContDiffMapSupportedIn), `ContDiffMapSupportedIn.compact_supp` (Analysis.Distribution.ContDiffMapSupportedIn) state exactly the same thing (Lean-checked). Reviewer: Same file: `HasCompactSupport f` for f in 𝓓^{n}_{K} is proved at line 161 and again at line 265, both via `HasCompactSupport.intro K.isCompact`. Keep hasCompactSupport (predicate name, several uses) and deprecate compact_supp (1 use in TestFunction.lean).","fix":"Deprecate `ContDiffMapSupportedIn.compact_supp` in favour of `ContDiffMapSupportedIn.hasCompactSupport`.","ev":"dupscan/Check.lean: `example := (@ContDiffMapSupportedIn.compact_supp : type_of% @ContDiffMapSupportedIn.hasCompactSupport)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 2, rating MAJOR): Both are protected methods with the same explicit argument and no differing attributes; `compact_supp` provides no additional calling convention. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Analysis/Distribution/ContDiffMapSupportedIn.lean#L161).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-c5ed06","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.derivCLM","line":58,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"rclike-where-normedfield-suffices","claim":"derivCLM (and so derivCLM_apply) assumes `[RCLike 𝕜]` (section variable, line 54), but the construction only needs `[NormedField 𝕜] [NormedSpace 𝕜 F] [SMulCommClass ℝ 𝕜 F]`. That is the convention of `mkCLM`, `evalCLM` and the seminorm API in SchwartzSpace/Basic.lean; `TestFunction.fderivCLM` similarly uses NontriviallyNormedField + IsScalarTower. Under RCLike the needed `SMulCommClass ℝ 𝕜 F` is found silently through the instance `Real.isScalarTower`.","fix":"In the Derivatives section, replace `[RCLike 𝕜]` with `[NormedField 𝕜] [SMulCommClass ℝ 𝕜 F]`, keeping RCLike only for lineDerivOp_compCLMOfContinuousLinearEquiv (needed by compCLMOfContinuousLinearEquiv).","ev":"hunts/schwartz-deriv/batch0/CopyB.lean: src.lean with line 54 replaced by `section NF` / `variable [NormedField 𝕜] [NormedSpace 𝕜 F] [SMulCommClass ℝ 𝕜 F]`, line 78 removed, `end NF` + `variable [RCLike 𝕜] [NormedSpace 𝕜 F]` + `open LineDeriv` after `end fderiv`. The whole file compiles (exit 0) and `#check @SchwartzMap.derivCLM` shows `[NormedField 𝕜] → [NormedSpace 𝕜 F] → [SMulCommClass ℝ 𝕜 F] → 𝓢(ℝ, F) →L[𝕜] 𝓢(ℝ, F)`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-b93683","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.derivCLM","line":58,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-compatibility-lemma","claim":"No lemma in Mathlib relates derivCLM to the rest of the derivative API on 𝓢(ℝ, F). Neither `derivCLM 𝕜 F f = ∂_{1} f` (or `= lineDerivOpCLM 𝕜 𝓢(ℝ, F) 1`) nor `derivCLM 𝕜 F f x = fderivCLM 𝕜 ℝ F f x 1` exists. As a result the parallel 1-D APIs (derivCLM and the `deriv` integration-by-parts lemmas, against ∂_{m} and the `lineDerivOp` integration-by-parts lemmas) cannot be converted into each other without unfolding.","fix":"Add `derivCLM_eq_lineDerivOp (f : 𝓢(ℝ, F)) : derivCLM 𝕜 F f = ∂_{(1 : ℝ)} f := rfl` (and optionally `derivCLM_eq_lineDerivOpCLM`).","ev":"hunts/schwartz-deriv/batch0/Probe3.lean: `example (f : 𝓢(ℝ, F)) : derivCLM 𝕜 F f = ∂_{(1 : ℝ)} f := by ext x; simp [lineDerivOp_apply_eq_fderiv]` and `example (f : 𝓢(ℝ, F)) (x : ℝ) : derivCLM 𝕜 F f x = fderivCLM 𝕜 ℝ F f x 1 := by simp` compile. `git grep -n -E 'derivCLM\\b' origin/master -- Mathlib` (fderivCLM and lineDerivOpCLM excluded) hits only Deriv.lean (def, apply, tsupport, integration by parts) and TemperedDistribution.lean:331-344; no compatibility lemma.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-d869f1","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.fderivCLM","line":82,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-smulcommclass-with-rclike","claim":"fderivCLM, and with it fderivCLM_apply, the `LineDerivSMul 𝕜` instance (L111) and lineDerivOpCLM_eq, assumes both `[RCLike 𝕜]` and `[SMulCommClass ℝ 𝕜 F]` (line 78). The pair is inconsistent. Under RCLike the SMulCommClass binder is redundant: `Real.isScalarTower` (Mathlib/Topology/Instances/RealVectorSpace.lean:57) plus `IsScalarTower.to_smulCommClass` synthesise it, and derivCLM already relies on this. If the binder is kept, RCLike can be weakened to NormedField.","fix":"Either delete `variable [SMulCommClass ℝ 𝕜 F]` (line 78, and the copy at line 162 that tsupport_fderivCLM_subset then no longer uses), or keep it and weaken `[RCLike 𝕜]` to `[NormedField 𝕜]` as in finding 0. Both compile.","ev":"hunts/schwartz-deriv/batch0/Probe3.lean: with `[RCLike 𝕜] [NormedSpace ℝ F] [NormedSpace 𝕜 F]` and no SMulCommClass binder, `example : SMulCommClass ℝ 𝕜 F := inferInstance`, `noncomputable example : 𝓢(E, F) →L[𝕜] 𝓢(E, E →L[ℝ] F) := fderivCLM 𝕜 E F` and `example : LineDerivSMul 𝕜 E 𝓢(E, F) 𝓢(E, F) := inferInstance` compile. (Probe2: `#synth SMulCommClass ℝ 𝕜 F` = `IsScalarTower.to_smulCommClass` via `Real.isScalarTower`; it fails for `[NormedField 𝕜]`.) hunts/schwartz-deriv/batch0/CopyA.lean (line 78 removed) compiles with exit 0. fderivCLM, fderivCLM_apply and lineDerivOpCLM_eq lose the binder, and the only new message is the unusedSectionVars warning for tsupport_fderivCLM_subset's line-162 binder. hunts/schwartz-deriv/batch0/CopyB.lean (NormedField + SMulCommClass) compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-4a7f3b","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.instLineDeriv","line":99,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-def-lemma","claim":"The LineDeriv instance on 𝓢(E, F) has no element-level unfolding lemma `∂_{m} f = SchwartzMap.evalCLM ℝ E F m (fderivCLM ℝ E F f)`. There is only the pointwise `lineDerivOp_apply_eq_fderiv` and the 𝕜-CLM-level `lineDerivOpCLM_eq`. So downstream SchwartzSpace/Fourier.lean (lineDerivOp_fourier_eq L184, fourier_lineDerivOp_eq L195) unfolds the instance with `change … SchwartzMap.evalCLM ℝ V E m (fderivCLM ℝ V E _)`. The sibling TestFunction API provides `lineDerivOp_eq_lineDerivCLM` for this.","fix":"Add `theorem lineDerivOp_eq_evalCLM_fderivCLM (m : E) (f : 𝓢(E, F)) : ∂_{m} f = SchwartzMap.evalCLM ℝ E F m (fderivCLM ℝ E F f) := rfl` and use it in Fourier.lean in place of `change`.","ev":"hunts/schwartz-deriv/batch0/Probe3.lean: `example (m : E) (f : 𝓢(E, F)) : ∂_{m} f = SchwartzMap.evalCLM ℝ E F m (fderivCLM ℝ E F f) := rfl` compiles. The existing route needs `rw [← lineDerivOpCLM_apply (R := ℝ) (E := 𝓢(E, F)), lineDerivOpCLM_eq, ContinuousLinearMap.comp_apply]` (also compiles). Measured: `change` at Mathlib/Analysis/Distribution/SchwartzSpace/Fourier.lean:184 and :195; `lineDerivOp_eq_lineDerivCLM` at Mathlib/Analysis/Distribution/TestFunction.lean:620.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-0a8114","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.instLaplacian","line":191,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"operator-instance-missing-linearity-lemmas","claim":"The `Laplacian 𝓢(E, F) 𝓢(E, F)` instance comes with no linearity API: `Δ (f + g) = Δ f + Δ g`, `Δ (c • f) = c • Δ f`, `Δ 0 = 0` and `Δ (-f) = -Δ f` all fail with `simp made no progress` and have no named lemma, so every use has to rewrite backwards through `laplacianCLM_eq'`/`laplacianCLM_eq` and apply `map_add`/`map_smul`. The line derivative has `lineDerivOp_add`/`lineDerivOp_smul` and @[simp] `lineDerivOp_zero`/`lineDerivOp_neg`/`lineDerivOp_sum`. (TemperedDistribution's Laplacian instance has the same gap.)","fix":"Add `@[simp]` lemmas `laplacian_add`, `laplacian_smul`, `laplacian_zero`, `laplacian_neg`, `laplacian_sum` for `𝓢(E, F)`, each proved by `map_*` of `laplacianCLM ℝ E 𝓢(E, F)`.","ev":"-- hunts/schwartz-deriv/batch1/Probe2.lean, lines 11-14 fail with `simp made no progress`, lines 17-22 compile\nexample (f g : 𝓢(E, F)) : Δ (f + g) = Δ f + Δ g := by simp            -- simp made no progress\nexample (c : ℝ) (f : 𝓢(E, F)) : Δ (c • f) = c • Δ f := by simp     -- simp made no progress\nexample : Δ (0 : 𝓢(E, F)) = 0 := by simp                           -- simp made no progress\nexample (f : 𝓢(E, F)) : Δ (-f) = -Δ f := by simp                   -- simp made no progress\nexample (f g : 𝓢(E, F)) : Δ (f + g) = Δ f + Δ g := by\n  simp only [← laplacianCLM_eq', map_add]                            -- compiles\nexample (c : ℝ) (f : 𝓢(E, F)) : Δ (c • f) = c • Δ f := by\n  simp only [← laplacianCLM_eq', map_smul]                           -- compiles","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-38ed8b","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.laplacianCLM_eq'","line":194,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"special-case-duplicate-lemma","claim":"`laplacianCLM_eq' (f) : laplacianCLM ℝ E 𝓢(E, F) f = Δ f` is exactly the 𝕜 := ℝ instance of the @[simp] lemma `laplacianCLM_eq 𝕜 f` eight lines below; it has no consumer anywhere in Mathlib (git grep origin/master: only its own declaration), and the sibling file TemperedDistribution.lean has only the single general lemma.","fix":"Deprecate `laplacianCLM_eq'` in favour of `laplacianCLM_eq ℝ`.","ev":"-- hunts/schwartz-deriv/batch1/Probe1.lean (section B), compiles\nexample {E F : Type*} [NormedAddCommGroup E] [InnerProductSpace ℝ E] [FiniteDimensional ℝ E]\n    [NormedAddCommGroup F] [NormedSpace ℝ F] (f : 𝓢(E, F)) :\n    laplacianCLM ℝ E 𝓢(E, F) f = Δ f := laplacianCLM_eq ℝ f\n-- git grep -n \"laplacianCLM_eq'\" origin/master -- Mathlib  => only Deriv.lean:194","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-251ec8","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.integral_mul_deriv_eq_neg_deriv_mul","line":237,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"nonunital-ring-suffices","claim":"`[NormedRing 𝕜]` is stronger than used: the proof is a one-line application of the bilinear version to `ContinuousLinearMap.mul ℝ 𝕜`, which only needs `[NonUnitalSeminormedRing 𝕜] [NormedSpace ℝ 𝕜] [IsScalarTower ℝ 𝕜 𝕜] [SMulCommClass ℝ 𝕜 𝕜]`. The same statement and proof compile under `[NonUnitalNormedRing 𝕜]`, while the current lemma cannot be applied to a non-unital normed ring (`failed to synthesize NormedRing R`). (Moreover the two tower classes always hold for a normed ring with a real normed-space structure, since multiplication is continuous and biadditive, hence ℝ-bilinear by `map_real_smul`; probe `G1.mul_deriv'` builds them in two lines.) Mathlib's non-Schwartz analogue `integral_mul_deriv_eq_deriv_mul_of_integrable` is also unital-only, so this is a nice-to-have generalisation.","fix":"Replace `[NormedRing 𝕜]` by `[NonUnitalNormedRing 𝕜]` in the `variable … in` line in front of the lemma (L233).","ev":"hunts/schwartz-deriv/batch2/probe3.lean, `G1.mul_deriv` (compiles): `variable {𝕜 : Type*} [NonUnitalNormedRing 𝕜] [NormedSpace ℝ 𝕜] [IsScalarTower ℝ 𝕜 𝕜] [SMulCommClass ℝ 𝕜 𝕜]  theorem mul_deriv (f g : 𝓢(ℝ, 𝕜)) : ∫ x : ℝ, f x * deriv g x = -∫ x : ℝ, deriv f x * g x := integral_bilinear_deriv_right_eq_neg_left f g (ContinuousLinearMap.mul ℝ 𝕜)`; and hunts/schwartz-deriv/batch2/probe4_fail.lean F2: `integral_mul_deriv_eq_neg_deriv_mul (𝕜 := R) f g` with `[NonUnitalNormedRing R]` fails with `failed to synthesize instance of type class NormedRing R`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-f8f05b","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.integral_smul_deriv_right_eq_neg_left","line":246,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"copy-pasted-docstring","claim":"The docstring says \"Version for a Schwartz function with values in continuous linear maps.\" — copied verbatim from the next lemma `integral_clm_comp_deriv_right_eq_neg_left` (L250-252). This lemma is the scalar-multiplication version (`f : 𝓢(ℝ, 𝕜)`, `f x • deriv g x`); its line-derivative and Laplacian analogues (`integral_smul_lineDerivOp_right_eq_neg_left`, `integral_smul_laplacian_right_eq_left`) correctly say \"Version for scalar multiplication.\" The name and statement make the intent clear, so MINOR rather than MAJOR.","fix":"Change the second docstring paragraph to \"Version for scalar multiplication.\"","ev":"hunts/schwartz-deriv/batch2/probe3.lean section D (`findDocString?`), output in hunts/schwartz-deriv/batch2/probe3.out: integral_smul_deriv_right_eq_neg_left and integral_clm_comp_deriv_right_eq_neg_left both return \"…1-dimensional derivative.\\n\\nVersion for a Schwartz function with values in continuous linear maps.\"; the smul lineDerivOp/laplacian versions return \"…\\n\\nVersion for scalar multiplication.\"","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-060a1a","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.integral_smul_deriv_right_eq_neg_left","line":246,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"rclike-where-lsmul-suffices","claim":"`[RCLike 𝕜] [NormedSpace 𝕜 F]` is stronger than used: the proof is a one-line application of the bilinear version to `ContinuousLinearMap.lsmul ℝ 𝕜`, whose assumptions are `[NormedRing 𝕜] [NormedAlgebra ℝ 𝕜] [Module 𝕜 F] [IsBoundedSMul 𝕜 F] [IsScalarTower ℝ 𝕜 F]` (the tower is found automatically by `Real.isScalarTower`). Under these the same proof compiles; the generalised lemma covers non-commutative scalars, e.g. `f : 𝓢(ℝ, ℍ)` acting on `g : 𝓢(ℝ, ℍ × ℍ)`, which the current lemma rejects (`failed to synthesize RCLike ℍ`), and it still specialises to the RCLike statement (also in the `[NormedSpace ℂ F]`-only setting used by TemperedDistribution). The file's own `mul` versions already allow a non-commutative `NormedRing 𝕜`. (Weakening only to `NormedField 𝕜 + NormedAlgebra ℝ 𝕜`, as in Mathlib's non-Schwartz `integral_smul_fderiv_eq_neg_fderiv_smul_of_integrable`, would be mathematically vacuous: such fields are ℝ or ℂ.)","fix":"State the smul version under `[NormedRing 𝕜] [NormedAlgebra ℝ 𝕜] [Module 𝕜 F] [IsBoundedSMul 𝕜 F]` (splitting the shared `variable [RCLike 𝕜] …` line at L241); the TemperedDistribution consumers (𝕜 = ℂ) are untouched mathematically but were not rebuilt.","ev":"hunts/schwartz-deriv/batch2/probe3.lean namespace G2 (compiles): `variable {𝕜 F : Type*} [NormedRing 𝕜] [NormedAlgebra ℝ 𝕜] [NormedAddCommGroup F] [NormedSpace ℝ F] [Module 𝕜 F] [IsBoundedSMul 𝕜 F]` and `theorem smul_deriv (f : 𝓢(ℝ, 𝕜)) (g : 𝓢(ℝ, F)) : ∫ x : ℝ, f x • deriv g x = -∫ x : ℝ, deriv f x • g x … := integral_bilinear_deriv_right_eq_neg_left f g (ContinuousLinearMap.lsmul ℝ 𝕜)`; plus the ℍ / ℍ × ℍ instance and the RCLike-recovery example; hunts/schwartz-deriv/batch2/probe4_fail.lean F1: `integral_smul_deriv_right_eq_neg_left (𝕜 := ℍ) f g` fails with `failed to synthesize instance of type class RCLike ℍ`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-1ee969","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.integral_mul_lineDerivOp_right_eq_neg_left","line":282,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"nonunital-ring-suffices","claim":"`[NormedRing 𝕜]` is stronger than used: the proof is a one-line application of the bilinear version to `ContinuousLinearMap.mul ℝ 𝕜`, which only needs `[NonUnitalSeminormedRing 𝕜] [NormedSpace ℝ 𝕜] [IsScalarTower ℝ 𝕜 𝕜] [SMulCommClass ℝ 𝕜 𝕜]`. The same statement and proof compile under `[NonUnitalNormedRing 𝕜]`, while the current lemma cannot be applied to a non-unital normed ring (`failed to synthesize NormedRing R`). (Moreover the two tower classes always hold for a normed ring with a real normed-space structure, since multiplication is continuous and biadditive, hence ℝ-bilinear by `map_real_smul`; probe `G1.mul_deriv'` builds them in two lines.) Mathlib's non-Schwartz analogue `integral_mul_deriv_eq_deriv_mul_of_integrable` is also unital-only, so this is a nice-to-have generalisation.","fix":"Replace `[NormedRing 𝕜]` by `[NonUnitalNormedRing 𝕜]` in the `variable … in` line in front of the lemma (L278).","ev":"hunts/schwartz-deriv/batch2/probe3.lean, `G1.mul_lineDerivOp` (compiles): under `[NonUnitalNormedRing 𝕜] [NormedSpace ℝ 𝕜] [IsScalarTower ℝ 𝕜 𝕜] [SMulCommClass ℝ 𝕜 𝕜]`, `theorem mul_lineDerivOp (f g : 𝓢(D, 𝕜)) (v : D) : ∫ x, f x * ∂_{v} g x ∂μ = -∫ x, ∂_{v} f x * g x ∂μ := integral_bilinear_lineDerivOp_right_eq_neg_left f g (ContinuousLinearMap.mul ℝ 𝕜) v`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-ac8a61","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.integral_smul_lineDerivOp_right_eq_neg_left","line":291,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"rclike-where-lsmul-suffices","claim":"`[RCLike 𝕜] [NormedSpace 𝕜 F]` is stronger than used: the proof is a one-line application of the bilinear version to `ContinuousLinearMap.lsmul ℝ 𝕜`, whose assumptions are `[NormedRing 𝕜] [NormedAlgebra ℝ 𝕜] [Module 𝕜 F] [IsBoundedSMul 𝕜 F] [IsScalarTower ℝ 𝕜 F]` (the tower is found automatically by `Real.isScalarTower`). Under these the same proof compiles; the generalised lemma covers non-commutative scalars, e.g. `f : 𝓢(ℝ, ℍ)` acting on `g : 𝓢(ℝ, ℍ × ℍ)`, which the current lemma rejects (`failed to synthesize RCLike ℍ`), and it still specialises to the RCLike statement (also in the `[NormedSpace ℂ F]`-only setting used by TemperedDistribution). The file's own `mul` versions already allow a non-commutative `NormedRing 𝕜`. (Weakening only to `NormedField 𝕜 + NormedAlgebra ℝ 𝕜`, as in Mathlib's non-Schwartz `integral_smul_fderiv_eq_neg_fderiv_smul_of_integrable`, would be mathematically vacuous: such fields are ℝ or ℂ.)","fix":"State the smul version under `[NormedRing 𝕜] [NormedAlgebra ℝ 𝕜] [Module 𝕜 F] [IsBoundedSMul 𝕜 F]` (splitting the shared `variable [RCLike 𝕜] …` line at L286); the TemperedDistribution consumers (𝕜 = ℂ) are untouched mathematically but were not rebuilt.","ev":"hunts/schwartz-deriv/batch2/probe3.lean namespace G2 (compiles): `variable {𝕜 F : Type*} [NormedRing 𝕜] [NormedAlgebra ℝ 𝕜] [NormedAddCommGroup F] [NormedSpace ℝ F] [Module 𝕜 F] [IsBoundedSMul 𝕜 F]` and `theorem smul_lineDerivOp (f : 𝓢(D, 𝕜)) (g : 𝓢(D, F)) (v : D) : ∫ x, f x • ∂_{v} g x ∂μ = -∫ x, ∂_{v} f x • g x ∂μ … := integral_bilinear_lineDerivOp_right_eq_neg_left f g (ContinuousLinearMap.lsmul ℝ 𝕜) v`; plus the ℍ / ℍ × ℍ instance and the RCLike-recovery example; hunts/schwartz-deriv/batch2/probe4_fail.lean F1: `integral_smul_deriv_right_eq_neg_left (𝕜 := ℍ) f g` fails with `failed to synthesize instance of type class RCLike ℍ`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-49f05d","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.integral_mul_laplacian_right_eq_left","line":334,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"nonunital-ring-suffices","claim":"`[NormedRing 𝕜]` is stronger than used: the proof is a one-line application of the bilinear version to `ContinuousLinearMap.mul ℝ 𝕜`, which only needs `[NonUnitalSeminormedRing 𝕜] [NormedSpace ℝ 𝕜] [IsScalarTower ℝ 𝕜 𝕜] [SMulCommClass ℝ 𝕜 𝕜]`. The same statement and proof compile under `[NonUnitalNormedRing 𝕜]`, while the current lemma cannot be applied to a non-unital normed ring (`failed to synthesize NormedRing R`). (Moreover the two tower classes always hold for a normed ring with a real normed-space structure, since multiplication is continuous and biadditive, hence ℝ-bilinear by `map_real_smul`; probe `G1.mul_deriv'` builds them in two lines.) Mathlib's non-Schwartz analogue `integral_mul_deriv_eq_deriv_mul_of_integrable` is also unital-only, so this is a nice-to-have generalisation.","fix":"Replace `[NormedRing 𝕜]` by `[NonUnitalNormedRing 𝕜]` in the `variable … in` line in front of the lemma (L330).","ev":"hunts/schwartz-deriv/batch2/probe3.lean, `G1.mul_laplacian` (compiles): under `[NonUnitalNormedRing 𝕜] [NormedSpace ℝ 𝕜] [IsScalarTower ℝ 𝕜 𝕜] [SMulCommClass ℝ 𝕜 𝕜]`, `theorem mul_laplacian (f g : 𝓢(E, 𝕜)) : ∫ x, f x * Δ g x ∂ν = ∫ x, Δ f x * g x ∂ν := integral_bilinear_laplacian_right_eq_left f g (ContinuousLinearMap.mul ℝ 𝕜)`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-db00f5","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.integral_smul_laplacian_right_eq_left","line":343,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"rclike-where-lsmul-suffices","claim":"`[RCLike 𝕜] [NormedSpace 𝕜 F]` is stronger than used: the proof is a one-line application of the bilinear version to `ContinuousLinearMap.lsmul ℝ 𝕜`, whose assumptions are `[NormedRing 𝕜] [NormedAlgebra ℝ 𝕜] [Module 𝕜 F] [IsBoundedSMul 𝕜 F] [IsScalarTower ℝ 𝕜 F]` (the tower is found automatically by `Real.isScalarTower`). Under these the same proof compiles; the generalised lemma covers non-commutative scalars, e.g. `f : 𝓢(ℝ, ℍ)` acting on `g : 𝓢(ℝ, ℍ × ℍ)`, which the current lemma rejects (`failed to synthesize RCLike ℍ`), and it still specialises to the RCLike statement (also in the `[NormedSpace ℂ F]`-only setting used by TemperedDistribution). The file's own `mul` versions already allow a non-commutative `NormedRing 𝕜`. (Weakening only to `NormedField 𝕜 + NormedAlgebra ℝ 𝕜`, as in Mathlib's non-Schwartz `integral_smul_fderiv_eq_neg_fderiv_smul_of_integrable`, would be mathematically vacuous: such fields are ℝ or ℂ.)","fix":"State the smul version under `[NormedRing 𝕜] [NormedAlgebra ℝ 𝕜] [Module 𝕜 F] [IsBoundedSMul 𝕜 F]` (splitting the shared `variable [RCLike 𝕜] …` line at L338); the TemperedDistribution consumers (𝕜 = ℂ) are untouched mathematically but were not rebuilt.","ev":"hunts/schwartz-deriv/batch2/probe3.lean namespace G2 (compiles): `variable {𝕜 F : Type*} [NormedRing 𝕜] [NormedAlgebra ℝ 𝕜] [NormedAddCommGroup F] [NormedSpace ℝ F] [Module 𝕜 F] [IsBoundedSMul 𝕜 F]` and `theorem smul_laplacian (f : 𝓢(E, 𝕜)) (g : 𝓢(E, F)) : ∫ x, f x • Δ g x ∂ν = ∫ x, Δ f x • g x ∂ν … := integral_bilinear_laplacian_right_eq_left f g (ContinuousLinearMap.lsmul ℝ 𝕜)`; plus the ℍ / ℍ × ℍ instance and the RCLike-recovery example; hunts/schwartz-deriv/batch2/probe4_fail.lean F1: `integral_smul_deriv_right_eq_neg_left (𝕜 := ℍ) f g` fails with `failed to synthesize instance of type class RCLike ℍ`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-8f5b7c","file":"Mathlib/Analysis/FunctionalSpaces/BesselPotentialSpace.lean","decl":"BesselPotentialSpace.copy","line":94,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"unexposed-definition-no-api","claim":"The module docstring justifies storing both `toDistr` and `toLp` because it 'gives better definitional equalities', and `copy` is a transport whose point is definitional, but the file is a `public noncomputable section` without `@[expose]`: in any importing module `(ofLp 1 v).toLp = v` and `(f.copy 1 rfl).toLp = f.toLp` fail by `rfl`, so the advertised definitional behaviour exists only inside this file.","fix":"`@[expose]` the definitions whose reductions are intended (`copy`, `ofLp`, the structure projections' constructors), or drop the defeq rationale and rely on the simp lemmas.","ev":"module\npublic import Mathlib.Analysis.FunctionalSpaces.BesselPotentialSpace\nopen MeasureTheory BesselPotentialSpace\nexample (v : Lp ℂ 2 (volume : Measure ℝ)) : (ofLp 1 v).toLp = v := by rfl   -- error: rfl failed\nexample (f : H^{1, 2}(ℝ, ℂ)) : (f.copy 1 rfl).toLp = f.toLp := by rfl     -- error: rfl failed","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-be37ec","file":"Mathlib/Analysis/FunctionalSpaces/BesselPotentialSpace.lean","decl":"BesselPotentialSpace.coeAddMonoidHom","line":193,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"The inclusion H^{s,p} → 𝓢' is bundled only as an `AddMonoidHom` (with no apply lemma); it is ℂ-linear and continuous (it is J_{-s} ∘ (Lp → 𝓢') ∘ toLpₗᵢ) but no continuous linear map or continuity lemma is provided: `fun_prop` cannot prove `Continuous fun u : H^{0,2}(ℝ, ℂ) => u.toDistr`.","fix":"Add `toDistrCLM : H^{s,p}(E, F) →L[ℂ] 𝓢'(E, F)` with `@[simp]` apply lemma and a `@[fun_prop]` continuity lemma.","ev":"example : Continuous (fun u : H^{(0:ℝ), 2}(ℝ, ℂ) => u.toDistr) := by fun_prop\n-- fun_prop was unable to prove … No theorems found for BesselPotentialSpace.toDistr","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-36455f","file":"Mathlib/Analysis/FunctionalSpaces/BesselPotentialSpace.lean","decl":"BesselPotentialSpace.ofLp","line":215,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"Missing basic simp API: the defining identity `bessel_toDistr_eq_toLp` and `memSobolev_toDistr` are not simp; `ofLp` has no `norm_ofLp`, `ofLp_add`, `ofLp_smul`; the round trips `u.copy s rfl = u` and `u.memSobolev_toDistr.toBesselPotentialSpace = u` are missing.","fix":"Add the listed lemmas (each one line via `ext`/`injective_toLp`).","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-cdabc1","file":"Mathlib/Analysis/FunctionalSpaces/BesselPotentialSpace.lean","decl":"BesselPotentialSpace.toLpₗᵢ_symm_apply","line":262,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"The inverse of `toLpₗᵢ` has no usable simp form: `toLpₗᵢ_symm_apply` only rewrites the tempered-distribution coercion `↑((toLpₗᵢ E F s p).symm f)`, there is no `(toLpₗᵢ E F s p).symm f = ofLp s f`, and `simp` makes no progress on `((toLpₗᵢ E F s p).symm f).toLp = f` or on `(toLpₗᵢ E F s p).symm f = ofLp s f`.","fix":"Add `@[simp] toLpₗᵢ_symm_apply : (toLpₗᵢ E F s p).symm f = ofLp s f` (by rfl) and rename the current lemma `coe_toLpₗᵢ_symm_apply`.","ev":"example (f : Lp F p (volume : Measure E)) : ((toLpₗᵢ E F s p).symm f).toLp = f := by simp  -- simp made no progress\nexample (f : Lp F p (volume : Measure E)) : (toLpₗᵢ E F s p).symm f = ofLp s f := by simp  -- simp made no progress","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261007-b37f84","file":"Mathlib/Analysis/InnerProductSpace/Dual.lean","decl":"toDualMap","line":61,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-overclaims-at-declared-generality","claim":"`toDualMap` is declared for `[SeminormedAddCommGroup E]`, but its docstring calls it an 'isometric embedding' and says that for complete `E` it is 'surjective, hence a conjugate-linear isometric equivalence'. For a seminormed space the map is not injective (its kernel is the null submodule; e.g. `ℝ` with the zero inner product is complete and `toDualMap 0 = toDualMap 1`), and `toDual` exists only for normed `E`. The docstring of `nullSubmodule_le_ker_toDualMap_left` also describes `x ↦ ⟪·, x⟫` while the statement is about `x ↦ ⟪x, ·⟫` (Astra A1 items 1-2).","fix":"Say 'norm-preserving conjugate-linear map' (an embedding when `E` is normed; an equivalence `toDual` when normed and complete) and fix the `_left` docstring.","ev":"Doc-only finding: L61-66 vs the `[SeminormedAddCommGroup E]` section (L55); `toDual` is in the `[NormedAddCommGroup E]` section (L102). Counterexample from Astra A1 item 1 (not formalised).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-63f0dd","file":"Mathlib/Analysis/InnerProductSpace/Dual.lean","decl":"innerSL_norm","line":108,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`innerSL_norm` assumes `[NormedAddCommGroup E] [Nontrivial E]`, but `‖innerSL 𝕜‖ = 1` holds for `[SeminormedAddCommGroup E] [NontrivialTopology E]`, by the same one-term proof (`(toDualMap 𝕜 E).norm_toContinuousLinearMap`) (Astra A1 item 4). The kernel of `toDualMap` is exactly the null submodule, a stronger form of `nullSubmodule_le_ker_toDualMap_left` (suspected, not compiled here).","fix":"Move `innerSL_norm` to the seminormed section with `[NontrivialTopology E]`; add `ker_toDualMap : ker = nullSubmodule`.","ev":"hunts/ips-dual/probe1.lean (C): the seminormed `[NontrivialTopology E]` version compiles, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-d950ed","file":"Mathlib/Analysis/InnerProductSpace/Dual.lean","decl":"toDual","line":136,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"long-proof-inside-def","claim":"The surjectivity proof of the Fréchet-Riesz theorem is a 33-line tactic block inside the `def toDual` (L138-170), with a `set`, an undocumented `change` (L147), a nested `haveI … calc` and a final `calc`; it is not available as a named theorem (`toDualMap` surjective).","fix":"State `toDualMap_surjective` as a theorem (decomposed) and define `toDual := LinearIsometryEquiv.ofSurjective _ toDualMap_surjective`.","ev":"Measured: L138-170 of the audited file.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-5a480c","file":"Mathlib/Analysis/InnerProductSpace/Dual.lean","decl":"OrthonormalBasis.norm_dual","line":236,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"real-only-statement-holds-over-rclike","claim":"`OrthonormalBasis.norm_dual` (`‖L‖ ^ 2 = ∑ i, L (b i) ^ 2`) is stated only over `ℝ`; over any `RCLike 𝕜` the identity `‖L‖ ^ 2 = ∑ i, ‖L (b i)‖ ^ 2` holds with the same proof (via `toDual`, `sum_sq_norm_inner_left`), and the real statement follows by `simpa`.","fix":"State it over `RCLike 𝕜` with norms and keep the real form as a corollary.","ev":"hunts/ips-dual/probe1.lean: `OrthonormalBasis.norm_dual'` over `[RCLike 𝕜]` and the real corollary by `simpa using b.norm_dual' L` compile, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261006-082ca3","file":"Mathlib/Analysis/InnerProductSpace/NormDet.lean","decl":"LinearMap.normDet_ne_zero_tfae","line":138,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"Basic facts are only reachable by index into two TFAE lists (`.out 2 4` means different things in the two lists): there is no named `normDet_ne_zero_iff_injective`, `normDet_pos_iff`, `normDet_eq_zero_iff_finrank_range_lt`, nor the advertised square-root formula `normDet = √(re det gram)`.","fix":"Export the named iff lemmas and the square-root formula.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-07b18d","file":"Mathlib/Analysis/InnerProductSpace/NormDet.lean","decl":"LinearMap.normDet_subtype","line":224,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`normDet_subtype` (`p.subtype.normDet = 1`) assumes the ambient space U finite-dimensional (section variable), but only `[FiniteDimensional 𝕜 p]` is needed — the same one-line proof `p.subtypeₗᵢ.normDet_eq_one` works for a finite-dimensional subspace of an infinite-dimensional space, which the file otherwise explicitly supports. Similarly `normDet_comp_of_finrank_eq` only needs `finrank V ≤ finrank U` (strict inequality makes both sides 0).","fix":"State `normDet_subtype` for `{E} (p : Submodule 𝕜 E) [FiniteDimensional 𝕜 p]`; add an `_of_finrank_le` version of the composition lemma.","ev":"example {E : Type*} [NormedAddCommGroup E] [InnerProductSpace ℝ E]\n    (p : Submodule ℝ E) [FiniteDimensional ℝ p] : p.subtype.normDet = 1 :=\n  p.subtypeₗᵢ.normDet_eq_one","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261007-5d9af3","file":"Mathlib/Analysis/InnerProductSpace/Subspace.lean","decl":"ClosedSubmodule.coe_inner","line":41,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `Submodule.coe_inner` (Analysis.InnerProductSpace.Subspace), `ClosedSubmodule.coe_inner` (Analysis.InnerProductSpace.Subspace) have exactly the same statement (Lean-checked), so `ClosedSubmodule.coe_inner` does not state what its name promises and the intended lemma is missing. Reviewer: ClosedSubmodule.coe_inner is mis-stated: it takes `(W : Submodule 𝕜 E)` instead of `(W : ClosedSubmodule 𝕜 E)`, so it is a verbatim copy of Submodule.coe_inner and never applies to the ClosedSubmodule.innerProductSpace instance defined just above it. Restate with W : ClosedSubmodule.","fix":"Restate `ClosedSubmodule.coe_inner` as its name says (keep `Submodule.coe_inner`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@ClosedSubmodule.coe_inner : type_of% @Submodule.coe_inner)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 8, rating MAJOR): The binder conflicts with the docstring and placement. Correct: `(W : ClosedSubmodule 𝕜 E) (x y : W) : ⟪x, y⟫_𝕜 = ⟪(x : E), y⟫_𝕜`. However, **“never applies” is false**: closed submodules coerce to submodules, and the closed-submodule inner product is inherited from `W.toSubmodule`. The existing general theorem already supplies the result. [Inner product instances](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Analysis/InnerProductSpace/Subspace.lean#L35-L66), [coercion](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Topology/Algebra/Module/","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-480f93","file":"Mathlib/Analysis/Meromorphic/IsolatedZeros.lean","decl":"MeromorphicOn.codiscreteWithin_setOfPred_ne_zero","line":73,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `MeromorphicOn.codiscreteWithin_setOfPred_ne_zero` (Analysis.Meromorphic.IsolatedZeros), `MeromorphicOn.eventually_codiscreteWithin_apply_ne_zero` (Analysis.Meromorphic.Order) state exactly the same thing (Lean-checked). Reviewer: Same hypotheses and the same `∀ᶠ x in codiscreteWithin U, f x ≠ 0`, proved separately in two files; IsolatedZeros imports Order. Keep the Order.lean lemma (lower in the import graph, name matches the ∀ᶠ form, 4 uses in LogDeriv) and deprecate codiscreteWithin_setOfPred_ne_zero (1 use, FirstMainTheorem).","fix":"Deprecate `MeromorphicOn.codiscreteWithin_setOfPred_ne_zero` in favour of `MeromorphicOn.eventually_codiscreteWithin_apply_ne_zero`.","ev":"dupscan/Check.lean: `example := (@MeromorphicOn.eventually_codiscreteWithin_apply_ne_zero : type_of% @MeromorphicOn.codiscreteWithin_setOfPred_ne_zero)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 3, rating MAJOR): Both support the same `MeromorphicOn` receiver and express eventual nonvanishing; there is no separate filter-normalization role. Keep the lower-file theorem and redirect existing deprecated aliases too. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Analysis/Meromorphic/IsolatedZeros.lean#L73).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: both names are in active use (drop side 3 uses), so the pair looks like intended API.","at":"2026-10-07","commit":""},{"id":"RT-20261013-129ada","file":"Mathlib/Analysis/Normed/Affine/MazurUlam.lean","decl":"IsometryEquiv.midpoint_fixed","line":34,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`midpoint_fixed` and `map_midpoint` take `[NormedAddCommGroup E]`, `[NormedAddCommGroup F]` and `[MetricSpace PF]` from the file's variable line, but their proofs only use `[SeminormedAddCommGroup E]`, `[SeminormedAddCommGroup F]` and `[PseudoMetricSpace PF]` (the domain still needs `[MetricSpace PE]`). The `pointReflection` isometry API they rely on is already stated for seminormed groups.","fix":"Give the two midpoint lemmas their own variable line with `[SeminormedAddCommGroup E] [SeminormedAddCommGroup F] [PseudoMetricSpace PF]`; keep the normed classes for the linear and affine conversions.","ev":"hunts/mazur-ulam/copyG.lean: the file's header and both lemmas, unchanged except for the weakened variable line, compile with the Mathlib linter set, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-036be8","file":"Mathlib/Analysis/Normed/Affine/MazurUlam.lean","decl":"IsometryEquiv.map_midpoint","line":88,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`IsometryEquiv.map_midpoint : f (midpoint ℝ x y) = midpoint ℝ (f x) (f y)` is not `@[simp]`, although its siblings `AffineMap.map_midpoint` and `AffineEquiv.map_midpoint` (LinearAlgebra/AffineSpace/Midpoint.lean:52-60) are; `simp` makes no progress on its own statement.","fix":"Tag it `@[simp]`, matching `AffineMap.map_midpoint` and `AffineEquiv.map_midpoint`.","ev":"hunts/mazur-ulam/probe.lean (A): `example (f : PE ≃ᵢ PF) (x y : PE) : f (midpoint ℝ x y) = midpoint ℝ (f x) (f y) := by simp` fails with '`simp` made no progress' at 4e77f237dc2.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-7bb562","file":"Mathlib/Analysis/Normed/Affine/MazurUlam.lean","decl":"(file)","line":99,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-docstring","claim":"The section note at L99-102 says 'We define a conversion to a `ContinuousLinearEquiv` first, then a conversion to an `AffineMap`', but the file defines `LinearIsometryEquiv`s (`toRealLinearIsometryEquivOfMapZero`, `toRealLinearIsometryEquiv`) and an `AffineIsometryEquiv` (`toRealAffineIsometryEquiv`). The docstring of `midpoint_fixed` says 'an isometric self-homeomorphism of a normed vector space', but the statement is about an isometry equivalence of a normed additive torsor `PE`; its proof comments at L50 and L61 likewise say `e : E ≃ᵢ E` and `f : (E ≃ᵢ E) → (E ≃ᵢ E)` where the code uses `PE ≃ᵢ PE`.","fix":"Say 'a conversion to a `LinearIsometryEquiv` first, then to an `AffineIsometryEquiv`', and 'an isometry equivalence of a real normed affine space' in `midpoint_fixed`; write `PE ≃ᵢ PE` in the L50/L61 comments.","ev":"Measured: source L99-102 vs the types of L107, L123, L139; L44-46 vs L47-48 (`e : PE ≃ᵢ PE`, `[NormedAddTorsor E PE]`); L50 and L61 comments vs L51 `set s := { e : PE ≃ᵢ PE | … }`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-7940aa","file":"Mathlib/Analysis/Normed/Affine/MazurUlam.lean","decl":"IsometryEquiv.toRealLinearIsometryEquivOfMapZero","line":109,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reproves-existing-lemma","claim":"The `norm_map'` field re-proves `‖f x‖ = ‖x‖` from `f 0 = 0` by a `simp only` chain; that is exactly `Isometry.norm_map_of_map_zero` (Analysis/Normed/Group/Uniform.lean, the additive form of `Isometry.norm_map_of_map_one`), already imported.","fix":"`norm_map' := f.isometry.norm_map_of_map_zero h0`.","ev":"hunts/mazur-ulam/copyR.lean: the full file with this field replaced (together with s-10, s-11) compiles with the Mathlib linter set, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-3bbda5","file":"Mathlib/Analysis/Normed/Affine/MazurUlam.lean","decl":"IsometryEquiv.toRealLinearIsometryEquiv","line":123,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reinvents-existing-equiv","claim":"`toRealLinearIsometryEquiv` builds `x ↦ f x - f 0` as `f.trans (addRight (f 0)).symm`, so it needs `simpa only [sub_eq_add_neg] using! sub_self (f 0)` for the map-zero side condition and `(sub_eq_add_neg _ _).symm` for its `_apply` lemma. `IsometryEquiv.subRight (f 0)` is definitionally `· - f 0`: with it the side condition is `by simp` and `toRealLinearIsometryEquiv_apply` is `rfl`.","fix":"Define it as `(f.trans (IsometryEquiv.subRight (f 0))).toRealLinearIsometryEquivOfMapZero (by simp)` and prove `toRealLinearIsometryEquiv_apply` by `rfl`.","ev":"hunts/mazur-ulam/copyR.lean: with this definition, `toRealLinearIsometryEquiv_apply := rfl` and `toRealLinearIsometryEquiv_symm_apply := rfl` both compile, and so does every later declaration, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-79e4b1","file":"Mathlib/Analysis/Normed/Affine/MazurUlam.lean","decl":"IsometryEquiv.toRealAffineIsometryEquiv","line":139,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"`toRealAffineIsometryEquiv` has a `coe` simp lemma but none for its inverse: `f.toRealAffineIsometryEquiv.symm y = f.symm y` is not `rfl` (the inverse comes from `AffineIsometryEquiv.mk'` through the linear part) and `simp` makes no progress on it, unlike `toRealLinearIsometryEquivOfMapZero` (which has `coe_…_symm`) and `toRealLinearIsometryEquiv` (`…_symm_apply`).","fix":"Add `@[simp] theorem coe_toRealAffineIsometryEquiv_symm (f : PE ≃ᵢ PF) : ⇑f.toRealAffineIsometryEquiv.symm = f.symm` (proof: `funext fun y => by rw [AffineIsometryEquiv.symm_apply_eq, coeFn_toRealAffineIsometryEquiv, apply_symm_apply]`).","ev":"hunts/mazur-ulam/probe.lean (B): `simp` makes no progress on `f.toRealAffineIsometryEquiv.symm y = f.symm y`; hunts/mazur-ulam/probe_ok.lean: `coe_toRealAffineIsometryEquiv_symm'` (`⇑f.toRealAffineIsometryEquiv.symm = f.symm`) compiles with `rw [AffineIsometryEquiv.symm_apply_eq, coeFn_toRealAffineIsometryEquiv, apply_symm_apply]`, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-b9a70e","file":"Mathlib/Analysis/Normed/Affine/MazurUlam.lean","decl":"IsometryEquiv.toRealAffineIsometryEquiv","line":139,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"Nothing relates the two Mazur–Ulam constructions: for `f : E ≃ᵢ F` between normed spaces, the linear part `f.toRealAffineIsometryEquiv.linearIsometryEquiv` equals `f.toRealLinearIsometryEquiv`, but `simp` cannot show it and no lemma states it, so a user of the affine version cannot reach the `toRealLinearIsometryEquiv_apply` API (the affine version's linear part is built from `Classical.arbitrary PE`).","fix":"Add `theorem linearIsometryEquiv_toRealAffineIsometryEquiv (f : E ≃ᵢ F) : f.toRealAffineIsometryEquiv.linearIsometryEquiv = f.toRealLinearIsometryEquiv` (four-line proof via `map_vadd 0 v`), and a lemma giving the linear part as `v ↦ f (v +ᵥ p) -ᵥ f p` for any `p`.","ev":"hunts/mazur-ulam/probe.lean (C): `simp` makes no progress; `ext v; have h := f.toRealAffineIsometryEquiv.map_vadd 0 v; simp only [vadd_eq_add, add_zero, coeFn_toRealAffineIsometryEquiv] at h; simp [h]` proves it: hunts/mazur-ulam/probe_ok.lean `linearIsometryEquiv_toRealAffineIsometryEquiv` compiles, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-e198b8","file":"Mathlib/Analysis/Normed/Affine/MazurUlam.lean","decl":"IsometryEquiv.toRealAffineIsometryEquiv","line":139,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"No round-trip lemmas: `a.toIsometryEquiv.toRealAffineIsometryEquiv = a` (for `a : PE ≃ᵃⁱ[ℝ] PF`) and `a.toIsometryEquiv.toRealLinearIsometryEquiv = a` (for `a : E ≃ₗᵢ[ℝ] F`) are true but absent, and `simp` makes no progress on either.","fix":"Add `@[simp] theorem AffineIsometryEquiv.toRealAffineIsometryEquiv_toIsometryEquiv (a : PE ≃ᵃⁱ[ℝ] PF) : a.toIsometryEquiv.toRealAffineIsometryEquiv = a := by ext; rfl` and the linear analogue `LinearIsometryEquiv.toRealLinearIsometryEquiv_toIsometryEquiv` (`by ext; simp`).","ev":"hunts/mazur-ulam/probe2.lean: `simp` makes no progress on either round trip; hunts/mazur-ulam/probe2ok.lean: `ext x; rfl` (affine) and `ext x; simp` (linear) prove them, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261007-2214fd","file":"Mathlib/Analysis/Normed/Group/Real.lean","decl":"Real.enorm_eq_ofReal","line":106,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Real.enorm_eq_ofReal` (Analysis.Normed.Group.Real), `Real.enorm_of_nonneg` (Analysis.Normed.Group.Real) state exactly the same thing (Lean-checked). Reviewer: Same file: `0 ≤ r → ‖r‖ₑ = .ofReal r` appears at line 97 and again at line 106 with a different proof. Keep enorm_of_nonneg (matches norm_of_nonneg/nnnorm_of_nonneg just above) and deprecate enorm_eq_ofReal.","fix":"Deprecate `Real.enorm_eq_ofReal` in favour of `Real.enorm_of_nonneg`.","ev":"dupscan/Check.lean: `example := (@Real.enorm_of_nonneg : type_of% @Real.enorm_eq_ofReal)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 4, rating MAJOR): Neither theorem has a distinguishing attribute or calling convention, and their rewrite directions coincide. The `norm_of_nonneg` naming family supports the proposed keeper. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Analysis/Normed/Group/Real.lean#L94).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: both names are in active use (drop side 15 uses), so the pair looks like intended API.","at":"2026-10-07","commit":""},{"id":"RT-20261007-b78b6d","file":"Mathlib/Analysis/Normed/Group/Uniform.lean","decl":"Real.isClosedEmbedding_intCast","line":483,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Real.isClosedEmbedding_intCast` (Analysis.Normed.Group.Uniform), `Int.isClosedEmbedding_coe_real` (Topology.Instances.Int) state exactly the same thing (Lean-checked). Reviewer: `IsClosedEmbedding ((↑) : ℤ → ℝ)` is proved in Topology/Instances/Int and again (via isometry_intCast) in Analysis/Normed/Group/Uniform, which transitively imports the Int file. Keep the lower Int.isClosedEmbedding_coe_real (possibly renaming it to the intCast convention) and deprecate Real.isClosedEmbedding_intCast.","fix":"Deprecate `Real.isClosedEmbedding_intCast` in favour of `Int.isClosedEmbedding_coe_real`.","ev":"dupscan/Check.lean: `example := (@Int.isClosedEmbedding_coe_real : type_of% @Real.isClosedEmbedding_intCast)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 5, rating MAJOR): The target-side namespace offers discoverability, but no receiver or automation distinction justifies another proof. Consolidation in the lower topology file is appropriate. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Topology/Instances/Int.lean#L46).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: both names are in active use (drop side 4 uses), so the pair looks like intended API.","at":"2026-10-07","commit":""},{"id":"RT-20261006-2c1a4b","file":"Mathlib/Analysis/Normed/Operator/Fredholm/Basic.lean","decl":"(module docstring)","line":62,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-drops-hypothesis","claim":"The module docstring's Main statements say `of_isInvertible_restrict` holds for an isomorphism 'between finite codimension subspaces' and `of_restrict` for 'finite codimension subspaces', dropping the closedness the theorems need. Without F₁ closed the informal claim is false: for a dense hyperplane H = ker φ (φ a discontinuous functional) of a normed space V, the inclusion H ↪ V restricts to the identity H ≅ H between finite-codimension subspaces but its range H is not closed, so it is not Fredholm.","fix":"Say 'closed finite codimension subspaces' in both Main statements bullets (as the declaration docstrings and condition 3 already do).","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-4b7865","file":"Mathlib/Analysis/Normed/Operator/Fredholm/Basic.lean","decl":"FredholmDecomposition","line":147,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-instance","claim":"`FiniteDimensional 𝕜 dec.X₀` and `dec.X₁.CoFG` are not instances, so every use writes `have := dec.finite_X₀` / `have := pkg.decDom.cofg_X₁` by hand (4 times in this file, once in Fredholm/Open.lean).","fix":"Add `instance (dec : FredholmDecomposition 𝕜 E) : FiniteDimensional 𝕜 dec.X₀ := dec.finite_X₀` and the `CoFG` analogue; delete the manual `have`s.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-e74995","file":"Mathlib/Analysis/Normed/Operator/Fredholm/Basic.lean","decl":"ContinuousLinearMap.FredholmPackage","line":178,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"There is no `FredholmPackage.index_eq : u.index = finrank 𝕜 pkg.decDom.X₀ - finrank 𝕜 pkg.decCodom.X₀`, the package's most immediate index computation (three rewrites from `ker_eq`, `range_eq` and `quotientEquivOfIsCompl`); Fredholm/Open.lean's private `eventually_nhds_isFredholm_and_index_eq` re-derives that expression.","fix":"Add `FredholmPackage.index_eq` next to `ker_eq`/`range_eq`.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-a028a5","file":"Mathlib/Analysis/Normed/Operator/Fredholm/Basic.lean","decl":"ContinuousLinearMap.isFredholm_tfae","line":343,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-hypothesis","claim":"In condition 3 of `isFredholm_tfae` (which assumes `[T2Space E]`), `IsClosed (E₁ : Set E)` follows from the other conditions: with π a continuous projection onto the closed finite-codimensional F₁, E₁ is the fixed-point set of the continuous map E₁.subtypeL ∘ e⁻¹ ∘ π ∘ u. The same hypothesis `E₁_closed` of `IsFredholm.of_isInvertible_restrict` is redundant whenever E is Hausdorff.","fix":"Drop `IsClosed E₁` from TFAE condition 3 (it holds under the file's T2 assumption), or add a lemma `isClosed_of_isInvertible_restrict` and a T2 variant of `of_isInvertible_restrict` without `E₁_closed`.","ev":"-- hunts/fredholm-basic: under [CompleteSpace 𝕜] [IsTopologicalAddGroup F] [ContinuousSMul 𝕜 F] [T2Space E]\nexample {u : E →L[𝕜] F} {E₁ : Submodule 𝕜 E} {F₁ : Submodule 𝕜 F} (F₁_closed : IsClosed (F₁ : Set F)) [F₁.CoFG]\n    (h_mapsto : MapsTo u E₁ F₁) (h_inv : (u.restrict h_mapsto).IsInvertible) : IsClosed (E₁ : Set E) := by\n  obtain ⟨π, hπ⟩ := ClosedComplemented.of_finiteDimensional_quotient F₁_closed\n  obtain ⟨e, he⟩ := h_inv\n  let p : E →L[𝕜] E := E₁.subtypeL ∘L (e.symm : F₁ →L[𝕜] E₁) ∘L π ∘L u\n  have hfix : (E₁ : Set E) = {x | p x = x} := by ... -- 12 lines\n  rw [hfix]; exact isClosed_eq p.continuous continuous_id","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-5c02ba","file":"Mathlib/Analysis/Normed/Operator/Fredholm/Basic.lean","decl":"ContinuousLinearMap.FredholmPackage.isFredholm","line":364,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"alias-inherits-assumptions","claim":"Lemmas obtained from the TFAE or from an iff inherit assumptions only the other direction needs: `FredholmPackage.isFredholm` holds with just `[ContinuousSub E] [ContinuousSub F] [T1Space F]` (no `CompleteSpace 𝕜`, `ContinuousSMul`, `T2Space E`); `IsFredholm.exists_isQuasiInverse` needs no `T2Space E/F` or `ContinuousSMul 𝕜 E`; the forward directions `IsFredholm.codRestrict` and `IsFredholm.restrict` need neither `IsClosed B` nor `[B.CoFG]` (B contains the closed finite-codimensional range).","fix":"Prove `FredholmPackage.isFredholm` and `IsFredholm.exists_isQuasiInverse` directly before the T2 section; state `IsFredholm.codRestrict`/`restrict` as standalone lemmas without the B hypotheses instead of iff aliases.","ev":"-- base variables + [ContinuousSub E] [ContinuousSub F] [T1Space F]\nexample {u : E →L[𝕜] F} (pkg : FredholmPackage u) : IsFredholm u := by\n  refine ⟨?_, ?_, ?_, ?_, ?_⟩  -- strict via isQuotientMap_projectionOntoL; range/ker via pkg.range_eq/ker_eq\n  ...\n-- [CompleteSpace 𝕜] [IsTopologicalAddGroup E] [IsTopologicalAddGroup F] [ContinuousSMul 𝕜 F]\nexample {u : E →L[𝕜] F} (hu : IsFredholm u) : ∃ v : F →L[𝕜] E, v.IsQuasiInverse u := by\n  obtain ⟨pkg⟩ := hu.nonempty_fredholmPackage\n  exact ⟨pkg.quasiInverse, pkg.isQuasiInverse⟩\n-- file's T2 context, no hypotheses on B\nexample {f : E →L[𝕜] F} (h : IsFredholm f) {B : Submodule 𝕜 F} (hB : ∀ x, f x ∈ B) :\n    IsFredholm (f.codRestrict B hB) := by\n  have hle : f.range ≤ B := by rintro _ ⟨x, rfl⟩; exact hB x\n  have : f.range.CoFG := h.finite_coker\n  have : B.CoFG := h.finite_coker.of_le hle\n  exact (isFredholm_codRestrict_iff\n    (Submodule.isClosed_mono_of_finiteDimensional_quotient h.isClosed_range hle) hB).mpr h","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-c87a53","file":"Mathlib/Analysis/Normed/Operator/Fredholm/Open.lean","decl":"ContinuousLinearMap.FredholmPackage.eventually_nhds_isInvertible","line":46,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"The block-invertibility lemma needs neither a normed codomain (a `SeminormedAddCommGroup F` suffices, as for `IsInvertible.eventually_nhds`) nor completeness of all of E (only of `pkg.decDom.X₁`); the file's variable block imposes `[NormedAddCommGroup F]` and `[CompleteSpace E]` on it.","fix":"State it with `[SeminormedAddCommGroup F]` (its own variable block); optionally take `[CompleteSpace pkg.decDom.X₁]`.","ev":"example {𝕜 E F : Type*} [NontriviallyNormedField 𝕜]\n    [NormedAddCommGroup E] [SeminormedAddCommGroup F] [NormedSpace 𝕜 E] [NormedSpace 𝕜 F]\n    [CompleteSpace E] {T₀ : E →L[𝕜] F} (pkg : T₀.FredholmPackage) :\n    ∀ᶠ T in 𝓝 T₀, (pkg.decCodom.proj ∘L T ∘L pkg.decDom.X₁.subtypeL).IsInvertible := by\n  <the file's proof, unchanged>","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261007-89d68b","file":"Mathlib/Analysis/Normed/Operator/LinearIsometry.lean","decl":"LinearIsometryEquiv.coe_coe","line":880,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `LinearIsometryEquiv.coe_toContinuousLinearEquiv` (Analysis.Normed.Operator.LinearIsometry), `LinearIsometryEquiv.coe_coe` (Analysis.Normed.Operator.LinearIsometry) state exactly the same thing (Lean-checked). Reviewer: `coe_coe : ⇑(e : E ≃SL[σ₁₂] E₂) = e` (not simp, unused) restates `coe_toContinuousLinearEquiv` (@[simp]) because the coercion is toContinuousLinearEquiv. Deprecate coe_coe.","fix":"Deprecate `LinearIsometryEquiv.coe_coe` in favour of `LinearIsometryEquiv.coe_toContinuousLinearEquiv`.","ev":"dupscan/Check.lean: `example := (@LinearIsometryEquiv.coe_coe : type_of% @LinearIsometryEquiv.coe_toContinuousLinearEquiv)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup1 item 6, rating MINOR): I would retain `coe_coe` as a conventional coercion-name alias alongside the projection-name theorem. It is also actually used at the pinned commit in [Bounds.lean:156](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Analysis/Calculus/ContDiff/Bounds.lean#L156), contrary to the reviewer’s claim.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-401491","file":"Mathlib/Analysis/ODE/Transform.lean","decl":"IsIntegralCurveAt.comp_mul_ne_zero","line":130,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-hypothesis","claim":"`IsIntegralCurveAt.comp_mul_ne_zero` assumes `ha : a ≠ 0`, but its conclusion holds for every `a`: at `a = 0` the rescaled curve `γ ∘ (· * 0)` is constant and the rescaled field `0 • v ∘ (· * 0)` is `0`, so it is a global integral curve whatever `γ` is. Its siblings `IsIntegralCurveOn.comp_mul` and `IsIntegralCurve.comp_mul` already take no `a ≠ 0`; only the iff forms need it (their converse fails at `a = 0`).","fix":"Drop `ha` (case-split `a = 0` in the proof) and rename to `IsIntegralCurveAt.comp_mul`, matching `IsIntegralCurveOn.comp_mul` and `IsIntegralCurve.comp_mul`; keep a deprecated alias.","ev":"hunts/ode-transform/probe1.lean P1zero (`IsIntegralCurve (γ ∘ (· * 0)) (0 • v ∘ (· * 0))` for any γ) and P1comp_mul (the lemma without `ha`) compile; P2 shows the iff's converse is false at `a = 0` (γ = id, v = 0). Exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-d06ca7","file":"Mathlib/Analysis/ODE/Transform.lean","decl":"isIntegralCurve_const","line":168,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-iff-counterpart","claim":"Only the introduction direction is provided for constant integral curves: `isIntegralCurve_const : (∀ t, v t x = 0) → IsIntegralCurve (fun _ ↦ x) v`. The converse also holds (derivative uniqueness), so the natural characterisation `isIntegralCurve_const_iff` is a one-liner that is missing; local/relative constructors (vanishing eventually near `t₀`, or on `s`) are missing too.","fix":"Add `isIntegralCurve_const_iff : IsIntegralCurve (fun _ ↦ x) v ↔ ∀ t, v t x = 0 := ⟨fun h t ↦ (h t).unique (hasDerivAt_const t x), isIntegralCurve_const⟩`, and the `On`/`At` constructors.","ev":"hunts/ode-transform/probe3.lean P6 compiles (exit 0). Raised by Astra's A1 pass (item 4).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261006-24a7a0","file":"Mathlib/Analysis/SpecialFunctions/Bessel.lean","decl":"(module docstring)","line":15,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-docstring","claim":"The module docstring promises 'scoped notation in the namespace Complex for these functions', but both notations (`J`, `F₀₁`) are `local` and nothing is exported; its displayed formula J_a(x) = (x/2)^a ₀F₁(;a+1;-(x/2)²)/Γ(a+1) is meaningless at negative integer a (Lean's Γ(0) = 0 would make the quotient 0, while J_{-1}(2i) ≠ 0) without saying so; and the branch convention on the cut (principal, arg ∈ (-π, π]) is not stated.","fix":"Drop or implement the scoped notation; qualify the formula for a ∉ {-1, -2, …}; state the principal branch.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-2d912c","file":"Mathlib/Analysis/SpecialFunctions/Bessel.lean","decl":"Complex.besselJ_int_neg","line":62,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"name-describes-wrong-shape","claim":"`besselJ_int_neg` (J a (-x) = (-1)^a J a x, the argument negated) and `besselJ_neg_int` (J (-a) x = (-1)^a J a x, the order negated) differ only in word order while negating different variables; `besselJ_neg_comm` (J (-a) x = J a (-x)) does not say what commutes.","fix":"e.g. `besselJ_int_apply_neg`, `besselJ_neg_int_order` (or `besselJ_neg_natCast`), `besselJ_neg_int_eq_apply_neg`.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-d6109b","file":"Mathlib/Analysis/SpecialFunctions/Bessel.lean","decl":"Complex.besselJ_zero","line":118,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"junk-value-presented-as-fact","claim":"The module docstring states as mathematics '$J_a(0) = 0$ for all complex $a ≠ 0$' (citing `besselJ_zero`), but for Re a ≤ 0 with a not an integer the value 0 is Lean's junk `0 ^ a = 0`: e.g. J_{-1/2}(x) = √(2/(πx)) cos x → ∞ as x → 0⁺, and for Re a = 0, a ≠ 0, J_a has no limit at 0. `besselJ_zero` is true of the Lean function but holds for those a only by the cpow convention.","fix":"Say 'J_a(0) = 0 when Re a > 0 or a is a nonzero integer; for other a ≠ 0 the value 0 comes from the convention 0 ^ a = 0' in the module doc and on `besselJ_zero`.","ev":"","evr":"","astraV":"agrees","astraS":"Blind pass raised the same point independently: J_{-1/2}(t) = √(2/(πt)) cos t → ∞, so the assigned 0 is not a continuous extension; a ↦ J a 0 is also discontinuous at 0. Fix: say 'by the cpow convention'.","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-8e65af","file":"Mathlib/Analysis/SpecialFunctions/FrullaniIntegral.lean","decl":"(module docstring)","line":12,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-drops-hypothesis","claim":"The module docstring states the E-valued formula without saying E is a complete space, which the theorems need (for incomplete E the Bochner integral is 0, so the formula fails for f = v on x ≤ 1 and 0 beyond, with a = 1 and b = 2). The docstring of `tendsto_integral_inv_smul_atTop` omits `0 < a`, `0 < b` and completeness: for a = -1, b = -2 the advertised limit fails. The six public helper lemmas (`intervalIntegrable_inv_smul`, `intervalIntegrable_inv_smul_comp_mul`, `integral_comp_mul_inv_smul`, `norm_integral_inv_smul_sub_le`, `tendsto_integral_inv_smul_of_tendsto_uniform`, `tendsto_integral_inv_smul_nhdsWithin`) have no docstrings; the moving-interval uniformity hypothesis of `…_of_tendsto_uniform` especially needs one.","fix":"Say 'complete normed space' in the module docstring; add positivity to the atTop docstring; document the helpers or make them private.","ev":"#check @Frullani.tendsto_integral_inv_smul_atTop\n-- … [CompleteSpace E] … (ha : 0 < a) (hb : 0 < b) …","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-5d88bd","file":"Mathlib/Analysis/SpecialFunctions/FrullaniIntegral.lean","decl":"Frullani.intervalIntegrable_inv_smul","line":34,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"The interval helpers ask for `LocallyIntegrableOn f (Ioi 0)` on the whole half-line where much less is used. `intervalIntegrable_inv_smul` needs only `IntervalIntegrable f μ a b`, for any locally finite μ, not just `volume`; `intervalIntegrable_inv_smul_comp_mul` needs it only on `(c*a)..(c*b)`; `norm_integral_inv_smul_sub_le` needs interval integrability on `a..b`, an a.e. bound, and no `hδ : 0 ≤ δ` (that follows from `h` when a ≠ b, and both sides vanish when a = b). The three `tendsto_integral_inv_smul_*` lemmas inherit the global hypothesis although only integrability near the relevant endpoint matters (Astra A1: `f x = (x-1)⁻¹`, scales 1, 2).","fix":"State the helpers with interval-integrability hypotheses (any locally finite measure), use a.e. bounds and drop `hδ`; keep `LocallyIntegrableOn` only in the two main theorems.","ev":"example {μ : Measure ℝ} [IsLocallyFiniteMeasure μ] (hf : IntervalIntegrable f μ a b)\n    (ha : 0 < a) (hb : 0 < b) : IntervalIntegrable (fun x ↦ x⁻¹ • f x) μ a b := by\n  have hsub : uIcc a b ⊆ Ioi 0 := by simp [uIcc, Icc_subset_Ioi_iff, ha, hb]\n  exact hf.continuousOn_smul (continuousOn_inv₀.mono fun x hx ↦ ne_of_gt (hsub hx))","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-0ec0f8","file":"Mathlib/Analysis/SpecialFunctions/FrullaniIntegral.lean","decl":"Frullani.tendsto_integral_inv_smul_nhdsWithin","line":113,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"wrong-namespace-for-dot-notation","claim":"General facts about the scale-invariant weight x⁻¹ (`intervalIntegrable_inv_smul`, `integral_comp_mul_inv_smul`, `norm_integral_inv_smul_sub_le`, `tendsto_integral_inv_smul_*`) live in the namespace `Frullani`, where nobody looking for interval-integral API will find them, although they say nothing about Frullani's integral. Also `tendsto_integral_inv_smul_nhdsWithin` is specifically the right-limit at 0; Mathlib spells that filter `nhdsGT_zero` (e.g. `tendsto_inv_nhdsGT_zero`), so the name hides both the point and the side.","fix":"Move the general helpers to `intervalIntegral` (or make them private); rename to `tendsto_integral_inv_smul_nhdsGT_zero`.","ev":"#check @Frullani.integral_comp_mul_inv_smul\n-- ∫ x in ε..r, x⁻¹ • f (c * x) = ∫ x in c * ε..c * r, x⁻¹ • f x   (no Frullani content)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-6cb01e","file":"Mathlib/Analysis/SpecialFunctions/FrullaniIntegral.lean","decl":"Frullani.tendsto_intervalIntegral","line":174,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"The exact finite identity `∫ x in ε..r, x⁻¹ • (f (a x) - f (b x)) = (∫ x in aε..bε, x⁻¹ • f x) - ∫ x in ar..br, x⁻¹ • f x` (for positive scales and endpoints, needing only `hf`) is a local `have hsplit` inside `tendsto_intervalIntegral`. It is the natural statement for finite Frullani approximations and error bounds, and callers must reconstruct it.","fix":"Export `hsplit` as a lemma (e.g. `Frullani.intervalIntegral_eq_sub`) and use it in `tendsto_intervalIntegral`.","ev":"-- FrullaniIntegral.lean: `have hsplit {ε r : ℝ} (hε : 0 < ε) (hr : 0 < r) : ∫ x in ε..r, … = (∫ x in (a * ε)..(b * ε), u x) - ∫ x in (a * r)..(b * r), u x` is local to the proof","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-088c50","file":"Mathlib/Analysis/SpecialFunctions/FrullaniIntegral.lean","decl":"Frullani.integral_Ioi_eq","line":213,"sev":"MINOR","status":"suspected","cat":"generality","pattern":"redundant-hypothesis","claim":"(Astra A1, unverified in Lean) In `integral_Ioi_eq` the hypothesis `hf : LocallyIntegrableOn f (Ioi 0)` follows from the others when a ≠ b. With q = b/a > 1, `hint` makes d x = f x - f (q x) locally integrable; f x - R = Σₙ d (qⁿ x) gives a.e.-strong measurability; on a compact [α, β] ⊂ (0, ∞), f = Σ_{n<N} d (qⁿ ·) + f (q^N ·) with the last term bounded by `hR`. The a = b case is trivial. Proving this in Lean needs a telescoping argument the file does not have.","fix":"Optional: a hypothesis-free variant via the telescoping argument; low value.","ev":"-- not formalised; mathematical argument only","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-17c7da","file":"Mathlib/Analysis/SpecialFunctions/FrullaniIntegral.lean","decl":"Frullani.integral_Ioi_eq","line":213,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reprovable-from-existing-api","claim":"`integral_Ioi_eq` redoes, over 20 lines (curry filter, `mem_nhdsWithin_iff`, ε/2, `le_of_tendsto`, `linarith`), what `IntegrableOn.continuousWithinAt_Ici_primitive_Ioi`, `tendsto_integral_Ioi_zero` and `intervalIntegral.integral_Ioi_sub_Ioi'` give directly. A 9-line proof from them plus `tendsto_intervalIntegral` and `tendsto_nhds_unique` compiles. The two `intervalIntegrable_…` helpers also re-derive `IntegrableOn.intervalIntegrable` (`intervalIntegrable_iff.mpr (… .mono_set uIoc_subset_uIcc)`). Astra also suggests `Filter.Tendsto.uIcc` for the explicit radius/N arguments in the two endpoint lemmas; that one is not yet tested.","fix":"Use the three improper-integral lemmas in `integral_Ioi_eq`, and `IntegrableOn.intervalIntegrable` in the helpers.","ev":"  refine tendsto_nhds_unique ?_ (tendsto_intervalIntegral hf ha hb hL hR)\n  rw [← sub_zero (∫ x in Ioi 0, _)]\n  refine (((hint.continuousWithinAt_Ici_primitive_Ioi.mono_left\n    (nhdsWithin_mono 0 Ioi_subset_Ici_self)).comp tendsto_fst).sub\n    ((tendsto_integral_Ioi_zero (μ := volume)\n      (f := fun x ↦ x⁻¹ • (f (a * x) - f (b * x))) tendsto_id).comp tendsto_snd)).congr' ?_\n  filter_upwards [prod_mem_prod self_mem_nhdsWithin (Ioi_mem_atTop 0)] with ⟨ε, r⟩ ⟨hε, hr⟩\n  exact integral_Ioi_sub_Ioi' (hint.mono_set (Ioi_subset_Ioi (le_of_lt hε)))\n    (hint.mono_set (Ioi_subset_Ioi (le_of_lt hr)))\n-- hunts/frullani/ProbeReuse.lean compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-a68aa4","file":"Mathlib/Analysis/SpecialFunctions/OrdinaryHypergeometric.lean","decl":"ordinaryHypergeometric","line":81,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"junk-value-presented-as-fact","claim":"The docstring says `ordinaryHypergeometric` 'takes the junk value 0 outside the radius of convergence and for the poles', implying it is the series' sum on the closed disk; but as an unconditional `tsum` it is also 0 at boundary points where the series converges conditionally: ₂F₁(1,1;2;-1) = 0 although the series ∑ (-1)ⁿ/(n+1) converges to log 2 (radius 1, z = -1 on the boundary).","fix":"'…outside the radius of convergence, at boundary points where the series does not converge absolutely, and for the poles'.","ev":"example : ordinaryHypergeometric 1 1 (2 : ℂ) (-1 : ℂ) = 0 := by\n  have h := ordinaryHypergeometric_div_Gamma_eq (a := 1) (b := 1) (c := 2) (z := -1) two_ne\n  rw [regGauss_neg_one, div_eq_zero_iff] at h\n  exact h.resolve_right (Gamma_ne_zero two_ne)\n-- regGauss_neg_one : regularizedGaussHGFun 1 1 2 (-1) = 0 (see the RegularizedHypergeometric finding)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":""},{"id":"RT-20261007-3f30ff","file":"Mathlib/Analysis/SpecialFunctions/Pow/NNReal.lean","decl":"NNReal.rpow_sub_intCast","line":103,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `NNReal.rpow_sub_intCast` (Analysis.SpecialFunctions.Pow.NNReal), `NNReal.rpow_sub_natCast` (Analysis.SpecialFunctions.Pow.NNReal) have exactly the same statement (Lean-checked), so `NNReal.rpow_sub_intCast` does not state what its name promises and the intended lemma is missing. Reviewer: NNReal.rpow_sub_intCast is mis-stated: it takes `(n : ℕ)`, making it identical to rpow_sub_natCast, while its siblings NNReal.rpow_add_intCast and Real.rpow_sub_intCast take `(n : ℤ)`. Restate with n : ℤ (and zpow on the RHS). Astra rates it CRITICAL (a lemma weaker than or unrelated to its name).","fix":"Restate `NNReal.rpow_sub_intCast` as its name says (keep `NNReal.rpow_sub_natCast`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@NNReal.rpow_sub_natCast : type_of% @NNReal.rpow_sub_intCast)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 7, rating CRITICAL): A natural number can be passed through an integer cast, explaining why the proof succeeds, but the public statement excludes negative integers. Correct: `(hx : x ≠ 0) (y : ℝ) (n : ℤ) : x ^ (y - (n : ℝ)) = x ^ y / x ^ n`. The general `NNReal.rpow_sub` plus `rpow_intCast` already yields this. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Analysis/SpecialFunctions/Pow/NNReal.lean#L97-L162)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-c67dc3","file":"Mathlib/Analysis/SpecialFunctions/Pow/Real.lean","decl":"Real.rpow_le_of_le_log","line":833,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `Real.rpow_le_of_le_log` (Analysis.SpecialFunctions.Pow.Real), `Real.le_rpow_of_log_le` (Analysis.SpecialFunctions.Pow.Real) have exactly the same statement (Lean-checked), so `Real.rpow_le_of_le_log` does not state what its name promises and the intended lemma is missing. Reviewer: Statement and proof are verbatim copies (`log x ≤ z * log y → x ≤ y ^ z`). `rpow_le_of_le_log` sits in the `x ^ z ≤ y` block (after rpow_le_iff_le_log and le_log_of_rpow_le), so it looks like a misstatement of `z * log x ≤ log y → x ^ z ≤ y`. The same holds for pow_le_of_le_log and zpow_le_of_le_log at 838/841, which have no external uses. Restate the three or deprecate them. Astra rates it CRITICAL (a lemma weaker than or unrelated to its name).","fix":"Restate `Real.rpow_le_of_le_log` as its name says (keep `Real.le_rpow_of_log_le`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@Real.le_rpow_of_log_le : type_of% @Real.rpow_le_of_le_log)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 26, rating CRITICAL): The neighboring iff and forward logarithm implication conclusively identify the intended orientation. Correct: `(hy : 0 < y) (h : z * log x ≤ log y) : x ^ z ≤ y`. Positivity of `x` is sufficient but unnecessary; the existing absolute-power bound proves this general form. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean#L814-L837)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-62ec62","file":"Mathlib/Analysis/SpecialFunctions/Pow/Real.lean","decl":"Real.pow_le_of_le_log","line":838,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `Real.le_pow_of_log_le` (Analysis.SpecialFunctions.Pow.Real), `Real.pow_le_of_le_log` (Analysis.SpecialFunctions.Pow.Real) have exactly the same statement (Lean-checked), so `Real.pow_le_of_le_log` does not state what its name promises and the intended lemma is missing. Reviewer: This is a copy-paste mis-statement. rpow_le_of_le_log, pow_le_of_le_log and zpow_le_of_le_log (lines 833–842, next to rpow_le_iff_le_log and le_log_of_rpow_le) repeat le_rpow_of_log_le's `log x ≤ n * log y → x ≤ y ^ n` and its proof. By their names they should state `x ^ n ≤ y` from `n * log x ≤ log y`. Keep le_pow_of_log_le and fix or deprecate the `*_of_le_log` family; it is unused outside the file. Astra rates it CRITICAL (a lemma weaker than or unrelated to its name).","fix":"Restate `Real.pow_le_of_le_log` as its name says (keep `Real.le_pow_of_log_le`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@Real.pow_le_of_le_log : type_of% @Real.le_pow_of_log_le)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 16, rating CRITICAL): `pow_le_of_le_log` has the comparison orientation of `le_pow_of_log_le`. Correct: for `n : ℕ`, `(hy : 0 < y) (h : (n : ℝ) * log x ≤ log y) : x ^ n ≤ y`. The adjacent `pow_le_iff_le_log` already provides the positive-base implication; the defective directional wrapper remains a genuine naming error. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean#L814-L842)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-29c860","file":"Mathlib/Analysis/SpecialFunctions/Pow/Real.lean","decl":"Real.zpow_le_of_le_log","line":841,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `Real.le_zpow_of_log_le` (Analysis.SpecialFunctions.Pow.Real), `Real.zpow_le_of_le_log` (Analysis.SpecialFunctions.Pow.Real) have exactly the same statement (Lean-checked), so `Real.zpow_le_of_le_log` does not state what its name promises and the intended lemma is missing. Reviewer: zpow_le_of_le_log is a mis-stated copy: its name promises `x ^ n ≤ y` from `n * log x ≤ log y`, but it states `log x ≤ n * log y → x ≤ y ^ n`, exactly le_zpow_of_log_le. The whole rpow/pow/zpow_le_of_le_log and _lt_of_lt_log block (l.831-871) copies the le_/lt_rpow_of_log_* block; Real versions unused. Restate (needs 0 < x and 0 < y) or deprecate. Astra rates it CRITICAL (a lemma weaker than or unrelated to its name).","fix":"Restate `Real.zpow_le_of_le_log` as its name says (keep `Real.le_zpow_of_log_le`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@Real.zpow_le_of_le_log : type_of% @Real.le_zpow_of_log_le)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 1, rating CRITICAL): The order of `zpow_le` versus `le_zpow`, reinforced by the adjacent iff lemma, rules out the proposed alternative reading. Correct: `{n : ℤ} (hy : 0 < y) (h : (n : ℝ) * log x ≤ log y) : x ^ n ≤ y`. The positive-base implication already exists in `zpow_le_iff_le_log`; the named wrapper is wrong. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean#L814-L842)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-d825e6","file":"Mathlib/Analysis/SpecialFunctions/Pow/Real.lean","decl":"Real.rpow_lt_of_lt_log","line":862,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `Real.lt_rpow_of_log_lt` (Analysis.SpecialFunctions.Pow.Real), `Real.rpow_lt_of_lt_log` (Analysis.SpecialFunctions.Pow.Real) have exactly the same statement (Lean-checked), so `Real.rpow_lt_of_lt_log` does not state what its name promises and the intended lemma is missing. Reviewer: This is a copy-paste mis-statement. rpow_lt_of_lt_log, with pow_ and zpow_ variants, repeats lt_rpow_of_log_lt's statement and proof verbatim. By name and position it should give `x ^ z < y` from `z * log x < log y`. Keep lt_rpow_of_log_lt and fix or deprecate rpow_lt_of_lt_log (unused outside the file). Astra rates it CRITICAL (a lemma weaker than or unrelated to its name).","fix":"Restate `Real.rpow_lt_of_lt_log` as its name says (keep `Real.lt_rpow_of_log_lt`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@Real.rpow_lt_of_lt_log : type_of% @Real.lt_rpow_of_log_lt)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 17, rating CRITICAL): Neither variable renaming nor a different reading of `of_lt_log` explains putting the power on the opposite side. Correct: `(hy : 0 < y) (h : z * log x < log y) : x ^ z < y`. `rpow_lt_iff_lt_log` already contains the positive-base version; the absolute-power bound gives the formulation without a positivity assumption on `x`. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean#L844-L871)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-f9ab5d","file":"Mathlib/Analysis/SpecialFunctions/Pow/Real.lean","decl":"Real.pow_lt_of_lt_log","line":867,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `Real.pow_lt_of_lt_log` (Analysis.SpecialFunctions.Pow.Real), `Real.lt_pow_of_log_lt` (Analysis.SpecialFunctions.Pow.Real) have exactly the same statement (Lean-checked), so `Real.pow_lt_of_lt_log` does not state what its name promises and the intended lemma is missing. Reviewer: pow_lt_of_lt_log is mis-stated: its name promises `x ^ n < y`, but it states `log x < n * log y → x < y ^ n`, identical to lt_pow_of_log_lt (copy-paste of the lt_*_of_log_lt block, see the le/zpow group). It is unused (Chebyshev.lean:272 resolves to Nat.pow_le_of_le_log). Restate or deprecate. Astra rates it CRITICAL (a lemma weaker than or unrelated to its name).","fix":"Restate `Real.pow_lt_of_lt_log` as its name says (keep `Real.lt_pow_of_log_lt`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@Real.lt_pow_of_log_lt : type_of% @Real.pow_lt_of_lt_log)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 3, rating CRITICAL): The name promises a power on the left of `<`; the declaration puts it on the right. Correct: for `n : ℕ`, `(hy : 0 < y) (h : (n : ℝ) * log x < log y) : x ^ n < y`. `pow_lt_iff_lt_log` already supplies the positive-base version. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean#L844-L871)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-22047c","file":"Mathlib/Analysis/SpecialFunctions/Pow/Real.lean","decl":"Real.zpow_lt_of_lt_log","line":870,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `Real.lt_zpow_of_log_lt` (Analysis.SpecialFunctions.Pow.Real), `Real.zpow_lt_of_lt_log` (Analysis.SpecialFunctions.Pow.Real) have exactly the same statement (Lean-checked), so `Real.zpow_lt_of_lt_log` does not state what its name promises and the intended lemma is missing. Reviewer: Misnamed lemma: `zpow_lt_of_lt_log` states `log x < n * log y → x < y ^ n`, exactly `lt_zpow_of_log_lt` (the whole `rpow/pow/zpow_lt_of_lt_log` block at 862-871 copies `lt_*_of_log_lt` at 804-813; the name suggests `x ^ n < y` from `n * log x < log y`). Keep `lt_zpow_of_log_lt`; deprecate `zpow_lt_of_lt_log`, or restate it to match its name. Astra rates it CRITICAL (a lemma weaker than or unrelated to its name).","fix":"Restate `Real.zpow_lt_of_lt_log` as its name says (keep `Real.lt_zpow_of_log_lt`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@Real.zpow_lt_of_lt_log : type_of% @Real.lt_zpow_of_log_lt)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 21, rating CRITICAL): The integer-power wrapper has the same reversed orientation as the other defective members. Correct: `{n : ℤ} (hy : 0 < y) (h : (n : ℝ) * log x < log y) : x ^ n < y`. `zpow_lt_iff_lt_log` already supplies its positive-base specialization. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean#L844-L871)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261006-9fdac3","file":"Mathlib/Analysis/SpecialFunctions/RegularizedHypergeometric.lean","decl":"(module docstring)","line":12,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-drops-hypothesis","claim":"The module docstring is stale: it describes the parameters as `a : Fin p → ℂ`, `b : Fin q → ℂ` and states the results as 'if p < q + 1' / 'if p = q + 1', but the code takes multisets `a b : Multiset ℂ` (conditions on `a.card`, `b.card`); and it lists `radius_regularizedHGFunSeries_eq_one` ('if p = q + 1, then the series has convergence radius 1') without that theorem's hypothesis that no `a`-parameter is a nonpositive integer, which is false without it: for a = {0, 0}, b = {1} the series is a polynomial with radius ⊤. Further false statements in the same docstring: 'To recover the usual hypergeometric function, simply multiply by ∏ Gamma (b i)' fails at lower-parameter poles (Gamma 0 * regularizedGaussHGFun a b 0 0 = 0 but ordinaryHypergeometric a b 0 0 = 1); 'the regularized hypergeometric function only appears in the literature only for the Gaussian case' is false (DLMF 16.2.5 defines the regularized pFq; Olver's 13.2.3); the Gaussian radius-1 bullet also omits its termination exception.","fix":"Describe the multiset parameters, state results with `a.card`/`b.card`, and add 'unless some a_j is a nonpositive integer' to the radius-1 bullet.","ev":"example : ¬ (regularizedHGFunSeries {0, 0} {1}).radius = 1 := by\n  rw [radius_regularizedHGFunSeries_eq_top_of_finite (j := 0) (n := 0) (by simp) (by simp)]\n  simp","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-fdb9e8","file":"Mathlib/Analysis/SpecialFunctions/RegularizedHypergeometric.lean","decl":"Nat.factorial_ne_zero","line":70,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"global-attribute-on-foreign-lemma","claim":"The special-functions file globally adds `attribute [grind .] Nat.factorial_ne_zero` to a core `Nat` lemma (exported to every importer, e.g. Bessel.lean); every other file that needs an attribute on this lemma uses `attribute [local simp] … in`.","fix":"Make it `local` (or tag `Nat.factorial_ne_zero` `@[grind]` in Data/Nat/Factorial/Basic.lean if that is wanted globally).","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-509780","file":"Mathlib/Analysis/SpecialFunctions/RegularizedHypergeometric.lean","decl":"Complex.regularizedHGFunSeries_eq_zero","line":166,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"name-describes-wrong-shape","claim":"`regularizedHGFunSeries_eq_zero` is an iff about the degree-n term (`regularizedHGFunSeries a b n = 0 ↔ …`), but its name reads as 'the series is zero'; also `Gamma_inv_mul_ordinaryHypergeometricSeries_eq` is about one coefficient, `coeff_regularizedGaussHGFunSeries` reverses `regularizedHGFunSeries_coeff`'s order, and `…_zero` means the empty multiset in `analyticAt_regularizedHGFun_zero` but the argument 0 in `regularizedHGFun_zero`.","fix":"`regularizedHGFunSeries_apply_eq_zero_iff`, `…Series_coeff_eq`, consistent coefficient naming, `…_zero_left` for the empty multiset.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-1b4e02","file":"Mathlib/Analysis/SpecialFunctions/RegularizedHypergeometric.lean","decl":"Complex.radius_regularizedHGFunSeries_ge_one","line":294,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-hypothesis","claim":"`radius_regularizedHGFunSeries_ge_one`, `analyticOnNhd_regularizedHGFun_of_card_eq_add_one` and `analyticAt_regularizedHGFun_of_card_eq_add_one` assume `a.card = b.card + 1`; their conclusions hold under `a.card ≤ b.card + 1` (the `<` case has radius ⊤), e.g. for a = b = 0 (the exponential), where the current hypothesis cannot hold.","fix":"Weaken to `a.card ≤ b.card + 1` (rename `_of_card_le_add_one`).","ev":"example {a b : Multiset ℂ} (h : a.card ≤ b.card + 1) : 1 ≤ (regularizedHGFunSeries a b).radius := by\n  rcases Nat.lt_or_eq_of_le h with h | h\n  · rw [radius_regularizedHGFunSeries_eq_top (by omega)]; exact le_top\n  · exact radius_regularizedHGFunSeries_ge_one h","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-c834ed","file":"Mathlib/Analysis/SpecialFunctions/RegularizedHypergeometric.lean","decl":"Complex.regularizedGaussHGFun","line":359,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"junk-value-presented-as-fact","claim":"`regularizedHGFun` and `regularizedGaussHGFun` are documented as 'the regularized (Gaussian) hypergeometric function', but they are unconditional `tsum`s of the series: they take the junk value 0 outside the disk of convergence (₂F̃₁(1,1;1;-2) = 0, standard value 1/3) and even at boundary points where the series converges only conditionally (₂F̃₁(1,1;2;-1) = 0, standard value log 2). Unlike `ordinaryHypergeometric`, no junk-value caveat is given.","fix":"Add to both docstrings: 'defined as the (unconditional) sum of the series; it takes the junk value 0 outside the disk of convergence and wherever the series does not converge absolutely'.","ev":"theorem regGauss_neg_one : regularizedGaussHGFun 1 1 2 (-1) = 0 := by\n  rw [regularizedGaussHGFun, FormalMultilinearSeries.sum]\n  apply tsum_eq_zero_of_not_summable\n  intro h\n  have hn : ¬ Summable (fun n : ℕ => 1 / ((n : ℝ) + 1)) := by\n    simpa using (summable_nat_add_iff 1 (f := fun n : ℕ => 1 / (n : ℝ))).not.mpr Real.not_summable_one_div_natCast\n  refine hn (h.norm.congr fun n ↦ ?_)\n  rw [FormalMultilinearSeries.apply_eq_pow_smul_coeff, coeff_eq, norm_smul, norm_pow, norm_neg,\n    norm_one, one_pow, one_mul, norm_div, norm_one]\n  norm_cast\n-- coeff_eq : (regularizedGaussHGFunSeries 1 1 2).coeff n = 1 / (n + 1)  (proved via ascPochhammer_eval_one, Gamma_nat_eq_factorial)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261007-c83a90","file":"Mathlib/Analysis/SpecialFunctions/Trigonometric/Sinc.lean","decl":"sinc","line":40,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"Missing characteristic API for `Real.sinc`: no differentiability/analyticity (`fun_prop` cannot prove `Differentiable ℝ sinc`, and nothing in Mathlib states it; `sinc` is entire), no strict bound `|sinc x| < 1` for `x ≠ 0` (a two-line consequence of `abs_sin_lt_abs`), and no link from `continuous_sinc` to the existing `Real.tendsto_sin_div_nhdsNE_zero` (Trigonometric/Deriv.lean:412), which the module docstring's 'squeeze behind the limit of `sin x / x` at `0`' alludes to.","fix":"Add `differentiable_sinc`/`analyticAt_sinc` (e.g. via `dslope`), `abs_sinc_lt_one`, and cross-reference the limit lemma.","ev":"hunts/sinc/probe1.lean: `|sinc x| < 1` for `x ≠ 0` compiles in two lines; `example : Differentiable ℝ sinc := by fun_prop` fails.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-8c4eb3","file":"Mathlib/Analysis/SpecialFunctions/Trigonometric/Sinc.lean","decl":"cos_le_sinc","line":100,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-false-at-junk-value","claim":"`cos_le_sinc`'s docstring says 'For `|x| < π / 2` … this gives the squeeze `cos x ≤ sin x / x ≤ 1`', which is false at `x = 0` (allowed by `|x| < π / 2`): Lean's `sin 0 / 0 = 0 < 1 = cos 0`. The squeeze holds for `sinc x`, or for `sin x / x` only with `x ≠ 0` (the limit is `Real.tendsto_sin_div_nhdsNE_zero` on `𝓝[≠] 0`). Also (Astra A1 items 2-3): `attribute [grind =] tan_mul_cos sinc_of_ne_zero` (L96) is global, so importing this file changes `grind` behaviour on `tan` downstream; and `cos_le_sinc` holds on `|x| ≤ π` (for `π/2 ≤ |x| ≤ π`, `cos x ≤ 0 ≤ sinc x`), e.g. `cos π ≤ sinc π` is outside the stated hypothesis.","fix":"State the squeeze for `sinc x` (or add `x ≠ 0`); make the `grind` attribute `local`; weaken the hypothesis to `|x| ≤ π`.","ev":"hunts/sinc/probe2.lean: `|(0:ℝ)| < π / 2` and `¬ (cos 0 ≤ sin 0 / 0)` both compile; `cos π ≤ sinc π` compiles (outside `cos_le_sinc`'s hypothesis).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-1eaae4","file":"Mathlib/Analysis/SpecificLimits/Basic.lean","decl":"uniformity_basis_dist_pow_of_lt_one","line":226,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Metric.uniformity_basis_dist_pow` (Topology.MetricSpace.Pseudo.Defs), `uniformity_basis_dist_pow_of_lt_one` (Analysis.SpecificLimits.Basic) state exactly the same thing (Lean-checked). Reviewer: Same statement and essentially the same proof (`Metric.mk_uniformity_basis` + `exists_pow_lt_of_lt_one`) in two files, no cross-reference. Keep `Metric.uniformity_basis_dist_pow` (much lower in the import graph, used), deprecate root `uniformity_basis_dist_pow_of_lt_one` (no uses).","fix":"Deprecate `uniformity_basis_dist_pow_of_lt_one` in favour of `Metric.uniformity_basis_dist_pow`.","ev":"dupscan/Check.lean: `example := (@uniformity_basis_dist_pow_of_lt_one : type_of% @Metric.uniformity_basis_dist_pow)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 48, rating MAJOR): The lower Metric theorem supplies exactly the required basis without the later analysis imports; the root copy adds no distinct interface or attribute.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-3f952e","file":"Mathlib/Analysis/SpecificLimits/Normed.lean","decl":"IsUnit.one_sub_of_norm_lt_one","line":420,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `isUnit_one_sub_of_norm_lt_one` (Analysis.SpecificLimits.Normed), `IsUnit.one_sub_of_norm_lt_one` (Analysis.SpecificLimits.Normed) state exactly the same thing (Lean-checked). Reviewer: Same file and the same section (`[NormedRing R] [HasSummableGeomSeries R]`): `‖x‖ < 1 → IsUnit (1 - x)` is proved twice under synonym names. Keep isUnit_one_sub_of_norm_lt_one (standard name, used at line 712) and deprecate IsUnit.one_sub_of_norm_lt_one (unused; move its docstring).","fix":"Deprecate `IsUnit.one_sub_of_norm_lt_one` in favour of `isUnit_one_sub_of_norm_lt_one`.","ev":"dupscan/Check.lean: `example := (@IsUnit.one_sub_of_norm_lt_one : type_of% @isUnit_one_sub_of_norm_lt_one)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup1 item 7, rating MINOR): The namespaced version supports expected-type notation such as `.one_sub_of_norm_lt_one hx` for an `IsUnit` goal. That is a useful constructor-style alias, even though it is not a method on the norm-bound hypothesis. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Analysis/SpecificLimits/Normed.lean#L420).","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-da85c5","file":"Mathlib/Basic/NNReal/Defs.lean","decl":"NNReal.zero_le_coe","line":525,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `NNReal.zero_le_coe` (Basic.NNReal.Defs), `NNReal.coe_nonneg` (Basic.NNReal.Defs) state exactly the same thing (Lean-checked). Reviewer: Same file, both proved by `.2`: `0 ≤ (q : ℝ)` appears as @[bound] coe_nonneg (explicit r, used with dot notation) and as @[simp] zero_le_coe (implicit q), with no comment. Keep coe_nonneg, add @[simp], and deprecate zero_le_coe. Both are well used, so this is high-churn.","fix":"Deprecate `NNReal.zero_le_coe` in favour of `NNReal.coe_nonneg`.","ev":"dupscan/Check.lean: `example := (@NNReal.coe_nonneg : type_of% @NNReal.zero_le_coe)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup1 item 8, rating MINOR): Merging attributes preserves automation but loses the distinction between implicit `zero_le_coe` and explicit, receiver-friendly `coe_nonneg`. Given both names’ established use, retaining convenience aliases is preferable to this churn. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Basic/NNReal/Defs.lean#L170).","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-a44d21","file":"Mathlib/CategoryTheory/Bicategory/Opposites.lean","decl":"Bicategory.Opposite.homCategory_id_unop2","line":154,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Bicategory.Opposite.homCategory_id_unop2` (CategoryTheory.Bicategory.Opposites), `Bicategory.Opposite.unop2_id` (CategoryTheory.Bicategory.Opposites) state exactly the same thing (Lean-checked). Reviewer: `@[simps! homCategory_id_unop2 …]` on the bicategory instance regenerates `unop2 (𝟙 f) = 𝟙 f.unop`, already the manual @[simp] `unop2_id` in the op2/unop2 API. Both are simp. Drop homCategory_id_unop2, and likely homCategory_comp_unop2 versus unop2_comp, from the simps! list.","fix":"Deprecate `Bicategory.Opposite.homCategory_id_unop2` in favour of `Bicategory.Opposite.unop2_id`.","ev":"dupscan/Check.lean: `example := (@Bicategory.Opposite.unop2_id : type_of% @Bicategory.Opposite.homCategory_id_unop2)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup1 item 9, rating MINOR): The proposed edit targets the wrong generator: `homCategory_id_unop2` comes from `@[simps!]` on `homCategory` at line 54; the line-154 list generates `bicategory_homCategory_id_unop2`. Removing entries from the latter leaves the reported duplicate intact. [Declarations](https://leanprover-community.github.io/mathlib4_docs/Mathlib/CategoryTheory/Bicategory/Opposites.html#Bicategory.Opposite.homCategory_id_unop2).","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-84aad4","file":"Mathlib/CategoryTheory/Category/Cat.lean","decl":"CategoryTheory.Cat.comp_eq_comp","line":356,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CategoryTheory.Cat.Hom.comp_toFunctor` (CategoryTheory.Category.Cat), `CategoryTheory.Cat.comp_eq_comp` (CategoryTheory.Category.Cat) state exactly the same thing (Lean-checked). Reviewer: Same file, both `rfl`: `(F ≫ G).toFunctor = F.toFunctor ⋙ G.toFunctor`. Keep `Hom.comp_toFunctor`, which is @[simp, push_cast], has 14 uses, and belongs to the Hom.* family. Deprecate `Cat.comp_eq_comp`, which is unused by full name. The same applies to `Cat.id_eq_id` versus `Hom.id_toFunctor`.","fix":"Deprecate `CategoryTheory.Cat.comp_eq_comp` in favour of `CategoryTheory.Cat.Hom.comp_toFunctor`.","ev":"dupscan/Check.lean: `example := (@CategoryTheory.Cat.comp_eq_comp : type_of% @CategoryTheory.Cat.Hom.comp_toFunctor)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 10, rating MAJOR): `Hom.comp_toFunctor` preserves the explicit arguments and carries the useful `simp`/`push_cast` registrations. The older name contributes no separate interface here. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/Category/Cat.lean#L255).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the names live in different namespaces, plausibly deliberate for discoverability/dot notation.","at":"2026-10-07","commit":""},{"id":"RT-20261007-d5f763","file":"Mathlib/CategoryTheory/Comma/Arrow.lean","decl":"CategoryTheory.Arrow.Hom.w_assoc","line":1,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `CategoryTheory.Arrow.Hom.w_assoc` (CategoryTheory.Comma.Arrow), `CategoryTheory.Arrow.w_assoc` (CategoryTheory.Comma.Arrow) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: Both are generated by `@[reassoc]`: on `theorem w` and on the intended dot-notation `@[to_dual none, reassoc] alias Hom.w := w`. Reassoc on the alias produces a separately proved Hom.w_assoc; the fix is `alias Hom.w_assoc := w_assoc`.","fix":"Declare `CategoryTheory.Arrow.Hom.w_assoc` as an `alias` of `CategoryTheory.Arrow.w_assoc`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-9ab4a9","file":"Mathlib/CategoryTheory/Comma/Over/Basic.lean","decl":"CategoryTheory.Under.Hom.w_assoc","line":1,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `CategoryTheory.Under.w_assoc` (CategoryTheory.Comma.Over.Basic), `CategoryTheory.Under.Hom.w_assoc` (CategoryTheory.Comma.Over.Basic) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: Both are generated by `@[reassoc]`: on `Under.w` and on the intended dot-notation twin `lemma Hom.w … := Under.w φ`. The reassoc on Hom.w builds a fresh proof. The fix is `alias Hom.w_assoc := w_assoc` instead of `@[reassoc]` on Hom.w.","fix":"Declare `CategoryTheory.Under.Hom.w_assoc` as an `alias` of `CategoryTheory.Under.w_assoc`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-77e7e5","file":"Mathlib/CategoryTheory/Comma/StructuredArrow/Basic.lean","decl":"CategoryTheory.CostructuredArrow.Hom.w_assoc","line":1,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `CategoryTheory.CostructuredArrow.w_assoc` (CategoryTheory.Comma.StructuredArrow.Basic), `CategoryTheory.CostructuredArrow.Hom.w_assoc` (CategoryTheory.Comma.StructuredArrow.Basic) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: Both are generated by `@[reassoc]`: on CostructuredArrow.w and on the intended dot-notation twin `theorem Hom.w … := CostructuredArrow.w f`. Hom.w_assoc should be `alias Hom.w_assoc := w_assoc`.","fix":"Declare `CategoryTheory.CostructuredArrow.Hom.w_assoc` as an `alias` of `CategoryTheory.CostructuredArrow.w_assoc`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-0662ef","file":"Mathlib/CategoryTheory/Comma/StructuredArrow/Basic.lean","decl":"CategoryTheory.StructuredArrow.Hom.w_assoc","line":1,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `CategoryTheory.StructuredArrow.w_assoc` (CategoryTheory.Comma.StructuredArrow.Basic), `CategoryTheory.StructuredArrow.Hom.w_assoc` (CategoryTheory.Comma.StructuredArrow.Basic) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: Both are generated by `@[reassoc]`: on StructuredArrow.w and on the intended dot-notation twin `lemma Hom.w … := StructuredArrow.w f`. Hom.w_assoc should be `alias Hom.w_assoc := w_assoc`.","fix":"Declare `CategoryTheory.StructuredArrow.Hom.w_assoc` as an `alias` of `CategoryTheory.StructuredArrow.w_assoc`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-e4632d","file":"Mathlib/CategoryTheory/Comma/StructuredArrow/Basic.lean","decl":"CategoryTheory.CostructuredArrow.hom_eq_iff","line":92,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CategoryTheory.CostructuredArrow.hom_ext_iff` (CategoryTheory.Comma.StructuredArrow.Basic), `CategoryTheory.CostructuredArrow.hom_eq_iff` (CategoryTheory.Comma.StructuredArrow.Basic), `CategoryTheory.CostructuredArrow.ext_iff` (CategoryTheory.Comma.StructuredArrow.Basic) state exactly the same thing (Lean-checked). Reviewer: Same pattern as StructuredArrow: hom_ext_iff is generated by @[ext] hom_ext, and @[simp] hom_eq_iff (l.556, used in Indization/ParallelPair.lean) plus manual ext_iff (l.660, unused) restate it. Deprecate ext_iff and hom_eq_iff, with `attribute [simp] hom_ext_iff`.","fix":"Deprecate `CategoryTheory.CostructuredArrow.hom_eq_iff` in favour of `CategoryTheory.CostructuredArrow.hom_ext_iff`.","ev":"dupscan/Check.lean: `example := (@CategoryTheory.CostructuredArrow.hom_eq_iff : type_of% @CategoryTheory.CostructuredArrow.hom_ext_iff)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 13, rating MAJOR): Transferring `simp` to `hom_ext_iff` preserves the only distinguishing attribute. The two manual iff declarations serve the same rewriting interface. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/Comma/StructuredArrow/Basic.lean#L551).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the two declarations differ in which arguments are explicit, which Mathlib sometimes keeps deliberately for rewriting.","at":"2026-10-07","commit":""},{"id":"RT-20261007-ebafcd","file":"Mathlib/CategoryTheory/Comma/StructuredArrow/Basic.lean","decl":"CategoryTheory.CostructuredArrow.ext","line":194,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CategoryTheory.CostructuredArrow.hom_ext` (CategoryTheory.Comma.StructuredArrow.Basic), `CategoryTheory.CostructuredArrow.ext` (CategoryTheory.Comma.StructuredArrow.Basic) state exactly the same thing (Lean-checked). Reviewer: @[ext] hom_ext (l.552) and plain ext (l.657) have the same statement and proof. hom_ext is the @[ext] lemma and is used about 4 times; ext only feeds proj_faithful. Deprecate ext.","fix":"Deprecate `CategoryTheory.CostructuredArrow.ext` in favour of `CategoryTheory.CostructuredArrow.hom_ext`.","ev":"dupscan/Check.lean: `example := (@CategoryTheory.CostructuredArrow.ext : type_of% @CategoryTheory.CostructuredArrow.hom_ext)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 12, rating MAJOR): Both expose the same explicit morphisms and equality hypothesis; only the keeper supplies the extensionality registration. There is no additional convenience lost by deprecating `ext`. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/Comma/StructuredArrow/Basic.lean#L552).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: both names are in active use (drop side 4 uses), so the pair looks like intended API.","at":"2026-10-07","commit":""},{"id":"RT-20261007-e3882f","file":"Mathlib/CategoryTheory/Comma/StructuredArrow/Basic.lean","decl":"CategoryTheory.StructuredArrow.ext","line":194,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CategoryTheory.StructuredArrow.ext` (CategoryTheory.Comma.StructuredArrow.Basic), `CategoryTheory.StructuredArrow.hom_ext` (CategoryTheory.Comma.StructuredArrow.Basic) state exactly the same thing (Lean-checked). Reviewer: `StructuredArrow.ext (f g) : f.right = g.right → f = g` re-proves the @[ext] `hom_ext` 100 lines earlier, and `ext_iff` similarly duplicates `hom_eq_iff`. The CostructuredArrow versions (l.657/660 versus l.552/556) repeat the pattern. Deprecate `ext`, which has 1 use in Adjunction/Comma.","fix":"Deprecate `CategoryTheory.StructuredArrow.ext` in favour of `CategoryTheory.StructuredArrow.hom_ext`.","ev":"dupscan/Check.lean: `example := (@CategoryTheory.StructuredArrow.hom_ext : type_of% @CategoryTheory.StructuredArrow.ext)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 14, rating MAJOR): `ext` supplies neither a different receiver nor an implicit-argument convenience; `hom_ext` also describes morphism extensionality more precisely. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/Comma/StructuredArrow/Basic.lean#L194).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: both names are in active use (drop side 5 uses), so the pair looks like intended API.","at":"2026-10-07","commit":""},{"id":"RT-20261007-31303a","file":"Mathlib/CategoryTheory/Comma/StructuredArrow/Basic.lean","decl":"CategoryTheory.StructuredArrow.ext_iff","line":197,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CategoryTheory.StructuredArrow.ext_iff` (CategoryTheory.Comma.StructuredArrow.Basic), `CategoryTheory.StructuredArrow.hom_eq_iff` (CategoryTheory.Comma.StructuredArrow.Basic), `CategoryTheory.StructuredArrow.hom_ext_iff` (CategoryTheory.Comma.StructuredArrow.Basic) state exactly the same thing (Lean-checked). Reviewer: hom_ext_iff is generated by @[ext] on hom_ext (l.87-88). hom_eq_iff (@[simp], l.92) and the later manual ext_iff (l.197, unused) restate it, and `ext` (l.194) likewise duplicates hom_ext. Deprecate ext/ext_iff and replace hom_eq_iff by `attribute [simp] hom_ext_iff` (hom_eq_iff has 1 use).","fix":"Deprecate `CategoryTheory.StructuredArrow.ext_iff` in favour of `CategoryTheory.StructuredArrow.hom_ext_iff`.","ev":"dupscan/Check.lean: `example := (@CategoryTheory.StructuredArrow.hom_eq_iff : type_of% @CategoryTheory.StructuredArrow.ext_iff)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 11, rating MAJOR): Keeping `hom_ext` and its generated iff, with the proposed `simp` registration, preserves both extensionality automation and simplification. The additional names have no distinct binder interface. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/Comma/StructuredArrow/Basic.lean#L87).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the two declarations differ in which arguments are explicit, which Mathlib sometimes keeps deliberately for rewriting.","at":"2026-10-07","commit":""},{"id":"RT-20261007-389509","file":"Mathlib/CategoryTheory/ConcreteCategory/Basic.lean","decl":"CategoryTheory.ConcreteCategory.ext_apply","line":141,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CategoryTheory.ConcreteCategory.hom_ext` (CategoryTheory.ConcreteCategory.Basic), `CategoryTheory.ConcreteCategory.ext_apply` (CategoryTheory.ConcreteCategory.Basic) state exactly the same thing (Lean-checked). Reviewer: Adjacent, both `(∀ x, f x = g x) → f = g` with the same proof `ext (DFunLike.ext _ _ _)`, differing only in explicit vs implicit `f g`. Keep `hom_ext` (has `@[ext low]`, ~50 uses), deprecate `ext_apply` (2 uses in SemiNormedGrp).","fix":"Deprecate `CategoryTheory.ConcreteCategory.ext_apply` in favour of `CategoryTheory.ConcreteCategory.hom_ext`.","ev":"dupscan/Check.lean: `example := (@CategoryTheory.ConcreteCategory.ext_apply : type_of% @CategoryTheory.ConcreteCategory.hom_ext)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup1 item 18, rating MINOR): `ext_apply h` infers both morphisms and belongs naturally beside `ext` and `coe_ext`; `hom_ext f g h` has a different convenient application shape. Preserve the implicit helper as an alias. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/ConcreteCategory/Basic.lean#L134).","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-40f61d","file":"Mathlib/CategoryTheory/ConcreteCategory/Basic.lean","decl":"CategoryTheory.hom_id","line":176,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CategoryTheory.hom_id` (CategoryTheory.ConcreteCategory.Basic), `CategoryTheory.ConcreteCategory.coe_id` (CategoryTheory.ConcreteCategory.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file: `(𝟙 X : ToType X → ToType X) = id` is proved `by ext; simp` at both lines, once inside `namespace ConcreteCategory` and once after `end ConcreteCategory` in the root namespace. Neither is used. Keep ConcreteCategory.coe_id and deprecate CategoryTheory.hom_id, whose name clashes with the `X.hom_id` `.hom` lemmas. The same applies to hom_comp/coe_comp.","fix":"Deprecate `CategoryTheory.hom_id` in favour of `CategoryTheory.ConcreteCategory.coe_id`.","ev":"dupscan/Check.lean: `example := (@CategoryTheory.ConcreteCategory.coe_id : type_of% @CategoryTheory.hom_id)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 16, rating MAJOR): Both concern coercion to functions, making `coe_id` the clearer name. The root theorem supplies no additional registration or argument convention. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/ConcreteCategory/Basic.lean#L155).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the names live in different namespaces, plausibly deliberate for discoverability/dot notation.","at":"2026-10-07","commit":""},{"id":"RT-20261007-8910a7","file":"Mathlib/CategoryTheory/ConcreteCategory/Basic.lean","decl":"CategoryTheory.hom_comp","line":180,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CategoryTheory.hom_comp` (CategoryTheory.ConcreteCategory.Basic), `CategoryTheory.ConcreteCategory.coe_comp` (CategoryTheory.ConcreteCategory.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file: `ConcreteCategory.coe_comp` (159) and, after `end ConcreteCategory`, `CategoryTheory.hom_comp` (180) both state `(f ≫ g : ToType X → ToType Z) = g ∘ f`, proved by `ext; simp` separately, no comment. The root name `CategoryTheory.hom_comp` also clashes with the per-category `XCat.hom_comp : (f ≫ g).hom = ...` convention. Keep `ConcreteCategory.coe_comp`, deprecate `CategoryTheory.hom_comp` (same for `hom_id`/`coe_id`).","fix":"Deprecate `CategoryTheory.hom_comp` in favour of `CategoryTheory.ConcreteCategory.coe_comp`.","ev":"dupscan/Check.lean: `example := (@CategoryTheory.ConcreteCategory.coe_comp : type_of% @CategoryTheory.hom_comp)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 17, rating MAJOR): `coe_comp` accurately identifies the function-coercion equation, while the root copy adds no distinct automation or application behavior. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/ConcreteCategory/Basic.lean#L159).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the names live in different namespaces, plausibly deliberate for discoverability/dot notation.","at":"2026-10-07","commit":""},{"id":"RT-20261007-86e3a8","file":"Mathlib/CategoryTheory/ConcreteCategory/Forget.lean","decl":"CategoryTheory.forget₂_comp_apply","line":101,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CategoryTheory.forget₂_comp_apply` (CategoryTheory.ConcreteCategory.Forget), `CategoryTheory.ConcreteCategory.forget₂_comp_apply` (CategoryTheory.ConcreteCategory.Forget) state exactly the same thing (Lean-checked). Reviewer: Same file, identical statement and proof (`rw [Functor.map_comp, CategoryTheory.comp_apply]`). The root CategoryTheory.forget₂_comp_apply is unused, while ConcreteCategory.forget₂_comp_apply has 7 uses (Homology/ConcreteCategory.lean).","fix":"Deprecate `CategoryTheory.forget₂_comp_apply` in favour of `CategoryTheory.ConcreteCategory.forget₂_comp_apply`.","ev":"dupscan/Check.lean: `example := (@CategoryTheory.ConcreteCategory.forget₂_comp_apply : type_of% @CategoryTheory.forget₂_comp_apply)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 15, rating MAJOR): The namespace difference creates no useful dot-notation distinction, and neither declaration carries a special attribute. Consolidating under `ConcreteCategory` is reasonable. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/ConcreteCategory/Forget.lean#L101).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the names live in different namespaces, plausibly deliberate for discoverability/dot notation.","at":"2026-10-07","commit":""},{"id":"RT-20261007-a626d3","file":"Mathlib/CategoryTheory/Functor/Category.lean","decl":"CategoryTheory.NatTrans.vcomp_app'","line":67,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CategoryTheory.NatTrans.vcomp_app'` (CategoryTheory.Functor.Category), `CategoryTheory.NatTrans.comp_app` (CategoryTheory.Functor.Category) state exactly the same thing (Lean-checked). Reviewer: `vcomp_app'` and `comp_app` (@[simp, grind, reassoc]) are both `(α ≫ β).app X = α.app X ≫ β.app X := rfl`. The NatTrans.lean:95 comment promising `vcomp_app'` predates comp_app taking that role. vcomp_app' has no uses, so deprecate it and update the comment.","fix":"Deprecate `CategoryTheory.NatTrans.vcomp_app'` in favour of `CategoryTheory.NatTrans.comp_app`.","ev":"dupscan/Check.lean: `example := (@CategoryTheory.NatTrans.comp_app : type_of% @CategoryTheory.NatTrans.vcomp_app')` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 20, rating MAJOR): Both also have `to_dual self`, so dualization does not distinguish them. Keep `comp_app` and update the comment concerning the genuinely different underlying `vcomp_app`. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/Functor/Category.lean#L66).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-88ef64","file":"Mathlib/CategoryTheory/Functor/KanExtension/Adjunction.lean","decl":"CategoryTheory.Functor.leftKanExtensionUnit_leftKanExtension_map_leftKanExtensionObjIsoColimit_hom","line":99,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CategoryTheory.Functor.ι_leftKanExtensionObjIsoColimit_hom` (CategoryTheory.Functor.KanExtension.Adjunction), `CategoryTheory.Functor.leftKanExtensionUnit_leftKanExtension_map_leftKanExtensionObjIsoColimit_hom` (CategoryTheory.Functor.KanExtension.Adjunction) state exactly the same thing (Lean-checked). Reviewer: Consecutive lemmas with identical statement and identical proof term; the first is @[reassoc (attr := simp)] and pairs with ι_..._inv, the long-named second has no attributes and one use (line 112).","fix":"Deprecate `CategoryTheory.Functor.leftKanExtensionUnit_leftKanExtension_map_leftKanExtensionObjIsoColimit_hom` in favour of `CategoryTheory.Functor.ι_leftKanExtensionObjIsoColimit_hom`.","ev":"dupscan/Check.lean: `example := (@CategoryTheory.Functor.leftKanExtensionUnit_leftKanExtension_map_leftKanExtensionObjIsoColimit_hom : type_of% @CategoryTheory.Functor.ι_leftKanExtensionObjIsoColimit_hom)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 19, rating MAJOR): The shorter theorem already provides the same arguments plus the useful reassociation and simplification infrastructure. The long name adds no independent role. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/Functor/KanExtension/Adjunction.lean#L91).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-2d8fcd","file":"Mathlib/CategoryTheory/Limits/Preorder.lean","decl":"Preorder.isTerminalTop","line":119,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"`Preorder.isTerminalTop`/`isInitialBot` (Limits/Preorder.lean:119, 136, explicit `C`) repeat `CategoryTheory.Limits.isTerminalTop`/`isInitialBot` (Shapes/IsTerminal.lean:90, `to_dual`, implicit `α`): the same `IsTerminal.ofUnique _` one-liners, which Preorder.lean already imports.","fix":"Make the Preorder versions aliases (or drop them).","ev":"Found by dupscan/DefScan.lean: identical type and body after normalisation.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-558d34","file":"Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean","decl":"CategoryTheory.Limits.Fork.IsLimit.mono","line":478,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `CategoryTheory.Limits.Fork.IsLimit.mono` (CategoryTheory.Limits.Shapes.Equalizers), `CategoryTheory.Limits.mono_of_isLimit_fork` (CategoryTheory.Limits.Shapes.Equalizers) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: `Fork.IsLimit.mono` is the intended dot-notation twin (`hs.mono`) of `mono_of_isLimit_fork`, but both are built separately from `hom_ext`. One should be an `alias` of the other; either can stay, since both are used (5 and 9 uses).","fix":"Declare `CategoryTheory.Limits.Fork.IsLimit.mono` as an `alias` of `CategoryTheory.Limits.mono_of_isLimit_fork`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-3b5be5","file":"Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean","decl":"CategoryTheory.Limits.Cofork.IsColimit.epi","line":498,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `CategoryTheory.Limits.epi_of_isColimit_cofork` (CategoryTheory.Limits.Shapes.Equalizers), `CategoryTheory.Limits.Cofork.IsColimit.epi` (CategoryTheory.Limits.Shapes.Equalizers) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: Cofork.IsColimit.epi (line 498) is the dot-notation twin (`hs.epi`) of epi_of_isColimit_cofork (line 1119). Both are proved by building `Epi` from Cofork.IsColimit.hom_ext. It should be an `alias`.","fix":"Declare `CategoryTheory.Limits.Cofork.IsColimit.epi` as an `alias` of `CategoryTheory.Limits.epi_of_isColimit_cofork`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-2674eb","file":"Mathlib/CategoryTheory/Limits/Shapes/Pullback/IsPullback/Basic.lean","decl":"CategoryTheory.IsPullback.id_vert","line":312,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CategoryTheory.IsPullback.of_id_snd` (CategoryTheory.Limits.Shapes.Pullback.IsPullback.Basic), `CategoryTheory.IsPullback.id_vert` (CategoryTheory.Limits.Shapes.Pullback.IsPullback.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file, 11 lines apart: `IsPullback f (𝟙 _) (𝟙 _) f` is proved by of_vert_isIso both times, with f implicit in of_id_snd and explicit in id_vert. The same of_id_fst/id_horiz pair, and the IsPushout copies at 677–691, follow the pattern. Keep of_id_snd (about 6 uses) and deprecate id_vert (unused; move its diagram docstring).","fix":"Deprecate `CategoryTheory.IsPullback.id_vert` in favour of `CategoryTheory.IsPullback.of_id_snd`.","ev":"dupscan/Check.lean: `example := (@CategoryTheory.IsPullback.id_vert : type_of% @CategoryTheory.IsPullback.of_id_snd)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup1 item 22, rating MINOR): `id_vert f` constructs a square with an explicit morphism, while `of_id_snd` conveniently infers it from the expected square. The documented constructor and implicit helper are defensible convenience twins. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/Limits/Shapes/Pullback/IsPullback/Basic.lean#L299).","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-79dc40","file":"Mathlib/CategoryTheory/Limits/Shapes/Pullback/IsPullback/Basic.lean","decl":"CategoryTheory.IsPullback.id_horiz","line":324,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CategoryTheory.IsPullback.id_horiz` (CategoryTheory.Limits.Shapes.Pullback.IsPullback.Basic), `CategoryTheory.IsPullback.of_id_fst` (CategoryTheory.Limits.Shapes.Pullback.IsPullback.Basic) state exactly the same thing (Lean-checked). Reviewer: `id_horiz (f)` and `of_id_fst` (f implicit) both state `IsPullback (𝟙 X) f f (𝟙 Z)` via of_horiz_isIso, 25 lines apart. id_vert/of_id_snd and the IsPushout copies (l.677-702) repeat the pattern. Keep `of_id_fst`/`of_id_snd`, which are used more and are the `.of_id_fst` dot form, and move the diagram docstrings to them. Deprecate id_horiz/id_vert.","fix":"Deprecate `CategoryTheory.IsPullback.id_horiz` in favour of `CategoryTheory.IsPullback.of_id_fst`.","ev":"dupscan/Check.lean: `example := (@CategoryTheory.IsPullback.of_id_fst : type_of% @CategoryTheory.IsPullback.id_horiz)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup1 item 23, rating MINOR): The explicit `id_horiz f` and expected-type-driven `of_id_fst` offer different construction interfaces, consistently with the vertical and pushout families. Retaining aliases is reasonable. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/Limits/Shapes/Pullback/IsPullback/Basic.lean#L324).","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-780ce6","file":"Mathlib/CategoryTheory/Limits/Types/Limits.lean","decl":"CategoryTheory.Limits.Types.limit_ext_iff'","line":240,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CategoryTheory.Limits.Types.limit_ext'_iff` (CategoryTheory.Limits.Types.Limits), `CategoryTheory.Limits.Types.limit_ext_iff'` (CategoryTheory.Limits.Types.Limits) state exactly the same thing (Lean-checked). Reviewer: `limit_ext'` carries `@[ext]`, which generates `limit_ext'_iff`. The manual `limit_ext_iff'` right below restates it, with no comment. Deprecate the manual one; its 2 uses are in Sites/EqualizerSheafCondition.","fix":"Deprecate `CategoryTheory.Limits.Types.limit_ext_iff'` in favour of `CategoryTheory.Limits.Types.limit_ext'_iff`.","ev":"dupscan/Check.lean: `example := (@CategoryTheory.Limits.Types.limit_ext_iff' : type_of% @CategoryTheory.Limits.Types.limit_ext'_iff)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup1 item 21, rating MINOR): Prefer preserving the established `limit_ext_iff'` spelling and suppressing automatic iff generation on `limit_ext'`. Moving the prime into the middle of the name offers little benefit. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/Limits/Types/Limits.lean#L235).","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-f97210","file":"Mathlib/CategoryTheory/Monoidal/Comon_.lean","decl":"CategoryTheory.Comon.tensorObj_X","line":347,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CategoryTheory.Comon.tensorObj_X` (CategoryTheory.Monoidal.Comon_), `CategoryTheory.Comon.monoidal_tensorObj_X` (CategoryTheory.Monoidal.Comon_) state exactly the same thing (Lean-checked). Reviewer: `@[simps! tensorObj_X …]` on `Comon.monoidal` generates the simp lemma `monoidal_tensorObj_X`. The manual non-simp `tensorObj_X` right after it restates the same rfl and is unused. Delete it, or drop tensorObj_X from the simps list and mark the manual lemma simp.","fix":"Deprecate `CategoryTheory.Comon.tensorObj_X` in favour of `CategoryTheory.Comon.monoidal_tensorObj_X`.","ev":"dupscan/Check.lean: `example := (@CategoryTheory.Comon.monoidal_tensorObj_X : type_of% @CategoryTheory.Comon.tensorObj_X)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 28, rating MINOR): One theorem suffices, but I prefer the reviewer’s alternative: retain the clean public name `tensorObj_X`, mark it `simp`, and suppress the generated copy. This is low-value generated/manual redundancy. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/Monoidal/Comon_.lean#L334).","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-dbc1cf","file":"Mathlib/CategoryTheory/Monoidal/Mon.lean","decl":"CategoryTheory.AddMon.tensor_zero","line":675,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CategoryTheory.AddMon.tensorObj_zero` (CategoryTheory.Monoidal.Mon), `CategoryTheory.AddMon.tensor_zero` (CategoryTheory.Monoidal.Mon) state exactly the same thing (Lean-checked). Reviewer: to_additive images of Mon.tensorObj_one (l.675) and Mon.tensor_one (l.706), both @[simp] rfl lemmas with the same statement 30 lines apart; fixed together with group Mon.tensorObj_one/tensor_one. Keep the tensorObj_* names (family tensorUnit_one/tensorObj_X).","fix":"Deprecate `CategoryTheory.AddMon.tensor_zero` in favour of `CategoryTheory.AddMon.tensorObj_zero`.","ev":"dupscan/Check.lean: `example := (@CategoryTheory.AddMon.tensor_zero : type_of% @CategoryTheory.AddMon.tensorObj_zero)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 24, rating MAJOR): This is duplication inherited from the multiplicative source, rather than a separately needed additive interface. Consolidate the source declarations and preserve the surviving `to_additive` mapping. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/Monoidal/Mon.lean#L674).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-452f0d","file":"Mathlib/CategoryTheory/Monoidal/Mon.lean","decl":"CategoryTheory.Mon.tensor_mul","line":709,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CategoryTheory.Mon.tensorObj_mul` (CategoryTheory.Monoidal.Mon), `CategoryTheory.Mon.tensor_mul` (CategoryTheory.Monoidal.Mon) state exactly the same thing (Lean-checked). Reviewer: Both @[to_additive (attr := simp)] rfl lemmas with the same statement 30 lines apart in the same section, no comment. tensorObj_mul fits tensorUnit_mul/tensorObj_X; deprecate tensor_mul (and AddMon.tensor_add).","fix":"Deprecate `CategoryTheory.Mon.tensor_mul` in favour of `CategoryTheory.Mon.tensorObj_mul`.","ev":"dupscan/Check.lean: `example := (@CategoryTheory.Mon.tensor_mul : type_of% @CategoryTheory.Mon.tensorObj_mul)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 25, rating MAJOR): Both declarations have the same arguments and attribute setup; `to_additive` does not require both source names. The `tensorObj_*` family supplies a coherent survivor. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/Monoidal/Mon.lean#L677).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-7f1ef2","file":"Mathlib/CategoryTheory/Monoidal/Subcategory.lean","decl":"CategoryTheory.ObjectProperty.ι_η","line":107,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `CategoryTheory.ObjectProperty.ι_ε` (CategoryTheory.Monoidal.Subcategory), `CategoryTheory.ObjectProperty.ι_η` (CategoryTheory.Monoidal.Subcategory) have exactly the same statement (Lean-checked), so `CategoryTheory.ObjectProperty.ι_η` does not state what its name promises and the intended lemma is missing. Reviewer: This is a typo bug. `@[simp] lemma ι_η : ε P.ι = 𝟙 _ := rfl` restates ι_ε on the line above; by its name and its sibling ι_δ it should state `η P.ι = 𝟙 _` (Functor.OplaxMonoidal is opened at line 104). Fix ι_η's statement. Astra rates it CRITICAL (a lemma weaker than or unrelated to its name).","fix":"Restate `CategoryTheory.ObjectProperty.ι_η` as its name says (keep `CategoryTheory.ObjectProperty.ι_ε`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@CategoryTheory.ObjectProperty.ι_η : type_of% @CategoryTheory.ObjectProperty.ι_ε)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 15, rating CRITICAL): Both structure maps happen to be identities here, but `ε` and `η` name distinct components. The nearby `ιOfLE_η` further confirms the convention. Correct: `ι_η : η P.ι = 𝟙 _ := rfl`. The existing `ι_ε` does not provide the intended rewrite rule headed by `η`. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/Monoidal/Subcategory.lean#L94-L139)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261006-dabd86","file":"Mathlib/CategoryTheory/Monoidal/Widesubcategory.lean","decl":"CategoryTheory.MorphismProperty.IsMonoidalStable","line":55,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-instance","claim":"No bridge from existing isomorphism API: for `[P.IsMonoidal] [P.RespectsIso]` the six coherence fields of `IsMonoidalStable` are each `P.of_isIso _`, yet `infer_instance` fails, so every user re-proves them (and two more for braiding).","fix":"Add instances (or constructors) `IsStableUnderAssociator`/`IsStableUnderUnitor`/`IsStableUnderBraiding` from `RespectsIso` + `ContainsIdentities`.","ev":"-- hunts/monoidal-widesub/P2.lean: `example [P.IsMonoidal] [P.RespectsIso] : P.IsMonoidalStable := by infer_instance` fails (synthInstanceFailed); the `where associator_hom_mem _ _ _ := P.of_isIso _ ...` version compiles.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-fe7f2f","file":"Mathlib/CategoryTheory/Monoidal/Widesubcategory.lean","decl":"CategoryTheory.WideSubcategory.instBraidedCategory","line":89,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-instance","claim":"The file makes `WideSubcategory P` braided (and symmetric) when `P.IsStableUnderBraiding`, but the inclusion `wideSubcategoryInclusion P` gets no `Functor.Braided` instance, although it is `Monoidal` (via `Monoidal.induced`) and preserves the braiding on the nose.","fix":"Add `instance : (wideSubcategoryInclusion P).Braided` (braiding compatibility by `rfl`/`simp`).","ev":"-- hunts/monoidal-widesub/P.lean: `example [P.IsMonoidalStable] : (wideSubcategoryInclusion P).Monoidal := inferInstance` compiles; `example [BraidedCategory C] [P.IsStableUnderBraiding] : (wideSubcategoryInclusion P).Braided := inferInstance` fails (synthInstanceFailed).","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-60e17b","file":"Mathlib/CategoryTheory/ObjectProperty/Comma.lean","decl":"CategoryTheory.ObjectProperty.instIsStableUnderRetractsCommaComma","line":38,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-instance","claim":"The retract instance hand-combines two general facts that `ObjectProperty/Retract.lean` does not provide as instances: `(P ⊓ Q).IsStableUnderRetracts` and `(P.inverseImage G).IsStableUnderRetracts` (`infer_instance` fails on the first). Also missing: `(comma F₁ F₂ P₁ P₂).isoClosure = comma F₁ F₂ P₁.isoClosure P₂.isoClosure` (the key step of the `EssentiallySmall` proof) and ⊥/⊤ simp lemmas for `comma`.","fix":"Add the ⊓/inverseImage retract instances in Retract.lean (then `unfold comma; infer_instance` here) and the isoClosure lemma.","ev":"example (P Q : ObjectProperty C₁) [P.IsStableUnderRetracts] [Q.IsStableUnderRetracts] :\n    (P ⊓ Q).IsStableUnderRetracts := by infer_instance\n-- error: failed to synthesize","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-0b09a4","file":"Mathlib/CategoryTheory/ObjectProperty/Comma.lean","decl":"CategoryTheory.ObjectProperty.instIsClosedUnderIsomorphismsCommaComma","line":44,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reprovable-from-existing-api","claim":"The `IsClosedUnderIsomorphisms` instance re-proves what the existing instances for `inverseImage` and `⊓` give: `unfold comma; infer_instance` proves it. The `EssentiallySmall` proof also obtains `h₁ h₂ : Q ≤ P` it never uses (`exists_small_le'` suffices) and closes a conjunction with `tauto`.","fix":"`:= by unfold comma; infer_instance`; use `exists_small_le'` and `⟨hX₁, hX₂⟩`.","ev":"instance [P₁.IsClosedUnderIsomorphisms] [P₂.IsClosedUnderIsomorphisms] :\n    (comma F₁ F₂ P₁ P₂).IsClosedUnderIsomorphisms := by\n  unfold comma; infer_instance   -- compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-500142","file":"Mathlib/CategoryTheory/ObjectProperty/Comma.lean","decl":"CategoryTheory.ObjectProperty.instSmallCommaComma","line":50,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"The `Small`/`EssentiallySmall` instances for `comma F₁ F₂ P₁ P₂` assume `[LocallySmall.{w} D]` (all hom-types of D small) but only use smallness of `F₁.obj X₁ ⟶ F₂.obj X₂` for `P₁ X₁`, `P₂ X₂`; the `Small` instance compiles unchanged with `[∀ X₁ X₂, Small.{w} (F₁.obj X₁.val ⟶ F₂.obj X₂.val)]`. This admits e.g. D = Type 1 with both functors picking `PUnit`.","fix":"State a lemma with the endpoint hom-smallness hypothesis and derive the LocallySmall instances from it.","ev":"instance [ObjectProperty.Small.{w} P₁] [ObjectProperty.Small.{w} P₂]\n    [∀ (X₁ : Subtype P₁) (X₂ : Subtype P₂), _root_.Small.{w} (F₁.obj X₁.val ⟶ F₂.obj X₂.val)] :\n    ObjectProperty.Small.{w} (comma F₁ F₂ P₁ P₂) := <original proof>\n-- hunts/objprop-comma/ProbeCopy.lean compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-e8642f","file":"Mathlib/CategoryTheory/Retract.lean","decl":"CategoryTheory.Iso.retract","line":179,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"`Iso.retract` (Retract.lean:179, `@[simps]`) and `Retract.ofIso` (L91) are the same definition (`i := e.hom, r := e.inv`); a dot-notation twin defined twice instead of one being an alias.","fix":"Make `Retract.ofIso` an alias of `Iso.retract` (or vice versa).","ev":"Found by dupscan/DefScan.lean: identical type and body after normalisation.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-3cfc04","file":"Mathlib/CategoryTheory/Shift/Pullback.lean","decl":"CategoryTheory.PullbackShift.functor","line":152,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"synonym-missing-forwarded-instances","claim":"The synonyms forward only the shift structure: `PullbackShift C φ` gets `Preadditive` and `HasZeroObject` but not `HasZeroMorphisms` (needed without preadditivity), and `PullbackShift.functor φ F` gets `CommShift` but none of `F`'s ordinary properties. `infer_instance` fails for `(PullbackShift.functor φ F).Additive` (with `[F.Additive]`), for `.Faithful` (with `[F.Faithful]`), and for `HasZeroMorphisms (PullbackShift C φ)` (with `[HasZeroMorphisms C]`). Since `PullbackShift` is a `def`, instance search does not unfold it.","fix":"Add `inferInstanceAs` forwarding instances (`HasZeroMorphisms`, `Functor.Additive`, `Faithful`, `Full`, …) for the synonyms.","ev":"probe2.lean L12, L13, L15: failed to synthesize `(PullbackShift.functor φ F).Additive`, `.Faithful`, `HasZeroMorphisms (PullbackShift C φ)`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-0e443c","file":"Mathlib/CategoryTheory/Shift/Pullback.lean","decl":"CategoryTheory.Adjunction.commShiftPullback","line":302,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-wrong-direction","claim":"Docstrings disagree with the code: the instance `Adjunction.commShiftPullback` speaks of \"an additive map `φ : B →+ A`\", but `φ : A →+ B` throughout the file (the pullback goes from a `B`-shift to an `A`-shift); the module docstring writes `PullbackShift.functor F φ`, `PullbackShift.natTrans τ φ` and `PullbackShift.adjunction adj φ`, but all three take `φ` first (`PullbackShift.functor φ F`, `natTrans φ τ`, `adjunction φ adj`), as do the docstrings of `natTrans` and `natIsoId` (\"`PullbackShift.functor (𝟭 C) φ`\").","fix":"Write `φ : A →+ B` and put `φ` first in every displayed application.","ev":"Source L41/L51 `(φ : A →+ B)`, L305 `φ : B →+ A`; L18/L23/L29 vs. L152/L161/L285 and uses at L162, L286.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-e011ba","file":"Mathlib/CategoryTheory/Sites/Hypercover/ZeroFamily.lean","decl":"CategoryTheory.PreZeroHypercover.presieve₀_mem_precoverage_iff","line":61,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"A family can only be evaluated on `PreZeroHypercover.{max u v}`, and `presieve₀_mem_precoverage_iff` only takes such hypercovers. There is no lemma for an arbitrary index universe (`E.presieve₀ ∈ P.precoverage X ↔ P E.shrink`), although it is a 3-line consequence. `AlgebraicGeometry.Scheme.presieve₀_mem_qcPrecoverage_iff` (Sites/QuasiCompact.lean:53) re-derives exactly this shrinking argument.","fix":"Add `presieve₀_mem_precoverage_iff_shrink` for `E : PreZeroHypercover.{w} X` and use it in QuasiCompact.lean.","ev":"-- hunts/hypercover-zerofam/P2.lean: `example (P) (E : PreZeroHypercover.{w} X) : Prop := P E` fails (application type mismatch); `example : E.presieve₀ ∈ P.precoverage X ↔ P E.shrink := by simpa only [presieve₀_shrink] using presieve₀_mem_precoverage_iff (E := E.shrink)` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-22d75b","file":"Mathlib/CategoryTheory/Sites/Hypercover/ZeroFamily.lean","decl":"CategoryTheory.Precoverage.preZeroHypercoverFamily","line":72,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-instance","claim":"The file does not connect the base-change constructor's isomorphism-closure hypothesis to the existing class `Precoverage.RespectsIso`: `[K.RespectsIso]` does not give `(K.preZeroHypercoverFamily (X := X)).IsClosedUnderIsomorphisms`, although it is one line (`presieve₀_mem_of_iso`).","fix":"Add that instance (and the converse lemma) so `IsStableUnderBaseChange.of_preZeroHypercoverFamily_of_isClosedUnderIsomorphisms` can be fed from `RespectsIso`.","ev":"-- hunts/hypercover-zerofam/P2.lean: `example [K.RespectsIso] (X : C) : (K.preZeroHypercoverFamily (X := X)).IsClosedUnderIsomorphisms := by infer_instance` fails (synthInstanceFailed); the `where of_iso e hE := PreZeroHypercover.presieve₀_mem_of_iso e hE` version compiles.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-39619a","file":"Mathlib/CategoryTheory/Sites/Sieves/Functoriality.lean","decl":"CategoryTheory.Sieve.functorPullback_arrows","line":209,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CategoryTheory.Sieve.functorPullback_apply` (CategoryTheory.Sites.Sieves.Functoriality), `CategoryTheory.Sieve.functorPullback_arrows` (CategoryTheory.Sites.Sieves.Functoriality) state exactly the same thing (Lean-checked). Reviewer: @[simps] on Sieve.functorPullback (l.199) generates `functorPullback_apply`, which is used in CoverLifting and PreservesLocallyBijective. The manual @[simp] `functorPullback_arrows` right below restates it with no comment. Delete or deprecate the manual one, which is unused.","fix":"Deprecate `CategoryTheory.Sieve.functorPullback_arrows` in favour of `CategoryTheory.Sieve.functorPullback_apply`.","ev":"dupscan/Check.lean: `example := (@CategoryTheory.Sieve.functorPullback_arrows : type_of% @CategoryTheory.Sieve.functorPullback_apply)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 29, rating MAJOR): Despite its `apply` suffix, the generated theorem is itself the equality of underlying presieves; there is no function-level versus pointwise distinction to preserve. Both carry `simp`. [Declarations](https://leanprover-community.github.io/mathlib4_docs/Mathlib/CategoryTheory/Sites/Sieves/Functoriality.html#CategoryTheory.Sieve.functorPullback_apply).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261006-74e137","file":"Mathlib/Combinatorics/Enumerative/Pentagonal/Basic.lean","decl":"pentagonal_neg","line":36,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"Only integer-arithmetic forms (`... .toNat`) are provided. The natural-number index formulas `pentagonal (k + 1) = (k + 1) * (3 * k + 2) / 2` and `pentagonal (-k) = k * (3 * k + 1) / 2` (for `k : ℕ`) are missing, and the one consumer, `Pentagonal.tprod_one_sub_pow` (Pentagonal/Ring.lean L162–163), proves both locally as `h1`/`h2`.","fix":"Add `pentagonal_natCast_add_one` and `pentagonal_neg_natCast` to Basic.lean and use them in Ring.lean.","ev":"origin/master Pentagonal/Ring.lean L162-163: `have h1 (k : ℕ) : pentagonal (k + 1) = ((k + 1) * (3 * k + 2) / 2) := by grind [pentagonal_def]`, `have h2 (k : ℕ) : pentagonal (-k) = (k * (3 * k + 1) / 2) := by grind [pentagonal_neg]`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-5af966","file":"Mathlib/Combinatorics/Enumerative/Pentagonal/EulerFunction.lean","decl":"Pentagonal.multipliable_one_sub_pow_add","line":79,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reprovable-from-existing-api","claim":"`multipliable_one_sub_pow_add` rebuilds the geometric-series bound by hand; `summable_norm_geometric_of_norm_lt_one` with `summable_nat_add_iff` gives it in one step. The ℂ, k = 0 case already exists as `ModularForm.multipliable_one_sub_pow` (DedekindEta.lean), so a public general lemma could serve both.","fix":"Prove it as below and make a public general version shared with DedekindEta.","ev":"  apply multipliable_one_sub_of_summable\n  simpa [Nat.add_assoc] using\n    (summable_nat_add_iff (k + 1)).2 (summable_norm_geometric_of_norm_lt_one hx)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-3e60c9","file":"Mathlib/Combinatorics/Enumerative/Pentagonal/EulerFunction.lean","decl":"eulerFunction","line":95,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"junk-value-presented-as-fact","claim":"`eulerFunction` is a `tsum` for every x, so it is 0 wherever the series diverges (e.g. x = (1, 0) in ℝ × ℝ gives (0, 0), while ∏'(1 - xⁿ⁺¹) = (0, 1)); the docstring states φ(x) = Σ (-1)^k x^{k(3k-1)/2} without that caveat or a pointer to `hasSum_eulerFunction_pentagonal`. The module docstring says 'complete normed ring' but the API needs a commutative ring with `‖1‖ = 1`. The exponents are generalized pentagonal numbers, and the `(-k, k+1)` pairing in the `_pair` lemmas is undocumented.","fix":"Document the domain/convention, the actual typeclasses, 'generalized pentagonal', and the pairing.","ev":"#check @eulerFunction_eq_tprod  -- [NormedCommRing R] [NormOneClass R] [CompleteSpace R] … (hx : ‖x‖ < 1)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-e9188e","file":"Mathlib/Combinatorics/Enumerative/Pentagonal/EulerFunction.lean","decl":"eulerFunction","line":95,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`eulerFunction`, `eulerFunction_def` and `eulerFunction_eq_tsum_pentagonal` use no norm: they hold verbatim over `[CommRing R] [TopologicalSpace R]`. Astra also notes `NormOneClass` is unnecessary for the summability theorems (rescaled norm on ℝ) — not tested.","fix":"Define `eulerFunction` over a topological commutative ring; keep the norm only for the convergence results.","ev":"noncomputable def eulerFunction' {R : Type*} [CommRing R] [TopologicalSpace R] (x : R) : R :=\n  ∑' n, (PowerSeries.pentagonalSeries R).coeff n * x ^ n\ntheorem eulerFunction'_eq_tsum_pentagonal {R : Type*} [CommRing R] [TopologicalSpace R] (x : R) :\n    eulerFunction' x = ∑' k, k.negOnePow * x ^ pentagonal k := by\n  simp [eulerFunction', PowerSeries.coeff_pentagonalSeries_mul_eq_extend, pentagonal_injective]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2ea14f","file":"Mathlib/Combinatorics/Enumerative/Pentagonal/EulerFunction.lean","decl":"eulerFunction","line":95,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"There is no `eulerFunction_zero` (`eulerFunction 0 = 1`): `simp` makes no progress on it. The absolute summability proved inside `hasSum_eulerFunction_pentagonalSeries` (valid without completeness) is not exported.","fix":"Add `@[simp] eulerFunction_zero` and `summable_norm_…` lemmas.","ev":"example {R : Type*} [NormedCommRing R] [NormOneClass R] : eulerFunction (0 : R) = 1 := by simp\n-- error: `simp` made no progress","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-2873d6","file":"Mathlib/Combinatorics/HalesJewett.lean","decl":"Combinatorics.Subspace.apply_def","line":134,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Combinatorics.Subspace.coe_apply` (Combinatorics.HalesJewett), `Combinatorics.Subspace.apply_def` (Combinatorics.HalesJewett) state exactly the same thing (Lean-checked). Reviewer: Same file, both `l x i = (l.idxFun i).elim id x` by rfl. Keep `Subspace.coe_apply` (6 uses, parallels `Line.coe_apply`), deprecate `Subspace.apply_def` (used only in `apply_inl`/`apply_inr`). `Line.apply_def` is a different, function-level statement.","fix":"Deprecate `Combinatorics.Subspace.apply_def` in favour of `Combinatorics.Subspace.coe_apply`.","ev":"dupscan/Check.lean: `example := (@Combinatorics.Subspace.apply_def : type_of% @Combinatorics.Subspace.coe_apply)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 30, rating MAJOR): These have identical explicit arguments and no differing attributes. The distinct function-level `Line.apply_def` does not justify this second pointwise `Subspace` theorem. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Combinatorics/HalesJewett.lean#L111).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261006-1f9cfa","file":"Mathlib/Combinatorics/Hypergraph/Basic.lean","decl":"Hypergraph.IsIsolated","line":174,"sev":"MINOR","status":"confirmed","cat":"correctness","pattern":"predicate-ignores-carrier","claim":"`IsIsolated` is documented as 'A vertex is isolated if it is not incident to any edges', but the predicate `∀ e ∈ E(H), x ∉ e` does not require `x ∈ V(H)`: every point outside the vertex set counts as isolated (e.g. every n : ℕ in `⊥`), so `{x | H.IsIsolated x}` is not a set of vertices. Unlike `SimpleGraph.IsIsolated` (whose vertex set is the whole type), this file has an explicit vertex set.","fix":"Define `IsIsolated H x := x ∈ V(H) ∧ ∀ e ∈ E(H), x ∉ e` (the one consumer already restricts to `x ∈ V(H)`), or document the ambient convention.","ev":"example : (⊥ : Hypergraph ℕ).IsIsolated 0 ∧ 0 ∉ V((⊥ : Hypergraph ℕ)) := by simp [Hypergraph.IsIsolated]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-73c633","file":"Mathlib/Combinatorics/Hypergraph/Basic.lean","decl":"Hypergraph.IsComplete.completeOn","line":273,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"wrong-namespace-for-dot-notation","claim":"`IsComplete.completeOn (f) : (completeOn f).IsComplete` and `IsTrivial.trivialOn (hf : f.Nonempty) : (trivialOn f).IsTrivial` sit in the predicates' namespaces but take no `IsComplete`/`IsTrivial` hypothesis, so dot notation on them is meaningless; the file's own `not_isTrivial_completeOn` uses the right shape.","fix":"Rename to `isComplete_completeOn` and `isTrivial_trivialOn`.","ev":"#check @Hypergraph.IsComplete.completeOn  -- ∀ {α} (f : Set α), (completeOn f).IsComplete\n#check @Hypergraph.IsTrivial.trivialOn   -- ∀ {α} {f : Set α}, f.Nonempty → (trivialOn f).IsTrivial","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-59d2c8","file":"Mathlib/Combinatorics/Hypergraph/Basic.lean","decl":"Hypergraph.IsTrivial.isLinear","line":297,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-hypothesis","claim":"`IsTrivial.isLinear` (docstring: 'A hypergraph with no edges is linear') assumes `IsTrivial`, which also demands a vertex, so it does not apply to `⊥` (not trivial); `E(H) = ∅` (or `E(H).Subsingleton`) suffices. Similarly `edgeSet.ext_iff` assumes `e, e' ∈ E(H)` where `e, e' ⊆ V(H)` suffices.","fix":"State `isLinear_of_edgeSet_subsingleton` and derive the trivial case; weaken `edgeSet.ext_iff` to subsets.","ev":"example {α : Type*} (H : Hypergraph α) (hE : E(H) = ∅) : H.IsLinear := by\n  rw [Hypergraph.isLinear_def, hE]; exact Set.pairwise_empty _\nexample : ¬ (⊥ : Hypergraph ℕ).IsTrivial := by simp [IsTrivial]\nexample {α : Type*} {V e f : Set α} (he : e ⊆ V) (hf : f ⊆ V) : e = f ↔ ∀ x ∈ V, x ∈ e ↔ x ∈ f := by\n  simpa only [Set.sep_eq_of_subset he, Set.sep_eq_of_subset hf] using (Set.sep_ext_iff (s := V) (p := fun x => x ∈ e) (q := fun x => x ∈ f))","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261007-517f40","file":"Mathlib/Combinatorics/Matroid/Basic.lean","decl":"Matroid.ext_iff_indep","line":741,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Matroid.ext_iff_indep` (Combinatorics.Matroid.Basic), `Matroid.ext_indep_iff` (Combinatorics.Matroid.Basic) state exactly the same thing (Lean-checked). Reviewer: `ext_indep` carries @[ext], which auto-generates `ext_indep_iff`. The manual `ext_iff_indep` proves exactly that iff again, with no comment, and probably predates ext_iff generation. Deprecate ext_iff_indep and migrate its 10 uses. Alternatively, keep it and use `@[ext (iff := false)]`.","fix":"Deprecate `Matroid.ext_iff_indep` in favour of `Matroid.ext_indep_iff`.","ev":"dupscan/Check.lean: `example := (@Matroid.ext_indep_iff : type_of% @Matroid.ext_iff_indep)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 32, rating MINOR): The redundancy is real, but prefer the offered `iff := false` alternative to preserve the established manual name and avoid migrating its users. This is generator overlap rather than a substantial API defect. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Combinatorics/Matroid/Basic.lean#L731).","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-4809b3","file":"Mathlib/Combinatorics/Matroid/Loop.lean","decl":"Matroid.eq_loopyOn_iff_loops_eq","line":265,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Matroid.eq_loopyOn_iff_loops_eq` (Combinatorics.Matroid.Loop), `Matroid.eq_loopyOn_iff_loops` (Combinatorics.Matroid.Loop) state exactly the same thing (Lean-checked). Reviewer: Same file, 16 lines apart: `M = loopyOn E ↔ M.loops = E ∧ M.E = E`, both proved by the same closure_empty_eq_ground_iff argument. Keep the earlier `eq_loopyOn_iff_loops`, used at l.254. Deprecate `_loops_eq`, which has 1 use in Minor/Contract.","fix":"Deprecate `Matroid.eq_loopyOn_iff_loops_eq` in favour of `Matroid.eq_loopyOn_iff_loops`.","ev":"dupscan/Check.lean: `example := (@Matroid.eq_loopyOn_iff_loops : type_of% @Matroid.eq_loopyOn_iff_loops_eq)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 33, rating MAJOR): Neither theorem has a distinct attribute, argument convention, or rewriting direction. The additional `_eq` suffix supplies no useful alternate interface. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Combinatorics/Matroid/Loop.lean#L249).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-a1a0fe","file":"Mathlib/Combinatorics/Matroid/Minor/Restrict.lean","decl":"Matroid.IsBasis.restrict_isBase","line":165,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Matroid.IsBasis.restrict_isBase` (Combinatorics.Matroid.Minor.Restrict), `Matroid.IsBasis.isBase_restrict` (Combinatorics.Matroid.Minor.Restrict) state exactly the same thing (Lean-checked). Reviewer: In the same file, `IsBasis.restrict_isBase` and `IsBasis.isBase_restrict` (@[simp]) are both `(isBase_restrict_iff h.subset_ground).2 h`. Keep isBase_restrict, which matches `IsBasis'.isBase_restrict` and is used more. Deprecate restrict_isBase.","fix":"Deprecate `Matroid.IsBasis.restrict_isBase` in favour of `Matroid.IsBasis.isBase_restrict`.","ev":"dupscan/Check.lean: `example := (@Matroid.IsBasis.isBase_restrict : type_of% @Matroid.IsBasis.restrict_isBase)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 31, rating MAJOR): Both already support the same `IsBasis` receiver, and the keeper retains `simp` while matching the primed API. No dot-notation capability is lost. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Combinatorics/Matroid/Minor/Restrict.lean#L162).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-1cc466","file":"Mathlib/Combinatorics/Quiver/ConnectedComponent.lean","decl":"Quiver.StronglyConnectedComponent.IsSStronglyConnected.pos_cycle","line":150,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Quiver.IsSStronglyConnected.exists_pos_cycle` (Combinatorics.Quiver.ConnectedComponent), `Quiver.StronglyConnectedComponent.IsSStronglyConnected.pos_cycle` (Combinatorics.Quiver.ConnectedComponent) state exactly the same thing (Lean-checked). Reviewer: Both are `h v v`. The second sits in namespace StronglyConnectedComponent, so it is Quiver.StronglyConnectedComponent.IsSStronglyConnected.pos_cycle and not reachable by dot notation on h. Both unused; keep the correctly namespaced one (exists_pos_path family).","fix":"Deprecate `Quiver.StronglyConnectedComponent.IsSStronglyConnected.pos_cycle` in favour of `Quiver.IsSStronglyConnected.exists_pos_cycle`.","ev":"dupscan/Check.lean: `example := (@Quiver.StronglyConnectedComponent.IsSStronglyConnected.pos_cycle : type_of% @Quiver.IsSStronglyConnected.exists_pos_cycle)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 34, rating MAJOR): The nested namespace does not provide the intended method on `Quiver.IsSStronglyConnected`; the correctly namespaced theorem already supplies that API. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Combinatorics/Quiver/ConnectedComponent.lean#L150).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the two declarations differ in which arguments are explicit, which Mathlib sometimes keeps deliberately for rewriting.","at":"2026-10-07","commit":""},{"id":"RT-20261007-772c3d","file":"Mathlib/Combinatorics/SimpleGraph/Basic.lean","decl":"SimpleGraph.Adj.mem_support_left","line":415,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `SimpleGraph.Adj.mem_support_left` (Combinatorics.SimpleGraph.Basic), `SimpleGraph.Adj.left_mem_support` (Combinatorics.SimpleGraph.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file, about 10 lines apart: `G.Adj u v → u ∈ G.support`, proved twice under synonym names. There is no comment. Keep left_mem_support (matches left_mem_Icc-style naming; also used in Maps.lean) and deprecate Adj.mem_support_left.","fix":"Deprecate `SimpleGraph.Adj.mem_support_left` in favour of `SimpleGraph.Adj.left_mem_support`.","ev":"dupscan/Check.lean: `example := (@SimpleGraph.Adj.left_mem_support : type_of% @SimpleGraph.Adj.mem_support_left)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 35, rating MAJOR): Both serve adjacency-proof dot notation, without distinct attributes. Account for the earlier theorem’s implicit `G` when migrating direct applications, but that does not justify two synonymous method names. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Combinatorics/SimpleGraph/Basic.lean#L414).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the two declarations differ in which arguments are explicit, which Mathlib sometimes keeps deliberately for rewriting.","at":"2026-10-07","commit":""},{"id":"RT-20261007-d7e71a","file":"Mathlib/Combinatorics/SimpleGraph/Basic.lean","decl":"SimpleGraph.Adj.mem_support_right","line":419,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `SimpleGraph.Adj.mem_support_right` (Combinatorics.SimpleGraph.Basic), `SimpleGraph.Adj.right_mem_support` (Combinatorics.SimpleGraph.Basic) state exactly the same thing (Lean-checked). Reviewer: This is the right-hand twin of the mem_support_left/left_mem_support group, in the same file about 10 lines apart. Keep right_mem_support (also used in Maps.lean) and deprecate Adj.mem_support_right.","fix":"Deprecate `SimpleGraph.Adj.mem_support_right` in favour of `SimpleGraph.Adj.right_mem_support`.","ev":"dupscan/Check.lean: `example := (@SimpleGraph.Adj.right_mem_support : type_of% @SimpleGraph.Adj.mem_support_right)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 37, rating MAJOR): Both provide the same adjacency-proof method, so choosing a consistent left/right naming family is appropriate. As on the left, preserve useful inference behavior when migrating applications. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Combinatorics/SimpleGraph/Basic.lean#L418).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the two declarations differ in which arguments are explicit, which Mathlib sometimes keeps deliberately for rewriting.","at":"2026-10-07","commit":""},{"id":"RT-20261007-df569e","file":"Mathlib/Combinatorics/SimpleGraph/Basic.lean","decl":"SimpleGraph.mk'_mem_incidenceSet_left_iff","line":768,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `SimpleGraph.mem_incidenceSet` (Combinatorics.SimpleGraph.Basic), `SimpleGraph.mk'_mem_incidenceSet_left_iff` (Combinatorics.SimpleGraph.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file: `s(v, w) ∈ G.incidenceSet v ↔ G.Adj v w` is stated as @[simp] mem_incidenceSet (line 863) and as mk'_mem_incidenceSet_left_iff (line 768). Keep the simp lemma and deprecate `_left_iff` (2 uses); `_right_iff` is a different statement.","fix":"Deprecate `SimpleGraph.mk'_mem_incidenceSet_left_iff` in favour of `SimpleGraph.mem_incidenceSet`.","ev":"dupscan/Check.lean: `example := (@SimpleGraph.mk'_mem_incidenceSet_left_iff : type_of% @SimpleGraph.mem_incidenceSet)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup1 item 36, rating MINOR): `_left_iff` has implicit vertices and belongs to the explicit left/right theorem family; `mem_incidenceSet` takes both vertices explicitly. The former is useful for inferred `.mp`/`.mpr` applications, making this defensible alias redundancy. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Combinatorics/SimpleGraph/Basic.lean#L765).","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-3f49bf","file":"Mathlib/Combinatorics/SimpleGraph/Dart.lean","decl":"Dart","line":23,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"conflicting-terminology","claim":"The module docstring and `Dart`'s docstring say a dart is 'also known as a half-edge or bond', but in graph theory (and in Mathlib's own `Graph.IsBond`, Combinatorics/Graph/Connected/EdgeCut.lean) a bond is a minimal nonempty edge cut, a different notion (Astra A1 item 2).","fix":"Drop 'bond' or qualify it with a reference.","ev":"Measured: source L13-14, L24-26; `Graph.IsBond` at Combinatorics/Graph/Connected/EdgeCut.lean:164.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-654b0d","file":"Mathlib/Combinatorics/SimpleGraph/Dart.lean","decl":"Dart.fintype","line":55,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"Missing characteristic API: no `Finite G.Dart` instance from `[Finite V]` (only the computational `Fintype` one), no `DecidableRel G.DartAdj` instance although `DartAdj` is an equality of vertices, `Dart.symm_ne` is not `@[simp]` (so `simp` cannot prove `d.symm ≠ d`), the equivalence `(Σ v, G.neighborSet v) ≃ G.Dart` is buried inside the instance, and the bijection `G.neighborSet v ≃ {d // d.fst = v}` described in `dartOfNeighborSet`'s docstring is not provided (Astra A1 items 1, 4-7).","fix":"Add `instance [Finite V] : Finite G.Dart`, `instance [DecidableEq V] : DecidableRel G.DartAdj`, `@[simp]` on `symm_ne`, the sigma equivalence and the neighbor-set equivalence.","ev":"hunts/sg-dart/probe2.lean: `infer_instance` fails for `Finite G.Dart` (L5) and `DecidableRel G.DartAdj` (L13), `simp` fails on `d.symm ≠ d` (L15); `Finite.of_injective Dart.toProd Dart.toProd_injective` compiles (L6).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-f1ef15","file":"Mathlib/Combinatorics/SimpleGraph/Dart.lean","decl":"Dart.fintype","line":55,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`Dart.fintype` assumes `[DecidableRel G.Adj]`, but the construction only needs `[∀ v, Fintype (G.neighborSet v)]` (locally finite enumerations), the convention of `SimpleGraph.degree` and friends (Astra A1 item 3).","fix":"Assume `[∀ v, Fintype (G.neighborSet v)]` (the `DecidableRel` instance path still provides it).","ev":"hunts/sg-dart/probe2.lean L8-11: the same body compiles under `[Fintype V] [∀ v, Fintype (G.neighborSet v)]`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-ad6ac1","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsMatching","line":24,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"module-docstring-misstates-definition","claim":"The module docstring (L24-25) says 'we represent a matching as a subgraph whose vertices are each incident to at most one edge', but `IsMatching` (L67, and its own docstring) requires every vertex of `M.verts` to have exactly one `M`-neighbour, so a subgraph with an isolated vertex is not a matching. Witness: `⊤ : Subgraph (⊥ : SimpleGraph (Fin 1))` meets the 'at most one edge' description but is not `IsMatching`.","fix":"Change 'at most one edge' to 'exactly one edge' in the module docstring (so the vertex set of the subgraph is exactly the set of matched vertices).","ev":"batch0/probe1.lean (output batch0/probe1.out) section P1b: `example : ¬ (⊤ : Subgraph (⊥ : SimpleGraph (Fin 1))).IsMatching := by intro h; obtain ⟨w, hw, -⟩ := h (v := 0) trivial; simp at hw` and `example : ∀ v : Fin 1, ∀ w w', (⊤ : Subgraph (⊥ : SimpleGraph (Fin 1))).Adj v w → (⊤ : Subgraph (⊥ : SimpleGraph (Fin 1))).Adj v w' → w = w' := by intro v w w' h; simp at h` both compile.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-798ee8","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsMatching","line":49,"sev":"MINOR","status":"confirmed","cat":"hygiene","pattern":"stale-todo-already-done","claim":"The module docstring's TODO list still has '* Tutte's Theorem' (L49), but Tutte's theorem is already in Mathlib: `Mathlib/Combinatorics/SimpleGraph/Tutte.lean:317: theorem tutte : (∃ M : Subgraph G, M.IsPerfectMatching) ↔ ∀ u, ¬ G.IsTutteViolator u`, and it is built on this file's API.","fix":"Delete the 'Tutte's Theorem' TODO item, or replace it with a pointer to `SimpleGraph.tutte` in `Mathlib.Combinatorics.SimpleGraph.Tutte`.","ev":"`git -C mathlib4 grep -n -E '(theorem|lemma) tutte' origin/master -- Mathlib` -> `Mathlib/Combinatorics/SimpleGraph/Tutte.lean:317:theorem tutte : (∃ M : Subgraph G, M.IsPerfectMatching) ↔ ∀ u, ¬ G.IsTutteViolator u := by`; src.lean L49 `* Tutte's Theorem` under `## TODO`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-8fbf34","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsMatching","line":67,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-standard-definition-bridge","claim":"`IsMatching` lacks its characteristic API. (1) Nothing relates it to the standard definition the module docstring states ('a set of disjoint pairs of adjacent vertices'): there is no lemma `M.IsMatching ↔ M.verts ⊆ M.support ∧ M.edgeSet.Pairwise (edges share no vertex)`; the file never mentions pairwise-disjoint edges. The equivalence holds and is about 20 lines (probe P1d compiles), which also confirms the definition is correct. (2) There is no `isMatching_bot`: `simp` makes no progress on `(⊥ : Subgraph G).IsMatching`.","fix":"Add `isMatching_iff_pairwise_disjoint` (verts ⊆ support and pairwise vertex-disjoint edges) and a `@[simp] isMatching_bot`.","ev":"batch0/probe1.lean (output batch0/probe1.out) P1a: `example : (⊥ : Subgraph G).IsMatching := by simp` -> error 'simp made no progress' (probe1.out L1), while `by simp [IsMatching]` compiles; P1d: `theorem isMatching_iff_pairwise (M : G.Subgraph) : M.IsMatching ↔ M.verts ⊆ M.support ∧ M.edgeSet.Pairwise fun e f => ∀ x, x ∈ e → x ∉ f` compiles (proof via `eq_of_adj_left`, `Sym2.congr_right`). `git grep -n -i 'pairwise\\|disjoint' origin/master -- Mathlib/Combinatorics/SimpleGraph/Matching.lean` shows only support-disjointness hypotheses (L121, L141, L175).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-dc5014","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsMatching.toEdge_eq_of_adj","line":73,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"avoidable-backward-transparency-option","claim":"`toEdge_eq_of_adj`, `toEdge_eq_toEdge_of_adj` and `toEdge_preimage_singleton` each carry `set_option backward.isDefEq.respectTransparency.types false in` (L73, L82, L91). They need it only because their proofs rewrite with `Subtype.mk_eq_mk`/`simp` on terms that typecheck only by defeq: the statement uses `hvw : M.Adj v w` as a proof of `s(v, w) ∈ M.edgeSet`, and `toEdge` takes `Exists.choose` of an `∃!` proof. Removing the three options gives three errors ('Did not find an occurrence of the pattern … target expression is not type-correct under the implicit transparency level'). Equally short proofs (`Subtype.ext` plus `ExistsUnique.unique`, then `Subtype.ext Sym2.eq_swap`) compile with no option, the definition unchanged, and the whole file still builds.","fix":"Drop the three `set_option backward.isDefEq.respectTransparency.types false in` lines and prove via `Subtype.ext <| congrArg (s(v, ·)) <| (h hvw.fst_mem).unique (h hvw.fst_mem).choose_spec.1 hvw` and `Subtype.ext Sym2.eq_swap` (batch0/src_variantB.lean).","ev":"batch0/src_nobackward.lean (src.lean minus the 3 set_option lines) -> 3 errors at L75, L83, L95 (batch0/src_nobackward.out). batch0/src_variantB.lean (no set_option; `toEdge_eq_of_adj := Subtype.ext <| congrArg (s(v, ·)) <| (h hvw.fst_mem).unique (h hvw.fst_mem).choose_spec.1 hvw`; `toEdge_eq_toEdge_of_adj`: `rw [h.toEdge_eq_of_adj ha, h.toEdge_eq_of_adj ha.symm]; exact Subtype.ext Sym2.eq_swap`; `toEdge_preimage_singleton` second case `exact (h.toEdge_eq_of_adj huv.symm).trans (Subtype.ext Sym2.eq_swap)`) compiles, exit 0, no output, whole file. batch0/src_variantC.lean also redefines `toEdge` via `(h v.property).exists.choose` and `Subgraph.mem_edgeSet.mpr`, and compiles too.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-4486ed","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsMatching.mem_coe_toEdge","line":87,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`mem_coe_toEdge` (`v ∈ ↑(h.toEdge ⟨v, hv⟩)`) is not `@[simp]`, and nothing else lets simp see through `toEdge`: `simp` makes no progress on the goal. With the lemma added to the simp set, simp closes it, including inside a larger goal, so it works as a simp lemma. The `toEdge` API has no consumers anywhere in Mathlib, so the practical impact is small.","fix":"Tag `IsMatching.mem_coe_toEdge` with `@[simp]`.","ev":"batch0/probe1.lean (output batch0/probe1.out) P4: `example (h : M.IsMatching) (hv : v ∈ M.verts) : v ∈ (h.toEdge ⟨v, hv⟩ : Sym2 V) := by simp` -> 'simp made no progress' (probe1.out); the same goal and `(v ∈ ↑(h.toEdge ⟨v, hv⟩)) ∧ P` close with `simp [IsMatching.mem_coe_toEdge, hP]`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-6c5c7a","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsMatching.map_ofLE","line":100,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"special-case-of-general-lemma-in-file","claim":"`IsMatching.map_ofLE` is the special case `f := Hom.ofLE hGG'` of the same file's `IsMatching.map` (L202: `(f : G →g G') (hf : Injective f) (hM : M.IsMatching) : (M.map f).IsMatching`). `⇑(Hom.ofLE h) = id` holds by `rfl`, so the one-liner `h.map _ injective_id` proves it, where the file spends 6 lines redoing the argument. Its only consumer is `IsMatchingFree.mono` (L356).","fix":"Move `map_ofLE` after `IsMatching.map` and prove it as `h.map _ injective_id` (or deprecate it in favour of `.map`).","ev":"batch0/probe1.lean (output batch0/probe1.out) P5: `example (h : M.IsMatching) (hGG' : G ≤ G') : (M.map (Hom.ofLE hGG')).IsMatching := h.map _ injective_id` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-1cdc75","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsMatching.sup","line":120,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"binary-case-reprovable-from-indexed","claim":"The 17-line proof (L122-138, with a local `aux` and a `sup_comm` swap) re-does, for two subgraphs, the argument of `IsMatching.iSup` proved right after it (L140). With `sup_eq_iSup : x ⊔ y = ⨆ b : Bool, cond b x y` (Order/CompleteLattice/Lemmas.lean:58) the lemma is a 3-line corollary of `IsMatching.iSup`.","fix":"State `IsMatching.sup` after `IsMatching.iSup` and prove it as `by rw [sup_eq_iSup]; exact .iSup (Bool.forall_bool.2 ⟨hM', hM⟩) fun i j _ ↦ by cases i <;> cases j <;> simp_all [hd.symm]`.","ev":"batch1/probe1.lean section P6: `example (hM : M.IsMatching) (hM' : M'.IsMatching) (hd : Disjoint M.support M'.support) : (M ⊔ M').IsMatching := by rw [sup_eq_iSup]; exact .iSup (Bool.forall_bool.2 ⟨hM', hM⟩) fun i j hij ↦ by cases i <;> cases j <;> simp_all [hd.symm]` (no errors in batch1/probe1.out)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-0c31e3","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsMatching.iSup","line":140,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-general-api","claim":"`IsMatching.sup`/`iSup` require disjoint supports, excluding compatible overlapping matchings (`M ⊔ M`, increasing families); a version assuming partners agree on overlaps is missing.","fix":"Add `IsMatching.sup_of_compatible` with `∀ ⦃v w w'⦄, M.Adj v w → M'.Adj v w' → w = w'`.","ev":"hunts/sg-matching/verify6/p4_sup_of_compatible.lean: `IsMatching.sup_of_compatible` (hypothesis `∀ ⦃v w w'⦄, M.Adj v w → M'.Adj v w' → w = w'`) and `IsMatching.iSup_of_compatible` compile (6-line proofs); `IsMatching.sup` is recovered as a corollary, `(M ⊔ M).IsMatching` and increasing ℕ-families of matchings are covered, and `¬ Disjoint M.support M.support` for any M with an edge shows the existing lemma cannot do this.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-606ffe","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsMatching.coeSubgraph","line":163,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"special-case-reproves-general-lemma","claim":"`Subgraph.coeSubgraph` is `protected abbrev coeSubgraph {G' : G.Subgraph} : G'.coe.Subgraph → G.Subgraph := Subgraph.map G'.hom` (Subgraph.lean:1045) and `Subgraph.hom_injective : Function.Injective x.hom` (Subgraph.lean:752), so the lemma is the one-liner `hM.map _ hom_injective` from `IsMatching.map` (L202). The 9-line proof (L165-173) re-proves `IsMatching.map` for this map by unfolding `coeSubgraph_adj`/`verts_coeSubgraph`; it only exists because `IsMatching.map` is stated 40 lines later.","fix":"Move `IsMatching.coeSubgraph` below `IsMatching.map` and prove it as `hM.map _ hom_injective`.","ev":"batch1/probe1.lean section P5: `example {G' : Subgraph G} {M : Subgraph G'.coe} (hM : M.IsMatching) : (Subgraph.coeSubgraph M).IsMatching := hM.map _ hom_injective`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-1fc608","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsMatching.exists_of_disjoint_sets_of_equiv","line":175,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"private-reimplementation-of-existing-construction","claim":"Hall.lean duplicates this construction: its `private abbrev hall_subgraph` (Hall.lean:39-54, verts `p ∪ Set.range f`, `Adj v w := if h : v ∈ p then f ⟨v, h⟩ = w else if h : w ∈ p then f ⟨w, h⟩ = v else False`) is the same subgraph, and `exists_isMatching_of_forall_ncard_le` (Hall.lean:72-80) and `exists_isPerfectMatching_of_forall_ncard_le` (Hall.lean:122-131) each re-prove its matching property by hand. Both follow directly from this lemma with `Equiv.ofInjective f hf₁` resp. `Equiv.ofBijective b hb₁`, after which `hall_subgraph` is unused.","fix":"In Hall.lean, obtain the matchings from `Subgraph.IsMatching.exists_of_disjoint_sets_of_equiv` (with `Equiv.ofInjective`/`Equiv.ofBijective`) and delete the private `hall_subgraph`.","ev":"batch1/probe1.lean section P7 (full statement of `exists_isMatching_of_forall_ncard_le`; after Hall's first 7 proof lines: `obtain ⟨M, hM, hMm⟩ := Subgraph.IsMatching.exists_of_disjoint_sets_of_equiv (s := p₁) (t := Set.range f) (Set.disjoint_left.2 fun a ha ⟨x, hx⟩ ↦ this x (hx ▸ ha)) (Equiv.ofInjective f hf₁) fun v ↦ (G.mem_neighborFinset _ _).mp (hf₂ v); exact ⟨M, hM ▸ Set.subset_union_left, hMm⟩`) and batch1/probe2.lean (full statement of `exists_isPerfectMatching_of_forall_ncard_le` in 3 lines: `obtain ⟨b, hb₁, hb₂⟩ := exists_bijective_of_forall_ncard_le h₁ h₂; obtain ⟨M, hM, hMm⟩ := Subgraph.IsMatching.exists_of_disjoint_sets_of_equiv h₁.disjoint (Equiv.ofBijective b hb₁) hb₂; exact ⟨M, hMm, Subgraph.isSpanning_iff.mpr (hM.trans (union_eq_univ_of_forall_ncard_le h₁ h₂))⟩`)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"Checked 2026-10-07 for a MAJOR re-grade; Astra A2 claim 5 disagrees: `hall_subgraph` accepts non-injective `f` and specifies edges, while the public lemma needs an equivalence and only asserts existence, so this is a proof refactor (delete the helper by reusing the lemma), not a duplicate construction. Stays MINOR.","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-7e7316","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsMatching.exists_of_disjoint_sets_of_equiv","line":175,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"statement-discards-witness","claim":"The conclusion forgets the supplied pairing `f`: it does not guarantee `M.Adj v (f v)` (in `K₄` with `0 ↦ 2, 1 ↦ 3` it also allows `{01, 23}`).","fix":"Add `∀ v : s, M.Adj v (f v)` to the conclusion.","ev":"hunts/sg-matching/verify6/p5_exists_of_equiv_adj.lean: the Mathlib proof with conclusion strengthened to `... ∧ M.IsMatching ∧ ∀ v : s, M.Adj v (f v)` compiles (extra conjunct is `fun v ↦ .inl ⟨v.2, rfl⟩`), the original follows as a corollary, and the K₄ witness `{01, 23}` is checked to satisfy the old conclusion for s = {0,1}, t = {2,3} with neither prescribed edge 02 nor 13.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-e7a333","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsMatching.map","line":202,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"injective-where-injon-suffices","claim":"`hf : Injective f` is stronger than needed: the proof only ever compares `f w = f v` for `w, v ∈ M.verts`, so `Set.InjOn f M.verts` suffices (e.g. a homomorphism that identifies a vertex outside `M` with a matched vertex still maps the matching to a matching). The same proof goes through verbatim with `hf (M.edge_vert hw) hv hw'`. (`IsMatching.map_ofLE` at L100 is also just this lemma at the injective `Hom.ofLE`.)","fix":"Take `hf : Set.InjOn f M.verts` (callers with a globally injective map pass `hf.injOn`).","ev":"batch1/probe1.lean section P2: `theorem IsMatching.map_of_injOn {G' : SimpleGraph W} (f : G →g G') (hf : Set.InjOn f M.verts) (hM : M.IsMatching) : (M.map f).IsMatching := by rintro _ ⟨v, hv, rfl⟩; obtain ⟨v', hv'⟩ := hM hv; refine ⟨f v', ⟨v, v', hv'.1, rfl, rfl⟩, ?_⟩; rintro _ ⟨w, w', hw, hw', rfl⟩; obtain rfl := hf (M.edge_vert hw) hv hw'; rw [hv'.2 w' hw]`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-3ec2eb","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.Iso.isMatching_map","line":213,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"iso-only-iff-holds-for-injective","claim":"The `↔` holds for every injective homomorphism, in particular every embedding `G ↪g G'`, not only isomorphisms: the reverse direction needs only injectivity (`hf ha ▸ hab` and `hf (hu _ ⟨v, y, hy, rfl, rfl⟩)`), not `f.symm`. The iso statement is then a corollary.","fix":"Add `isMatching_map_iff_of_injective (f : G →g G') (hf : Injective f) : (M.map f).IsMatching ↔ M.IsMatching` (or an `Embedding` version) and derive the isomorphism version from it.","ev":"batch1/probe1.lean section P3: `theorem isMatching_map_iff_of_injective {G' : SimpleGraph W} (f : G →g G') (hf : Injective f) : (M.map f).IsMatching ↔ M.IsMatching := by refine ⟨fun h v hv ↦ ?_, (·.map f hf)⟩; obtain ⟨_, ⟨a, b, hab, ha, rfl⟩, hu⟩ := h ⟨v, hv, rfl⟩; exact ⟨b, hf ha ▸ hab, fun y hy ↦ hf (hu _ ⟨v, y, hy, rfl, rfl⟩)⟩` plus `example (f : G ↪g G') : (M.map f.toHom).IsMatching ↔ M.IsMatching := isMatching_map_iff_of_injective _ f.injective`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-e66bb3","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsMatching.verts_eq_biUnion_edgeSet","line":218,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"specialised-lemma-missing-general-identity","claim":"The `⊇` half holds for every subgraph and the `⊆` half only uses that each vertex of `M` has a neighbour (`M.verts ⊆ M.support`), not uniqueness. Underneath is the general identity `M.support = ⋃ e ∈ M.edgeSet, (e : Set V)`, true for every subgraph and absent from Mathlib (no `⋃ e ∈ …edgeSet` lemma in Combinatorics/SimpleGraph besides this one); the matching lemma is that identity rewritten by `IsMatching.support_eq_verts` (L238).","fix":"Add `Subgraph.support_eq_biUnion_edgeSet` to Subgraph.lean and prove this lemma as `by rw [← h.support_eq_verts, support_eq_biUnion_edgeSet]` (or under `M.verts ⊆ M.support`).","ev":"batch1/probe1.lean section P4: `theorem support_eq_biUnion_edgeSet (M : Subgraph G) : M.support = ⋃ e ∈ M.edgeSet, (e : Set V)` (4-line proof via `Sym2.mem_iff_exists`), then `example (h : M.IsMatching) : M.verts = ⋃ e ∈ M.edgeSet, (e : Set V) := by rw [← h.support_eq_verts, support_eq_biUnion_edgeSet]` and `example (h : M.verts ⊆ M.support) : M.verts = ⋃ e ∈ M.edgeSet, (e : Set V) := by rw [← (M.support_subset_verts.antisymm h), support_eq_biUnion_edgeSet]`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-f2f4af","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsMatching.injOn_edgeSet","line":225,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"hypothesis-stronger-than-needed","claim":"`injOn_edgeSet` and `strictMonoOn_edgeSet` use only `M.support = M.verts` (no isolated vertices), not uniqueness of partners; a triangle satisfies the hypothesis but is not a matching.","fix":"State them for subgraphs with `M.support = M.verts`; keep the matching versions as corollaries.","ev":"hunts/sg-matching/verify6/p3_injOn_edgeSet_support.lean: `verts_eq_biUnion_edgeSet`, `injOn_edgeSet` and `strictMonoOn_edgeSet` reproved for `{M | M.support = M.verts}` with essentially the original proofs, the IsMatching versions derived as corollaries via `support_eq_verts`, and `⊤ : (⊤ : SimpleGraph (Fin 3)).Subgraph` (triangle) shown to have support = verts but not be a matching.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-b12838","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsPerfectMatching","line":236,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-named-projections","claim":"`IsPerfectMatching` is a bare `And` with no named API. There is no `IsPerfectMatching.isMatching`, `.isSpanning` or `.existsUnique_adj` (grep finds none in Mathlib), so consumers use anonymous projections. The pattern `hM.1 (hM.2 v)` (= `∃! w, M.Adj v w`) is written 7 times (Matching.lean L326, L442, L443, L605, L629, L630; Tutte.lean L248), and bare `.1`/`.2` appear at Matching.lean L268, L280 and Tutte.lean L147, L212.","fix":"Add `IsPerfectMatching.isMatching`, `IsPerfectMatching.isSpanning` and `IsPerfectMatching.existsUnique_adj (h) (v) : ∃! w, M.Adj v w := h.1 (h.2 v)`, and use them at those sites.","ev":"hunts/sg-matching/batch2/probe1.lean (section 'api: one-line named projections': isMatching', isSpanning', existsUnique_adj' all compile); `git grep -nE \"h[A-Za-z0-9']*\\.1 \\(h[A-Za-z0-9']*\\.2 \" origin/master -- Mathlib/Combinatorics/SimpleGraph` gives 7 hits; `git grep -nE \"(lemma|theorem|def) +(Subgraph\\.)?IsPerfectMatching\\.\"` lists no projection lemmas","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-a36bbd","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsMatching.even_card","line":247,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"fintype-where-ncard-suffices","claim":"`[Fintype M.verts]` is only there to make `toFinset` typecheck. `Even M.verts.ncard` holds for every matching with no finiteness assumption: the finite case follows from this lemma, and in the infinite case `ncard = 0` (a junk value, so add `[Finite M.verts]` if a junk-free statement is preferred). Both ncard-phrased consumers have to work around the Fintype form. `IsClique.even_iff_exists_isMatching` (L291-294) needs `@hMr.even_card _ _ _ hu.fintype` plus a three-lemma `simpa … using!`, and it becomes `fun ⟨M, hM, hMr⟩ ↦ hM ▸ hMr.even_ncard`. Tutte.lean L130-131 needs `-Set.toFinset_card, ← Set.ncard_eq_toFinset_card'`, and it becomes `simpa [Set.even_ncard_compl_iff hveven] using hM.even_ncard`.","fix":"Add `IsMatching.even_ncard (h : M.IsMatching) : Even M.verts.ncard` (or make it the main form) and use it in `IsClique.even_iff_exists_isMatching` and Tutte.lean.","ev":"hunts/sg-matching/batch2/probe1.lean (theorem Subgraph.IsMatching.even_ncard' and the two consumer examples compile); hunts/sg-matching/batch2/Matching_gen.lean (copy of src.lean with `IsMatching.even_ncard` added and `IsClique.even_iff_exists_isMatching`'s ← direction replaced by a one-liner compiles cleanly)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-cf0c3e","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsMatching.even_card","line":247,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"statement-not-simp-normal","claim":"The conclusion `Even M.verts.toFinset.card` is not in simp normal form. `Set.toFinset_card` is `@[simp]` (Mathlib/Data/Fintype/Card.lean:97-98: `s.toFinset.card = Fintype.card s`), so `simp` rewrites the lemma's own statement. Consumers have to normalise it by hand: L317 `simp only [Subgraph.induce_verts, Set.toFinset_card] at this`, L294 `← Set.toFinset_card`, and Tutte.lean L130 `-Set.toFinset_card` to stop simp undoing it.","fix":"State the conclusion as `Even (Fintype.card M.verts)`, or better replace it by the `ncard` form `Even M.verts.ncard`.","ev":"hunts/sg-matching/batch2/probe1.lean: `example [Fintype M.verts] (h : M.IsMatching) : Even (Fintype.card M.verts) := by simpa using h.even_card` and `example [Fintype M.verts] : M.verts.toFinset.card = Fintype.card M.verts := by simp only [Set.toFinset_card]` both compile","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-635b7d","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsPerfectMatching.even_card","line":265,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"fintype-card-where-nat-card-suffices","claim":"The lemma is stated with `[Fintype V]` and `Fintype.card V`. `[Finite V]` with `Nat.card V` suffices, and the statement even holds unconditionally (infinite `V` gives the junk value `Nat.card V = 0`). Tutte.lean, the main client of this theory, phrases parity as `Even (Nat.card V)` (L122, L271, L321), so this lemma does not plug in there. It has no consumers anywhere in Mathlib.","fix":"Restate as `[Finite V] (h : M.IsPerfectMatching) : Even (Nat.card V)`, or add that form beside it.","ev":"hunts/sg-matching/batch2/probe1.lean (theorems Subgraph.IsPerfectMatching.even_natCard' under [Finite V] and even_natCard'' with no finiteness both compile)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-9695bd","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsMatching.induce_connectedComponent","line":270,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"special-case-of-easy-general","claim":"The proof uses only that `c.supp` is closed under `M.Adj`. The general statement, `M.induce (M.verts ∩ s)` is a matching for every `s` closed under `M.Adj`, has a 3-line term proof and gives this lemma in one line. It also handles the matching part of `ConnectedComponent.odd_matches_node_outside` (L324-335), which re-proves the same fact by hand for a component of a different graph (`(⊤.deleteVerts u).coe`) that this lemma cannot reach.","fix":"Add `IsMatching.induce_of_adj_mem (h : M.IsMatching) (hs : ∀ ⦃v w⦄, v ∈ s → M.Adj v w → w ∈ s) : (M.induce (M.verts ∩ s)).IsMatching` and derive `induce_connectedComponent` (and the `hMmatch` step of `odd_matches_node_outside`) from it.","ev":"hunts/sg-matching/batch2/Matching_gen.lean (adds IsMatching.induce_of_adj_mem, reproves induce_connectedComponent as a one-liner from it, and rewrites hMmatch in odd_matches_node_outside with it; the whole copy compiles); also hunts/sg-matching/batch2/probe1.lean section 'induce_connectedComponent for any M.Adj-closed set'","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-3ad1cc","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.IsClique.even_iff_exists_isMatching","line":289,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-finiteness-hypothesis","claim":"`hu : u.Finite` is redundant: for an infinite clique `u` both sides hold (`Even u.ncard` since `ncard = 0`, and an infinite clique has a perfect matching on `u` by `Set.Infinite.exists_union_disjoint_cardinal_eq_of_infinite`), exactly as `Set.exists_union_disjoint_cardinal_eq_iff` needs no finiteness. The proof without `hu` (via `Set.exists_union_disjoint_cardinal_eq_of_even` and `Cardinal.eq`) is no longer than the current one. Both consumers (Tutte.lean L91, L129) pass `Set.toFinite _`.","fix":"Drop `hu` (or state with `encard` if one wants to avoid the junk `ncard` on infinite sets).","ev":"hunts/sg-matching/batch3/probe1.lean section (D) (compiled with `lake env lean -DmaxSynthPendingDepth=3 -DautoImplicit=false -Dpp.unicode.fun=true -Dlinter.mathlibStandardSet=true -Dlinter.style.longFile=1500`, exit 0):\n/-! (D) `IsClique.even_iff_exists_isMatching` without `hu : u.Finite`. -/\n\nlemma even_iff_exists_isMatching' {u : Set V} (hc : G.IsClique u) :\n    Even u.ncard ↔ ∃ (M : Subgraph G), M.verts = u ∧ M.IsMatching := by\n  refine ⟨fun h ↦ ?_, ?_⟩\n  · obtain ⟨t, w, rfl, hd, hcard⟩ := Set.exists_union_disjoint_cardinal_eq_of_even h\n    obtain ⟨f⟩ : Nonempty (t ≃ w) := Cardinal.eq.mp hcard\n    exact Subgraph.IsMatching.exists_of_disjoint_sets_of_equiv hd f\n      fun v ↦ hc (by simp) (by simp) <| hd.ne_of_mem (by simp) (by simp)\n  · rintro ⟨M, rfl, hM⟩\n    obtain hu | hu := M.verts.finite_or_infinite\n    · simpa [Set.ncard_eq_toFinset_card _ hu, Set.toFinite_toFinset,\n        ← Set.toFinset_card] using! @hM.even_card _ _ _ hu.fintype\n    · simp [hu.ncard]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-a27597","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.ConnectedComponent.even_card_of_isPerfectMatching","line":307,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"fintype-card-forces-decidable-instances","claim":"Stating the conclusion as `Even (Fintype.card c.supp)` forces `[Fintype V] [DecidableEq V] [DecidableRel G.Adj]` (only to build the `Fintype c.supp` instance, which also needs the `#adaptation_note` `let` workaround in the proof: removing it still fails, `failed to synthesize Fintype ↑(M.induce c.supp).verts`). The `ncard` form used by `oddComponents` and by `odd_matches_node_outside` needs only `[Finite V]`. The lemma has no consumer in Mathlib.","fix":"State it as `[Finite V] ... : Even c.supp.ncard` (or `Nat.card c.supp`), dropping the decidability instances.","ev":"hunts/sg-matching/batch3/probe1.lean section (C2) (compiled with `lake env lean -DmaxSynthPendingDepth=3 -DautoImplicit=false -Dpp.unicode.fun=true -Dlinter.mathlibStandardSet=true -Dlinter.style.longFile=1500`, exit 0):\n/-! (C2) The same statement with `Nat.card`/`ncard` and only `[Finite V]` (no `Fintype`,\n`DecidableEq`, `DecidableRel`). -/\n\nlemma even_ncard_supp_of_isPerfectMatching [Finite V] (c : ConnectedComponent G)\n    (hM : M.IsPerfectMatching) : Even c.supp.ncard := by\n  classical\n  have := Fintype.ofFinite V\n  simpa [Set.ncard_eq_toFinset_card'] using c.even_card_of_isPerfectMatching hM\n-- and hunts/sg-matching/batch3/probe_c1_adaptation.lean (original proof without the `let`) fails: failed to synthesize `Fintype ↑(M.induce c.supp).verts`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-40cb2a","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.ConnectedComponent.odd_matches_node_outside","line":320,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-finite-typeclass","claim":"`[Finite V]` is not needed: `c` is an odd component, and `oddComponents` is `{c | Odd c.supp.ncard}`, so `c.supp` is finite already (ncard of an infinite set is 0). The same proof goes through for arbitrary `V`, deriving finiteness from `c.prop`. Its only consumer (`Tutte.not_isTutteViolator_of_isPerfectMatching`) is under a section `[Finite V]` anyway.","fix":"Drop `[Finite V]` and get `Finite c.val.supp` from `Set.finite_of_ncard_ne_zero c.prop.pos.ne'`.","ev":"hunts/sg-matching/batch3/probe1.lean section (B) (compiled with `lake env lean -DmaxSynthPendingDepth=3 -DautoImplicit=false -Dpp.unicode.fun=true -Dlinter.mathlibStandardSet=true -Dlinter.style.longFile=1500`, exit 0):\n/-! (B) `odd_matches_node_outside` without `[Finite V]`: odd components are finite anyway. -/\n\nlemma odd_matches_node_outside' {u : Set V}\n    (hM : M.IsPerfectMatching) (c : (Subgraph.deleteVerts ⊤ u).coe.oddComponents) :\n    ∃ᵉ (w ∈ u) (v : ((⊤ : G.Subgraph).deleteVerts u).verts), M.Adj v w ∧ v ∈ c.val.supp := by\n  by_contra! h\n  have hMmatch : (M.induce c.val.supp).IsMatching := by\n    intro v hv\n    obtain ⟨w, hw⟩ := hM.1 (hM.2 v)\n    obtain ⟨⟨v', hv'⟩, ⟨hv, rfl⟩⟩ := hv\n    use w\n    have hwnu : w ∉ u := fun hw' ↦ h w hw' ⟨v', hv'⟩ (hw.1) hv\n    refine ⟨⟨⟨⟨v', hv'⟩, hv, rfl⟩, ?_, hw.1⟩, fun _ hy ↦ hw.2 _ hy.2.2⟩\n    apply ConnectedComponent.mem_coe_supp_of_adj ⟨⟨v', hv'⟩, ⟨hv, rfl⟩⟩ ⟨by trivial, hwnu⟩\n    simp only [Subgraph.induce_verts, Subgraph.verts_top, Set.mem_sdiff, Set.mem_univ, true_and,\n      Subgraph.induce_adj, hwnu, not_false_eq_true, and_self, Subgraph.top_adj, M.adj_sub hw.1,\n      and_true] at hv' ⊢\n    trivial\n  apply Nat.not_even_iff_odd.2 c.prop\n  have : Finite c.val.supp := (Set.finite_of_ncard_ne_zero c.prop.pos.ne').to_subtype\n  have : Fintype ↑(Subgraph.induce M (Subtype.val '' ConnectedComponent.supp c.val)).verts :=\n    @Fintype.ofFinite _ (Finite.Set.finite_image _ _)\n  classical\n  have := Fintype.ofFinite c.val.supp\n  simpa [Finset.card_image_of_injective] using hMmatch.even_card","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-4f2c83","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.IsMatchingFree","line":349,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"predicate-without-characteristic-api","claim":"The predicate has no characteristic API (no `not_isMatchingFree_iff : ¬ G.IsMatchingFree ↔ ∃ M : Subgraph G, M.IsPerfectMatching`, no intro/elim lemmas), and outside this file nothing states anything with it: Tutte's `exists_isTutteViolator` takes `h : ∀ (M : G.Subgraph), ¬M.IsPerfectMatching` and `tutte` uses `∃ M : Subgraph G, M.IsPerfectMatching`; even `exists_maximal_isMatchingFree` concludes with `∃ M : Subgraph G', M.IsPerfectMatching` instead of `¬ G'.IsMatchingFree`. The only uses of the name are the three declarations in this file.","fix":"Add `not_isMatchingFree_iff` (simp) and use `IsMatchingFree` in the Tutte statements, or drop the predicate in favour of `¬ ∃ M, M.IsPerfectMatching`.","ev":"measured: `git grep -n 'MatchingFree\\|isMatchingFree' origin/master -- Mathlib` gives only Matching.lean L35, L349, L351-352, L361-362 and Tutte.lean L276/L288/L310 (local hypothesis names). The missing iff is one line: hunts/sg-matching/batch3/probe1.lean section (G):\n/-! (G) `IsMatchingFree`: no intro/elim lemma; the `¬`/`∃` form is just `not_forall_not`. -/\nexample : ¬ G.IsMatchingFree ↔ ∃ M : Subgraph G, M.IsPerfectMatching := by\n  simp [IsMatchingFree]","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-a532e9","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.IsCycles","line":375,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"degree-two-definition-admits-infinite-paths","claim":"`IsCycles` is documented (module docstring: 'means that a graph consists of cycles (including cycles of length 0 ...)'; def docstring: 'A graph `G` consists of a set of cycles, if each vertex is either isolated or connected to exactly two vertices') as a disjoint union of cycles, but the definition is only 'every non-isolated vertex has exactly two neighbours'. For infinite vertex types that admits two-way infinite paths: the Hasse diagram of `ℤ` (n ~ n±1) satisfies `IsCycles`, is connected and infinite, and no cycle walk has its component as vertex set. Every lemma that extracts cycles (`exists_cycle_toSubgraph_verts_eq_connectedComponentSupp`, `reachable_deleteEdges`, ...) carries `[Finite V]`, so no theorem is false, but the name and both docstrings overstate the definition for infinite graphs. Graded MINOR, not MAJOR: the def docstring states the actual condition right after the gloss, and no theorem is false.","fix":"Say in the def and module docstrings that this is 'every vertex has degree 0 or 2', which means a disjoint union of cycles only for finite graphs (infinite graphs may also contain two-way infinite paths).","ev":"hunts/sg-matching/batch3/probe1.lean section (A) (compiled with `lake env lean -DmaxSynthPendingDepth=3 -DautoImplicit=false -Dpp.unicode.fun=true -Dlinter.mathlibStandardSet=true -Dlinter.style.longFile=1500`, exit 0):\n/-! (A) `IsCycles` holds for the bi-infinite path on `ℤ`, which is connected and infinite, so it\nis not a disjoint union of cycles: no cycle has the component of `0` as its vertex set. -/\n\ntheorem hasse_int_neighborSet (v : ℤ) : (hasse ℤ).neighborSet v = {v - 1, v + 1} := by\n  ext w\n  simp only [mem_neighborSet, hasse_adj, Order.covBy_iff_add_one_eq, Set.mem_insert_iff,\n    Set.mem_singleton_iff]\n  omega\n\ntheorem hasse_int_isCycles : (hasse ℤ).IsCycles := by\n  intro v _\n  rw [hasse_int_neighborSet, Set.ncard_pair (by omega)]\n\ntheorem hasse_int_no_cycle :\n    ¬ ∃ p : (hasse ℤ).Walk 0 0, p.IsCycle ∧\n      p.toSubgraph.verts = ((hasse ℤ).connectedComponentMk 0).supp := by\n  rintro ⟨p, -, h⟩\n  have hu : ((hasse ℤ).connectedComponentMk 0).supp = Set.univ := by\n    ext v\n    simp only [ConnectedComponent.mem_supp_iff, ConnectedComponent.eq, Set.mem_univ, iff_true]\n    exact hasse_preconnected_of_succ ℤ v 0\n  rw [hu, Walk.verts_toSubgraph] at h\n  exact Set.infinite_univ (h ▸ p.support.finite_toSet)\n\n/-- So the `[Finite V]` in `IsCycles.exists_cycle_toSubgraph_verts_eq_connectedComponentSupp` is\nessential, and \"`G` consists of cycles\" is false for `IsCycles` graphs in general. -/\nexample : (hasse ℤ).IsCycles ∧ ((hasse ℤ).neighborSet 0).Nonempty ∧\n    ¬ ∃ p : (hasse ℤ).Walk 0 0, p.IsCycle ∧\n      p.toSubgraph.verts = ((hasse ℤ).connectedComponentMk 0).supp :=\n  ⟨hasse_int_isCycles, ⟨1, by simp [hasse_int_neighborSet]⟩, hasse_int_no_cycle⟩","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-6548a1","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.IsCycles","line":375,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"general-material-in-specialised-file","claim":"General graph theory in the matchings file: `IsCycles` and the 11 declarations after it (L368-554: `other_adj_of_adj`, `existsUnique_ne_adj`, `toSimpleGraph`, `Walk.IsCycle.isCycles_spanningCoe_toSubgraph`, `Walk.IsPath.isCycles_spanningCoe_toSubgraph_sup_edge`, `Walk.IsCycle.adj_toSubgraph_iff_of_isCycles`, `snd_of_mem_support_of_isPath_of_adj`, `reachable_sdiff_toSubgraph_spanningCoe(_aux)`, `reachable_deleteEdges`, `exists_cycle_toSubgraph_verts_eq_connectedComponentSupp`) are about graphs of maximum degree 2 and walks; only `Subgraph.IsPerfectMatching.symmDiff_isCycles` mentions matchings. The definition also lacks its basic characterisation by degrees (`G.IsCycles ↔ ∀ v, G.degree v = 0 ∨ G.degree v = 2` under `LocallyFinite`), the analogue of `isMatching_iff_forall_degree`.","fix":"Move `IsCycles` and its matching-free lemmas to a graph file (e.g. next to `Walk.IsCycle` in `Connectivity`/`Acyclic`-adjacent material) and add a degree characterisation.","ev":"measured: `awk 'NR>=368 && NR<=554' src.lean | grep -n 'Matching'` hits only L438-440 (`Subgraph.IsPerfectMatching.symmDiff_isCycles`); `git grep -n IsCycles origin/master -- Mathlib` outside Matching.lean/Tutte.lean: no hits (no degree characterisation anywhere).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-09c273","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Walk.IsPath.isCycles_spanningCoe_toSubgraph_sup_edge","line":414,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-hypothesis-degenerate-case","claim":"The hypothesis `h : u ≠ v` is redundant: if u = v then the path p : G.Walk u u is nil and `edge u u = ⊥`, so the graph is ⊥, which is trivially IsCycles. The statement holds with only `hp` and `hs`.","fix":"Drop `h`, case-splitting on `u = v` inside the proof (the nil case closes by `cases p` + `simp [edge_self_eq_bot]`); update the one caller Tutte.lean:50.","ev":"hunts/sg-matching/batch4/probe1.lean, theorem probe_sup_edge_no_ne: `theorem probe_sup_edge_no_ne {u v : V} {p : G.Walk u v} (hp : p.IsPath) (hs : s(v, u) ∉ p.edges) : (p.toSubgraph.spanningCoe ⊔ edge v u).IsCycles := by obtain rfl | h := eq_or_ne u v; · cases p with | nil => rintro w ⟨x, hx⟩; simp [edge_self_eq_bot] at hx | cons _ q => simp at hp; · exact hp.isCycles_spanningCoe_toSubgraph_sup_edge h hs` (compiled with: cd mathlib4 && lake env lean -DmaxSynthPendingDepth=3 -DautoImplicit=false -Dpp.unicode.fun=true -Dlinter.mathlibStandardSet=true -Dlinter.style.longFile=1500 hunts/sg-matching/batch4/probe1.lean, exit 0, no warnings)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-f0e574","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Walk.IsCycle.adj_toSubgraph_iff_of_isCycles","line":424,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-typeclass-derivable-finiteness","claim":"`[LocallyFinite G]` is unnecessary: `hcyc : G.IsCycles` already gives `(G.neighborSet v).ncard = 2` at every vertex of the cycle, hence finiteness via `Set.finite_of_ncard_ne_zero`. The only caller (Tutte.lean:209) has to manufacture `have (G : SimpleGraph V) : LocallyFinite G := fun _ ↦ Fintype.ofFinite _` to call it.","fix":"Remove `[LocallyFinite G]` and take finiteness from `Set.finite_of_ncard_ne_zero` applied to the IsCycles ncard.","ev":"hunts/sg-matching/batch4/copy.lean (copy of src.lean, L424-431): `lemma Walk.IsCycle.adj_toSubgraph_iff_of_isCycles {u} {p : G.Walk u u} (hp : p.IsCycle) (hcyc : G.IsCycles) (hv : v ∈ p.toSubgraph.verts) : ∀ w, p.toSubgraph.Adj v w ↔ G.Adj v w := by have h2 := hp.ncard_neighborSet_toSubgraph_eq_two (p.mem_verts_toSubgraph.mp hv); have hG := hcyc <| (Set.nonempty_of_ncard_ne_zero (by simp [h2])).mono (p.toSubgraph.neighborSet_subset v); exact Set.ext_iff.mp <| Set.eq_of_subset_of_ncard_le (p.toSubgraph.neighborSet_subset v) (hG.trans h2.symm).le (Set.finite_of_ncard_ne_zero (s := G.neighborSet v) (by simp [hG]))`; whole copy compiles (exit 0, no warnings), #print axioms clean (hunts/sg-matching/batch4/copy_check.lean). Also hunts/sg-matching/batch4/probe1.lean example (G): `(hcyc : G.IsCycles) (v : V) : (G.neighborSet v).Finite` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-ac9562","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsPerfectMatching.symmDiff_isCycles","line":438,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"special-case-of-equally-easy-general-statement","claim":"Perfectness is stronger than needed: the symmetric difference of any two matchings with the same vertex set (`M.verts = M'.verts`) is IsCycles, with the same proof plus a two-line case for vertices outside the common vertex set. The perfect-matching lemma is the special case `verts = univ`.","fix":"Add `Subgraph.IsMatching.symmDiff_isCycles (hM : M.IsMatching) (hM' : M'.IsMatching) (h : M.verts = M'.verts)` and derive the perfect version from it.","ev":"hunts/sg-matching/batch4/probe1.lean: theorem probe_symmDiff_isCycles_of_verts_eq {M : Subgraph G} {M' : Subgraph G'} (hM : M.IsMatching) (hM' : M'.IsMatching) (h : M.verts = M'.verts) : (M.spanningCoe ∆ M'.spanningCoe).IsCycles (proved), plus `example ... (hM : M.IsPerfectMatching) (hM' : M'.IsPerfectMatching) : ... := probe_symmDiff_isCycles_of_verts_eq hM.1 hM'.1 (hM.2.verts_eq_univ.trans hM'.2.verts_eq_univ.symm)`; compiles, exit 0, no warnings.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-43978d","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.IsCycles.snd_of_mem_support_of_isPath_of_adj","line":453,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-typeclass-derivable-finiteness","claim":"`[Finite V]` is unnecessary: it is only used for `Set.toFinite` on two neighbour sets, but the walk's neighbour set is always finite and `G.neighborSet (p.getVert n)` is finite because `hcyc` gives it ncard 2. The lemma holds for arbitrary V.","fix":"Drop `[Finite V]` and obtain finiteness from `Set.finite_of_ncard_ne_zero` (ncard = 2).","ev":"hunts/sg-matching/batch4/copy.lean L449-461: `lemma IsCycles.snd_of_mem_support_of_isPath_of_adj {v w w' : V} (hcyc : G.IsCycles) (p : G.Walk v w) (hw : w ≠ w') (hw' : w' ∈ p.support) (hp : p.IsPath) (hadj : G.Adj v w') : p.snd = w' := by apply hp.snd_of_toSubgraph_adj; rw [Walk.mem_support_iff_exists_getVert] at hw'; obtain ⟨n, ⟨rfl, hnl⟩⟩ := hw'; by_cases hn : n = 0 ∨ n = p.length; · aesop; have h2 := hcyc (Set.nonempty_of_mem hadj.symm); have h2' := hp.ncard_neighborSet_toSubgraph_internal_eq_two (i := n) (by lia) (by lia); rw [Subgraph.adj_comm]; exact (Set.ext_iff.mp (Set.eq_of_subset_of_ncard_le (p.toSubgraph.neighborSet_subset _) (by lia) (Set.finite_of_ncard_ne_zero (by lia))) v).mpr hadj.symm`; copy compiles (exit 0); `#check` shows no Finite V binder and #print axioms is clean (hunts/sg-matching/batch4/copy_check.lean).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-bfaef3","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.IsCycles.exists_cycle_toSubgraph_verts_eq_connectedComponentSupp","line":526,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"hypothesis-stronger-than-needed","claim":"`[Finite V]` on `exists_cycle_toSubgraph_verts_eq_connectedComponentSupp`, `reachable_sdiff_toSubgraph_spanningCoe` and `reachable_deleteEdges` could be weakened to finiteness of the relevant component (e.g. infinitely many disjoint triangles on `ℕ × Fin 3`); some finiteness is essential (two-way infinite path).","fix":"Add versions assuming `c.supp.Finite` and derive the `[Finite V]` ones.","ev":"hunts/sg-matching/verify6/p0_finite_component.lean: primed copies of reachable_sdiff_toSubgraph_spanningCoe(_aux), reachable_deleteEdges and exists_cycle_toSubgraph_verts_eq_connectedComponentSupp compile with `(G.connectedComponentMk _).supp.Finite` / `c.supp.Finite` instead of [Finite V] (termination measure `supp.ncard + 1 - p.length` via a new 9-line `IsPath.length_lt_ncard_supp`; neighbour-set finiteness from IsCycles' ncard = 2), the [Finite V] versions follow by `Set.toFinite _`, and an `ℕ × Fin 3` disjoint-triangles graph (IsCycles, every component finite, V infinite) shows the generalisation is strict. Bonus: snd_of_mem_support_of_isPath_of_adj needs no finiteness hypothesis at all.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-a96710","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.IsCycles.exists_cycle_toSubgraph_verts_eq_connectedComponentSupp","line":526,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reproves-sibling-lemma","claim":"The closure argument re-proves `Walk.IsCycle.adj_toSubgraph_iff_of_isCycles` (same file), including its `Cardinal.eq` detour; it could be `fun v hv w hadj => (hp.1.adj_toSubgraph_iff_of_isCycles h hv w).mpr hadj`.","fix":"Use `adj_toSubgraph_iff_of_isCycles` for the closure step.","ev":"hunts/sg-matching/verify6/p1_closure_reuse.lean: copy of exists_cycle_toSubgraph_verts_eq_connectedComponentSupp with the whole closure block replaced by `fun v hv w hadj ↦ (hp.1.adj_toSubgraph_iff_of_isCycles h hv w).mpr hadj` compiles, given one added line `have := Fintype.ofFinite V` (after `classical`) to supply `LocallyFinite G`; without that line it fails with `failed to synthesize G.LocallyFinite`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-a75c88","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.IsAlternating.spanningCoe","line":571,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"one-line-corollary-of-sibling","claim":"The statement is `IsAlternating.mono` (same file, L568) applied to `Subgraph.spanningCoe_le`, so the term `halt.mono H.spanningCoe_le` proves it. It has a 4-line tactic proof instead, and its only consumer is one private lemma in Tutte.lean (`hcalt.spanningCoe p.toSubgraph`).","fix":"Replace the proof with the term `halt.mono H.spanningCoe_le`, or drop the lemma and write `hcalt.mono p.toSubgraph.spanningCoe_le` at its single use in Tutte.lean.","ev":"example (halt : G.IsAlternating G') (H : Subgraph G) : H.spanningCoe.IsAlternating G' :=\n  halt.mono H.spanningCoe_le\n-- hunts/sg-matching/batch5/evidence.lean E2","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-77a30c","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsPerfectMatching.isAlternating_symmDiff_left","line":625,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"perfect-matching-hypothesis-only-needs-matching","claim":"The hypotheses `M.IsPerfectMatching` and `M'.IsPerfectMatching` are stronger than needed. The conclusion `(M.spanningCoe ∆ M'.spanningCoe).IsAlternating M.spanningCoe` holds for any matchings `M.IsMatching`, `M'.IsMatching`, since the proof only uses that each vertex has at most one partner in each. The perfect version is recovered as `hM.1.isAlternating_symmDiff_left hM'.1`, and the generalisation is strict, because `⊥` is a matching but is not perfect when `V` is nonempty.","fix":"Restate it as `Subgraph.IsMatching.isAlternating_symmDiff_left (hM : M.IsMatching) (hM' : M'.IsMatching)` (deprecated alias for the old name), and pass `hM.1`/`hM'.1` at the consumer.","ev":"theorem Subgraph.IsMatching.isAlternating_symmDiff_left' {M' : Subgraph G'}\n    (hM : M.IsMatching) (hM' : M'.IsMatching) :\n    (M.spanningCoe ∆ M'.spanningCoe).IsAlternating M.spanningCoe := by\n  intro v w w' hww' hvw hvw'\n  have h1 := hM.eq_of_adj_left (u := v) (v := w) (w := w')\n  have h2 := hM'.eq_of_adj_left (u := v) (v := w) (w := w')\n  simp only [symmDiff_def] at *\n  aesop\nexample {M' : Subgraph G'} (hM : M.IsPerfectMatching) (hM' : M'.IsPerfectMatching) :\n    (M.spanningCoe ∆ M'.spanningCoe).IsAlternating M.spanningCoe :=\n  hM.1.isAlternating_symmDiff_left' hM'.1\nexample [Nonempty V] : (⊥ : Subgraph G).IsMatching ∧ ¬ (⊥ : Subgraph G).IsPerfectMatching := by\n  refine ⟨fun v hv ↦ by simp at hv, fun h ↦ ?_⟩\n  obtain ⟨v⟩ := ‹Nonempty V›\n  simpa using h.2 v\n-- hunts/sg-matching/batch5/evidence.lean E1","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-38095b","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsPerfectMatching.isAlternating_symmDiff_right","line":634,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"perfect-matching-hypothesis-only-needs-matching","claim":"Same over-restriction as `_left`: the result holds for matchings `M.IsMatching`, `M'.IsMatching`, not only for perfect matchings. Its single consumer, Tutte.lean `tutte_exists_isPerfectMatching_of_near_matchings` (`hM1.isAlternating_symmDiff_right hM2`), would pass `hM1.1 hM2.1`.","fix":"Restate it as `Subgraph.IsMatching.isAlternating_symmDiff_right (hM : M.IsMatching) (hM' : M'.IsMatching)`, proved by `simpa [symmDiff_comm] using hM'.isAlternating_symmDiff_left hM`, with a deprecated alias.","ev":"theorem Subgraph.IsMatching.isAlternating_symmDiff_right' {M' : Subgraph G'}\n    (hM : M.IsMatching) (hM' : M'.IsMatching) :\n    (M.spanningCoe ∆ M'.spanningCoe).IsAlternating M'.spanningCoe := by\n  simpa [symmDiff_comm] using hM'.isAlternating_symmDiff_left' hM\nexample {M' : Subgraph G'} (hM : M.IsPerfectMatching) (hM' : M'.IsPerfectMatching) :\n    (M.spanningCoe ∆ M'.spanningCoe).IsAlternating M'.spanningCoe :=\n  hM.1.isAlternating_symmDiff_right' hM'.1\n-- hunts/sg-matching/batch5/evidence.lean E1 (uses the generalised _left above)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-aca023","file":"Mathlib/Combinatorics/SimpleGraph/Paths.lean","decl":"SimpleGraph.Adj.isPath_toWalk","line":233,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `SimpleGraph.Walk.IsPath.of_adj` (Combinatorics.SimpleGraph.Paths), `SimpleGraph.Adj.isPath_toWalk` (Combinatorics.SimpleGraph.Paths) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: Dot-notation twin: Adj.isPath_toWalk (`h.isPath_toWalk`, unused) vs Walk.IsPath.of_adj (used as `.of_adj` in Acyclic.lean:190 and Matching.lean:524). They are proved separately (`simp [h.ne]` vs `aesop`) 30 lines apart. Fix: make Adj.isPath_toWalk an alias.","fix":"Declare `SimpleGraph.Adj.isPath_toWalk` as an `alias` of `SimpleGraph.Walk.IsPath.of_adj`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-354099","file":"Mathlib/Combinatorics/SimpleGraph/VertexCover.lean","decl":"SimpleGraph.IsVertexCover","line":35,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-decidable-instance","claim":"`IsVertexCover` has no `Decidable` instance: for `[Fintype V] [DecidableRel G.Adj] [DecidablePred (· ∈ c)]`, `infer_instance` fails on `Decidable (G.IsVertexCover c)` (a plain `def`), although `unfold IsVertexCover; infer_instance` succeeds, so `decide` cannot check vertex covers of concrete graphs.","fix":"Add `instance [Fintype V] [DecidableRel G.Adj] [DecidablePred (· ∈ c)] : Decidable (G.IsVertexCover c) := by unfold IsVertexCover; infer_instance`.","ev":"probe1.lean L5: `infer_instance` fails; L8 `unfold …; infer_instance` compiles.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-3ba352","file":"Mathlib/Combinatorics/SimpleGraph/VertexCover.lean","decl":"SimpleGraph.vertexCoverNum","line":92,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-theorem","claim":"The file proves the set-level duality `isIndepSet_compl_iff_isVertexCover` but never relates `vertexCoverNum` to the independence number `SimpleGraph.indepNum` (defined in the imported `Clique.lean`): Gallai's identity `vertexCoverNum G + indepNum G = Nat.card V` (finite `V`), or the `ℕ∞` analogue, is absent from Mathlib, and `vertexCoverNum` has no use outside this file.","fix":"Add `vertexCoverNum_add_indepNum` (finite case) from the complement duality.","ev":"`git grep -nw vertexCoverNum origin/master -- Mathlib` outside VertexCover.lean: no hits; `indepNum` is defined at `Clique.lean:1047` with only clique/complement lemmas.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-7069e2","file":"Mathlib/Combinatorics/SimpleGraph/VertexCover.lean","decl":"SimpleGraph.exists_of_le_vertexCoverNum","line":109,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"nat-where-enat-suffices","claim":"`exists_of_le_vertexCoverNum` takes `(n : ℕ)` but the same proof works verbatim for `(n : ℕ∞)` (`Set.exists_superset_subset_encard_eq` already accepts extended naturals), covering e.g. `n = ⊤` for infinite `V`. `vertexCoverNum_le_iff` also only repackages `iInf_le_iff`; the useful characterisation `vertexCoverNum G ≤ n ↔ ∃ s, IsVertexCover G s ∧ s.encard ≤ n` (the infimum is attained) is missing.","fix":"Generalise `n` to `ℕ∞`; add the witness characterisation of `vertexCoverNum_le_iff`.","ev":"probe1.lean `exists_of_le_vertexCoverNum'` with `(n : ℕ∞)` and the original proof compiles.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-d43779","file":"Mathlib/Data/Bool/Basic.lean","decl":"Bool.coe_sort_false","line":67,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Bool.coe_false` (Data.Bool.Basic), `Bool.coe_sort_false` (Data.Bool.Basic) state exactly the same thing (Lean-checked). Reviewer: This is the `false` twin of the coe_true/coe_sort_true group. `↑false` and `(false : Prop)` elaborate to the same `false = true` (Lean 3 coe/coe_sort port artifact). Deprecate coe_sort_false; it has 1 use, in BoxIntegral/Basic.","fix":"Deprecate `Bool.coe_sort_false` in favour of `Bool.coe_false`.","ev":"dupscan/Check.lean: `example := (@Bool.coe_sort_false : type_of% @Bool.coe_false)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 40, rating MAJOR): There is likewise no separate sort-coercion rule to preserve for `false`; the extra declaration only repeats the same equality. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Data/Bool/Basic.lean#L63).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-0af818","file":"Mathlib/Data/Bool/Basic.lean","decl":"Bool.coe_sort_true","line":69,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Bool.coe_sort_true` (Data.Bool.Basic), `Bool.coe_true` (Data.Bool.Basic) state exactly the same thing (Lean-checked). Reviewer: These are adjacent. In Lean 4, `↑true` and `(true : Prop)` both elaborate to `true = true`, so coe_true and coe_sort_true are the same. This is a Lean 3 coe/coe_sort port artifact. Deprecate coe_sort_true (unused).","fix":"Deprecate `Bool.coe_sort_true` in favour of `Bool.coe_true`.","ev":"dupscan/Check.lean: `example := (@Bool.coe_true : type_of% @Bool.coe_sort_true)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 39, rating MAJOR): The two surface coercion spellings do not create different Lean 4 rewrite patterns or automation roles. Keeping the shorter name is appropriate. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Data/Bool/Basic.lean#L65).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-91818e","file":"Mathlib/Data/Bool/Basic.lean","decl":"Bool.bool_eq_false","line":81,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Bool.bool_eq_false` (Data.Bool.Basic), `Bool.eq_false_of_not_eq_true` (Data.Bool.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file: bool_eq_false (`¬b → b = false`, the coercion being `¬b = true`) and eq_false_of_not_eq_true have the same statement. bool_eq_false is unused; eq_false_of_not_eq_true has 1 use. Core also has Bool.eq_false_of_ne_true (stated with `≠`).","fix":"Deprecate `Bool.bool_eq_false` in favour of `Bool.eq_false_of_not_eq_true`.","ev":"dupscan/Check.lean: `example := (@Bool.eq_false_of_not_eq_true : type_of% @Bool.bool_eq_false)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 38, rating MAJOR): Boolean-to-`Prop` coercion supplies no separate logical interface here, and neither declaration has a distinguishing attribute. The core theorem is also a reasonable eventual consolidation target. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Data/Bool/Basic.lean#L41).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-ef8f42","file":"Mathlib/Data/DFinsupp/Order.lean","decl":"DFinsupp.coe_strictMono","line":78,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `DFinsupp.coe_strictMono` (Data.DFinsupp.Order), `DFinsupp.coe_mono` (Data.DFinsupp.Order) have exactly the same statement (Lean-checked), so `DFinsupp.coe_strictMono` does not state what its name promises and the intended lemma is missing. Reviewer: coe_strictMono is mis-stated: it says `Monotone ((⇑) : (Π₀ i, α i) → ∀ i, α i)`, a verbatim copy of coe_mono. It should be `StrictMono`; the same proof `fun _ _ ↦ id` works since coe_lt_coe is Iff.rfl. Unused. Astra rates it CRITICAL (a lemma weaker than or unrelated to its name).","fix":"Restate `DFinsupp.coe_strictMono` as its name says (keep `DFinsupp.coe_mono`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@DFinsupp.coe_mono : type_of% @DFinsupp.coe_strictMono)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 5, rating CRITICAL): `Monotone` cannot reasonably stand for `StrictMono` here. Correct: `StrictMono ((⇑) : (Π₀ i, α i) → ∀ i, α i)`, with the same proof. The desired property is already obtainable from `orderEmbeddingToFun.strictMono`, so the fact itself is available. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Data/DFinsupp/Order.lean#L46-L78)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-1b9f23","file":"Mathlib/Data/EReal/Basic.lean","decl":"EReal.coe_coe_eq_natCast","line":791,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `EReal.coe_natCast` (Data.EReal.Basic), `EReal.coe_coe_eq_natCast` (Data.EReal.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file: @[simp, norm_cast] protected coe_natCast {n} and coe_coe_eq_natCast (n) both state `((n : ℝ) : EReal) = (n : EReal)` by rfl. Deprecate coe_coe_eq_natCast (a handful of `rw [← ...]` uses).","fix":"Deprecate `EReal.coe_coe_eq_natCast` in favour of `EReal.coe_natCast`.","ev":"dupscan/Check.lean: `example := (@EReal.coe_coe_eq_natCast : type_of% @EReal.coe_natCast)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 41, rating MAJOR): The keeper already carries `simp` and `norm_cast`, and reverse rewrites can specify `(n := n)`. The explicit argument on the second name does not establish a separate cast-normalization role. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Data/EReal/Basic.lean#L73).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the two declarations differ in which arguments are explicit, which Mathlib sometimes keeps deliberately for rewriting.","at":"2026-10-07","commit":""},{"id":"RT-20261007-d62b92","file":"Mathlib/Data/Fin/SuccPred.lean","decl":"Fin.succAbove_zero_apply","line":602,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Fin.zero_succAbove` (Data.Fin.SuccPred), `Fin.succAbove_zero_apply` (Data.Fin.SuccPred) state exactly the same thing (Lean-checked). Reviewer: Same file: @[simp] rfl zero_succAbove (7 uses) and succAbove_zero_apply (proved by `rw [succAbove_zero]`, unused) both state `succAbove 0 i = i.succ`. Deprecate succAbove_zero_apply.","fix":"Deprecate `Fin.succAbove_zero_apply` in favour of `Fin.zero_succAbove`.","ev":"dupscan/Check.lean: `example := (@Fin.succAbove_zero_apply : type_of% @Fin.zero_succAbove)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 43, rating MAJOR): The useful function-level theorem `succAbove_zero` remains available; the disputed pair consists of two identical pointwise versions. Keeping the established simp name loses no formulation. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Data/Fin/SuccPred.lean#L599).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-a39ffe","file":"Mathlib/Data/Finset/Empty.lean","decl":"Finset.Nonempty.coe_sort","line":80,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Finset.Nonempty.to_subtype` (Data.Finset.Empty), `Finset.Nonempty.coe_sort` (Data.Finset.Empty) state exactly the same thing (Lean-checked). Reviewer: `alias ⟨_, Nonempty.coe_sort⟩ := nonempty_coe_sort` and `theorem Nonempty.to_subtype := nonempty_coe_sort.2` state the same implication 16 lines apart (Set has the same pair at Set/Basic.lean:335/404). to_subtype is used about 200 times and coe_sort about 20, so deprecate coe_sort.","fix":"Deprecate `Finset.Nonempty.coe_sort` in favour of `Finset.Nonempty.to_subtype`.","ev":"dupscan/Check.lean: `example := (@Finset.Nonempty.coe_sort : type_of% @Finset.Nonempty.to_subtype)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup1 item 44, rating MINOR): `coe_sort` is already a directional `alias`, mirrors the `Set` API, and has established users. This fits low-value convenience redundancy better than an accidental duplicate requiring deprecation. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Data/Finset/Empty.lean#L58).","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-968eaf","file":"Mathlib/Data/Finset/Max.lean","decl":"Finset.max_eq_sup_coe","line":41,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Finset.max_eq_sup_coe` (Data.Finset.Max), `Finset.max_eq_sup_withBot` (Data.Finset.Max) state exactly the same thing (Lean-checked). Reviewer: Adjacent @[to_dual] rfl lemmas differing only in s implicit ({s}) vs explicit. max_eq_sup_withBot is the older (mathlib3) name and its dual min_eq_inf_withTop is used; max_eq_sup_coe has about 6 uses. Deprecate max_eq_sup_coe.","fix":"Deprecate `Finset.max_eq_sup_coe` in favour of `Finset.max_eq_sup_withBot`.","ev":"dupscan/Check.lean: `example := (@Finset.max_eq_sup_withBot : type_of% @Finset.max_eq_sup_coe)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup1 item 45, rating MINOR): The implicit `_coe` and explicit `_withBot` versions offer different application conventions, including an explicit finset receiver for the latter. Their duals should be treated consistently; item 47 proposes the opposite survivor. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Data/Finset/Max.lean#L40).","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-2f3fe5","file":"Mathlib/Data/Finset/Max.lean","decl":"Finset.min_eq_inf_withTop","line":45,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Finset.min_eq_inf_withTop` (Data.Finset.Max), `Finset.min_eq_inf_coe` (Data.Finset.Max) state exactly the same thing (Lean-checked). Reviewer: Both are to_dual images of the adjacent rfl lemmas `max_eq_sup_coe {s}` and `max_eq_sup_withBot (s)`, which state the same `s.max = s.sup (↑)` and differ only in whether s is explicit. Keep the `_coe` pair, which has 6 external uses. Deprecate `_withBot`/`_withTop`, whose 2 uses are at l.194 and l.199.","fix":"Deprecate `Finset.min_eq_inf_withTop` in favour of `Finset.min_eq_inf_coe`.","ev":"dupscan/Check.lean: `example := (@Finset.min_eq_inf_coe : type_of% @Finset.min_eq_inf_withTop)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup1 item 47, rating MINOR): `min_eq_inf_withTop` retains the explicit-finset interface, while `_coe` infers it. Deprecating this family also contradicts item 45’s choice for its `to_dual` source; retaining the convenience aliases is reasonable. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Data/Finset/Max.lean#L40).","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-eef5cd","file":"Mathlib/Data/Finset/SDiff.lean","decl":"Finset.union_sdiff_self","line":205,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Finset.union_sdiff_self` (Data.Finset.SDiff), `Finset.union_sdiff_right` (Data.Finset.SDiff) state exactly the same thing (Lean-checked). Reviewer: Both are `(s ∪ t) \\ t = s \\ t := sup_sdiff_right_self` in the same file. Keep `union_sdiff_right`, which pairs with union_sdiff_left and matches Set.union_sdiff_right. Deprecate `Finset.union_sdiff_self`, whose name means something different for sets: Set.union_sdiff_self is `s ∪ t \\ s = s ∪ t`.","fix":"Deprecate `Finset.union_sdiff_self` in favour of `Finset.union_sdiff_right`.","ev":"dupscan/Check.lean: `example := (@Finset.union_sdiff_right : type_of% @Finset.union_sdiff_self)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 46, rating MAJOR): The proposed keeper matches the left/right family and avoids the misleading correspondence with `Set.union_sdiff_self`. There is no attribute or binder distinction to defend. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Data/Finset/SDiff.lean#L131).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-6e7690","file":"Mathlib/Data/Finsupp/MonomialOrder.lean","decl":"MonomialOrder","line":60,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"derivable-structure-field","claim":"The structure field `toSyn_monotone : Monotone toSyn` is derivable from the other fields (additive equivalence + linear order + `IsOrderedAddMonoid` + `WellFoundedLT`: a least element `z` gives `0 ≤ a` by cancellation, and pointwise `c ≤ d` means `d = c + e`), so every constructor of a `MonomialOrder` carries a needless proof obligation (Astra A1 item 5). The field comment of `isOrderedAddMonoid_syn` also says 'linearly ordered cancellative', which describes neither that field nor its content.","fix":"Give `toSyn_monotone` a default proof (after the order fields) or derive it as a lemma; fix the field comment.","ev":"hunts/monomial-order/probe2.lean (2): `Monotone e` for any `e : (σ →₀ ℕ) ≃+ A` with `[AddCancelCommMonoid A] [LinearOrder A] [IsOrderedAddMonoid A] [WellFoundedLT A]` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-89a3e1","file":"Mathlib/Data/Finsupp/MonomialOrder.lean","decl":"orderBot","line":105,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-standard-instance","claim":"`m.syn` has `OrderBot` with `⊥ = 0` (`bot_eq_zero`, `zero_le`) but no `IsBotZeroClass m.syn` instance, so the generic `zero_le`/`nonpos_iff_eq_zero`/`pos_iff_ne_zero` do not apply and the file restates them (`zero_le`, `eq_zero_iff`, `toSyn_lt_iff_ne_zero`); `Finsupp` and `Lex (α →₀ N)` both have the instance (Astra A1 item 1).","fix":"Add `instance : IsBotZeroClass m.syn := ⟨m.zero_le⟩` and deprecate the restated lemmas in favour of the generic ones.","ev":"hunts/monomial-order/probe2.lean (1): `infer_instance` fails to synthesize `IsBotZeroClass m.syn`; `⟨m.zero_le⟩` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-8f56f7","file":"Mathlib/Data/Finsupp/MonomialOrder.lean","decl":"toSyn_lt_iff_ne_zero","line":122,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"name-describes-other-statement","claim":"`MonomialOrder.toSyn_lt_iff_ne_zero {a : m.syn} : 0 < a ↔ a ≠ 0` has no `toSyn` and no `lt` of `toSyn` in its statement: the name describes a different lemma (it is `pos_iff_ne_zero` for `m.syn`, i.e. `bot_lt_iff_ne_bot`).","fix":"Rename to `MonomialOrder.pos_iff_ne_zero` (protected) with a deprecated alias.","ev":"Measured: source L122-123.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-8719a8","file":"Mathlib/Data/Finsupp/MonomialOrder.lean","decl":"instance@L183","line":183,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"duplicate-instance","claim":"The anonymous `noncomputable instance … : IsOrderedCancelAddMonoid (Lex (α →₀ N))` (L182-187) restates, with identical hypotheses (`[LinearOrder α] [AddCommMonoid N] [PartialOrder N] [IsOrderedCancelAddMonoid N]`), the instance `Finsupp.Lex.isOrderedCancelAddMonoid` of `Data/Finsupp/Lex.lean:241`, which this file already imports (via `Finsupp.WellFounded`). It is a `Prop` instance, so a duplicate theorem rather than a second construction; it adds a redundant synthesis path. Its comment is malformed (`-- … -/`), calls it 'the linear order', and `noncomputable` is meaningless on a `Prop`.","fix":"Delete the instance (and its comment).","ev":"hunts/monomial-order/probe-noinst.lean: module-mode copy of the file with the instance removed compiles (including `MonomialOrder.lex`, which needs it), exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-848918","file":"Mathlib/Data/Finsupp/MonomialOrder.lean","decl":"MonomialOrder.lex_lt_iff_of_unique","line":218,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"specialised-instead-of-general","claim":"`lex_lt_iff_of_unique`/`lex_le_iff_of_unique` hold for every monomial order `m` on a one-variable index type (no order on `σ` needed): in one variable all monomial orders agree with the exponent order (Astra A1 item 6).","fix":"State them for arbitrary `m : MonomialOrder σ` with `[Unique σ]`.","ev":"hunts/monomial-order/probe2.lean (3): `c ≺[m] d ↔ c default < d default` for arbitrary `m` with `[Unique σ]` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-143c49","file":"Mathlib/Data/Int/GCD.lean","decl":"Int.gcd_def","line":159,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Int.gcd_def` (Data.Int.GCD), `Int.gcd_eq_natAbs` (Algebra.GCDMonoid.Nat) state exactly the same thing (Lean-checked). Reviewer: Both are `rfl` proofs of `Int.gcd a b = Nat.gcd a.natAbs b.natAbs`, and core already has Int.gcd_eq_natAbs_gcd_natAbs (Init/Data/Int/Gcd.lean:45). Deprecate both Mathlib copies (1 use each) in favour of the core lemma. If a Mathlib name must stay, keep Int.gcd_def, which is lower in the import graph.","fix":"Deprecate `Int.gcd_def` in favour of `Int.gcd_eq_natAbs_gcd_natAbs`.","ev":"dupscan/Check.lean: `example := (@Int.gcd_eq_natAbs : type_of% @Int.gcd_def)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 48, rating MAJOR): The pinned Lean toolchain already provides the exact core theorem, so neither Mathlib wrapper buys an import advantage or additional mathematical interface. [Core source](https://github.com/leanprover/lean4/blob/v4.35.0-rc4/src/Init/Data/Int/Gcd.lean#L45).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 after the user asked whether these are useful API: the two declarations differ in which arguments are explicit, which Mathlib sometimes keeps deliberately for rewriting.","at":"2026-10-07","commit":""},{"id":"RT-20261006-498528","file":"Mathlib/Data/List/Pairwise.lean","decl":"(file)","line":22,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-overstates","claim":"The module docstring says `pwFilter R l` 'yields `l'` as a maximal sublist of `l` such that `Pairwise R l'`'. That is false: `pwFilter (· < ·) [1, 2, 1] = [1]`, yet `[1, 2]` is a pairwise sublist of `[1, 2, 1]` that strictly contains `[1]`. The algorithm is a right-to-left greedy filter, maximal only with respect to the occurrences it kept. Batteries' `pwFilter` docstring has the same claim. The same module docstring also writes `Pairwise R [a 0, ..., a (n - 1)]` as `∀ i j, i < j → R (a i) (a j)` with no bound on `i, j`, and does not give the traversal direction. Graded MINOR under the user's calibration: a wrong module docstring, but no theorem is affected.","fix":"Say 'a pairwise sublist obtained by scanning from the right and keeping each element related to all kept ones', and bound the indices (`i j : Fin n`).","ev":"-- hunts/list-pairwise/P2.lean: `example : let l := [1,2,1]; let p := List.pwFilter (· < ·) l; p = [1] ∧ p.Sublist [1,2] ∧ [1,2].Sublist l ∧ [1,2].Pairwise (· < ·) ∧ p ≠ [1,2] := by decide` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-92a6c4","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.map_zero","line":68,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"unprotected-name-shadows-root-hom-lemma","claim":"`Multiset.map_zero` is not `protected` although its short name is the root-level hom lemma `map_zero` (`f 0 = 0`). Under `open Multiset` (61 Mathlib files) `rw [map_zero]` and `simp only [map_zero]` resolve to the Multiset lemma and silently stop rewriting `f 0`, so callers must write `_root_.map_zero`, as Mathlib/Algebra/Polynomial/Roots.lean:663 does. The analogous `Polynomial.map_zero` (Algebra/Polynomial/Eval/Defs.lean:510) is `protected`.","fix":"Mark `Multiset.map_zero` `protected` (as `Polynomial.map_zero` is) and qualify its short-name uses.","ev":"-- hunts/multiset-mapfold/batch0/probe2.lean, lines 28-35\nsection\nopen Multiset\nexample {R S : Type*} [Semiring R] [Semiring S] (f : R →+* S) : f 0 = 0 := by simp only [map_zero]\n  -- error: `simp` made no progress\nexample {R S : Type*} [Semiring R] [Semiring S] (f : R →+* S) : f 0 = 0 := by\n  simp only [_root_.map_zero]  -- compiles\nend\nexample {R S : Type*} [Semiring R] [Semiring S] (f : R →+* S) : f 0 = 0 := by simp only [map_zero]  -- compiles (no open)\n-- also hunts/multiset-mapfold/batch0/RootsCopy.lean = Polynomial/Roots.lean with line 663's `_root_.map_zero` replaced by `map_zero`: error 'Tactic `rewrite` failed: Did not find an occurrence of the pattern Multiset.map ?f 0'","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-eb8c5c","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.map_add","line":88,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"unprotected-name-shadows-root-hom-lemma","claim":"`Multiset.map_add` is not `protected` although its short name is the root-level hom lemma `map_add` (`f (x + y) = f x + f y`). Under `open Multiset`, `rw [map_add]` fails on a ring-hom goal and `simp only [map_add, …]` silently drops it (the unused-simp-arg linter fires), forcing `_root_.map_add`. `Polynomial.map_add` (Algebra/Polynomial/Eval/Defs.lean:514) is `protected` for this reason.","fix":"Mark `Multiset.map_add` `protected` and qualify its short-name uses.","ev":"-- hunts/multiset-mapfold/batch0/probe1.lean, P7\nsection\nopen Multiset\nexample {R S : Type*} [Semiring R] [Semiring S] (f : R →+* S) (x y : R) :\n    f (x + y) = f x + f y := by rw [map_add]\n  -- error: Did not find an occurrence of the pattern map ?f (?s + ?t)\nexample {R S : Type*} [Semiring R] [Semiring S] (f : R →+* S) (x y : R) :\n    f (x + y + 0) = f x + f y := by simp only [map_add, map_zero, add_zero]\n  -- error: unsolved goals; linter: simp arguments map_add, map_zero unused\nend\nexample {R S : Type*} [Semiring R] [Semiring S] (f : R →+* S) (x y : R) :\n    f (x + y) = f x + f y := by rw [map_add]  -- compiles (no open)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-419736","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.map_eq_zero","line":109,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"unprotected-name-shadows-root-hom-lemma","claim":"`Multiset.map_eq_zero` is not `protected` although its short name is the root-level `@[simp]` lemma `map_eq_zero` (`f a = 0 ↔ a = 0` for a `MonoidWithZeroHomClass` out of a `GroupWithZero`). Under `open Multiset`, `rw [map_eq_zero]` and `simp only [map_eq_zero]` pick the Multiset lemma and fail on that goal. `Polynomial.map_eq_zero` (Algebra/Polynomial/FieldDivision.lean:271) is `protected`.","fix":"Mark `Multiset.map_eq_zero` `protected` and qualify its short-name uses.","ev":"-- hunts/multiset-mapfold/batch0/probe2.lean, lines 22-34\nsection\nopen Multiset\nexample {G M : Type*} [GroupWithZero G] [MulZeroOneClass M] [Nontrivial M] (f : G →*₀ M) (a : G) :\n    f a = 0 ↔ a = 0 := by rw [map_eq_zero]\n  -- error: Did not find an occurrence of the pattern map ?m.14 ?m.13 = 0\nexample {G M : Type*} [GroupWithZero G] [MulZeroOneClass M] [Nontrivial M] (f : G →*₀ M) (a : G) :\n    f a = 0 ↔ a = 0 := by simp only [map_eq_zero]  -- error: `simp` made no progress\nend\nexample {G M : Type*} [GroupWithZero G] [MulZeroOneClass M] [Nontrivial M] (f : G →*₀ M) (a : G) :\n    f a = 0 ↔ a = 0 := by rw [map_eq_zero]  -- compiles (no open)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-783250","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.map_eq_singleton","line":119,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-vs-list-analogue","claim":"`map_eq_singleton` is not `@[simp]`, while its `List` counterpart `List.map_eq_singleton_iff` is `@[simp]` in core. As a result `simpa using h` cannot turn `h : s.map f = {b}` into `∃ a, s = {a} ∧ f a = b`. Making it a local simp lemma closes such goals and causes no loop in a test.","fix":"Tag `Multiset.map_eq_singleton` `@[simp]`, matching `List.map_eq_singleton_iff`.","ev":"example (f : α → β) (s : Multiset α) (b : β) (h : s.map f = {b}) : ∃ a, s = {a} ∧ f a = b := by\n  simpa using h  -- error: after simplification h : Multiset.map f s = {b}\n-- with `attribute [local simp] Multiset.map_eq_singleton` it closes, and `s.map id = {b} ↔ s = {b}` closes by simp\n(hunts/multiset-mapfold/batch1/ProbeA.lean P4, ProbeB.lean P11); core: `@[simp] theorem List.map_eq_singleton_iff` (Init/Data/List/Lemmas.lean:1188)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-49723c","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.map_const","line":161,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-on-const-variant","claim":"`map_const` (the `Function.const` form) is not `@[simp]`, and the comment above it says the simp-normal form lemma is `map_const'`. But simp does not rewrite `Function.const α b` to `fun _ ↦ b`, so `map_const'` never fires on this form and `simp` makes no progress on `map (const α b) s = replicate (card s) b`. Core's `List.map_const` (the same `Function.const` form) is `@[simp]`.","fix":"Tag `map_const` `@[simp]` (as `List.map_const` is), and drop or correct the misleading `-- simp-normal form lemma is map_const'` comment.","ev":"hunts/multiset-mapfold/batch1/ProbeA.lean P3: `example (s : Multiset α) (b : β) : Multiset.map (Function.const α b) s = Multiset.replicate (Multiset.card s) b := by simp` -> error: `simp` made no progress. hunts/multiset-mapfold/batch1/ProbeB.lean P10: the same goal closes by `simp` under `attribute [local simp] Multiset.map_const`. Core: `@[simp] theorem List.map_const {l : List α} {b : β} : map (Function.const α b) l = replicate l.length b` (Init/Data/List/Lemmas.lean:2285).","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6951e7","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.eq_of_mem_map_const","line":167,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"list-binder-in-multiset-lemma","claim":"This was copied from `List.eq_of_mem_map_const` and keeps the binder `{l : List α}`. The statement is `b₁ ∈ Multiset.map (Function.const α b₂) ↑l → b₁ = b₂`, so it only applies to multisets written as coerced lists. For an abstract `s : Multiset α` you must first destructure `s`. The general form has the same one-line proof.","fix":"Restate with `{s : Multiset α}` and prove it by `eq_of_mem_replicate (by rwa [map_const] at h)`.","ev":"#check @Multiset.eq_of_mem_map_const  -- ∀ {α β} {b₁ b₂ : β} {l : List α}, b₁ ∈ Multiset.map (Function.const α b₂) ↑l → b₁ = b₂\nexample {b₁ b₂ : β} {s : Multiset α} (h : b₁ ∈ Multiset.map (Function.const α b₂) s) : b₁ = b₂ :=\n  Multiset.eq_of_mem_replicate (by rwa [Multiset.map_const] at h)\n(hunts/multiset-mapfold/batch1/ProbeA.lean P1/P1b)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4ad8aa","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.eq_of_mem_map_const","line":167,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"one-line-reprovable-unused","claim":"`simp_all` proves this from the existing simp API (`mem_map`, `Function.const_apply`), even for an arbitrary multiset. Nothing in Mathlib uses `Multiset.eq_of_mem_map_const`: `git grep -w eq_of_mem_map_const` finds only its definition and the `List` original.","fix":"Deprecate it, or keep only the generalised `s : Multiset α` form if a named lemma is wanted.","ev":"example {b₁ b₂ : β} {s : Multiset α} (h : b₁ ∈ Multiset.map (Function.const α b₂) s) : b₁ = b₂ := by\n  simp_all\n(hunts/multiset-mapfold/batch1/ProbeA.lean P1b); consumers measured by `git grep -nw eq_of_mem_map_const origin/master -- Mathlib MathlibTest` (2 hits: the List and Multiset declarations)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4353c7","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.map_erase","line":192,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"injective-stronger-than-needed","claim":"Requiring `Function.Injective f` is stronger than needed. The equation `(s.erase x).map f = (s.map f).erase (f x)` holds exactly when `f x ∈ s.map f → x ∈ s`. Under that sharp hypothesis both `map_erase` (injective `f`) and the neighbouring `map_erase_of_mem` (`x ∈ s`) are one-line corollaries. It also covers cases neither lemma reaches, such as a non-injective `f` with `x ∉ s`. The probe also shows the hypothesis is necessary.","fix":"Weaken the hypothesis to `(h : f x ∈ s.map f → x ∈ s)`, or add that form and derive `map_erase` and `map_erase_of_mem` from it. The 2 Mathlib consumers both have injective `f`.","ev":"theorem map_erase_sharp [DecidableEq α] [DecidableEq β] (f : α → β) (x : α) (s : Multiset α)\n    (h : f x ∈ s.map f → x ∈ s) : (s.erase x).map f = (s.map f).erase (f x) := by\n  by_cases hx : x ∈ s\n  · exact Multiset.map_erase_of_mem f s hx\n  · rw [Multiset.erase_of_notMem hx, Multiset.erase_of_notMem (mt h hx)]\n-- + corollaries for injective f and for x ∈ s, a non-injective instance (min · 2, x = 5, s = {0,1}),\n-- and necessity: `(({0,1}).erase 5).map (min · 1) ≠ (({0,1}).map (min · 1)).erase (min 5 1)` by decide\n(hunts/multiset-mapfold/batch1/ProbeB.lean P6)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a8a369","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.map_surjective_of_surjective","line":208,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-iff-converse","claim":"Only one direction is provided; the converse holds (via singletons and map_eq_singleton), and the List API has the @[simp] iff `List.map_surjective_iff : Surjective (List.map f) ↔ Surjective f` (Mathlib/Data/List/Basic.lean:782). `Multiset.map_surjective_iff` does not exist anywhere in Mathlib (git grep; `#check` fails). Neither do Multiset map_injective_iff / map_bijective_iff.","fix":"Add `@[simp] theorem map_surjective_iff : Surjective (map f) ↔ Surjective f` (proof below; passes simpNF), mirroring List.","ev":"batch2/probe1.lean (output batch2/probe1.out) PROBE-G `#check @Multiset.map_surjective_iff` -> Unknown constant (fails-as-expected); PROBE-H compiles:\ntheorem map_surjective_iff' {f : α → β} : Function.Surjective (map f) ↔ Function.Surjective f := by\n  refine ⟨fun h b => ?_, map_surjective_of_surjective⟩\n  obtain ⟨s, hs⟩ := h {b}\n  obtain ⟨a, -, rfl⟩ := map_eq_singleton.1 hs\n  exact ⟨a, rfl⟩\nAlso added as @[simp] in batch2/copy.lean (copy of src.lean, compiled clean incl. `#lint only simpNF`; output batch2/copy.out)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-94382b","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.foldl","line":226,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-docstring-argument","claim":"The docstring describes the call as `foldl f H b s`, but there is no explicit `H` argument: the right-commutativity proof is now the instance argument `[RightCommutative f]`. This is a Lean 3 leftover; the actual signature is `foldl (f : β → α → β) [RightCommutative f] : β → Multiset α → β`. Also, the section header at line 218 reads `### Multiset.fold`, but the section defines foldl/foldr; `Multiset.fold` lives in Mathlib/Data/Multiset/Fold.lean.","fix":"Say `foldl f b s` and that it needs a `RightCommutative f` instance; retitle the line-218 header to `### Multiset.foldl and Multiset.foldr`.","ev":"batch2/probe1.lean (output batch2/probe1.out): `#check @Multiset.foldl` prints `{α β} → (f : β → α → β) → [RightCommutative f] → β → Multiset α → β` (no explicit H); docstring line 223 says \"`foldl f H b s`\"","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-e09849","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.foldl","line":226,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-singleton-simp-lemma","claim":"`foldr_singleton` exists (@[simp], line 264), but its twin `foldl_singleton : foldl f b {a} = f b a` exists nowhere in Mathlib (git grep). As a result `simp` cannot evaluate `foldl f b {a}` (it makes no progress), even though the equation is `rfl`.","fix":"Add `@[simp] theorem foldl_singleton (b a) : foldl f b ({a} : Multiset α) = f b a := rfl` after foldl_add (checked: compiles, passes simpNF).","ev":"batch2/probe1.lean (output batch2/probe1.out) PROBE-A `example (b : β) (a : α) : foldl f b ({a} : Multiset α) = f b a := by simp` -> `simp` made no progress (fails-as-expected); PROBE-B same statement `:= rfl` compiles; PROBE-C foldr analogue `by simp` compiles; lemma added in batch2/copy.lean (copy of src.lean, compiled clean incl. `#lint only simpNF`; output batch2/copy.out)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ab1cce","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.foldl_add","line":240,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"simp-set-not-confluent","claim":"The simp set {foldl_add, foldl_cons, add_cons} is not confluent, because the characteristic right-commutativity lemma `foldl f (f b a) s = f (foldl f b s) a` is missing. simp leaves `foldl f (foldl f (f b a) s) t = foldl f (f (foldl f b s) a) t` unsolved on the true goal `foldl f b (s + a ::ₘ t) = foldl f (f (foldl f b s) a) t`. With that lemma the goal closes by simp.","fix":"Add `theorem foldl_cons_comm (b a s) : foldl f (f b a) s = f (foldl f b s) a` (4-line induction, proof in probe) and consider @[simp].","ev":"batch2/probe1.lean (output batch2/probe1.out) PROBE-E `example (b : β) (a : α) (s t : Multiset α) : foldl f b (s + a ::ₘ t) = foldl f (f (foldl f b s) a) t := by simp` -> unsolved goals (fails-as-expected); `theorem foldl_cons_comm` (induction generalizing b; rw [foldl_cons, foldl_cons, RightCommutative.right_comm (op := f) b a x, ih]) compiles; `by simp [foldl_cons_comm]` then closes PROBE-E","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7440ce","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.foldr","line":250,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-docstring-argument","claim":"The docstring describes the call as `foldr f H b s`, but there is no explicit `H` argument: the left-commutativity proof is now the instance argument `[LeftCommutative f]`. This is a Lean 3 leftover; the actual signature is `foldr (f : α → β → β) [LeftCommutative f] : β → Multiset α → β`.","fix":"Say `foldr f b s` and that it needs a `LeftCommutative f` instance.","ev":"batch2/probe1.lean (output batch2/probe1.out): `#check @Multiset.foldr` prints `{α β} → (f : α → β → β) → [LeftCommutative f] → β → Multiset α → β` (no explicit H); docstring line 247 says \"`foldr f H b s`\"","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a9d3a3","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.foldr_add","line":268,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"simp-set-not-confluent","claim":"The simp set {foldr_add, foldr_cons, add_cons} is not confluent, because the characteristic left-commutativity lemma `foldr g (g a b) s = g a (foldr g b s)` is missing. simp leaves `g a (foldr g (foldr g b t) s) = foldr g (g a (foldr g b t)) s` unsolved on the true goal `foldr g b (s + a ::ₘ t) = foldr g (g a (foldr g b t)) s`. With that lemma the goal closes by simp.","fix":"Add `theorem foldr_cons_comm (b a s) : foldr f (f a b) s = f a (foldr f b s)` (3-line induction, proof in probe) and consider @[simp].","ev":"batch2/probe1.lean (output batch2/probe1.out) PROBE-D `example (b : β) (a : α) (s t : Multiset α) : foldr g b (s + a ::ₘ t) = foldr g (g a (foldr g b t)) s := by simp` -> unsolved goals (fails-as-expected); `theorem foldr_cons_comm` (induction; rw [foldr_cons, foldr_cons, ih]; exact LeftCommutative.left_comm _ _ _) compiles; `by simp [foldr_cons_comm]` then closes PROBE-D","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c055ed","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.pmap_eq_map","line":322,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-of-list-counterpart","claim":"Not @[simp], although its List counterpart `List.pmap_eq_map` is @[simp] in core; `simp` cannot rewrite `s.pmap (fun a _ => f a) H` to `s.map f`, so callers pass it by hand (Algebra/Polynomial/Splits.lean:346, Data/Finset/Powerset.lean:256, RingTheory/UniqueFactorizationDomain/FactorSet.lean:195). A simp-tagged copy passes `#lint only simpNF`, and the file still compiles with the attribute added.","fix":"Tag `Multiset.pmap_eq_map` with `@[simp]` (as `List.pmap_eq_map`), then check downstream simp calls.","ev":"hunts/multiset-mapfold/batch3/probeA.lean P1a: `example (p : α → Prop) (f : α → β) (s : Multiset α) (H : ∀ a ∈ s, p a) : s.pmap (fun a _ => f a) H = s.map f := by simp` -- error: `simp` made no progress; P2 `@[simp]` copy + `#lint only simpNF` -- All linting checks passed; hunts/multiset-mapfold/batch3/copyB.lean (src with @[simp] added) EXIT=0","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-42aa4d","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.map_pmap","line":326,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-companion-lemma","claim":"The companion `pmap_map` (pmap of a map), which List has as `List.pmap_map` next to `List.map_pmap`, is missing for Multiset: `#check @Multiset.pmap_map` gives Unknown constant. It lifts in one line from the List lemma.","fix":"Add `Multiset.pmap_map : pmap g (map f s) H = pmap (fun a h => g (f a) h) s (fun _ h => H _ (mem_map_of_mem _ h))` next to `map_pmap`, proved by `Quot.inductionOn s fun _ H => congr_arg _ <| List.pmap_map H`.","ev":"hunts/multiset-mapfold/batch3/probeA.lean P5: `#check @Multiset.pmap_map` -- Unknown constant; `theorem pmap_map_probe {p : β → Prop} (g : ∀ b, p b → γ) (f : α → β) (s : Multiset α) : ∀ H, pmap g (map f s) H = pmap (fun a h => g (f a) h) s fun _ h => H _ (mem_map_of_mem _ h) := Quot.inductionOn s fun _ H => congr_arg _ <| List.pmap_map H` compiles (also inside hunts/multiset-mapfold/batch3/copyB.lean, EXIT=0)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-9c1aa2","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.attach_cons","line":343,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-of-list-counterpart","claim":"Not @[simp], whereas core `List.attach_cons` is `@[simp, grind =]`; `simp` makes no progress on `(a ::ₘ m).attach`, and callers pass it by hand (Data/Multiset/FinsetOps.lean:105 `simp [attach_cons, h]`). The simp-tagged copy is simpNF-clean, and MapFold still compiles with the attribute.","fix":"Tag `Multiset.attach_cons` with `@[simp]` (as `List.attach_cons`), then check downstream simp calls.","ev":"hunts/multiset-mapfold/batch3/probeA.lean P1b: `example (a : α) (m : Multiset α) : (a ::ₘ m).attach = ⟨a, mem_cons_self a m⟩ ::ₘ m.attach.map fun p => ⟨p.1, mem_cons_of_mem p.2⟩ := by simp` -- `simp` made no progress; P2 simpNF lint passed; hunts/multiset-mapfold/batch3/copyB.lean EXIT=0","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-006caa","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.attach_cons","line":343,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"backward-option-dependent-proof","claim":"The proof needs `set_option backward.isDefEq.respectTransparency false in` (a backward-compatibility escape hatch, about 4200 uses across Mathlib): with the option removed it fails (`rewrite` cannot find `List.map _ (List.pmap ..)`; target not type-correct at implicit transparency). The option-free one-liner `Quotient.inductionOn m fun _ => congr_arg _ List.attach_cons` compiles in the module file.","fix":"Drop the set_option and prove it as `Quotient.inductionOn m fun _ => congr_arg _ List.attach_cons`.","ev":"hunts/multiset-mapfold/batch3/copyC.lean (src with only the set_option line removed): error 348:12 Tactic `rewrite` failed ...; hunts/multiset-mapfold/batch3/copyB.lean with `theorem attach_cons ... := Quotient.inductionOn m fun _ => congr_arg _ List.attach_cons` and no set_option: EXIT=0 (also probeA.lean P3c)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d46d8b","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.rel_map_left","line":387,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-of-list-counterpart","claim":"Not @[simp], whereas the List counterpart `List.forall₂_map_left_iff` (Data/List/Forall2.lean:104) is @[simp]; `simp` makes no progress on `Rel r (s.map f) t`. The simp-tagged copy is simpNF-clean, and MapFold still compiles with the attribute.","fix":"Tag `Multiset.rel_map_left` with `@[simp]`, then check downstream simp calls.","ev":"hunts/multiset-mapfold/batch3/probeA.lean P1c: `example {r : α → β → Prop} {s : Multiset γ} {f : γ → α} {t : Multiset β} : Rel r (s.map f) t ↔ Rel (fun a b => r (f a) b) s t := by simp` -- `simp` made no progress; P2 simpNF lint passed; copyB.lean EXIT=0","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-8ab0b0","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.rel_map_right","line":391,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-of-list-counterpart","claim":"Not @[simp], whereas the List counterpart `List.forall₂_map_right_iff` (Data/List/Forall2.lean:110) is @[simp]; `simp` makes no progress on `Rel r s (t.map f)`. The simp-tagged copy is simpNF-clean, and MapFold still compiles with the attribute.","fix":"Tag `Multiset.rel_map_right` with `@[simp]`, then check downstream simp calls.","ev":"hunts/multiset-mapfold/batch3/probeA.lean P1d: `example {r : α → β → Prop} {s : Multiset α} {t : Multiset γ} {f : γ → β} : Rel r s (t.map f) ↔ Rel (fun a b => r a (f b)) s t := by simp` -- `simp` made no progress; P2 simpNF lint passed; copyB.lean EXIT=0","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-3c8172","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.map_injective","line":408,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-iff-converse","claim":"Only the forward direction exists: `Multiset.map_injective_iff : Injective (map f) ↔ Injective f` is missing (as is `map_surjective_iff`), although `List.map_injective_iff` and `List.map_surjective_iff` exist; the iff is a two-line proof via singletons.","fix":"Add `theorem map_injective_iff {f : α → β} : Injective (map f) ↔ Injective f` (and `map_surjective_iff`) beside `map_injective`.","ev":"example {f : α → β} : Function.Injective (Multiset.map f) ↔ Function.Injective f :=\n  ⟨fun h a b hab => by\n    simpa using h (show ({a} : Multiset α).map f = ({b} : Multiset α).map f by simp [hab]),\n   Multiset.map_injective⟩\n-- run_cmd in hunts/multiset-mapfold/batch4/probe1.lean: Multiset.map_injective_iff: false, List.map_injective_iff: true","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-89595d","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.map_mk_eq_map_mk_of_rel","line":415,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"special-case-of-one-line-general-form","claim":"Stated only for `Quot.mk r`, but the same one-line argument proves it for any `f g` with `r a b → f a = g b` and a heterogeneous `r : α → β → Prop`; `Quot.sound` is the only property of `Quot.mk` used, and the general form is a one-liner from `rel_eq`, `rel_map` and `Rel.mono`.","fix":"Add `map_eq_map_of_rel (hfg : ∀ a b, r a b → f a = g b) (hst : s.Rel r t) : s.map f = t.map g` and derive `map_mk_eq_map_mk_of_rel` from it with `Quot.sound`.","ev":"theorem map_eq_map_of_rel {r : α → β → Prop} {f : α → γ} {g : β → γ} {s : Multiset α}\n    {t : Multiset β} (hfg : ∀ a b, r a b → f a = g b) (hst : s.Rel r t) : s.map f = t.map g :=\n  Multiset.rel_eq.1 <| Multiset.rel_map.2 <| hst.mono fun a _ b _ h => hfg a b h\n\nexample {r : α → α → Prop} {s t : Multiset α} (hst : s.Rel r t) :\n    s.map (Quot.mk r) = t.map (Quot.mk r) :=\n  map_eq_map_of_rel (fun _ _ h => Quot.sound h) hst\n\nexample {s t : Multiset ℕ} (hst : s.Rel (fun a b => a % 2 = b % 2) t) :\n    s.map (· % 2) = t.map (· % 2) :=\n  map_eq_map_of_rel (fun _ _ h => h) hst","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b0dcda","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.exists_multiset_eq_map_quot_mk","line":419,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reprovable-from-surjective-map","claim":"It is surjectivity of `map (Quot.mk r)`, a one-liner from `Multiset.map_surjective_of_surjective` (same file, L208) and `Quot.mk_surjective` (Data/Quot.lean:338); the hand-rolled induction is unnecessary, and the lemma has no consumer outside this file (git grep: 0 hits), its only use being `induction_on_multiset_quot`, which reduces to the same one-liner.","fix":"Prove it (and `induction_on_multiset_quot`) as `(map_surjective_of_surjective Quot.mk_surjective s).imp fun _ => Eq.symm`, or deprecate it in favour of that term.","ev":"example {r : α → α → Prop} (s : Multiset (Quot r)) : ∃ t : Multiset α, s = t.map (Quot.mk r) :=\n  (Multiset.map_surjective_of_surjective Quot.mk_surjective s).imp fun _ => Eq.symm\n\nexample {r : α → α → Prop} {p : Multiset (Quot r) → Prop} (s : Multiset (Quot r)) :\n    (∀ s : Multiset α, p (s.map (Quot.mk r))) → p s := fun h =>\n  (Multiset.map_surjective_of_surjective Quot.mk_surjective s).elim fun t ht => ht ▸ h t","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-e9fe96","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.Nodup.pmap","line":461,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"injectivity-hypothesis-on-whole-domain","claim":"`hf : ∀ a ha b hb, f a ha = f b hb → a = b` demands injectivity of `f` on all of `p`, but only elements of `s` matter; with `f a _ = min a 2` on `s = {1, 2}` the hypothesis is false although `pmap f s` is `Nodup`. (Same hypothesis in `List.Nodup.pmap`.)","fix":"Weaken `hf` to `∀ a (ha : a ∈ s) b (hb : b ∈ s), f a (H a ha) = f b (H b hb) → a = b` (or add a `Nodup.pmap_on` and derive `Nodup.pmap`).","ev":"theorem Nodup.pmap_on {p : α → Prop} {f : ∀ a, p a → β} {s : Multiset α} {H : ∀ a ∈ s, p a}\n    (hf : ∀ a (ha : a ∈ s) b (hb : b ∈ s), f a (H a ha) = f b (H b hb) → a = b)\n    (hs : s.Nodup) : (s.pmap f H).Nodup := by\n  rw [Multiset.pmap_eq_map_attach]\n  exact hs.attach.map_on fun x _ y _ e => Subtype.ext (hf _ x.2 _ y.2 e)\n\nexample {p : α → Prop} {f : ∀ a, p a → β} {s : Multiset α} {H}\n    (hf : ∀ a ha b hb, f a ha = f b hb → a = b) : s.Nodup → (s.pmap f H).Nodup :=\n  Nodup.pmap_on fun a _ b _ e => hf a _ b _ e\n\nexample : ¬ ∀ (a : ℕ) (ha : True) (b : ℕ) (hb : True),\n    (fun a (_ : True) => min a 2) a ha = (fun a (_ : True) => min a 2) b hb → a = b :=\n  fun h => absurd (h 2 trivial 3 trivial rfl) (by decide)\n\nexample : (({1, 2} : Multiset ℕ).pmap (fun a (_ : True) => min a 2) fun _ _ => trivial).Nodup := by\n  refine Nodup.pmap_on ?_ (by simp)\n  intro a ha b hb\n  simp only [Multiset.insert_eq_cons, Multiset.mem_cons, Multiset.mem_singleton] at ha hb\n  rcases ha with rfl | rfl <;> rcases hb with rfl | rfl <;> decide","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-f8df79","file":"Mathlib/Data/Nat/Factorial/DoubleFactorial.lean","decl":"doubleFactorial","line":32,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"The characteristic API that `Nat.factorial` has is missing for `doubleFactorial`: no `n‼ ∣ n !` (`doubleFactorial_dvd_factorial`), no `n ≤ n‼` (`self_le_doubleFactorial`), no monotonicity (`doubleFactorial_le_succ` / `doubleFactorial_mono`), and no odd closed form `(2 * n + 1)! = (2 * n + 1)‼ * (2 ^ n * n !)` (the odd companion of `doubleFactorial_two_mul`). Each is a 1–5 line proof from the file's own lemmas.","fix":"Add `doubleFactorial_dvd_factorial`, `self_le_doubleFactorial`, `doubleFactorial_le_succ`/`doubleFactorial_mono` and `factorial_two_mul_add_one` (odd closed form).","ev":"hunts/double-factorial/probe1.lean P1: the five lemmas compile; `#check Nat.doubleFactorial_dvd_factorial` / `Nat.doubleFactorial_mono` fail with unknown constant (`#guard_msgs (drop error)`). Exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-d24d84","file":"Mathlib/Data/Nat/Factorial/DoubleFactorial.lean","decl":"(file)","line":89,"sev":"MINOR","status":"confirmed","cat":"correctness","pattern":"positivity-ext-assumes-instances","claim":"The positivity extension `Mathlib.Meta.Positivity.evalDoubleFactorial` uses `assumeInstancesCommute`, so it never checks that the `Zero ℕ`/`PartialOrder ℕ` instances it is handed are the standard ones; with a non-standard `Zero ℕ` (zero := 1) it returns `.positive` with a proof of `0 < 0‼` for the requested `1 < 0‼`, an invalid result that only fails later at type checking. Its siblings `evalFactorial` and `evalAscFactorial` use `assertInstancesCommute` and throw instead. The fallback arm `| _, _ =>` also has two patterns for three discriminants (accepted only by Qq's permissive match macro; the siblings write `| _, _, _`). No unsoundness: the kernel rejects the bad proof.","fix":"Use `assertInstancesCommute` and write the fallback as `| _, _, _ => throwError ...`, as in `evalFactorial`.","ev":"hunts/double-factorial/probe3.lean: `run_meta` calling `evalDoubleFactorial.eval` with `{ zero := 1 } : Zero ℕ` on `Nat.doubleFactorial 0` logs `.positive with proof type 0 < Nat.doubleFactorial 0; matches requested 1 < 0‼: false`, while the same call on `evalFactorial` logs `evalFactorial threw (instance check)`. Exit 0. Raised by Astra's A1 pass (items 1, 7).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261006-7d4969","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.squarefree_iff_nodup_primeFactorsList","line":34,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-module-docstring","claim":"The module docstring's only Main Results entry (L20-21) describes this theorem as 'A positive natural number `x` is squarefree iff the list `factors x` has no duplicate factors': `Nat.factors` no longer exists (renamed `Nat.primeFactorsList`), the variable is `n`, and the section omits the file's other main results (the `DecidablePred Squarefree` instance via `Nat.minSqFac`, `squarefree_iff_factorization_le_one`, `sum_divisors_filter_squarefree`, the `primeFactors` product lemmas).","fix":"Rewrite the Main Results entry with `n.primeFactorsList` and list the file's other main results.","ev":"measured: src.lean L19-21; `git -C mathlib4 grep -n -E '^(theorem|lemma|def|abbrev) factors\\b|alias factors\\b' origin/master -- Mathlib/Data/Nat` returns nothing (only `Nat.factors_eq : normalizedFactors n = n.primeFactorsList` remains, RingTheory/UniqueFactorizationDomain/Nat.lean:48).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-0272fe","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Squarefree.natFactorization_le_one","line":50,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"proof-reprovable-from-existing-api","claim":"The 11-line proof (case split on n = 0, `squarefree_iff_emultiplicity_le_one`, case split on primality) is a two-line consequence of `Squarefree.nodup_primeFactorsList` (L41), `Nat.primeFactorsList_count_eq` and `List.nodup_iff_count_le_one`, with no case splits.","fix":"Replace the proof by `rw [← primeFactorsList_count_eq]; exact List.nodup_iff_count_le_one.1 hn.nodup_primeFactorsList p`.","ev":"hunts/nat-squarefree/batch0/probe1.lean (P5): example {n : ℕ} (p : ℕ) (hn : Squarefree n) : n.factorization p ≤ 1 := by\n  rw [← Nat.primeFactorsList_count_eq]\n  exact List.nodup_iff_count_le_one.1 hn.nodup_primeFactorsList p","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-0372bb","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.squarefree_pow_iff","line":90,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"nat-special-case-of-monoid-lemma","claim":"The statement holds in any `Monoid` with `¬IsUnit x` in place of `n ≠ 1`, with a 3-line proof from `Squarefree.squarefree_of_dvd` and `Squarefree.eq_zero_or_one_of_pow_of_not_isUnit`; Mathlib has no general version (`git grep squarefree_pow` finds only this lemma and its use in Moebius.lean:118).","fix":"Add `squarefree_pow_iff_of_not_isUnit [Monoid R] (hx : ¬IsUnit x) (hk : k ≠ 0)` to Mathlib/Algebra/Squarefree/Basic.lean and derive the ℕ version from it via `Nat.isUnit_iff`.","ev":"hunts/nat-squarefree/batch0/probe1.lean (P6): theorem squarefree_pow_iff_of_not_isUnit' {R : Type*} [Monoid R] {x : R} {k : ℕ}\n    (hx : ¬IsUnit x) (hk : k ≠ 0) : Squarefree (x ^ k) ↔ Squarefree x ∧ k = 1 :=\n  ⟨fun h => ⟨h.squarefree_of_dvd (dvd_pow_self _ hk),\n    (h.eq_zero_or_one_of_pow_of_not_isUnit hx).resolve_left hk⟩, by rintro ⟨h, rfl⟩; simpa⟩\n\nexample {n k : ℕ} (hn : n ≠ 1) (hk : k ≠ 0) : Squarefree (n ^ k) ↔ Squarefree n ∧ k = 1 :=\n  squarefree_pow_iff_of_not_isUnit' (mt Nat.isUnit_iff.1 hn) hk","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b003fa","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.squarefree_pow_iff","line":90,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"inlines-existing-lemma","claim":"The forward direction re-derives `Squarefree.eq_zero_or_one_of_pow_of_not_isUnit` (Mathlib/Algebra/Squarefree/Basic.lean:91, `(h : Squarefree (x ^ n)) (h' : ¬ IsUnit x) : n = 0 ∨ n = 1`) inline (by_contradiction, `two_le_iff`, `pow_dvd_pow`) and needs a needless `n = 0` case; with that lemma the whole proof is 3 lines.","fix":"Prove it as `⟨fun h => ⟨h.squarefree_of_dvd (dvd_pow_self _ hk), (h.eq_zero_or_one_of_pow_of_not_isUnit (mt Nat.isUnit_iff.1 hn)).resolve_left hk⟩, by rintro ⟨h, rfl⟩; simpa⟩`.","ev":"hunts/nat-squarefree/batch0/probe1.lean (P6, third example): example {n k : ℕ} (hn : n ≠ 1) (hk : k ≠ 0) : Squarefree (n ^ k) ↔ Squarefree n ∧ k = 1 :=\n  ⟨fun h => ⟨h.squarefree_of_dvd (dvd_pow_self _ hk),\n    (h.eq_zero_or_one_of_pow_of_not_isUnit (mt Nat.isUnit_iff.1 hn)).resolve_left hk⟩,\n    by rintro ⟨h, rfl⟩; simpa⟩","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7bc352","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.squarefree_and_prime_pow_iff_prime","line":101,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"nat-special-case-of-monoid-lemma","claim":"`Squarefree x ∧ IsPrimePow x ↔ Prime x` holds in any `CommMonoidWithZero` with `IsCancelMulZero` (4-line proof from `Prime.squarefree`, `Prime.isPrimePow` and the general pow lemma above); the ℕ statement is then `this.trans Nat.prime_iff.symm`. Mathlib has no general version (no `git grep` hit pairing `IsPrimePow` with `Squarefree`).","fix":"State it for `[CommMonoidWithZero R] [IsCancelMulZero R]` in a file importing both `Mathlib.Algebra.Squarefree.Basic` and `Mathlib.Algebra.IsPrimePow`, and derive the ℕ version.","ev":"hunts/nat-squarefree/batch0/probe1.lean (P7, uses P6's lemma): theorem squarefree_and_isPrimePow_iff_prime' {R : Type*} [CommMonoidWithZero R]\n    [IsCancelMulZero R] {x : R} : Squarefree x ∧ IsPrimePow x ↔ Prime x := by\n  refine ⟨?_, fun hx => ⟨hx.squarefree, hx.isPrimePow⟩⟩\n  rintro ⟨h, p, k, hp, hk, rfl⟩\n  rwa [((squarefree_pow_iff_of_not_isUnit' hp.not_unit hk.ne').1 h).2, pow_one]\n\nexample {n : ℕ} : Squarefree n ∧ IsPrimePow n ↔ n.Prime :=\n  squarefree_and_isPrimePow_iff_prime'.trans Nat.prime_iff.symm","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-3b0cf7","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.minSqFacAux","line":110,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-omits-precondition","claim":"The docstring 'Assuming that `n` has no factors less than `k`, returns the smallest prime `p` such that `p^2 ∣ n`' is wrong. Read literally, the assumption holds only for k ≤ 1 (1 always divides n), and `minSqFacAux 4 1 = some 1` returns a non-prime. Read as 'no prime factors less than k', it is still false without the oddness of k that `minSqFacAux_has_prop` assumes (`k = 2 * i + 3`, `0 < n`): `minSqFacAux 9 2 = none` although 3² ∣ 9, and `minSqFacAux 25 4 = none` although 5² ∣ 25. The docstring also never mentions the `none` result. (Graded MINOR, not MAJOR, under the user's calibration: `minSqFacAux` is an internal helper with no uses outside this file, and `minSqFacAux_has_prop` states the correct precondition `k = 2 * i + 3`.)","fix":"Say: for `0 < n` and odd `k ≥ 3` such that every prime factor of `n` is at least `k`, returns `some p` with `p` the least prime with `p ^ 2 ∣ n`, or `none` if `n` is squarefree (see `minSqFacAux_has_prop`).","ev":"hunts/nat-squarefree/batch0/probe1.lean (P3), all compile:\nexample : (∀ m, Nat.Prime m → m ∣ 9 → 2 ≤ m) ∧ 3 * 3 ∣ 9 ∧ Nat.minSqFacAux 9 2 = none := by\n  refine ⟨fun m hm _ => hm.two_le, by norm_num, ?_⟩\n  rw [Nat.minSqFacAux]; simp; rw [Nat.minSqFacAux]; simp\nexample : (∀ m, Nat.Prime m → m ∣ 25 → 4 ≤ m) ∧ 5 * 5 ∣ 25 ∧ Nat.minSqFacAux 25 4 = none := ...\nexample : Nat.minSqFacAux 4 1 = some 1 := by rw [Nat.minSqFacAux]; simp\nexample : Nat.minSqFacAux 9 2 = none := by decide +kernel","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-012af3","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.minSqFacAux_has_prop","line":154,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-hypothesis-derivable-from-others","claim":"The hypothesis `n0 : 0 < n` is redundant: `e : k = 2 * i + 3` and `ih` applied to the prime 2 already force `n ≠ 0` (if `n = 0` then `2 ∣ n`, so `k ≤ 2`, contradicting `k ≥ 3`). Its only consumer, `minSqFac_has_prop`, case-splits on `n = 0` twice (L194-195, L201-202) just to supply it.","fix":"Drop `n0`, derive positivity inside the proof from `ih 2 prime_two`, and delete the two `n = 0` case splits in `minSqFac_has_prop`.","ev":"hunts/nat-squarefree/batch1/p1.lean, P4:\nexample {n : ℕ} (k i : ℕ) (e : k = 2 * i + 3) (ih : ∀ m, Nat.Prime m → m ∣ n → k ≤ m) :\n    MinSqFacProp n (n.minSqFacAux k) :=\n  minSqFacAux_has_prop k (Nat.pos_of_ne_zero fun h => by\n    have := ih 2 prime_two (by rw [h]; exact dvd_zero 2); omega) i e ih","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b636ff","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.minSqFacAux_has_prop","line":154,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"long-proof-over-30-lines","claim":"The proof is 33 lines (L156-188, plus `termination_by` at L189), over the 30-line threshold. It contains an uncommented `change 2 * (i + 2) ∣ n' at d` (L177) that relies on the defeq `2 * i + 3 + 1 = 2 * (i + 2)`. It is not slow: the whole file elaborates in about 1.5 s, and no declaration exceeds 50 ms.","fix":"Extract the `IH` block (L164-180, the step from `k` to `k + 2` that skips the even `k + 1`) as a helper lemma, and replace the `change` with an `omega`-justified rewrite or comment it.","ev":"wc: proof body src.lean L156-L188 = 33 lines; `change` at L177; profiler run hunts/nat-squarefree/batch1/src_prof.lean (set_option profiler true, threshold 50 ms) reports no declaration over threshold","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d32691","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.instDecidablePredSquarefree","line":235,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"wf-recursive-decidable-instance-blocks-decide","claim":"Plain `decide` cannot evaluate `Squarefree n` when `4 ∤ n`, so it fails for every squarefree `n`, including `Squarefree 1` and `Squarefree 6`. Reduction gets stuck at `match minSqFac n` because `minSqFacAux` is defined by well-founded recursion and is irreducible. Only multiples of 4 work, e.g. `¬ Squarefree 12`. Only `decide +kernel` works. The instance has no docstring saying so, and no `norm_num` extension exists: the port left it commented out (L416-597), along with its tests in MathlibTest/Tactic/NormNum/Ext.lean. Contrast `Nat.decidablePrime`, which is documented, works under `decide`, and has a `@[csimp]` fast VM variant.","fix":"Make the instance `decide`-friendly via a bounded characterisation (`Squarefree n ↔ n ≠ 0 ∧ ∀ m < n + 1, 2 ≤ m → ¬ m * m ∣ n`, see P14), keep `minSqFac` as its `@[csimp]` VM implementation, and document `decide`/`decide +kernel`.","ev":"hunts/nat-squarefree/batch1/p1.lean P1: `example : Squarefree 6 := by decide` and `example : Squarefree 1 := by decide` fail with 'Tactic `decide` failed to reduce ... reduction got stuck at match minSqFac 6 with'; `example : ¬ Squarefree 12 := by decide` succeeds. hunts/nat-squarefree/batch1/p2.lean P13: `by decide +kernel` proves Squarefree 6, 1, 30 and ¬ Squarefree 50. hunts/nat-squarefree/batch1/p3.lean P14: with the bounded characterisation as instance, plain `decide` proves Squarefree 30, Squarefree 1, ¬ Squarefree 50 (compiles).","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-9a9e89","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.divisors_filter_squarefree","line":248,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"nat-lemma-stated-via-normalizedfactors","claim":"The lemma is stated with the general `UniqueFactorizationMonoid.normalizedFactors n` and with multisets (`.val`, `x.val.prod`) instead of the `Nat` API `n.primeFactors` and `∏ p ∈ s, p`. Its only downstream use, via `sum_divisors_filter_squarefree` in NumberTheory/ArithmeticFunction/Misc.lean:88-91, has to `rw [factors_eq]` and `t.prod_val` to get back to `primeFactors`. The Finset form `{d ∈ n.divisors | Squarefree d} = n.primeFactors.powerset.image fun s => ∏ p ∈ s, p` follows in 10 lines from lemmas already in this file. h0 is genuinely needed: the statement fails at n = 0 (P15).","fix":"Restate it as the Finset image over `n.primeFactors.powerset` (P7), placed after `prod_primeFactors_of_squarefree` and `primeFactors_prod`.","ev":"hunts/nat-squarefree/batch1/p1.lean, P7 (theorem divisors_filter_squarefree'):\n{d ∈ n.divisors | Squarefree d} = n.primeFactors.powerset.image fun s => ∏ p ∈ s, p\nproved by ext/simp/rintro with primeFactors_mono, prod_primeFactors_of_squarefree, prod_primeFactors_dvd, squarefree_prod_of_pairwise_isCoprime, coprime_primes; hunts/nat-squarefree/batch1/p3.lean P15: `simp` proves the original statement false at n = 0","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-728c06","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.divisors_filter_squarefree","line":248,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"long-proof-over-30-lines","claim":"The proof is 45 lines (L252-296). It re-derives facts about unique factorization through `factors_unique` and `Multiset.rel_eq`, although `primeFactors_prod` and `prod_primeFactors_of_squarefree` in the same file give a 10-line proof (P7).","fix":"Move the lemma below the `primeFactors` product lemmas and prove it from them (see P7).","ev":"src.lean L252-L296 = 45 lines; replacement proof in hunts/nat-squarefree/batch1/p1.lean P7 is 10 lines","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2219d9","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.sum_divisors_filter_squarefree","line":298,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"nat-lemma-stated-via-normalizedfactors","claim":"The RHS uses `(normalizedFactors n).toFinset.powerset` and `f i.val.prod` instead of `n.primeFactors.powerset` and `f (∏ p ∈ s, p)`. The sole consumer, `prodPrimeFactors_add_of_squarefree` (ArithmeticFunction/Misc.lean:88-91), immediately rewrites with `factors_eq` and `t.prod_val`. There is also no multiplicative counterpart: the lemma is not `@[to_additive]`, and `prod_divisors_filter_squarefree` does not exist (git grep finds no hits). Both `primeFactors` versions follow in 4 lines from P7 and `prod_primeFactors_invOn_squarefree`, and the restatement agrees with the existing lemma.","fix":"State `@[to_additive] prod_divisors_filter_squarefree : ∏ d ∈ n.divisors with Squarefree d, f d = ∏ s ∈ n.primeFactors.powerset, f (∏ p ∈ s, p)` with `f` explicit (P8).","ev":"hunts/nat-squarefree/batch1/p1.lean, P8: prod_divisors_filter_squarefree' and sum_divisors_filter_squarefree' via `rw [divisors_filter_squarefree' h0, prod_image hinj]` with `hinj` from `prod_primeFactors_invOn_squarefree.1.injOn.mono`; agreement: `rw [sum_divisors_filter_squarefree h0, factors_eq]; refine sum_congr rfl fun s _ => ?_; rw [prod_val]; rfl`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-df6e81","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.sq_mul_squarefree_of_pos","line":312,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"inconsistent-witness-order-after-deprecation","claim":"The statement binds `∃ a b, … b ^ 2 * a = n`. That is the witness order the 2026-08-17 deprecation of `Nat.sq_mul_squarefree` (L306-307) calls wrong ('Use `exists_sq_mul_squarefree` instead, which binds the witnesses in the order in which they appear'), but the `_of_pos` variants were left unchanged. It also takes `0 < n` rather than `n ≠ 0`. Its Mathlib consumer (NumberTheory/SumTwoSquares.lean:222) renames the witnesses on destructuring (`⟨b, a, hb₀, ha₀, hab, hb⟩`).","fix":"Deprecate it in favour of `exists_sq_mul_squarefree_of_ne_zero (hn : n ≠ 0) : ∃ b a, 0 < b ∧ 0 < a ∧ b ^ 2 * a = n ∧ Squarefree a` (P9).","ev":"hunts/nat-squarefree/batch1/p1.lean, P9:\nexample {n : ℕ} (hn : n ≠ 0) : ∃ b a : ℕ, 0 < b ∧ 0 < a ∧ b ^ 2 * a = n ∧ Squarefree a := by\n  obtain ⟨b, a, h, hs⟩ := exists_sq_mul_squarefree n\n  exact ⟨b, a, Nat.pos_of_ne_zero (by rintro rfl; simp_all), Nat.pos_of_ne_zero hs.ne_zero, h, hs⟩","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a49acf","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.sq_mul_squarefree_of_pos'","line":317,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"shifted-successor-encoding-variant","claim":"This is a `+1`-shifted restatement of the unprimed lemma (`(b + 1) ^ 2 * (a + 1) = n ∧ Squarefree (a + 1)`), with the same deprecated witness order and a `Nat.pred`/`succ_pred_eq_of_pos` proof. It has one consumer, in Archive (Wiedijk100Theorems/SumOfPrimeReciprocalsDiverges.lean:179), and none in Mathlib. It follows in 3 lines from the unprimed lemma.","fix":"Deprecate it and inline the 3-line derivation (P10) at the Archive use site.","ev":"hunts/nat-squarefree/batch1/p1.lean, P10:\nexample {n : ℕ} (h : 0 < n) : ∃ a b : ℕ, (b + 1) ^ 2 * (a + 1) = n ∧ Squarefree (a + 1) := by\n  obtain ⟨a, b, ha, hb, hab, hs⟩ := sq_mul_squarefree_of_pos h\n  exact ⟨a - 1, b - 1, by rwa [Nat.sub_add_cancel ha, Nat.sub_add_cancel hb],\n    by rwa [Nat.sub_add_cancel ha]⟩","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-28df01","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.coprime_div_gcd_of_squarefree","line":336,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-hypothesis","claim":"The hypothesis `hn : n ≠ 0` is not needed. It is used only to get `0 < gcd m n`, and `Squarefree m` already gives `m ≠ 0`, hence `0 < gcd m n`. In the excluded case `n = 0` the statement still holds, since `m / gcd m 0 = m / m = 1` and `Coprime 1 0`. The lemma has no consumers anywhere in Mathlib, Archive, Counterexamples or MathlibTest (git grep), so dropping the hypothesis costs nothing.","fix":"Delete `(hn : n ≠ 0)` and replace `(gcd_ne_zero_right hn).bot_lt` with `gcd_pos_of_pos_left n hm.ne_zero.bot_lt`.","ev":"hunts/nat-squarefree/batch2/probeA.lean (P1, P1b) and in-file hunts/nat-squarefree/batch2/Copy.lean:\ntheorem P1 {m n : ℕ} (hm : Squarefree m) : Nat.Coprime (m / Nat.gcd m n) n := by\n  have : Nat.Coprime (m / Nat.gcd m n) (Nat.gcd m n) :=\n    Nat.coprime_of_squarefree_mul <| by simpa [Nat.div_mul_cancel, Nat.gcd_dvd_left]\n  simpa [Nat.div_mul_cancel, Nat.gcd_dvd_right] using\n    (Nat.coprime_div_gcd_div_gcd (m := m) (Nat.gcd_pos_of_pos_left n hm.ne_zero.bot_lt)).mul_right this\n\nexample {m : ℕ} (hm : Squarefree m) : Nat.Coprime (m / Nat.gcd m 0) 0 := P1 hm","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-fd3cb1","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.primeFactors_prod_primeFactors","line":368,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"nat-radical-shadow-of-ufm-radical-api","claim":"`∏ p ∈ n.primeFactors, p` is `UniqueFactorizationMonoid.radical n` (`Nat.radical_eq_prod_primeFactors`, RingTheory/Radical/NatInt.lean). So this lemma is the general `@[simp] UniqueFactorizationMonoid.primeFactors_radical : primeFactors (radical a) = primeFactors a` (RingTheory/Radical/Basic.lean:237) in Nat clothing. Its only consumers are `Nat.prod_primeFactors_dvd_iff` (this file) and `Nat.primeFactors_radical` (Radical/NatInt.lean:76), and that wrapper follows directly from the general lemma without it.","fix":"Prove `Nat.primeFactors_radical` from `primeFactors_radical` via `primeFactors_eq_natPrimeFactors`, then deprecate this lemma (or move it next to `Nat.radical_eq_prod_primeFactors` with a pointer to the general one).","ev":"hunts/nat-squarefree/batch2/probeB.lean (Q1, Q3), importing Mathlib.RingTheory.Radical.NatInt:\nexample (n : ℕ) : (∏ p ∈ n.primeFactors, p).primeFactors = n.primeFactors := by\n  simpa [Nat.radical_eq_prod_primeFactors, primeFactors_eq_natPrimeFactors] using\n    primeFactors_radical (a := n)\n\nexample (n : ℕ) : (radical n).primeFactors = n.primeFactors := by\n  rw [← primeFactors_eq_natPrimeFactors]; exact primeFactors_radical","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-94a0c0","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.prod_primeFactors_dvd_iff","line":372,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"nat-radical-shadow-of-ufm-radical-api","claim":"With `∏ p ∈ n.primeFactors, p = radical n` (`Nat.radical_eq_prod_primeFactors`), this is the general `UniqueFactorizationMonoid.radical_dvd_iff_primeFactors_subset (hb : b ≠ 0) : radical a ∣ b ↔ primeFactors a ⊆ primeFactors b` (RingTheory/Radical/Basic.lean:296). Its only consumer is `Nat.radical_dvd_iff` (Radical/NatInt.lean:80), which follows in one line from the general lemma.","fix":"Prove `Nat.radical_dvd_iff` from `radical_dvd_iff_primeFactors_subset` via `primeFactors_eq_natPrimeFactors`, then deprecate this lemma (or move it beside the radical API).","ev":"hunts/nat-squarefree/batch2/probeB.lean (Q2, Q3):\nexample {n k : ℕ} (hk : k ≠ 0) :\n    (∏ p ∈ n.primeFactors, p) ∣ k ↔ n.primeFactors ⊆ k.primeFactors := by\n  simpa [Nat.radical_eq_prod_primeFactors, primeFactors_eq_natPrimeFactors] using\n    radical_dvd_iff_primeFactors_subset (a := n) hk\n\nexample {n k : ℕ} (hk : k ≠ 0) : radical n ∣ k ↔ n.primeFactors ⊆ k.primeFactors := by\n  simpa [primeFactors_eq_natPrimeFactors] using radical_dvd_iff_primeFactors_subset (a := n) hk","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-b498e2","file":"Mathlib/Data/Option/Basic.lean","decl":"Option.casesOn'_coe","line":172,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Option.casesOn'_some` (Data.Option.Basic), `Option.casesOn'_coe` (Data.Option.Basic) state exactly the same thing (Lean-checked). Reviewer: Adjacent @[simp] rfl lemmas; `(a : Option α)` elaborates to `some a`, so `casesOn'_coe` is literally `casesOn'_some` (a Lean-3 coe port artefact, unused). Keep `casesOn'_some`, deprecate `casesOn'_coe`.","fix":"Deprecate `Option.casesOn'_coe` in favour of `Option.casesOn'_some`.","ev":"dupscan/Check.lean: `example := (@Option.casesOn'_coe : type_of% @Option.casesOn'_some)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 50, rating MAJOR): Both are simp lemmas with the same explicit arguments, and the coercion contributes no distinct rewrite pattern. There is no automation benefit to keeping both. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Data/Option/Basic.lean#L167).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-0a8d6e","file":"Mathlib/Data/Option/NAry.lean","decl":"Option.map₂_coe_coe","line":56,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Option.map₂_coe_coe` (Data.Option.NAry), `Option.map₂_some_some` (Data.Option.NAry) state exactly the same thing (Lean-checked). Reviewer: These are adjacent. In Lean 4 the Option coercion is `some`, so `map₂_coe_coe` (not simp) is a mathlib3-era copy of `map₂_some_some` (@[simp, grind =]), with the same rfl proof and no comment. Keep map₂_some_some.","fix":"Deprecate `Option.map₂_coe_coe` in favour of `Option.map₂_some_some`.","ev":"dupscan/Check.lean: `example := (@Option.map₂_some_some : type_of% @Option.map₂_coe_coe)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 51, rating MAJOR): The `some_some` theorem already handles coercion-written applications and retains both `simp` and `grind` support. The unannotated copy adds no separate behavior. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Data/Option/NAry.lean#L53).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-4047df","file":"Mathlib/Data/Part.lean","decl":"Part.toOption_eq_none_iff","line":280,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Part.toOption_eq_none_iff` (Data.Part), `Part.toOption_eq_none` (Data.Part) state exactly the same thing (Lean-checked). Reviewer: Same file: @[simp] toOption_eq_none (o) at l.74 next to toOption_isSome, and toOption_eq_none_iff {a} at l.280 with the same statement (`none` vs `Option.none`). The latter has 3 uses inside Part.lean.","fix":"Deprecate `Part.toOption_eq_none_iff` in favour of `Part.toOption_eq_none`.","ev":"dupscan/Check.lean: `example := (@Part.toOption_eq_none : type_of% @Part.toOption_eq_none_iff)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup1 item 52, rating MINOR): The implicit `_iff` supports concise applications such as `toOption_eq_none_iff.2 h` and matches `toOption_eq_some_iff`; the explicit theorem supplies a different calling convention. Keeping an alias is a reasonable low-cost API choice. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Data/Part.lean#L272).","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-820183","file":"Mathlib/Data/Part.lean","decl":"Part.ret_eq_some","line":530,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Part.ret_eq_some` (Data.Part), `Part.pure_eq_some` (Data.Part) state exactly the same thing (Lean-checked). Reviewer: Adjacent @[simp] rfl lemmas; term-mode `(return a : Part α)` elaborates to `pure a`, so `ret_eq_some` is literally `pure_eq_some` (Lean 3 `return` vs `pure` port artefact). Keep `pure_eq_some`, deprecate `ret_eq_some`.","fix":"Deprecate `Part.ret_eq_some` in favour of `Part.pure_eq_some`.","ev":"dupscan/Check.lean: `example := (@Part.pure_eq_some : type_of% @Part.ret_eq_some)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 1, rating MAJOR): Both have the same binder interface and simp rule; `return` introduces no distinct normal form requiring another lemma.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-f9c4c2","file":"Mathlib/Data/Set/Basic.lean","decl":"Set.inter_nonempty_iff_exists_left","line":391,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Set.inter_nonempty_iff_exists_left` (Data.Set.Basic), `Set.inter_nonempty` (Data.Set.Basic) state exactly the same thing (Lean-checked). Reviewer: These are adjacent in Set/Basic. `∃ x ∈ s, x ∈ t` elaborates to `∃ x, x ∈ s ∧ x ∈ t`, so `_iff_exists_left` (proved by `simp_rw [inter_nonempty]`) restates `inter_nonempty` (Iff.rfl). This is a port artifact from Lean 3's `∃ x (h : x ∈ s)`. Deprecate `_left` (3 uses); its `_right` sibling is a genuinely different statement.","fix":"Deprecate `Set.inter_nonempty_iff_exists_left` in favour of `Set.inter_nonempty`.","ev":"dupscan/Check.lean: `example := (@Set.inter_nonempty : type_of% @Set.inter_nonempty_iff_exists_left)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 2, rating MAJOR): The bounded existential adds no elaboration distinction here. The genuinely different `_right` lemma does not require retaining a redundant `_left`.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-e7167c","file":"Mathlib/Data/Set/Basic.lean","decl":"Set.Nonempty.coe_sort","line":404,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Set.Nonempty.to_subtype` (Data.Set.Basic), `Set.Nonempty.coe_sort` (Data.Set.Basic) state exactly the same thing (Lean-checked). Reviewer: Two dot-notation names for `s.Nonempty → Nonempty ↥s` in one file: `to_subtype := nonempty_subtype.2` and `alias ⟨_, Nonempty.coe_sort⟩ := nonempty_coe_sort`. Keep `to_subtype` (~200 uses), deprecate `Nonempty.coe_sort` (a handful of uses).","fix":"Deprecate `Set.Nonempty.coe_sort` in favour of `Set.Nonempty.to_subtype`.","ev":"dupscan/Check.lean: `example := (@Set.Nonempty.coe_sort : type_of% @Set.Nonempty.to_subtype)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup2 item 7, rating MINOR): `coe_sort` is explicitly an [alias](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Data/Set/Basic.lean#L332-L335), contradicting the scan’s stated exclusion. Both names are legitimate proof methods; consolidating them is optional API cleanup.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-f9f789","file":"Mathlib/Data/Set/Basic.lean","decl":"Set.not_subset_iff_exists_mem_notMem","line":603,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Set.not_subset` (Data.Set.Basic), `Set.not_subset_iff_exists_mem_notMem` (Data.Set.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file: `∃ a ∈ s, a ∉ t` elaborates to `∃ x, x ∈ s ∧ x ∉ t`, so not_subset_iff_exists_mem_notMem (line 603, `by simp [subset_def]`) restates not_subset (line 287). Keep not_subset (about 27 uses) and deprecate the long name (about 5 uses).","fix":"Deprecate `Set.not_subset_iff_exists_mem_notMem` in favour of `Set.not_subset`.","ev":"dupscan/Check.lean: `example := (@Set.not_subset_iff_exists_mem_notMem : type_of% @Set.not_subset)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 4, rating MAJOR): The longer name supplies no different binders, attributes, or proof interface.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-f9c60b","file":"Mathlib/Data/Set/Card.lean","decl":"Set.encard_eq_top","line":1,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `Set.Infinite.encard_eq` (Data.Set.Card), `Set.encard_eq_top` (Data.Set.Card) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: Dot-notation twin: Set.encard_eq_top is `alias ⟨_, encard_eq_top⟩ := encard_eq_top_iff`, while Infinite.encard_eq (@[simp], `h.encard_eq`) is proved separately and is itself used to prove encard_eq_top_iff. Fix: `alias encard_eq_top := Infinite.encard_eq`.","fix":"Declare `Set.encard_eq_top` as an `alias` of `Set.Infinite.encard_eq`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-84b658","file":"Mathlib/Data/Set/Card/Arithmetic.lean","decl":"Finset.exists_disjoint_union_of_even_card","line":34,"sev":"MINOR","status":"confirmed","cat":"hygiene","pattern":"general-material-in-heavy-file","claim":"The two elementary `Finset` lemmas (`Finset.exists_disjoint_union_of_even_card` and its iff) sit in a module that imports cardinal arithmetic and `Finprod`, although they compile with only `Mathlib.Data.Finset.Card` and `Mathlib.Algebra.Group.Nat.Even`; users of `Finset` parity must import the heavier file.","fix":"Move them to a `Finset` cardinality file (e.g. next to `Finset.exists_subset_card_eq`), keeping the `Set` versions here.","ev":"hunts/set-card-arith/probe5_placement.lean: both lemmas, verbatim, compile with only `import Mathlib.Data.Finset.Card` and `import Mathlib.Algebra.Group.Nat.Even` (exit 0). Raised by Astra's A1 pass (item 13).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-6c0729","file":"Mathlib/Data/Set/Card/Arithmetic.lean","decl":"finsum_one","line":47,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"statement-specialised-below-its-proof","claim":"`@[simp] finsum_one : ∑ᶠ i ∈ s, 1 = s.ncard` is stated only for `ℕ`, yet holds verbatim in every `AddCommMonoidWithOne M` as `∑ᶠ i ∈ s, (1 : M) = s.ncard` (same proof; its `by_cases h : 1 = 0` branch is exactly what the general case needs and is dead in `ℕ`). The `ℕ` lemma does not rewrite the `ℤ`/`ℝ`/`ZMod n` forms: `simp` makes no progress on `∑ᶠ i ∈ s, (1 : ℤ) = s.ncard`.","fix":"State it as `lemma finsum_mem_one [AddCommMonoidWithOne M] {s : Set α} : ∑ᶠ i ∈ s, (1 : M) = s.ncard`, or more generally `∑ᶠ i ∈ s, c = s.ncard • c` in an `AddCommMonoid`.","ev":"hunts/set-card-arith/probe1.lean P1 `P1finsum_mem_one` (AddCommMonoidWithOne M, the original proof with the cast) compiles; P1b recovers the file's statement with `M := ℕ`; P1c `∑ᶠ i ∈ s, (1 : ℤ) = s.ncard` by `fail_if_success simp; exact P1finsum_mem_one (M := ℤ)` compiles (simp makes no progress). Exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-93f74c","file":"Mathlib/Data/Set/Card/Arithmetic.lean","decl":"exists_union_disjoint_ncard_eq_of_even","line":94,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-iff-counterpart","claim":"The `ncard` member of the even-splitting family has no iff: `Even s.ncard ↔ ∃ t u, t ∪ u = s ∧ Disjoint t u ∧ t.ncard = u.ncard` holds for every `s` (as the `Finset` and cardinal versions do) but only the forward implication is provided.","fix":"Add `Set.even_ncard_iff_exists_union_disjoint_ncard_eq` (the converse is the finite/infinite case split of `exists_union_disjoint_cardinal_eq_iff` without `Cardinal.toNat`).","ev":"hunts/set-card-arith/probe3.lean P8 `P8even_ncard_iff` compiles. Exit 0. Raised by Astra's A1 pass (item 6).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-c207f0","file":"Mathlib/Data/Set/Card/Arithmetic.lean","decl":"Finite.ncard_biUnion","line":112,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-hypothesis","claim":"`Set.Finite.ncard_biUnion` assumes `ht : t.Finite` and `Set.ncard_iUnion_of_finite` assumes `[Finite ι]`, but both equalities hold without them: if infinitely many of the pairwise-disjoint `s i` (i ∈ t) are nonempty, the union is infinite and the `finsum` has infinite support, so both sides are `0`; otherwise both reduce to the finite subfamily. Only `hs` (each `s i` finite) and disjointness are needed. (The `encard` and `_le` versions do need finiteness of the index: counterexamples compile.)","fix":"Drop `ht` from `Finite.ncard_biUnion` (renaming it `ncard_biUnion`, keeping a deprecated alias) and `[Finite ι]` from `ncard_iUnion_of_finite`.","ev":"hunts/set-card-arith/probe1.lean P2 `P2ncard_biUnion` (no `ht`) and P2b `P2ncard_iUnion` (no `[Finite ι]`) compile; P2c (encard over the singletons of ℕ) and P3 (`_le` with infinitely many copies of `{0}`) show the other lemmas need the index finite; P2d shows `hs` is needed. Exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-68fbfe","file":"Mathlib/Data/Set/Card/Arithmetic.lean","decl":"ncard_iUnion_of_finite","line":116,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-api-variant","claim":"The API is lopsided: the `≤` bounds come in `Finset`/`Fintype` (`∑`) and `Set.Finite`/`Finite` (`∑ᶠ`) forms (`Finset.set_ncard_biUnion_le`, `ncard_iUnion_le_of_fintype`, `Finite.ncard_biUnion_le`, `ncard_iUnion_le_of_finite`, and the `encard` ones), but the disjoint equalities exist only in the `∑ᶠ` forms. `(⋃ i, s i).ncard = ∑ i, (s i).ncard` for `[Fintype ι]`, its `encard` analogue, and the `Finset`-indexed `(⋃ i ∈ t, s i).ncard = ∑ i ∈ t, (s i).ncard` each need a `finsum`-to-`sum` detour.","fix":"Add `ncard_iUnion_of_fintype`, `encard_iUnion_of_fintype` and `Finset.set_ncard_biUnion`/`set_encard_biUnion` (equalities with `∑`).","ev":"hunts/set-card-arith/probe2.lean P4: the three `∑` equalities compile only via `rw [ncard_iUnion_of_finite hs h, finsum_eq_sum_of_fintype]`, `rw [encard_iUnion_of_finite h, finsum_eq_sum_of_fintype]` and `rw [← finsum_mem_coe_finset, ← t.finite_toSet.ncard_biUnion hs h]; simp`; `git grep` finds no `ncard_iUnion_of_fintype` or `Finset`-indexed equality. Exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-9cfd7f","file":"Mathlib/Data/Set/Card/Arithmetic.lean","decl":"Finite.encard_biUnion","line":121,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"finite-index-instead-of-finite-support","claim":"The `encard` equalities and the `≤` bounds over a `Set` index (`Finite.encard_biUnion`, `encard_iUnion_of_finite`, `Finite.ncard_biUnion_le`, `Finite.encard_biUnion_le`, `ncard_iUnion_le_of_finite`, `encard_iUnion_le_of_finite`) assume the whole index set finite, but finiteness of the active part `{i ∈ t | (s i).Nonempty}` suffices; e.g. a family over `ℕ` with a single nonempty member is excluded. (Some support restriction is necessary: with infinitely many nonempty members the `finsum` collapses to `0`.)","fix":"Weaken the hypothesis to `{i ∈ t | (s i).Nonempty}.Finite` (or finiteness of the support of the summand), deriving the current finite-index forms as corollaries.","ev":"hunts/set-card-arith/probe3.lean P7 `P7encard_biUnion` with `ht : {i ∈ t | (s i).Nonempty}.Finite` compiles, and applies to the ℕ-indexed family `if n = 0 then {0} else ∅`. Exit 0. Raised by Astra's A1 pass (item 5).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261006-875da0","file":"Mathlib/Data/Set/Countable.lean","decl":"Set.Countable","line":43,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-claims-abbrev-for-def","claim":"The docstring of `Set.Countable` says \"Note that this is an abbreviation, so `hs : Set.Countable s` in the proof context is the same as an instance `Countable s`.\" Both halves are false. `Set.Countable` is a plain `protected def`, and its reducibility status is `semireducible`, not an `abbrev`. A hypothesis `hs : s.Countable` is not picked up as a `Countable ↥s` instance: `inferInstance` fails with \"failed to synthesize Countable ↑s\". The same test with an `abbrev` copy (`abbrev MyCountable s : Prop := Countable s`) succeeds, so the docstring describes behaviour the real declaration does not have. The file itself contradicts the note: it calls `hs.to_subtype` 11 times, often as `have := hs.to_subtype`, precisely to turn the hypothesis into an instance.","fix":"Replace the note with: \"`Set.Countable` is a `def`, not an instance; use `hs.to_subtype` (e.g. `have := hs.to_subtype`) to get `Countable s` from `hs : s.Countable`.\"","ev":"hunts/set-countable/batch0/probe1.lean. P1: `#print Set.Countable` prints `protected def Set.Countable … := fun {α} s ↦ Countable ↑s`, and `getReducibilityStatus` gives `semireducible`. P2: `example {α : Type u} {s : Set α} (hs : s.Countable) : Countable s := inferInstance` fails with `failed to synthesize instance of type class Countable ↑s` (as expected). P2b: the same with `abbrev MyCountable` compiles. `grep -c to_subtype src.lean` = 11.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-df5323","file":"Mathlib/Data/Set/Countable.lean","decl":"Set.countable_univ","line":138,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-on-instance-lemma","claim":"`Set.countable_univ [Countable α] : (univ : Set α).Countable` is not `@[simp]`, unlike its twin `Set.finite_univ [Finite α] : (@univ α).Finite` (`@[simp]`, Mathlib/Data/Set/Finite/Basic.lean:499), so `simp` cannot close `(univ : Set ℕ).Countable` (\"simp made no progress\") while it closes `(univ : Set (Fin 3)).Finite`. A copy of the file with `@[simp]` added compiles, `by simp` then closes the goal, and `#lint only simpNF` passes (0 errors in 64 declarations).","fix":"Tag `Set.countable_univ` with `@[simp]`, as `Set.finite_univ` is (check downstream `simp` calls for breakage).","ev":"hunts/set-countable/batch1/probeA.lean lines 32-38: `example : (univ : Set (Fin 3)).Finite := by simp` compiles; `example : (univ : Set ℕ).Countable := by simp` fails with `simp made no progress`; hunts/set-countable/batch1/probeB.lean (copy of src.lean with `@[simp] theorem countable_univ`) compiles, `example : (Set.univ : Set ℕ).Countable := by simp` succeeds there, and `#lint only simpNF` reports 0 errors","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2ef119","file":"Mathlib/Data/Set/Countable.lean","decl":"Set.Countable.image","line":159,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-countable-twin-of-finite-api","claim":"The image lemma has no iff companion under injectivity: Mathlib has `Set.finite_image_iff (hi : InjOn f s) : (f '' s).Finite ↔ s.Finite` (Mathlib/Data/Set/Finite/Basic.lean:691) and `Set.infinite_image_iff`, but no `Set.countable_image_iff`; the two directions exist separately as `Set.Countable.image` and `Set.countable_of_injective_of_countable_image` (line 208). Name lookup confirms `Set.countable_image_iff`, `Set.InjOn.countable_image_iff` and `Set.Countable.image_iff` are all absent, and git grep over origin/master finds no other statement of the form `(f '' s).Countable ↔ s.Countable`. The lemma is a one-liner.","fix":"Add `theorem Set.countable_image_iff (hi : InjOn f s) : (f '' s).Countable ↔ s.Countable := ⟨countable_of_injective_of_countable_image hi, (·.image f)⟩`.","ev":"hunts/set-countable/batch1/probeA.lean: `theorem Set.countable_image_iff' {s : Set α} {f : α → β} (hi : InjOn f s) : (f '' s).Countable ↔ s.Countable := ⟨countable_of_injective_of_countable_image hi, (·.image f)⟩` compiles; the `#eval env.contains` check prints `Set.countable_image_iff: false`, `Set.InjOn.countable_image_iff: false`, `Set.Countable.image_iff: false`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6e7ef4","file":"Mathlib/Data/Set/Countable.lean","decl":"Set.Countable.preimage","line":182,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-countable-twin-of-finite-api","claim":"The preimage lemmas have no converse: `Set.Finite` has `Set.Finite.of_preimage (h : (f ⁻¹' s).Finite) (hf : Surjective f) : s.Finite` (Mathlib/Data/Set/Finite/Basic.lean:605) and `Set.finite_of_finite_preimage (h : (f ⁻¹' s).Finite) (hs : s ⊆ range f) : s.Finite` (line 601), but there is no `Set.Countable.of_preimage` or `Set.countable_of_countable_preimage` (name lookup returns false; no git grep hit over origin/master). Both are one-liners from `Countable.image`.","fix":"Add `Set.Countable.of_preimage (h : (f ⁻¹' s).Countable) (hf : Surjective f) : s.Countable := image_preimage_eq s hf ▸ h.image f` and the `s ⊆ range f` variant `countable_of_countable_preimage`.","ev":"hunts/set-countable/batch1/probeA.lean: `theorem Set.Countable.of_preimage' {s : Set β} {f : α → β} (h : (f ⁻¹' s).Countable) (hf : Surjective f) : s.Countable := image_preimage_eq s hf ▸ h.image f` and `theorem Set.countable_of_countable_preimage' ... (hs : s ⊆ range f) : s.Countable := image_preimage_eq_of_subset hs ▸ h.image f` both compile; `#eval env.contains` prints false for `Set.Countable.of_preimage` and `Set.countable_of_countable_preimage`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c2646c","file":"Mathlib/Data/Set/Countable.lean","decl":"Set.Countable.of_sdiff","line":242,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-countable-analogue-of-finite-api","claim":"`Countable.of_sdiff` lacks its forward companion `Set.Countable.sdiff : s.Countable → (s \\ t).Countable`. The Finite file has `@[simp] Finite.sdiff` (Mathlib/Data/Set/Finite/Basic.lean:539) next to `Finite.of_sdiff` (L543). `Finite.inter_of_left/right` (L524/527) also have no Countable analogues, so simp cannot close `(s \\ t).Countable` from `hs` the way it does for Finite.","fix":"Add `@[simp] theorem Countable.sdiff (hs : s.Countable) : (s \\ t).Countable := hs.mono sdiff_subset` (and `inter_of_left/right`) beside `Countable.of_sdiff`.","ev":"hunts/set-countable/batch2/probe1.lean P4: `#check @Set.Countable.sdiff` / `@Set.Countable.diff` / `@Set.Countable.inter_of_left` -> Unknown constant; `#check @Set.Finite.sdiff` -> `s.Finite → (s \\ t).Finite`; `example {s : Set α} (hs : s.Countable) (t : Set α) : (s \\ t).Countable := hs.mono diff_subset` compiles","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b28ca8","file":"Mathlib/Data/Set/Countable.lean","decl":"Set.Countable.of_preimage_singleton","line":291,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"typeclass-stronger-than-needed","claim":"`[Countable β]` is stronger than needed: `(range f).Countable` is enough. The set-relative form `(f '' s).Countable → (∀ b ∈ f '' s, (s ∩ f ⁻¹' {b}).Countable) → s.Countable`, which is the analogue of `Set.Finite.of_finite_fibers` (Mathlib/Data/Set/Finite/Lattice.lean:234), is missing from Mathlib (`git grep` for `of_countable_fibers|countable_of_fiber|countable_fibers` gives no results). That form is one line, and both the current lemma and the `(range f).Countable` version follow from it in one line. The lemma has no consumers in Mathlib.","fix":"Add `Set.Countable.of_countable_fibers (f) (himage : (f '' s).Countable) (hfibers : ∀ x ∈ f '' s, (s ∩ f ⁻¹' {x}).Countable) : s.Countable` mirroring `Set.Finite.of_finite_fibers`, and derive this lemma from it (or restate it with `(range f).Countable`).","ev":"hunts/set-countable/batch3/Probe.lean L24-39:\ntheorem Set.Countable.of_countable_fibers_probe (f : α → β) {s : Set α}\n    (himage : (f '' s).Countable) (hfibers : ∀ x ∈ f '' s, (s ∩ f ⁻¹' {x}).Countable) :\n    s.Countable :=\n  (himage.biUnion hfibers).mono fun x hx ↦\n    mem_iUnion₂.2 (by exact ⟨f x, mem_image_of_mem f hx, hx, rfl⟩)\n\nexample {f : α → β} (hr : (range f).Countable) (h : ∀ b, (f ⁻¹' {b}).Countable) :\n    Countable α :=\n  countable_univ_iff.1 <| .of_countable_fibers_probe f (by rwa [image_univ])\n    fun b _ ↦ (h b).mono inter_subset_right\n\nexample {f : α → β} [Countable β] (h : ∀ b, (f ⁻¹' {b}).Countable) : Countable α :=\n  countable_univ_iff.1 <| .of_countable_fibers_probe f (countable_univ.mono (subset_univ _))\n    fun b _ ↦ (h b).mono inter_subset_right","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-41beae","file":"Mathlib/Data/Set/Countable.lean","decl":"Set.Countable.prod","line":304,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-converse-api","claim":"`Set.Countable.prod` has no converse. Mathlib lacks set-level analogues of `Set.Finite.of_prod_left`, `Set.Finite.of_prod_right` and the iff `Set.finite_prod` (Mathlib/Basic/Finite/Prod.lean:155,158,177); only the type-level `countable_left_of_prod_of_nonempty` and `countable_right_of_prod_of_nonempty` exist (Mathlib/Basic/Countable/Basic.lean:102,106). `git grep -E 'Countable\\.of_prod|countable_prod'` finds no set-level lemma. Each converse is one line from `Countable.image` and `fst_image_prod` or `snd_image_prod`.","fix":"Add `Set.Countable.of_prod_left`, `Set.Countable.of_prod_right` and `Set.countable_prod : (s ×ˢ t).Countable ↔ (s.Countable ∨ t = ∅) ∧ (t.Countable ∨ s = ∅)`, mirroring the `Set.Finite` API.","ev":"hunts/set-countable/batch3/Probe.lean L55-70:\ntheorem Set.Countable.of_prod_left_probe {s : Set α} {t : Set β} (h : (s ×ˢ t).Countable)\n    (ht : t.Nonempty) : s.Countable :=\n  fst_image_prod s ht ▸ h.image Prod.fst\n\ntheorem Set.Countable.of_prod_right_probe {s : Set α} {t : Set β} (h : (s ×ˢ t).Countable)\n    (hs : s.Nonempty) : t.Countable :=\n  snd_image_prod hs t ▸ h.image Prod.snd\n\ntheorem countable_prod_probe {s : Set α} {t : Set β} :\n    (s ×ˢ t).Countable ↔ (s.Countable ∨ t = ∅) ∧ (t.Countable ∨ s = ∅) := by\n  obtain rfl | hs := s.eq_empty_or_nonempty\n  · simp\n  obtain rfl | ht := t.eq_empty_or_nonempty\n  · simp\n  simp only [hs.ne_empty, ht.ne_empty, or_false]\n  exact ⟨fun h ↦ ⟨h.of_prod_left_probe ht, h.of_prod_right_probe hs⟩, fun h ↦ h.1.prod h.2⟩","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-52577c","file":"Mathlib/Data/Set/Countable.lean","decl":"Finset.countable_toSet","line":339,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`Finset.finite_toSet` is `@[simp]` (Mathlib/Data/Set/Finite/Basic.lean:362-363) but its countable counterpart `Finset.countable_toSet` is not. `simp` therefore proves `(↑s : Set α).Finite` but cannot prove `(↑s : Set α).Countable`, a side condition that appears throughout MeasureTheory (`measure_biUnion`, `lintegral_biUnion₀`, ...), where callers pass `s.countable_toSet` by hand.","fix":"Tag `Finset.countable_toSet` with `@[simp]`.","ev":"hunts/set-countable/batch3/Probe.lean L12-19:\nexample (s : Finset α) : (s : Set α).Finite := by simp\nexample (s : Finset α) : (s : Set α).Countable := by\n  fail_if_success simp\n  exact s.countable_toSet\nattribute [local simp] Finset.countable_toSet in\nexample (s : Finset α) : (s : Set α).Countable := by simp\n(all compile; also Copy.lean adds `@[simp]` at L324 and `example (s : Finset α) : (s : Set α).Countable := by simp` compiles there)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-6c4033","file":"Mathlib/Data/Set/Finite/Basic.lean","decl":"Finset.exists_notMem","line":854,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `Infinite.exists_notMem_finset` (Data.Fintype.EquivFin), `Finset.exists_notMem` (Data.Set.Finite.Basic) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: `Finset.exists_notMem (s)` is the dot-notation twin (`s.exists_notMem`) of `Infinite.exists_notMem_finset (s)`, re-proved through Set.Finite.exists_notMem. Declare it as an alias of the lower-in-import-graph EquivFin lemma, which has 8 uses.","fix":"Declare `Finset.exists_notMem` as an `alias` of `Infinite.exists_notMem_finset`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-4390f7","file":"Mathlib/Data/Set/Finite/Basic.lean","decl":"Finset.exists_card_eq","line":940,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Finset.exists_card_eq` (Data.Set.Finite.Basic), `Infinite.exists_subset_card_eq` (Data.Fintype.EquivFin) state exactly the same thing (Lean-checked). Reviewer: `[Infinite α] → ∃ s : Finset α, #s = n` proved twice (by induction vs via `natEmbedding`). Data/Set/Finite/Basic imports Data/Fintype/EquivFin. Keep the lower `Infinite.exists_subset_card_eq` (more uses, docstring cross-referenced with `exists_superset_card_eq`), deprecate `Finset.exists_card_eq` (2 uses), or alias it if the implicit-α form is wanted.","fix":"Deprecate `Finset.exists_card_eq` in favour of `Infinite.exists_subset_card_eq`.","ev":"dupscan/Check.lean: `example := (@Infinite.exists_subset_card_eq : type_of% @Finset.exists_card_eq)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 8, rating MINOR): Use the reviewer’s alias option if preserving implicit-α elaboration and discoverability under `Finset` matters. Sharing one proof is sensible, but the two calling interfaces have some value.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-ceb3d3","file":"Mathlib/Data/Set/Insert.lean","decl":"Set.set_compr_eq_eq_singleton","line":221,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Set.set_compr_eq_eq_singleton` (Data.Set.Insert), `Set.ofPred_eq_eq_singleton` (Data.Set.Insert) state exactly the same thing (Lean-checked). Reviewer: Same file, both `{b | b = a} = {a}` by rfl. `ofPred_eq_eq_singleton` is @[simp] and the target of the 2026-07-09 rename from `setOf_eq_eq_singleton`; `set_compr_eq_eq_singleton` is unused. Keep the former, deprecate the latter.","fix":"Deprecate `Set.set_compr_eq_eq_singleton` in favour of `Set.ofPred_eq_eq_singleton`.","ev":"dupscan/Check.lean: `example := (@Set.ofPred_eq_eq_singleton : type_of% @Set.set_compr_eq_eq_singleton)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 6, rating MAJOR): The existing renamed simp lemma already handles this comprehension exactly; the unused spelling supplies no separate interface.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-1fd6c9","file":"Mathlib/Data/Set/Lattice/Bounded.lean","decl":"Set.union_distrib_iInter₂_left","line":514,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Set.union_distrib_iInter₂_left` (Data.Set.Lattice.Bounded), `Set.union_iInter₂` (Data.Set.Lattice.Bounded) state exactly the same thing (Lean-checked). Reviewer: Same file, both `(s ∪ ⋂ i j, t i j) = ⋂ i j, s ∪ t i j`, proved separately by `simp_rw` from two different one-index lemmas (`union_iInter` vs `union_distrib_iInter_left`, themselves a duplicate pair). Keep `union_iInter₂` (fits the `union_iInter`/`iInter₂_union` family), deprecate `union_distrib_iInter₂_left`.","fix":"Deprecate `Set.union_distrib_iInter₂_left` in favour of `Set.union_iInter₂`.","ev":"dupscan/Check.lean: `example := (@Set.union_iInter₂ : type_of% @Set.union_distrib_iInter₂_left)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 5, rating MAJOR): Both distribute the same fixed set over the same double intersection; the alternative proof and naming family add no functionality.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-a0b61f","file":"Mathlib/Data/Set/Lattice/Bounded.lean","decl":"Set.union_distrib_iInter_right","line":517,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Set.iInter_union` (Data.Set.Lattice.Indexed), `Set.union_distrib_iInter_right` (Data.Set.Lattice.Bounded) state exactly the same thing (Lean-checked). Reviewer: Both are `(⋂ i, s i) ∪ t = ⋂ i, s i ∪ t := iInf_sup_eq _ _`; Bounded.lean imports Indexed.lean. Keep `iInter_union`, which is lower in the import graph and pairs with union_iInter. Deprecate union_distrib_iInter_right, which is used only by its ₂-version; union_distrib_iInter_left versus union_iInter is likely the same situation.","fix":"Deprecate `Set.union_distrib_iInter_right` in favour of `Set.iInter_union`.","ev":"dupscan/Check.lean: `example := (@Set.union_distrib_iInter_right : type_of% @Set.iInter_union)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 10, rating MAJOR): The earlier theorem provides the identical rewrite with fewer imports; the later family can consistently use it.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-1808da","file":"Mathlib/Data/Set/Lattice/Bounded.lean","decl":"Set.union_distrib_iInter₂_right","line":520,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Set.iInter₂_union` (Data.Set.Lattice.Bounded), `Set.union_distrib_iInter₂_right` (Data.Set.Lattice.Bounded) state exactly the same thing (Lean-checked). Reviewer: Both are in the same file, with the same binders and the same `simp_rw` proof. The later block union_distrib_iInter{,₂}_{left,right} re-develops union_iInter₂/iInter₂_union and iInter_union. Keep iInter₂_union (fits the iInter_union family; used in AlgebraicGeometry/Scheme) and deprecate union_distrib_iInter₂_right.","fix":"Deprecate `Set.union_distrib_iInter₂_right` in favour of `Set.iInter₂_union`.","ev":"dupscan/Check.lean: `example := (@Set.union_distrib_iInter₂_right : type_of% @Set.iInter₂_union)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 3, rating MAJOR): There is no attribute or indexing distinction; `iInter₂_union` already covers precisely this dependent double intersection.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-5f9562","file":"Mathlib/Data/Set/Prod.lean","decl":"Set.subset_prod","line":357,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Set.subset_prod` (Data.Set.Prod), `Set.subset_fst_image_prod_snd_image` (Data.Set.Prod) state exactly the same thing (Lean-checked). Reviewer: Same file, same statement `s ⊆ (Prod.fst '' s) ×ˢ (Prod.snd '' s)`, proved separately (aesop and mem_prod). Keep the descriptive name, which has 2 uses. Deprecate the vague `subset_prod`, which has 1 use in MeasureTheory/Measure/Prod.","fix":"Deprecate `Set.subset_prod` in favour of `Set.subset_fst_image_prod_snd_image`.","ev":"dupscan/Check.lean: `example := (@Set.subset_fst_image_prod_snd_image : type_of% @Set.subset_prod)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 9, rating MAJOR): Both names have the same implicit-set interface in the same namespace, so retaining the descriptive name loses no distinct method or attribute.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-824595","file":"Mathlib/Data/String/Basic.lean","decl":"String.lt_iff_ltb","line":88,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"simp-lemma-into-implementation","claim":"`String.lt_iff_ltb` is `@[simp]`, so `simp` rewrites every `s < t` on strings into `String.ltb (String.Legacy.iter s) (String.Legacy.iter t) = true`, a legacy iterator function with no order API. After `simp at h₁ h₂ ⊢`, a goal `s < u` from `s < t`, `t < u` can no longer be closed by `exact?` (no transitivity for `ltb`). The order on `String` is the `LinearOrder` instance of this file, so the simp normal form should stay `<` (or `toList <`).","fix":"Remove `@[simp]` from `lt_iff_ltb` (it remains usable as `rw`/`simp only` for `decide`-style evaluation).","ev":"probe1.lean: after `simp at h`, `h : String.ltb (String.Legacy.iter s) (String.Legacy.iter t) = true`; second example: `simp at h₁ h₂ ⊢; exact?` → could not close the goal.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-dd12be","file":"Mathlib/Data/String/Basic.lean","decl":"String.le_iff_not_lt","line":135,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reproves-core-lemma","claim":"The `LinearOrder String` instance re-derives `le_refl`, `le_trans`, `le_antisymm` and `le_total` through `le_iff_toList_le`, although core already provides `String.le_refl`, `String.le_trans`, `String.le_antisymm` and `String.le_total` with exactly these statements, and the private helper `String.le_iff_not_lt` is `String.not_lt.symm` from core.","fix":"Use the core lemmas in the instance fields and delete the private helper (or build the instance with `LinearOrder.ofStd`).","ev":"probe2.lean: `#check @String.le_refl/le_trans/le_antisymm/le_total` resolve to core declarations with the instance fields' statements; `s ≤ t ↔ ¬ t < s := String.not_lt.symm` compiles.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-077a46","file":"Mathlib/Data/Subtype.lean","decl":"Subtype.val_prop","line":214,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Subtype.coe_prop` (Data.Subtype), `Subtype.val_prop` (Data.Subtype) state exactly the same thing (Lean-checked). Reviewer: These are adjacent. Because coe is `.val` in Lean 4, `val_prop` (1 use) duplicates `coe_prop` (@[simp], about 39 uses); the pair is a mathlib3 relic. Keep coe_prop.","fix":"Deprecate `Subtype.val_prop` in favour of `Subtype.coe_prop`.","ev":"dupscan/Check.lean: `example := (@Subtype.val_prop : type_of% @Subtype.coe_prop)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 11, rating MAJOR): `val_prop` exposes no different projection or simplification behavior; `coe_prop` already covers the same term.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-b9e268","file":"Mathlib/Data/Sym/Sym2.lean","decl":"Sym2.ball","line":371,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Sym2.ball` (Data.Sym.Sym2), `Sym2.forall_mem_pair` (Data.Sym.Sym2) state exactly the same thing (Lean-checked). Reviewer: Same file, `(∀ c ∈ s(a, b), p c) ↔ p a ∧ p b` proved twice. `ball` is Lean-3-style naming with zero uses; `forall_mem_pair` follows current naming and is used (`pair_eq_pmap`). Keep `forall_mem_pair`, deprecate `Sym2.ball`.","fix":"Deprecate `Sym2.ball` in favour of `Sym2.forall_mem_pair`.","ev":"dupscan/Check.lean: `example := (@Sym2.forall_mem_pair : type_of% @Sym2.ball)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 12, rating MAJOR): `ball` has no special eliminator or binder behavior, and `forall_mem_pair` describes the statement directly.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-bf506b","file":"Mathlib/Data/ZMod/Basic.lean","decl":"ZMod.val_cast_of_lt","line":1009,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `ZMod.val_cast_of_lt` (Data.ZMod.Basic), `ZMod.val_natCast_of_lt` (Data.ZMod.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file: `a < n → (a : ZMod n).val = a` is proved at line 95 and again at line 1009, both via val_natCast and Nat.mod_eq_of_lt. Keep val_natCast_of_lt (current natCast naming, used by val_ofNat_of_lt) and deprecate ZMod.val_cast_of_lt (about 9 uses; Fin.val_cast_of_lt is a different lemma).","fix":"Deprecate `ZMod.val_cast_of_lt` in favour of `ZMod.val_natCast_of_lt`.","ev":"dupscan/Check.lean: `example := (@ZMod.val_natCast_of_lt : type_of% @ZMod.val_cast_of_lt)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 13, rating MAJOR): Both concern natural-number casts with identical hypotheses; there is no separate cast operation or normalization role to preserve.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-948dec","file":"Mathlib/Dynamics/SymbolicDynamics/Basic.lean","decl":"(module docstring)","line":47,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-docstring","claim":"The module docstring's 'Main definitions' lists `subshift_of_finite_type F`, which exists nowhere in Mathlib, and `languageOn X U`, whose actual name is `LanguageOn`; its namespacing policy says subshift-relative wrappers live in `SymbolicDynamics.Subshift`, but `MulSubshift.languageOn` (and `Subshift` itself) are in `SymbolicDynamics.FullShift`; 'Closeness results' (closedness).","fix":"Remove the nonexistent entry, use the real names and namespaces.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-b59d03","file":"Mathlib/Dynamics/SymbolicDynamics/Basic.lean","decl":"SymbolicDynamics.FullShift.mulShift","line":150,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-claims-more","claim":"The module docstring describes `shift` as 'using the **left** action of G on configurations', but `(mulShift g x) h = x (g * h)` gives a *right* action for noncommutative G: `mulShift_mul` states `mulShift (g₁ * g₂) = mulShift g₂ ∘ mulShift g₁`. The file explicitly targets noncommutative groups and monoids, where the distinction matters (the standard left shift on A^G is x ↦ (h ↦ x (g⁻¹ h))).","fix":"Say it is the right action by left translation (or switch to the left-action convention for groups).","ev":"example (g₁ g₂ : G) : (mulShift (A := A) (g₁ * g₂)) = mulShift g₂ ∘ mulShift g₁ := by\n  funext x; exact mulShift_mul g₁ g₂ x","evr":"compiles","astraV":"agrees","astraS":"Blind pass flagged the same point as P1: S_{gh} = S_h ∘ S_g, a right action (left action of Gᵐᵒᵖ); Perm (Fin 3) test distinguishes the orders.","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-953b9b","file":"Mathlib/Dynamics/SymbolicDynamics/Basic.lean","decl":"SymbolicDynamics.FullShift.MulSubshift","line":253,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"`MulSubshift`/`Subshift` (a carrier set plus two properties) have no `SetLike` instance, `@[ext]` lemma or membership API, and `Pattern` has no `@[ext]`; even equality of two subshifts with the same carrier needs a manual `cases`.","fix":"Add `SetLike (MulSubshift A G) (G → A)` with `@[ext]`, and `@[ext] Pattern.ext`.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-61dad6","file":"Mathlib/Dynamics/SymbolicDynamics/Basic.lean","decl":"SymbolicDynamics.FullShift.Pattern.mulShift_apply_mul_left_of_mem","line":414,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-hypothesis","claim":"`mulShift_apply_mul_left_of_mem`'s hypothesis `hw : w ∈ p.support` is unnecessary: under left cancellation `p.mulShift v (v * w) = p.config w` for every w (outside the support both sides are `default`).","fix":"Drop `hw` (rename `mulShift_apply_mul_left`).","ev":"example {A G : Type*} [Inhabited A] [Monoid G] [IsLeftCancelMul G] (p : Pattern A G) (v w : G) :\n    p.mulShift v (v * w) = p.config w := by\n  classical\n  by_cases hw : w ∈ p.support\n  · exact Pattern.mulShift_apply_mul_left_of_mem p v w hw\n  · simp only [Pattern.mulShift, Finset.mem_image, mul_right_inj, exists_eq_right, hw, dite_false, p.condition w hw]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-c703d0","file":"Mathlib/Dynamics/SymbolicDynamics/Basic.lean","decl":"SymbolicDynamics.FullShift.Pattern.mulOccursInAt_mulShift","line":443,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-claims-more","claim":"Several docstring formulas are wrong: `mulOccursInAt_mulShift` says p occurs in `mulShift h x` at g iff it occurs in x at `g * h` (the statement gives `h * g`; the additive docstring's `g + h` is wrong for noncommutative additive monoids); 'Why cancellativity?' displays `w + v = h`, which needs right cancellation, while the code solves `v + w = h`, and promises a unique solution although cancellation gives at most one; `mulShift`'s example 'G = ℤ (with addition) … mulShift 1 x shifts one step' is false since `mulShift (1 : ℤ) x = x`; the implementation note 'Closeness results use [T1Space A]' covers `isClosed_mulForbidden`, which needs discreteness (alphabet ℝ, forbidding the one-site pattern 0 gives the non-closed ℝ \\ {0}).","fix":"Correct the formulas (h * g; v + w = h, at most one solution; use `shift (1 : ℤ)`), and restrict the T1 note to cylinders/occurrence sets.","ev":"#check @Pattern.mulOccursInAt_mulShift\n-- p.mulOccursInAt (mulShift g x) h ↔ p.mulOccursInAt x (g * h)\nexample (x : ℤ → Bool) : mulShift (1 : ℤ) x = x := mulShift_one x","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-dffccd","file":"Mathlib/Dynamics/SymbolicDynamics/Basic.lean","decl":"SymbolicDynamics.FullShift.isOpen_mulOccursInAt","line":519,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`isOpen_mulOccursInAt`, `isClosed_mulOccursInAt`, `isClosed_mulForbidden` and `MulSubshift.ofForbidden` (and their additive versions) carry `[IsLeftCancelMul G]` only because they go through the cylinder description; directly, an occurrence set is the finite intersection ⋂_{h ∈ support} {x | x (g * h) = p.config h}, open (discrete A) and closed (T1 A) over any monoid, so subshifts defined by forbidden patterns exist over every monoid.","fix":"Prove the topological facts from the finite-intersection description and move them (and `ofForbidden`) out of the `IsLeftCancelMul` section.","ev":"variable {A : Type*} [TopologicalSpace A] [Inhabited A] {G : Type*} [Monoid G]\ntheorem isOpen_occ [DiscreteTopology A] (p : Pattern A G) (g : G) :\n    IsOpen { x : G → A | p.mulOccursInAt x g } := by\n  have : { x : G → A | p.mulOccursInAt x g } = ⋂ h ∈ p.support, {x | x (g * h) = p.config h} := by\n    ext x; simp [Pattern.mulOccursInAt]\n  rw [this]\n  exact isOpen_biInter_finset fun h _ ↦\n    (isOpen_discrete {p.config h}).preimage (continuous_apply (A := fun _ : G ↦ A) (g * h))\nexample [DiscreteTopology A] (F : Set (Pattern A G)) : IsClosed (mulForbidden F) := by\n  have : mulForbidden F = ⋂ p ∈ F, ⋂ v : G, {x | p.mulOccursInAt x v}ᶜ := by ext; simp [mulForbidden]\n  rw [this]\n  exact isClosed_biInter fun p _ ↦ isClosed_iInter fun v ↦ (isOpen_occ p v).isClosed_compl","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-5ecfdd","file":"Mathlib/Dynamics/SymbolicDynamics/Basic.lean","decl":"SymbolicDynamics.FullShift.LanguageOn","line":621,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"name-casing","claim":"`LanguageOn` is a `Set (Pattern A G)`-valued definition named in UpperCamelCase (reserved for types and props/structures); its own lemmas (`languageOn_mono`, `languageOn_union`, `languageOn_inter_subset`) and the wrapper `MulSubshift.languageOn` use `languageOn`.","fix":"Rename to `languageOn` (with a deprecated alias).","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-e8c540","file":"Mathlib/Dynamics/SymbolicDynamics/Basic.lean","decl":"SymbolicDynamics.FullShift.LanguageOn","line":621,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reprovable-from-existing-api","claim":"Existing Mathlib constructions are rebuilt without bridges: `LanguageOn X U` is by `rfl` the image `(Pattern.fromConfig · U) '' X`, so `languageOn_mono`/`_union`/`_inter_subset` are `Set.image_mono`/`image_union`/`image_inter_subset`; `mulShift g x` is by `rfl` `DomMulAct.mk g • x`; `Pattern.mulShift` re-implements `Function.extend`; `cylinder` overlaps `PiNat.cylinder` with no comparison lemma.","fix":"Define `LanguageOn` as the image and derive the lemmas from `Set.image_*`; add `mulShift_eq_domMulAct_smul`; relate `Pattern.mulShift` to `Function.extend` and `cylinder` to `PiNat.cylinder`.","ev":"example {A G : Type*} [Monoid G] (g : G) (x : G → A) : mulShift g x = DomMulAct.mk g • x := rfl\nexample {A G : Type*} [Inhabited A] (X : Set (G → A)) (U : Finset G) :\n    LanguageOn X U = (fun x => Pattern.fromConfig x U) '' X := rfl","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-7f8ac6","file":"Mathlib/Dynamics/SymbolicDynamics/Basic.lean","decl":"SymbolicDynamics.FullShift.MulSubshift.languageOn","line":649,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-to-additive","claim":"`MulSubshift.languageOn` has no `@[to_additive]`, so the additive `Subshift` (the documented main notation of the file) has no `languageOn`: `SymbolicDynamics.FullShift.Subshift.languageOn` is an unknown constant.","fix":"Tag it `@[to_additive]`.","ev":"#check @SymbolicDynamics.FullShift.Subshift.languageOn  -- Unknown constant","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261007-327c79","file":"Mathlib/FieldTheory/Fixed.lean","decl":"linearIndependent_toLinearMap","line":309,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `linearIndependent_algHom_toLinearMap` (LinearAlgebra.LinearIndependent.Lemmas), `linearIndependent_toLinearMap` (FieldTheory.Fixed) state exactly the same thing (Lean-checked). Reviewer: Dedekind/Artin linear independence of `AlgHom.toLinearMap` proved twice with the same argument (`linearIndependent_monoidHom` + `LinearMap.ltoFun`). Keep `linearIndependent_algHom_toLinearMap` (lower in the import graph, @[stacks 0CKM], more uses), deprecate `linearIndependent_toLinearMap` in FieldTheory/Fixed.","fix":"Deprecate `linearIndependent_toLinearMap` in favour of `linearIndependent_algHom_toLinearMap`.","ev":"dupscan/Check.lean: `example := (@linearIndependent_toLinearMap : type_of% @linearIndependent_algHom_toLinearMap)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 32, rating MAJOR): There is no algebra-hom versus linear-map distinction between these statements; retain the lower-import theorem and its Stacks attribution.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-927044","file":"Mathlib/Geometry/Convex/ConvexSpace/Barycenter.lean","decl":"Convexity.StdSimplex.subBarycenter","line":22,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"The section assumes `[Field K] [CharZero K] [LinearOrder K] [IsStrictOrderedRing K]`, but `CharZero` already follows from the strict ordered ring (`IsStrictOrderedRing.toCharZero`), and subtraction is never used: the whole file compiles with `[Semifield K] [LinearOrder K] [IsStrictOrderedRing K]`, admitting e.g. `K = ℝ≥0`.","fix":"Use `variable {K M : Type*} [Semifield K] [LinearOrder K] [IsStrictOrderedRing K]`.","ev":"-- hunts/barycenter/ProbeSemi.lean: the file with `[Semifield K] [LinearOrder K] [IsStrictOrderedRing K]` (no CharZero) compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-dadf79","file":"Mathlib/Geometry/Convex/ConvexSpace/Barycenter.lean","decl":"Convexity.StdSimplex.subBarycenter_weights_apply_eq_zero","line":32,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reprovable-from-existing-api","claim":"The 7-line proof of `subBarycenter_weights_apply_eq_zero` redoes `Finsupp.indicator_of_notMem`: the weights are `Finsupp.indicator S (fun _ _ ↦ (S.card)⁻¹)` by `Finsupp.indicator_eq_sum_single`, giving a 2-line proof. The name also breaks the `weights_` projection prefix used by `weights_subBarycenter`/`weights_barycenter_apply`.","fix":"`rw [weights_subBarycenter, ← Finsupp.indicator_eq_sum_single]; exact Finsupp.indicator_of_notMem hm _`; rename to `weights_subBarycenter_apply_of_notMem`.","ev":"example (S : Finset M) (hS : S.Nonempty) (m : M) (hm : m ∉ S) :\n    (subBarycenter (K := K) S hS).weights m = 0 := by\n  rw [weights_subBarycenter, ← Finsupp.indicator_eq_sum_single]\n  exact Finsupp.indicator_of_notMem hm _","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-e8892f","file":"Mathlib/Geometry/Convex/ConvexSpace/Barycenter.lean","decl":"Convexity.StdSimplex.barycenter_of_unique","line":57,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`barycenter_of_unique` has `[Unique M]` but no `[Fintype M]`, so it uses `Unique.fintype` and cannot be applied when the caller's own `Fintype M` instance is in scope (`exact barycenter_of_unique` fails: 'typeclass instance problem is stuck'). The coordinate lemmas `weights_barycenter_apply` and `subBarycenter_weights_apply_eq_zero` are not `@[simp]` (and `weights_subBarycenter` is `-isSimp`), so `simp` cannot compute any weight, unlike the deprecated `stdSimplex.barycenter_apply`; the value on `S` (`(S.card)⁻¹`) and `support = S` are missing, and the deprecated `stdSimplex.barycenter_eq_centerMass` has 'no replacement' bridging to `Finset.centerMass`/`centroidWeightsIndicator`.","fix":"Add `[Fintype M]` to `barycenter_of_unique`; tag the coordinate lemmas simp; add `weights_subBarycenter_apply` (if-then-else) and a centroid bridge.","ev":"example [Fintype M] [Nonempty M] (m : M) :\n    (barycenter (K := K) (M := M)).weights m = (Fintype.card M : K)⁻¹ := by simp   -- `simp` made no progress\nexample [Fintype M] [Unique M] : barycenter (K := K) (M := M) = .single default := by\n  exact barycenter_of_unique   -- typeclass instance problem is stuck","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-926a8e","file":"Mathlib/Geometry/Euclidean/Inversion/Calculus.lean","decl":"ContDiffWithinAt.inversion","line":41,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"contdiff-order-nat-enat","claim":"The four smoothness lemmas `ContDiffWithinAt/ContDiffOn/ContDiffAt/ContDiff.inversion` take `{n : ℕ∞}`, so they cannot be used at `n = ω` (analyticity), although `ContDiff` is indexed by `WithTop ℕ∞` and the same one-line proof works there: inversion is analytic away from its centre.","fix":"Change the section variable to `{n : WithTop ℕ∞}`; the proofs are unchanged.","ev":"Copy.lean appended `example` with `{n : WithTop ℕ∞}` and the proof of `ContDiffWithinAt.inversion` compiles.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-57e56c","file":"Mathlib/Geometry/Group/WordMetric.lean","decl":"(module docstring)","line":24,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-docstring","claim":"The module docstring's Main definitions list `Group.Generators.wordNorm` ('the word length as a norm on G') and describe `normedGroup` as 'induced by wordNorm', but no `wordNorm` exists — the norm is `Group.Generators.groupNorm`; also 'it.The definition' (missing space) and 'superceded'.","fix":"Replace `wordNorm` by `groupNorm`; fix the typos.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261007-f5faf6","file":"Mathlib/Geometry/Manifold/Algebra/Monoid.lean","decl":"ContMDiffAt.prod","line":328,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `contMDiffAt_finsetProd` (Geometry.Manifold.Algebra.Monoid), `ContMDiffAt.prod` (Geometry.Manifold.Algebra.Monoid) state exactly the same thing (Lean-checked). Reviewer: Same file: ContMDiffAt.prod and contMDiffAt_finsetProd have the same hypothesis `∀ i ∈ t, CMDiffAt n (f i) x` and conclusion. The ContMDiffAt.* name cannot be used with dot notation (the hypothesis is a ∀), so it is not an intended twin (ContMDiffWithinAt.prod/ContMDiff.prod likewise). Keep the finsetProd family (renamed 2026-04-08).","fix":"Deprecate `ContMDiffAt.prod` in favour of `contMDiffAt_finsetProd`.","ev":"dupscan/Check.lean: `example := (@ContMDiffAt.prod : type_of% @contMDiffAt_finsetProd)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 14, rating MAJOR): The quantified hypothesis does not support the usual `ContMDiffAt` proof-method notation, and neither declaration has a distinguishing attribute.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-901e7d","file":"Mathlib/Geometry/Manifold/Algebra/Monoid.lean","decl":"ContMDiffWithinAt.prod","line":328,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `contMDiffWithinAt_finsetProd` (Geometry.Manifold.Algebra.Monoid), `ContMDiffWithinAt.prod` (Geometry.Manifold.Algebra.Monoid) state exactly the same thing (Lean-checked). Reviewer: Same file, two parallel families for finite products (`ContMDiffWithinAt.prod` by induction; `contMDiffWithinAt_finsetProd` via the primed version), both @[to_additive], no comment. `ContMDiff*.prod` cannot be used with dot notation (its hypothesis is `∀ i ∈ t, ...`) and has no uses outside the file. Keep the `contMDiff*_finsetProd` family (complete with primed and `finprod` versions, renamed 2026-04-08), deprecate `ContMDiffWithinAt.prod`.","fix":"Deprecate `ContMDiffWithinAt.prod` in favour of `contMDiffWithinAt_finsetProd`.","ev":"dupscan/Check.lean: `example := (@ContMDiffWithinAt.prod : type_of% @contMDiffWithinAt_finsetProd)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 15, rating MAJOR): The separate induction proves the same finite-product closure result. Updating the internal `finprod` proof and preserving additive translations suffices.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-96378f","file":"Mathlib/Geometry/Manifold/Algebra/Monoid.lean","decl":"ContMDiff.prod","line":328,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `ContMDiff.prod` (Geometry.Manifold.Algebra.Monoid), `contMDiff_finsetProd` (Geometry.Manifold.Algebra.Monoid) state exactly the same thing (Lean-checked). Reviewer: `ContMDiff.prod` and `contMDiff_finsetProd` have the same hypothesis (∀ i ∈ t, …) and conclusion and are proved separately; dot notation does not apply because the hypothesis is a ∀. The same doubling exists for ContMDiffAt.prod and ContMDiffWithinAt.prod. Keep the root finsetProd family, which was renamed with deprecations in 2026-04 and matches finprod/finsetProd'/contMDiffOn_finsetProd. Deprecate the `.prod` trio, whose name also suggests a product of maps; none of them has external uses.","fix":"Deprecate `ContMDiff.prod` in favour of `contMDiff_finsetProd`.","ev":"dupscan/Check.lean: `example := (@contMDiff_finsetProd : type_of% @ContMDiff.prod)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 18, rating MAJOR): The root family already covers this exact product expression and its related variants; `.prod` provides neither a usable proof method nor special attributes here.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-cb8e85","file":"Mathlib/Geometry/Manifold/Algebra/Monoid.lean","decl":"ContMDiffWithinAt.sum","line":358,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `contMDiffWithinAt_finsetSum` (Geometry.Manifold.Algebra.Monoid), `ContMDiffWithinAt.sum` (Geometry.Manifold.Algebra.Monoid) state exactly the same thing (Lean-checked). Reviewer: These are the to_additive images of `contMDiffWithinAt_finsetProd` and `ContMDiffWithinAt.prod`. Both state `∀ i ∈ t, CMDiffAt[s] n (f i) x → CMDiffAt[s] n (fun x ↦ ∏ i ∈ t, f i x) x` and are proved separately (finsetProd' versus Finset induction). This is the same doubling as group 27: keep the finsetProd/finsetSum family and deprecate the `.prod`/`.sum` names.","fix":"Deprecate `ContMDiffWithinAt.sum` in favour of `contMDiffWithinAt_finsetSum`.","ev":"dupscan/Check.lean: `example := (@ContMDiffWithinAt.sum : type_of% @contMDiffWithinAt_finsetSum)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 19, rating MAJOR): These additive declarations concern the same pointwise **sum**; the product expression in the reviewer’s prose is a typo. Their additive-generation roles do not justify retaining both names.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-1cc8bc","file":"Mathlib/Geometry/Manifold/Algebra/Monoid.lean","decl":"ContMDiffAt.sum","line":370,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `ContMDiffAt.sum` (Geometry.Manifold.Algebra.Monoid), `contMDiffAt_finsetSum` (Geometry.Manifold.Algebra.Monoid) state exactly the same thing (Lean-checked). Reviewer: Additive image of the `ContMDiffAt.prod`/`contMDiffAt_finsetProd` pair: same file, both @[to_additive], separately proved, no comment. Keep the `contMDiff*_finsetProd/Sum` family, deprecate `ContMDiffAt.prod/sum`, which cannot be used with dot notation (see the WithinAt group).","fix":"Deprecate `ContMDiffAt.sum` in favour of `contMDiffAt_finsetSum`.","ev":"dupscan/Check.lean: `example := (@contMDiffAt_finsetSum : type_of% @ContMDiffAt.sum)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 16, rating MAJOR): `to_additive` does not require both additive spellings; deprecate this through the corresponding multiplicative declarations while retaining their translation mappings.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-c9bcca","file":"Mathlib/Geometry/Manifold/Algebra/Monoid.lean","decl":"ContMDiff.sum","line":428,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `ContMDiff.sum` (Geometry.Manifold.Algebra.Monoid), `contMDiff_finsetSum` (Geometry.Manifold.Algebra.Monoid) state exactly the same thing (Lean-checked). Reviewer: Additive image of `ContMDiff.prod` vs `contMDiff_finsetProd`: same file, both @[to_additive], separately proved, no comment. Keep the `contMDiff_finsetProd/Sum` family, deprecate `ContMDiff.prod/sum` (no dot-notation use possible, no uses outside the file).","fix":"Deprecate `ContMDiff.sum` in favour of `contMDiff_finsetSum`.","ev":"dupscan/Check.lean: `example := (@contMDiff_finsetSum : type_of% @ContMDiff.sum)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 17, rating MAJOR): Both conclude smoothness of the same pointwise sum, and the `.sum` namespace supplies no proof-method advantage for the quantified hypothesis.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-ce21be","file":"Mathlib/Geometry/Manifold/IntegralCurve/Transform.lean","decl":"IsMIntegralCurveAt.comp_mul_ne_zero","line":126,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-hypothesis","claim":"Mirror of the ODE finding RT-20261007-401491: `IsMIntegralCurveAt.comp_mul_ne_zero` assumes `ha : a ≠ 0`, but at `a = 0` the rescaled curve `γ ∘ (· * 0)` is constant and the field `0 • v` vanishes, so the conclusion holds for every `a` (by `isMIntegralCurve_const`). The siblings `IsMIntegralCurveOn.comp_mul` and `IsMIntegralCurve.comp_mul` take no `a ≠ 0`; only the iff forms need it.","fix":"Drop `ha` and rename to `IsMIntegralCurveAt.comp_mul` (deprecated alias), together with the ODE version.","ev":"hunts/ode-transform/probe1.lean P3 `P3comp_mul` (the lemma without `ha`, the `a = 0` case via `isMIntegralCurve_const (v := 0 • v)`) compiles with exit 0. Found by the pattern sweep from Mathlib/Analysis/ODE/Transform.lean; this file is not yet audited.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-014b1e","file":"Mathlib/GroupTheory/Finiteness.lean","decl":"Semigroup.exists_of_isMulFG","line":129,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `IsMulFG.out` (GroupTheory.Finiteness), `Semigroup.exists_of_isMulFG` (GroupTheory.Finiteness) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: The class field is declared `out (M) : ∃ S : Finset M, Subsemigroup.closure S = ⊤`. Semigroup.exists_of_isMulFG (`variable (M) in`, proved by `isMulFG_iff.mp`) states exactly the projection. It is the intended Semigroup member of the Semigroup/Monoid/Group.exists_of_isMulFG family, so it could be `@[to_additive] alias … := IsMulFG.out`.","fix":"Declare `Semigroup.exists_of_isMulFG` as an `alias` of `IsMulFG.out`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-1fa540","file":"Mathlib/GroupTheory/FreeGroup/Reduce.lean","decl":"FreeAddGroup.reduce.rev","line":186,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `FreeAddGroup.Red.reduce_left` (GroupTheory.FreeGroup.Reduce), `FreeAddGroup.reduce.rev` (GroupTheory.FreeGroup.Reduce) state exactly the same thing (Lean-checked). Reviewer: Additive image of `FreeGroup.Red.reduce_left` vs `FreeGroup.reduce.rev`: same file, both @[to_additive], `Red L₁ L₂ → Red L₂ (reduce L₁)` with the identical proof term. Keep `Red.reduce_left` (pairs with `Red.reduce_right`, dot notation on the `Red` hypothesis), deprecate `reduce.rev` (2 uses at line 291).","fix":"Deprecate `FreeAddGroup.reduce.rev` in favour of `FreeAddGroup.Red.reduce_left`.","ev":"dupscan/Check.lean: `example := (@FreeAddGroup.reduce.rev : type_of% @FreeAddGroup.Red.reduce_left)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 20, rating MAJOR): `Red.reduce_left` already provides the additive theorem and useful proof-method interface; `reduce.rev` has no separate role.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-51983e","file":"Mathlib/GroupTheory/FreeGroup/Reduce.lean","decl":"FreeGroup.reduce.rev","line":186,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `FreeGroup.Red.reduce_left` (GroupTheory.FreeGroup.Reduce), `FreeGroup.reduce.rev` (GroupTheory.FreeGroup.Reduce) state exactly the same thing (Lean-checked). Reviewer: Same file, `Red L₁ L₂ → Red L₂ (reduce L₁)` with the identical proof `(reduce.eq_of_red h).symm ▸ reduce.red`. Keep `Red.reduce_left` (pairs with `Red.reduce_right` at 152, dot notation on the hypothesis), deprecate `reduce.rev` (2 uses at 291, and keep its docstring on the kept lemma).","fix":"Deprecate `FreeGroup.reduce.rev` in favour of `FreeGroup.Red.reduce_left`.","ev":"dupscan/Check.lean: `example := (@FreeGroup.reduce.rev : type_of% @FreeGroup.Red.reduce_left)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 21, rating MAJOR): The proposed survivor preserves the genuine dot-notation interface and its relationship with `reduce_right`; move the explanatory docstring with it.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-532ecd","file":"Mathlib/GroupTheory/GroupAction/Quotient.lean","decl":"AddAction.Quotient.vadd_coe","line":92,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `AddAction.Quotient.vadd_mk` (GroupTheory.GroupAction.Quotient), `AddAction.Quotient.vadd_coe` (GroupTheory.GroupAction.Quotient) state exactly the same thing (Lean-checked). Reviewer: These are to_additive of adjacent @[simp] rfl `Quotient.smul_mk` and `Quotient.smul_coe`. Since `(g : G ⧸ H)` is QuotientGroup.mk g, the statements coincide; this is a coe/mk relic. Keep `_mk` and deprecate `_coe`, migrating MulActionHom.toQuotient at l.120.","fix":"Deprecate `AddAction.Quotient.vadd_coe` in favour of `AddAction.Quotient.vadd_mk`.","ev":"dupscan/Check.lean: `example := (@AddAction.Quotient.vadd_coe : type_of% @AddAction.Quotient.vadd_mk)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 25, rating MAJOR): One simp theorem covers both spellings. Make the change together with the multiplicative pair so additive mappings remain coherent.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-b69533","file":"Mathlib/GroupTheory/GroupAction/Quotient.lean","decl":"MulAction.Quotient.smul_coe","line":97,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `MulAction.Quotient.smul_coe` (GroupTheory.GroupAction.Quotient), `MulAction.Quotient.smul_mk` (GroupTheory.GroupAction.Quotient) state exactly the same thing (Lean-checked). Reviewer: Adjacent @[to_additive (attr := simp)] rfl lemmas. `(g : G ⧸ H)` elaborates to QuotientGroup.mk g, so smul_coe is literally smul_mk. Each has 2-3 uses; keep smul_mk (used by mk_smul_out) and deprecate smul_coe.","fix":"Deprecate `MulAction.Quotient.smul_coe` in favour of `MulAction.Quotient.smul_mk`.","ev":"dupscan/Check.lean: `example := (@MulAction.Quotient.smul_mk : type_of% @MulAction.Quotient.smul_coe)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 22, rating MAJOR): Both simp rules match the same quotient-constructor expression; there is no separate coercion-normalization case.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-1b23b3","file":"Mathlib/GroupTheory/GroupAction/Quotient.lean","decl":"AddAction.Quotient.coe_vadd_out","line":106,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `AddAction.Quotient.coe_vadd_out` (GroupTheory.GroupAction.Quotient), `AddAction.Quotient.mk_vadd_out` (GroupTheory.GroupAction.Quotient) state exactly the same thing (Lean-checked). Reviewer: to_additive images of MulAction.Quotient.coe_smul_out (proved `by simp`) and @[simp] mk_smul_out: `↑(b • q.out)` is QuotientGroup.mk (b • q.out). Keep mk_* as in the smul_mk/smul_coe group; coe_smul_out has 2 uses.","fix":"Deprecate `AddAction.Quotient.coe_vadd_out` in favour of `AddAction.Quotient.mk_vadd_out`.","ev":"dupscan/Check.lean: `example := (@AddAction.Quotient.mk_vadd_out : type_of% @AddAction.Quotient.coe_vadd_out)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 23, rating MAJOR): `mk_vadd_out` already supplies the same simplification; the coercion spelling contributes neither a distinct expression nor an additional attribute.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-fa8063","file":"Mathlib/GroupTheory/GroupAction/Quotient.lean","decl":"MulAction.Quotient.coe_smul_out","line":106,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `MulAction.Quotient.mk_smul_out` (GroupTheory.GroupAction.Quotient), `MulAction.Quotient.coe_smul_out` (GroupTheory.GroupAction.Quotient) state exactly the same thing (Lean-checked). Reviewer: Adjacent: `QuotientGroup.mk (b • q.out) = b • q` (@[simp]) and the `↑(b • q.out)` coe version, which is just `by simp`. The coercion is QuotientGroup.mk, so they coincide. Keep `mk_smul_out` and deprecate `coe_smul_out` after migrating its 2 uses in Transfer and Haar/Quotient.","fix":"Deprecate `MulAction.Quotient.coe_smul_out` in favour of `MulAction.Quotient.mk_smul_out`.","ev":"dupscan/Check.lean: `example := (@MulAction.Quotient.coe_smul_out : type_of% @MulAction.Quotient.mk_smul_out)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 24, rating MAJOR): The coercion wrapper adds no behavior beyond the existing simp theorem, so migrating its explicit uses is sufficient.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-d41ef9","file":"Mathlib/GroupTheory/GroupAction/SubMulAction/Combination.lean","decl":"fixedPoints_ne_univ_of_faithfulSMul","line":185,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"nat-card-excludes-infinite","claim":"`fixedPoints_ne_univ_of_faithfulSMul` assumes `hn' : n < Nat.card α`, which is false for every infinite `α` (`Nat.card α = 0`), although the lemma it rests on, `faithfulSMul`, is stated with `n < ENat.card α` and the conclusion holds for infinite `α` (e.g. `Perm ℕ` on `powersetCard ℕ 1`). It also uses `0 < n` where its neighbours use `1 ≤ n`.","fix":"State it with `(hn' : n < ENat.card α)` (and `1 ≤ n` for consistency); its proof then needs no `Nat.card` conversion.","ev":"hunts/submulaction-combination/probe2.lean P3fixedPoints_ne_univ (with `n < ENat.card α`) compiles and is applied to `Perm ℕ` on `powersetCard ℕ 1`, where `Nat.card ℕ = 0`. Exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-1c3e93","file":"Mathlib/GroupTheory/GroupAction/SubMulAction/Combination.lean","decl":"fixedPoints_ne_univ_of_faithfulSMul","line":185,"sev":"MINOR","status":"suspected","cat":"generality","pattern":"hypothesis-stronger-than-needed","claim":"Astra argues (not formalised here) that further assumptions are stronger than needed: `fixedPoints_ne_univ_of_faithfulSMul` only needs a nontrivial action (`fixedPoints G (powersetCard α n) = univ ↔ fixedPoints G α = univ` in the proper-size range), not a faithful one; the backward direction of `mulAction_faithful` holds for every `n` without `hn`, `hα`; and `subMulAction` only needs `[SMul G α] [IsLeftCancelSMul G α]` (as `Finset.card_smul_finset` does), so e.g. translations of `ℕ` are excluded today.","fix":"Add the fixed-point equivalence, split `mulAction_faithful`'s easy direction out, and weaken `subMulAction` to left-cancellative actions.","ev":"Suspected: Astra's A1 items 5, 13, 14 (paper arguments; finite enumeration by Astra); not compiled here.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-45ca76","file":"Mathlib/GroupTheory/GroupAction/SubMulAction/Combination.lean","decl":"isPreprimitive_perm","line":221,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"hypothesis-stronger-than-needed","claim":"`isPreprimitive_perm` assumes `Nat.card α ≠ 2 * n`, which excludes the true case `α = Fin 2`, `n = 1` (`Perm (Fin 2)` acting on its two singletons is primitive: the action is transported from the natural one through `mulActionHom_singleton`), and its `n < Nat.card α` excludes every infinite `α` (e.g. `n = 1`, where the action is again the natural, primitive, permutation action; Astra item 3, not formalised here).","fix":"Allow the degenerate case `Nat.card α = 2`, `n = 1` (or treat `n = 1` separately via `mulActionHom_singleton_bijective`), and consider `ENat.card` bounds.","ev":"hunts/submulaction-combination/probe3.lean: `IsPreprimitive (Perm (Fin 2)) (powersetCard (Fin 2) 1)` by `IsPreprimitive.of_surjective (mulActionHom_singleton_bijective …).surjective` compiles, while the library theorem needs `Nat.card (Fin 2) ≠ 2 * 1`. Exit 0. Raised by Astra's A1 pass (items 3-4).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-c24a43","file":"Mathlib/GroupTheory/GroupAction/SubMulAction/Combination.lean","decl":"isPreprimitive_alternatingGroup","line":279,"sev":"MINOR","status":"pr-open","cat":"correctness","pattern":"hypothesis-stronger-than-docstring","claim":"`Set.powersetCard.isPreprimitive_alternatingGroup` is documented as 'preprimitive provided `1 ≤ n < Nat.card α` and `Nat.card α ≠ 2 * n`' (the wording of its `Perm α` sibling `isPreprimitive_perm`, which does assume `1 ≤ n`), but the statement assumes `h_three_le : 3 ≤ n`, so it excludes `n = 1, 2`, which the docstring covers. Those cases are true and the same proof proves them: the only uses of `3 ≤ n` are to get `3 ≤ Nat.card α` (which follows from `1 ≤ n < Nat.card α`, `Nat.card α ≠ 2 * n` by `omega`), `0 < n` and nonemptiness; `alternatingGroup.isCoatom_stabilizer` itself needs no lower bound on `|s|`. So e.g. the primitivity of `alternatingGroup (Fin 5)` on 1- and 2-subsets is not available directly from the library theorem (it can be recovered indirectly through complementation, from subset sizes 4 and 3, but not through the documented interface).","fix":"Replace `(h_three_le : 3 ≤ n)` by `(h_one_le : 1 ≤ n)` (getting `3 ≤ Nat.card α` by `omega`), matching the docstring and `isPreprimitive_perm`; the two uses in `Alternating/Simple.lean` (at `n = 3` and `n = 4`, both discharging the bound by `simp`) are unaffected.","ev":"hunts/submulaction-combination/probe1.lean P1isPreprimitive_alternatingGroup (hypothesis `1 ≤ n`, the library proof with `omega` for the side conditions) compiles and is applied to `alternatingGroup (Fin 5)` on `powersetCard (Fin 5) 1` and `powersetCard (Fin 5) 2`; `#check` shows the library signature `3 ≤ n → n < Nat.card α → Nat.card α ≠ 2 * n → …`. Exit 0.","evr":"compiles","astraV":"agrees","astraS":"A2 (targeted refutation): agrees, MAJOR under the lane calibration: the hypothesis excludes true cases the docstring explicitly covers; no small-cardinality exception (1 ≤ n < m, m ≠ 2n force 3 ≤ m); fix = replace `3 ≤ n` by `1 ≤ n`, `isPretransitive_alternatingGroup (by omega)`, `powersetCard.nontrivial' h_one_le hn`. Corrections adopted: existing uses are at n = 3 and n = 4 (unaffected); the Fin 5 cases are reachable indirectly via complements but not through the documented interface. API/documentation mismatch, not a false theorem.","pr":44578,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: `3 ≤ n` narrower than the docstring's `1 ≤ n` (cases true, proof already covered them) is not MAJOR.","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-71f55e","file":"Mathlib/GroupTheory/QuotientGroup/Defs.lean","decl":"QuotientGroup.lift_mk'","line":257,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `QuotientGroup.lift_mk` (GroupTheory.QuotientGroup.Defs), `QuotientGroup.lift_mk'` (GroupTheory.QuotientGroup.Defs) state exactly the same thing (Lean-checked). Reviewer: These are adjacent, both rfl. `(g : Q)` and `(mk g : Q)` are the same term, so lift_mk' is a Lean 3 coe-vs-mk port artifact; the `-- TODO: replace mk with mk'` comment shows the primed form was meant to use `mk'`. Deprecate lift_mk' (2 uses), or restate it with `mk' N g` per the TODO.","fix":"Deprecate `QuotientGroup.lift_mk'` in favour of `QuotientGroup.lift_mk`.","ev":"dupscan/Check.lean: `example := (@QuotientGroup.lift_mk' : type_of% @QuotientGroup.lift_mk)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (mis item 9, rating MAJOR): This establishes redundant declarations, not a missing mathematical statement. A prime can designate a spelling variant; moreover, `mk' N g` has the same underlying quotient constructor, and `lift_comp_mk'` already gives the bundled formulation. The TODO’s proposed spelling is `lift N φ HN (mk' N g) = φ g`. Deprecating the duplicate is reasonable; the asserted porting history needs separate evidence. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/GroupTheory/QuotientGroup/Defs.lean#L245-L268)","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-6ca7e6","file":"Mathlib/GroupTheory/QuotientGroup/Defs.lean","decl":"QuotientAddGroup.lift_mk'","line":257,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `QuotientAddGroup.lift_mk` (GroupTheory.QuotientGroup.Defs), `QuotientAddGroup.lift_mk'` (GroupTheory.QuotientGroup.Defs) state exactly the same thing (Lean-checked). Reviewer: This is the additive (to_additive) image of QuotientGroup.lift_mk / lift_mk'. `(g : Q)` and `(mk g : Q)` are the same term, and a TODO there says the primed lemma was meant to use `mk'`. Deprecating or restating lift_mk' fixes both (3 uses of QuotientAddGroup.lift_mk' in Grp/Colimits).","fix":"Deprecate `QuotientAddGroup.lift_mk'` in favour of `QuotientAddGroup.lift_mk`.","ev":"dupscan/Check.lean: `example := (@QuotientAddGroup.lift_mk' : type_of% @QuotientAddGroup.lift_mk)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (mis item 11, rating MAJOR): As in the multiplicative case, the current statements express the same quotient-constructor computation. The optional revised spelling is `lift N φ HN (mk' N g) = φ g`; `QuotientAddGroup.lift_comp_mk'` already supplies the bundled version. This is the generated additive manifestation of one redundancy, not a second missing theorem. [Generating declarations](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/GroupTheory/QuotientGroup/Defs.lean#L251-L264)","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-dba590","file":"Mathlib/GroupTheory/QuotientGroup/Defs.lean","decl":"QuotientGroup.liftEquiv_coe","line":299,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `QuotientGroup.liftEquiv_mk` (GroupTheory.QuotientGroup.Defs), `QuotientGroup.liftEquiv_coe` (GroupTheory.QuotientGroup.Defs) state exactly the same thing (Lean-checked). Reviewer: These are adjacent @[simp] rfl lemmas: `(g : Q)` and `(mk g : Q)` are the same term, a coe-vs-mk port artifact like lift_mk/lift_mk'. Neither is used. Keep liftEquiv_mk (matches the lift_mk naming) and deprecate liftEquiv_coe.","fix":"Deprecate `QuotientGroup.liftEquiv_coe` in favour of `QuotientGroup.liftEquiv_mk`.","ev":"dupscan/Check.lean: `example := (@QuotientGroup.liftEquiv_coe : type_of% @QuotientGroup.liftEquiv_mk)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 26, rating MAJOR): Both are the same application equation with the same attributes; neither has a distinct `norm_cast` or elaboration role.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-a71273","file":"Mathlib/GroupTheory/QuotientGroup/Defs.lean","decl":"QuotientAddGroup.liftEquiv_coe","line":299,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `QuotientAddGroup.liftEquiv_coe` (GroupTheory.QuotientGroup.Defs), `QuotientAddGroup.liftEquiv_mk` (GroupTheory.QuotientGroup.Defs) state exactly the same thing (Lean-checked). Reviewer: Adjacent @[to_additive (attr := simp)] rfl lemmas. The quotient coercion `(g : Q)` is `QuotientGroup.mk g`, so the `_coe` and `_mk` lemmas coincide; this is a mathlib3 coe/mk relic. Keep `_mk` and deprecate `_coe`. Neither is used.","fix":"Deprecate `QuotientAddGroup.liftEquiv_coe` in favour of `QuotientAddGroup.liftEquiv_mk`.","ev":"dupscan/Check.lean: `example := (@QuotientAddGroup.liftEquiv_mk : type_of% @QuotientAddGroup.liftEquiv_coe)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 27, rating MAJOR): Additive generation preserves the same redundancy; retaining the `_mk` translation does not require an additional `_coe` declaration.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-e58105","file":"Mathlib/Lean/Meta/KAbstractPositions.lean","decl":"Lean.Meta.kabstractPositions","line":36,"sev":"MINOR","status":"confirmed","cat":"correctness","pattern":"mirror-drifts-from-core","claim":"`kabstractPositions` (and hence `viewKAbstractSubExpr`) can disagree with `kabstract`, which it is meant to mirror. (1) Core `kabstract` first runs `instantiateMVars e`, and this traversal does not. With `?m := Nat.zero` assigned in `Nat.add ?m Nat.zero`, it reports one occurrence and `occ = none`, yet `kabstract` abstracts both zeros (`Nat.add #0 #0`). The suggested `rw` without an occurrence would then rewrite both. (2) An `mdata` wrapper is counted together with its contents, so `mdata z` yields two positions and an unnecessary `occ = some 1`. Known callers instantiate metavariables first, which mitigates (1).","fix":"Instantiate metavariables before computing positions (or require it), and do not double-count `mdata`; add differential tests against `kabstract e p (.pos [n])`.","ev":"-- hunts/kabstract-pos/P.lean: `run_meta` with `?m := Nat.zero`, `e := Nat.add ?m Nat.zero`, `pos := root.pushAppArg` logs `positions=1 occ=none kabstract=Nat.add #0 #0`; with `e := .mdata default Nat.zero` logs `positions=2 occ=some (1)`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6bbffc","file":"Mathlib/Lean/Meta/KAbstractPositions.lean","decl":"Lean.Meta.kabstractIsTypeCorrect","line":91,"sev":"MINOR","status":"confirmed","cat":"correctness","pattern":"speculative-check-leaks-state","claim":"Both query functions leak unification state. `kabstractPositions` restores only the `MetavarContext` after a successful match, so postponed universe constraints survive: matching `Sort (max u ?v)` against `Sort u` leaves one postponed constraint. `kabstractIsTypeCorrect` can return `false` while leaving assignments behind: in `@Eq Nat (@id.{?u} Nat 0) 0` with the `Nat` argument abstracted, it returns `false` but has set `?u := 1`.","fix":"Wrap each speculative `isDefEq` and the whole `kabstractIsTypeCorrect` body in `withoutModifyingState` (or save/restore the full `Meta.State`).","ev":"-- hunts/kabstract-pos/P.lean: `run_meta` logs `postponed before=0 after=1` for `kabstractPositions (mkSort (.max u ?v)) (mkSort u)`, and `ok=false u:=1` for the `Eq`/`id` example.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-8bf80f","file":"Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean","decl":"AffineEquiv.coe_coe","line":112,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `AffineEquiv.coe_coe` (LinearAlgebra.AffineSpace.AffineEquiv), `AffineEquiv.coe_toAffineMap` (LinearAlgebra.AffineSpace.AffineEquiv) state exactly the same thing (Lean-checked). Reviewer: toAffineMap is @[coe] and the Coe instance is `⟨toAffineMap⟩`, so `((e : P₁ →ᵃ[k] P₂) : P₁ → P₂) = e` is literally coe_toAffineMap. Adjacent rfl lemmas. Move @[norm_cast] onto coe_toAffineMap and deprecate coe_coe, as OpenPartialHomeomorph did with coe_coe → coe_toPartialEquiv (2026-05-18).","fix":"Deprecate `AffineEquiv.coe_coe` in favour of `AffineEquiv.coe_toAffineMap`.","ev":"dupscan/Check.lean: `example := (@AffineEquiv.coe_toAffineMap : type_of% @AffineEquiv.coe_coe)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 28, rating MINOR): The [attribute difference](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean#L107-L113) is real, but the proposed transfer of `norm_cast` preserves it on one theorem. This is consolidation of an attribute twin, rather than removal of a different cast normal form.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-5a68ab","file":"Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean","decl":"AffineEquiv.coe_linear","line":116,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `AffineEquiv.coe_linear` (LinearAlgebra.AffineSpace.AffineEquiv), `AffineEquiv.linear_toAffineMap` (LinearAlgebra.AffineSpace.AffineEquiv) state exactly the same thing (Lean-checked). Reviewer: `(e : P₁ →ᵃ[k] P₂).linear` is `e.toAffineMap.linear` (toAffineMap is @[coe]), so @[simp] coe_linear (l.116) duplicates @[simp] linear_toAffineMap (l.74). Both are rfl; deprecate coe_linear together with coe_coe.","fix":"Deprecate `AffineEquiv.coe_linear` in favour of `AffineEquiv.linear_toAffineMap`.","ev":"dupscan/Check.lean: `example := (@AffineEquiv.linear_toAffineMap : type_of% @AffineEquiv.coe_linear)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 29, rating MAJOR): Both simplify the same linear projection through the same coercion, with no distinguishing attributes.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-a981a2","file":"Mathlib/LinearAlgebra/Determinant.lean","decl":"LinearMap.free_of_det_ne_one","line":326,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Module.Free.of_det_ne_one` (LinearAlgebra.Determinant), `LinearMap.free_of_det_ne_one` (LinearAlgebra.Determinant) state exactly the same thing (Lean-checked). Reviewer: Same file, identical statement and identical tactic proof (`by_cases H : ∃ s, Nonempty (Basis s R M) ...`). `Module.Free.of_det_ne_one` is used (Transvection/Basic.lean:680, via `Free.of_det_ne_one`) and follows the `Module.Free.of_*` convention; `LinearMap.free_of_det_ne_one` has no uses. Deprecate the latter.","fix":"Deprecate `LinearMap.free_of_det_ne_one` in favour of `Module.Free.of_det_ne_one`.","ev":"dupscan/Check.lean: `example := (@LinearMap.free_of_det_ne_one : type_of% @Module.Free.of_det_ne_one)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup2 item 30, rating MINOR): `f.free_of_det_ne_one hf` is a genuine `LinearMap` method, despite `f` being implicit, and it pairs with [`finite_of_det_ne_one`](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/LinearAlgebra/Determinant.lean#L325-L337). Share the proof while retaining this namespace interface.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-c14017","file":"Mathlib/LinearAlgebra/Dimension/Finite.lean","decl":"natCast_le_rank_iff","line":208,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Module.le_rank_iff` (LinearAlgebra.Dimension.Basic), `natCast_le_rank_iff` (LinearAlgebra.Dimension.Finite) state exactly the same thing (Lean-checked). Reviewer: `[Nontrivial R] : n ≤ Module.rank R M ↔ ∃ v : Fin n → M, LinearIndependent R v` is proved in Dimension/Basic (section variable Nontrivial R) and again in Dimension/Finite, which imports Basic. Keep Module.le_rank_iff (lower in the import graph) and deprecate natCast_le_rank_iff (unused).","fix":"Deprecate `natCast_le_rank_iff` in favour of `Module.le_rank_iff`.","ev":"dupscan/Check.lean: `example := (@natCast_le_rank_iff : type_of% @Module.le_rank_iff)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 31, rating MAJOR): The surrounding `Nontrivial` assumption does not create a stronger or weaker theorem; the lower-import declaration already provides the complete result.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-8d8514","file":"Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean","decl":"(file)","line":20,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-name-in-module-doc","claim":"The module docstring's \"Main definitions / results\" names two declarations that do not exist: `Module.End.iSup_genEigenspace_eq_top` (the theorem is `Module.End.iSup_maxGenEigenspace_eq_top`) and `Module.End.iSup_genEigenspace_restrict_eq_top` (the theorem is `Module.End.genEigenspace_restrict_eq_top`). The docs therefore point readers to dead names for both main results.","fix":"Replace the two names with `Module.End.iSup_maxGenEigenspace_eq_top` and `Module.End.genEigenspace_restrict_eq_top`.","ev":"`grep -rnw 'iSup_genEigenspace_eq_top\\|iSup_genEigenspace_restrict_eq_top' Mathlib`: only the two docstring lines (L20, L22) match; no declaration has either name.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-7965ef","file":"Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean","decl":"Module.End.exists_hasEigenvalue_of_genEigenspace_eq_top","line":51,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-hypothesis","claim":"`exists_hasEigenvalue_of_genEigenspace_eq_top` assumes `[Nontrivial M]` and `⨆ μ, f.genEigenspace μ k = ⊤`, but `⨆ μ, f.genEigenspace μ k ≠ ⊥` alone suffices (and needs no `Nontrivial M`): a nonzero generalized eigenspace gives an eigenvalue by `HasUnifEigenvalue.lt zero_lt_one`.","fix":"Add the `≠ ⊥` version and derive the current one from it.","ev":"probe2.lean third `example`: the `≠ ⊥` version compiles without `[Nontrivial M]`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-03681b","file":"Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean","decl":"Module.End.iSup_maxGenEigenspace_eq_top","line":74,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"long-proof","claim":"Two proofs exceed 50 lines: `Module.End.iSup_maxGenEigenspace_eq_top` (L74–136, 63 lines, a hand-rolled strong induction on `finrank` with nine `have`s) and `Submodule.inf_iSup_genEigenspace` (L145–224, 80 lines, with six internal lemmas `hg₀`–`hg₄`, `aux` about the auxiliary operator `g`).","fix":"Extract the `g`-operator facts of `inf_iSup_genEigenspace` (the noncommProd of `(f - μ')^l₀`, its injectivity on `genEigenspace μ k` and invariance of `p`) as private lemmas, and the induction step of `iSup_maxGenEigenspace_eq_top` as a lemma about `genEigenrange`.","ev":"measured: L74–136 and L145–224 of src.lean.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-cedea1","file":"Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean","decl":"Submodule.inf_iSup_genEigenspace","line":145,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"unneeded-finite-dimensional","claim":"`Submodule.inf_iSup_genEigenspace` (and through it `eq_iSup_inf_genEigenspace` and `Module.End.genEigenspace_restrict_eq_top`) assumes `[FiniteDimensional K V]`, which is only used by the `LinearMap.injOn_iff_surjOn` step of the 80-line `noncommProd` proof. The statement holds for every vector space: pass to `V ⧸ p`, where the images of the components lie in the generalized eigenspaces of `p.mapQ p f h` (`map_genEigenspace_le`) and sum to zero, so independence (`independent_genEigenspace`) kills each one. That proof is ~20 lines and also removes the `backward.isDefEq.respectTransparency.types` switch.","fix":"Replace the proof by the quotient argument in probe2.lean and drop `[FiniteDimensional K V]` from the three declarations.","ev":"probe2.lean `inf_iSup_genEigenspace'`: the statement without `[FiniteDimensional K V]`, proved via `V ⧸ p`, compiles with no messages.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-473999","file":"Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean","decl":"Submodule.eq_iSup_inf_genEigenspace","line":226,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"global-hypothesis-only-used-locally","claim":"`eq_iSup_inf_genEigenspace` and `genEigenspace_restrict_eq_top` assume the generalized eigenspaces span everything (`h' : ⨆ μ, f.genEigenspace μ k = ⊤`), but only `p ≤ ⨆ μ, f.genEigenspace μ k` is used: `rw [← inf_iSup_genEigenspace h k, inf_eq_left.mpr hp]` proves the decomposition from it.","fix":"Take `hp : p ≤ ⨆ μ, f.genEigenspace μ k`; the `= ⊤` versions follow by `le_top`.","ev":"probe2.lean second `example`: the `p ≤ ⨆` version compiles.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-1c73ac","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.charmatrix","line":49,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"fintype-forced-by-bundled-hom","claim":"`charmatrix` carries `[Fintype n]` (and `[CommRing R]`) only because it is assembled from the bundled ring homs `Matrix.scalar n` and `RingHom.mapMatrix`, both of which require `[Fintype n]`. The unbundled `diagonal (fun _ => X) - M.map C` is definitionally equal (`rfl`), needs only `[Ring R] [DecidableEq n]`, and all nine other batch-0 lemmas (charmatrix_apply, _apply_eq, _apply_ne, _zero, _diagonal, _one, _natCast, _ofNat, _transpose) reprove under just those assumptions with the same one-line proofs. The lemmas inherit the needless `[Fintype n]` from the definition (the file's `variable` line would also auto-include it). No current consumer needs infinite index types, hence MINOR.","fix":"Define `charmatrix M := diagonal (fun _ => X) - M.map C` in a section assuming only `[DecidableEq n]` (optionally `[Ring R]`), keep its entrywise/cast/transpose lemmas there, and adjust the few proofs that `rw`/`dsimp` through `scalar_apply, RingHom.mapMatrix_apply` (charmatrix_diagonal, charmatrix_blockTriangular_iff, charpoly_mul_comm', Charpoly/Univ.lean).","ev":"batch0/probe1.lean section B:\nvariable {R : Type*} [Ring R] {n : Type*} [DecidableEq n]\nnoncomputable def charmatrix' (M : Matrix n n R) : Matrix n n R[X] :=\n  Matrix.diagonal (fun _ => (X : R[X])) - M.map C\nexample {R : Type*} [CommRing R] [Fintype n] (M : Matrix n n R) : charmatrix' M = charmatrix M := rfl\ntheorem charmatrix'_apply : charmatrix' M i j = (Matrix.diagonal fun _ : n => X) i j - C (M i j) := rfl\ntheorem charmatrix'_apply_eq : charmatrix' M i i = (X : R[X]) - C (M i i) := by simp [charmatrix']\ntheorem charmatrix'_apply_ne (h : i ≠ j) : charmatrix' M i j = -C (M i j) := by simp [charmatrix', h]\ntheorem charmatrix'_diagonal (d : n → R) : charmatrix' (diagonal d) = diagonal fun i => X - C (d i) := by\n  rw [charmatrix', diagonal_map (map_zero _), diagonal_sub]\ntheorem charmatrix'_one : charmatrix' (1 : Matrix n n R) = diagonal fun _ => X - 1 := charmatrix'_diagonal _\ntheorem charmatrix'_natCast (k : ℕ) : charmatrix' (k : Matrix n n R) = diagonal fun _ => X - (k : R[X]) := charmatrix'_diagonal _\ntheorem charmatrix'_transpose : charmatrix' Mᵀ = (charmatrix' M)ᵀ := by simp [charmatrix', transpose_map]\n-- (+ _zero, _ofNat); whole file compiles, exit 0","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6ce148","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.charmatrix_natCast","line":80,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-intcast-sibling","claim":"Cast API asymmetry: there are `charmatrix_natCast`/`charmatrix_ofNat` (and `charpoly_natCast`/`charpoly_ofNat`) but no `charmatrix_intCast`/`charpoly_intCast`, although `R` is a commutative ring and Mathlib's matrix cast API pairs natCast with intCast (`diagonal_intCast`, `Matrix.map_intCast`, `transpose_intCast`, `conjTranspose_intCast`, `isHermitian_intCast`). `simp` makes no progress on `charmatrix (k : Matrix n n R)` or `charpoly (k : Matrix n n R)` for `k : ℤ`, while the lemma is the one-liner `charmatrix_diagonal _`.","fix":"Add `@[simp] theorem charmatrix_intCast (k : ℤ) : charmatrix (k : Matrix n n R) = diagonal fun _ => X - (k : R[X]) := charmatrix_diagonal _` (and the matching `charpoly_intCast`).","ev":"batch0/probe1.lean C2:\nexample (k : ℤ) : charmatrix (k : Matrix n n R) = diagonal fun _ => X - (k : R[X]) := by\n  fail_if_success simp\n  exact charmatrix_diagonal _\nexample (k : ℤ) : charpoly (k : Matrix n n R) = (X - (k : R[X])) ^ Fintype.card n := by\n  fail_if_success simp\n  simp [charpoly, ← diagonal_intCast]\n-- both compile: plain simp fails, the one-line proofs work","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-51c0f1","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.matPolyEquiv_charmatrix","line":93,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"proof-bypasses-existing-simp-api","claim":"The 10-line coefficient-chasing proof (ext k i j / by_cases / split_ifs) bypasses the matPolyEquiv simp API: the lemma follows in one line from the existing @[simp] lemmas `matPolyEquiv_diagonal_X : matPolyEquiv (diagonal fun _ : n => (X : R[X])) = X` and `matPolyEquiv_map_C (M : Matrix n n R) : matPolyEquiv (M.map C) = C M` (Mathlib/RingTheory/MatrixPolynomialAlgebra.lean:58,65, already imported).","fix":"Replace the proof by `by simp [charmatrix]` (or the explicit `rw [charmatrix, map_sub, scalar_apply, RingHom.mapMatrix_apply, matPolyEquiv_diagonal_X, matPolyEquiv_map_C]`).","ev":"hunts/charpoly-basic/batch1/probe1.lean (P1) and hunts/charpoly-basic/batch1/CopyA.lean (in-file):\nexample (M : Matrix n n R) : matPolyEquiv (charmatrix M) = X - C M := by\n  simp [charmatrix]\n\nexample (M : Matrix n n R) : matPolyEquiv (charmatrix M) = X - C M := by\n  rw [charmatrix, map_sub, scalar_apply, RingHom.mapMatrix_apply, matPolyEquiv_diagonal_X,\n    matPolyEquiv_map_C]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ba3454","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.charmatrix_reindex","line":104,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"special-case-of-missing-general-lemma","claim":"Special case of a missing general lemma `charmatrix_submatrix` for any injective `e : m → n`: `(M.submatrix e e).charmatrix = M.charmatrix.submatrix e e`, which yields both `charmatrix_reindex` (e := e.symm) and `charmatrix_toSquareBlock` (e := Subtype.val) as one-term corollaries. Because `reindex_apply` is @[simp], the reindex form is not in simp normal form, so neither this lemma nor anything else lets `simp` handle `charmatrix` of a submatrix (plain `simp` on the statement is left with `(M.submatrix ⇑e.symm ⇑e.symm).charmatrix = M.charmatrix.submatrix ⇑e.symm ⇑e.symm`). No `charmatrix`/`charpoly` submatrix lemma exists (git grep submatrix in Matrix/Charpoly/).","fix":"Add `charmatrix_submatrix (he : Function.Injective e)` and derive `charmatrix_reindex` and `charmatrix_toSquareBlock` from it.","ev":"hunts/charpoly-basic/batch1/probe1.lean (P3 compiles, P3b fails as expected) and hunts/charpoly-basic/batch1/CopyA.lean (in-file):\ntheorem charmatrix_submatrix (M : Matrix n n R) {e : m → n} (he : Function.Injective e) :\n    (M.submatrix e e).charmatrix = M.charmatrix.submatrix e e := by\n  ext i j : 1\n  by_cases h : i = j\n  · subst h; simp\n  · simp [h, he.ne h]\n\nexample (M : Matrix n n R) (e : n ≃ m) :\n    charmatrix (reindex e e M) = reindex e e (charmatrix M) :=\n  charmatrix_submatrix M e.symm.injective\n\nexample (M : Matrix n n R) {α : Type*} [DecidableEq α] {b : n → α} {a : α} :\n    (M.toSquareBlock b a).charmatrix = M.charmatrix.toSquareBlock b a :=\n  charmatrix_submatrix M Subtype.val_injective\n\n-- P3b: `example ... : charmatrix (reindex e e M) = reindex e e (charmatrix M) := by simp` fails with unsolved goal `(M.submatrix ⇑e.symm ⇑e.symm).charmatrix = M.charmatrix.submatrix ⇑e.symm ⇑e.symm`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b75176","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.charmatrix_blockTriangular_iff","line":124,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"operation-before-predicate-in-iff-name","claim":"The statement is `BlockTriangular (charmatrix M) b ↔ BlockTriangular M b`, so the naming convention (describe the conclusion in prefix order) gives `blockTriangular_charmatrix_iff`, matching the siblings `blockTriangular_reindex_iff` and `blockTriangular_transpose_iff` (Mathlib/LinearAlgebra/Matrix/Block.lean:81,94) and the uniform family `isSymm_transpose_iff`, `isSymm_map_iff`, `isHermitian_reindex_iff`, `isDiag_transpose_iff`, ... (20+ names). Across Mathlib only three names put the operation first for these matrix predicates: this one, `circulant_isSymm_iff`, `mk_isDiag_iff`.","fix":"Rename to `blockTriangular_charmatrix_iff` and keep `charmatrix_blockTriangular_iff` as a @[deprecated] alias (the dot-notation aliases `BlockTriangular.charmatrix`/`.of_charmatrix` stay).","ev":"git -C mathlib4 grep -hoE \"(theorem|lemma) (blockTriangular|isHermitian|isSymm|isDiag|isUnit|...)_[a-zA-Z]+_iff\" origin/master -- Mathlib/LinearAlgebra/Matrix Mathlib/Data/Matrix (20+ predicate-first names) vs grep -hoE \"(theorem|lemma) [a-z][a-zA-Z]*_(blockTriangular|isHermitian|isSymm|isDiag|isUpperTriangular|isLowerTriangular)_iff\" origin/master -- Mathlib (only charmatrix_blockTriangular_iff, circulant_isSymm_iff, mk_isDiag_iff)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-bbbb30","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.charpoly_diagonal","line":151,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"Missing @[simp]: its sibling `charmatrix_diagonal` and `charpoly_zero` are @[simp], but `simp` makes no progress on `charpoly (diagonal d)` (the lemma is only reachable by unfolding `charpoly`). Marking it @[simp] passes `#lint only simpNF` on a copy of the file (0 errors in 44 declarations) and the copy compiles; downstream consumers already feed it to simp by hand: `simp [charpoly_diagonal]` at Mathlib/Analysis/Matrix/Spectrum.lean:159 and Mathlib/Analysis/Matrix/HermitianFunctionalCalculus.lean:156.","fix":"Tag `charpoly_diagonal` with @[simp] (and drop the now-redundant `charpoly_diagonal` from downstream `simp [...]` calls).","ev":"hunts/charpoly-basic/batch1/probe1.lean (P4):\nexample (d : n → R) : charpoly (diagonal d) = ∏ i, (X - C (d i)) := by\n  simp   -- error: `simp` made no progress\n\nhunts/charpoly-basic/batch1/CopyA.lean: src.lean with `@[simp]` on charpoly_diagonal, `example (d : n → R) : charpoly (diagonal d) = ∏ i, (X - C (d i)) := by simp` and `#lint only simpNF` at the end -> compiles, \"Found 0 errors in 44 declarations ... All linting checks passed!\"","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-915599","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.charpoly_one","line":154,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`charpoly_one` is not `@[simp]`, although `charpoly_zero` (L147) and its own charmatrix counterpart `charmatrix_one` (L75) are. Plain `simp` cannot evaluate `charpoly (1 : Matrix n n R)`. Tagging it passes the simpNF linter and the file still compiles. Mathlib/LinearAlgebra/Charpoly/Basic.lean repeats the asymmetry: `LinearMap.charpoly_zero` is simp and `LinearMap.charpoly_one` is not.","fix":"Tag `charpoly_one` with `@[simp]`.","ev":"batch2/Probe.lean L28-32: `example : charpoly (0 : Matrix n n R) = X ^ Fintype.card n := by simp` compiles. So does `example : charpoly (1 : Matrix n n R) = (X - 1) ^ Fintype.card n := by fail_if_success (simp; done); exact charpoly_one`, which means simp fails on it. In batch2/Copy.lean, `@[simp]` is added to charpoly_one/natCast/ofNat. The file compiles (exit 0), `#lint only simpNF` reports 'Found 0 errors in 45 declarations', and `example : charpoly (1 : Matrix n n R) = (X - 1) ^ Fintype.card n := by simp` then compiles.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-058cf4","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.charpoly_natCast","line":157,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`charpoly_natCast` is not `@[simp]`, although `charmatrix_natCast` (L80) is. The cast family is also incomplete: Mathlib has no `charpoly_intCast` and no `charmatrix_intCast` (`git grep -nE 'charpoly_intCast|charmatrix_intCast' origin/master -- Mathlib` returns nothing). So `simp` evaluates neither `charpoly (↑(k : ℕ))` nor `charpoly (↑(k : ℤ))`. The intCast lemma takes two lines from existing API and passes simpNF as a simp lemma.","fix":"Tag `charpoly_natCast` `@[simp]` and add `@[simp] charpoly_intCast (k : ℤ) : charpoly (k : Matrix n n R) = (X - (k : R[X])) ^ Fintype.card n` (proof: `rw [← diagonal_intCast, charpoly_diagonal]; simp`).","ev":"batch2/Probe.lean L33-42: `fail_if_success (simp; done)` succeeds on `charpoly (k : Matrix n n R) = (X - (k : R[X])) ^ Fintype.card n` for k : ℕ and for k : ℤ. The ℤ version is then closed by `rw [← diagonal_intCast, charpoly_diagonal]; simp`. In batch2/Copy.lean, `@[simp] theorem charpoly_intCast` is added beside `charpoly_natCast`, which is also tagged. The file compiles, simpNF is clean, and `by simp` then proves both statements.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-07f517","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.charpoly_ofNat","line":161,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`charpoly_ofNat` is not `@[simp]`, although `charmatrix_ofNat` (L84) is. As a result `simp` cannot evaluate `charpoly (3 : Matrix n n R)`. Tagging it passes simpNF.","fix":"Tag `charpoly_ofNat` with `@[simp]`.","ev":"batch2/Probe.lean L36-38: `example : charpoly (3 : Matrix n n R) = (X - 3) ^ Fintype.card n := by fail_if_success (simp; done); exact charpoly_ofNat 3` compiles. In batch2/Copy.lean, the lemma is tagged `@[simp]`, the file compiles, simpNF is clean, and `by simp` then proves the statement.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-f9cc43","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.charpoly_reindex","line":169,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-normal-companion","claim":"The simp-normal companion `charpoly_submatrix_equiv_self` is missing. `reindex_apply` is `@[simp]`, so `simp` rewrites `reindex e e M` into `M.submatrix e.symm e.symm` and then gets stuck. As a result, `simp` closes neither `(reindex e e M).charpoly = M.charpoly` nor `(M.submatrix e e).charpoly = M.charpoly`. The determinant has exactly this pair: `det_reindex_self` and `@[simp] det_submatrix_equiv_self`, whose docstring explains why. `simp` closes both det statements.","fix":"Add `@[simp] theorem charpoly_submatrix_equiv_self (e : m ≃ n) (M : Matrix n n R) : (M.submatrix e e).charpoly = M.charpoly` (proof `simpa using charpoly_reindex e.symm M`).","ev":"batch2/Probe.lean L48-56: `fail_if_success (simp; done)` succeeds on `(reindex e e M).charpoly = M.charpoly` and on `(M.submatrix e e).charpoly = M.charpoly`. The `.det` analogues close `by simp`. In batch2/Copy.lean, the proposed `@[simp] charpoly_submatrix_equiv_self` compiles and passes simpNF. With it, `example (e : n ≃ m) (M : Matrix n n R) : (reindex e e M).charpoly = M.charpoly := by simp` compiles.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-e41ef4","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.BlockTriangular.charpoly","line":196,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"sibling-signature-mismatch","claim":"The signature differs from its direct sibling `Matrix.BlockTriangular.det` (Mathlib/LinearAlgebra/Matrix/Block.lean:348: `protected theorem BlockTriangular.det ... {M : Matrix m m R} ... (hM : BlockTriangular M b)`). First, it picks up `M` as an explicit argument from `variable (M₂₂ M : Matrix n n R)`, even though `h` determines it. `#check` gives `BlockTriangular.charpoly : ∀ ... (M : Matrix n n R) {α} {b} [LinearOrder α], M.BlockTriangular b → ...`, and `Matrix.BlockTriangular.charpoly h` fails to elaborate; only `h.charpoly` or `BlockTriangular.charpoly M h` work. Second, it is not `protected`. Inside `namespace Matrix.BlockTriangular`, the identifier `charpoly` therefore resolves to this lemma instead of `Matrix.charpoly`, while `det` there still means `Matrix.det`.","fix":"Declare it `protected lemma BlockTriangular.charpoly {M : Matrix n n R} {α : Type*} {b : n → α} [LinearOrder α] (h : M.BlockTriangular b)`, matching `BlockTriangular.det`.","ev":"batch2/Probe.lean L64-80: `Matrix.BlockTriangular.det h` compiles. `Matrix.BlockTriangular.charpoly h` errors with 'Application type mismatch: The argument h has type M.BlockTriangular b ... but is expected to have type Matrix ?m ?m ?m'. Inside `namespace Matrix.BlockTriangular`, `example (M : Matrix n n R) : det M = M.det := rfl` compiles. There, `example (M : Matrix n n R) : charpoly M = M.charpoly := rfl` errors, because `charpoly M` elaborates as the lemma, with type `M.BlockTriangular ?b → ...`. In batch2/Copy.lean, the version with `protected` and `{M}` compiles, and both `BlockTriangular.charpoly h` and `h.charpoly` elaborate.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-91c042","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.charpoly_of_isUpperTriangular","line":200,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-mirror-lemma","claim":"Only the upper-triangular case is stated. The `det` API it is built on has both cases (Mathlib/LinearAlgebra/Matrix/Block.lean:389 `det_of_isUpperTriangular [LinearOrder m] (h : M.IsUpperTriangular) : M.det = ∏ i : m, M i i` and :396 `det_of_isLowerTriangular [LinearOrder m] (M : Matrix m m R) (h : M.IsLowerTriangular) : M.det = ∏ i : m, M i i`), but `git grep charpoly_of_isLowerTriangular origin/master -- Mathlib` returns nothing. The missing lemma has a one-line proof.","fix":"Add `charpoly_of_isLowerTriangular [LinearOrder n] (M : Matrix n n R) (h : M.IsLowerTriangular) : M.charpoly = ∏ i : n, (X - C (M i i))`, proved by `simp [charpoly, det_of_isLowerTriangular _ h.charmatrix]`.","ev":"hunts/charpoly-basic/batch3/probe1.lean, P1 (lines 14-20): `theorem charpoly_of_isLowerTriangular [LinearOrder n] (M : Matrix n n R) (h : M.IsLowerTriangular) : M.charpoly = ∏ i : n, (X - C (M i i)) := by simp [charpoly, det_of_isLowerTriangular _ h.charmatrix]`. A second proof, `simpa using charpoly_of_isUpperTriangular Mᵀ h.transpose`, also works. Both compile with no diagnostics.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b8e726","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.aeval_self_charpoly","line":215,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"Cayley–Hamilton is not `@[simp]`, although the analogous root-of-its-polynomial fact `minpoly.aeval` is (Mathlib/FieldTheory/Minpoly/Basic.lean:88-89 `@[simp] theorem aeval : aeval x (minpoly A x) = 0`). `simp` makes no progress on `aeval M M.charpoly = 0`, and on `aeval M (p * M.charpoly) = 0` it rewrites but cannot finish. A `@[simp]`-tagged copy passes `#lint only simpNF` and closes the second goal outright.","fix":"Tag `Matrix.aeval_self_charpoly` with `@[simp]`, and likewise `LinearMap.aeval_self_charpoly`.","ev":"hunts/charpoly-basic/batch3/probe1.lean, P2 (lines 24-41). `example (M : Matrix n n R) : aeval M M.charpoly = 0 := by fail_if_success (simp; done); exact aeval_self_charpoly M` compiles, and the linter reports that `done` is never executed, so `simp` fails outright. The same pattern compiles on `aeval M (p * M.charpoly) = 0`, where `simp` progresses but does not close the goal. `@[simp] theorem aeval_self_charpoly_simp (M : Matrix n n R) : aeval M M.charpoly = 0 := aeval_self_charpoly M`, followed by `example ... : aeval M (p * M.charpoly) = 0 := by simp`, compiles. `#lint only simpNF` prints 'All linting checks passed!'.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-10fbd4","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.charpoly_units_conj","line":284,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-isunit-variant","claim":"Conjugation invariance exists only in the bundled-units form `(M : (Matrix n n R)ˣ)`. `det` and `trace` have both that form and an `IsUnit` form (Mathlib/LinearAlgebra/Matrix/NonsingularInverse.lean:781 `det_conj {M : Matrix m m α} (h : IsUnit M) (N) : det (M * N * M⁻¹) = det N`, plus `det_conj'`, `trace_conj` and `trace_conj'` at :785/:798/:802). `charpoly` has no `IsUnit` form, and `simp [charpoly_units_conj]` makes no progress on `(M * N * M⁻¹).charpoly = N.charpoly` given `IsUnit M`. Three consumers re-derive conjugation invariance by hand with `charpoly_mul_comm, ← mul_assoc`: Analysis/Matrix/Spectrum.lean:158, Analysis/Matrix/HermitianFunctionalCalculus.lean:155 and LinearAlgebra/Charpoly/ToMatrix.lean:60. In the first two the conjugator is unitary, so neither the units form nor an `IsUnit` form applies directly; a `Q * P = 1` form would.","fix":"Add `charpoly_conj`/`charpoly_conj'` taking `(h : IsUnit M)`, proved by `rw [← h.unit_spec, charpoly_units_conj]`. Optionally add a left-inverse form `(h : Q * P = 1) : (P * N * Q).charpoly = N.charpoly`, proved by `rw [charpoly_mul_comm, ← mul_assoc, h, one_mul]`.","ev":"hunts/charpoly-basic/batch3/probe1.lean, P3 (lines 45-71): `theorem charpoly_conj {M : Matrix n n R} (h : IsUnit M) (N : Matrix n n R) : (M * N * M⁻¹).charpoly = N.charpoly := by rw [← h.unit_spec, charpoly_units_conj]` compiles, and so does the primed version. `example ... (h : IsUnit M) ... := by fail_if_success simp [charpoly_units_conj]; exact charpoly_conj h N` compiles. `theorem charpoly_mul_mul_of_mul_eq_one {P Q} (h : Q * P = 1) (N) : (P * N * Q).charpoly = N.charpoly := by rw [charpoly_mul_comm, ← mul_assoc, h, one_mul]` compiles and gives the unitary case via `Unitary.star_mul_self_of_mem hU`. `git grep -nw 'charpoly_conj' origin/master -- Mathlib` finds only `LinearEquiv.charpoly_conj`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-810a65","file":"Mathlib/LinearAlgebra/Matrix/Polynomial.lean","decl":"(file)","line":12,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"module-doc-overstates-content","claim":"The module docstring is titled 'Matrices of polynomials and polynomials of matrices', but the file has nothing about polynomials of matrices; it says the results concern 'the polynomial given by `det (t * I + A)`', while three of the four lemmas are about the more general `det (X • A + B)`. None of the four public theorems has a docstring.","fix":"Retitle to 'Determinants of matrices of the form `X • A + B`', describe the lemmas, and add one-line docstrings.","ev":"Doc-only finding: L13 title and L16-17 vs the statements at L39, L61, L71 (`X • A.map C + B.map C`) and L85.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-6e62e9","file":"Mathlib/LinearAlgebra/Matrix/Polynomial.lean","decl":"natDegree_det_X_add_C_le","line":39,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"special-case-of-missing-general-lemma","claim":"`natDegree_det_X_add_C_le` is the special case `k = 1` of a missing general bound: if every entry of `M : Matrix n n R[X]` has `natDegree ≤ k` then `(det M).natDegree ≤ Fintype.card n * k`. The general lemma has a 5-line proof (`natDegree_sum_le_of_forall_le`, `natDegree_smul_le`, `natDegree_prod_le`, `Finset.sum_le_card_nsmul`), which also removes this proof's case split on `sign g = ±1` (L50-52, subsumed by `natDegree_smul_le`) and the `Multiset.max_le_of_forall_le` detour (L42-45). Mathlib has no other degree bound for determinants (no `natDegree_det`/`degree_det` declaration).","fix":"Add `Matrix.natDegree_det_le_of_forall` (entries of `natDegree ≤ k` give `≤ card n * k`) and derive `natDegree_det_X_add_C_le` from it in 3 lines.","ev":"hunts/matrix-polynomial/probe1.lean: `natDegree_det_le_of_forall` (5-line proof) and the corollary recovering `natDegree_det_X_add_C_le` (`simpa using natDegree_det_le_of_forall (k := 1) fun i j => by dsimp only [...]; compute_degree`) compile, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-d01796","file":"Mathlib/LinearAlgebra/Matrix/Polynomial.lean","decl":"leadingCoeff_det_X_one_add_C","line":85,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"leadingcoeff-one-instead-of-monic","claim":"`leadingCoeff_det_X_one_add_C` states `leadingCoeff (det (X • 1 + A.map C)) = 1` instead of `Monic (det (X • 1 + A.map C))`; its only consumer (`Matrix.adjugate_mul_distrib`, Adjugate.lean:471) rewrites `Polynomial.Monic.def` backwards to use it. The 14-line proof (subsingleton split, a degree case split and a contradiction branch) is `monic_of_natDegree_le_of_coeff_eq_one` applied to the file's own `natDegree_det_X_add_C_le 1 A` and `coeff_det_X_add_C_card 1 A`.","fix":"State `monic_det_X_one_add_C : (det (X • 1 + A.map C)).Monic` with the 4-line proof via `monic_of_natDegree_le_of_coeff_eq_one`, deprecate the `leadingCoeff` form (or keep it as `.leadingCoeff`), and use `.isRegular` directly at Adjugate.lean:471.","ev":"hunts/matrix-polynomial/probe1.lean: `monic_det_X_one_add_C` (4 lines via `monic_of_natDegree_le_of_coeff_eq_one`) and `example … leadingCoeff … = 1 := (monic_det_X_one_add_C A).leadingCoeff` compile, exit 0; consumer at Adjugate.lean:471 (`simp only [g, Polynomial.Monic.def, ← Polynomial.leadingCoeff_det_X_one_add_C M, add_comm]`).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-bd2fba","file":"Mathlib/LinearAlgebra/Matrix/Polynomial.lean","decl":"leadingCoeff_det_X_one_add_C","line":85,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"parallel-proof-no-bridge","claim":"The polynomial `det (X • 1 + A.map C)` is `(-A).charpoly` (`charmatrix (-A) = scalar n X - (-A).map C`), so this lemma and `Matrix.charpoly_monic` (Charpoly/Coeff.lean:119, proved separately via `charpoly_sub_diagonal_degree_lt`) are the same monicity fact proved twice, with no lemma linking the two forms.","fix":"Add the bridge `det (X • 1 + A.map C) = (-A).charpoly` in Charpoly/Basic and derive one monicity result from the other.","ev":"hunts/matrix-polynomial/probe1.lean: `example : det ((X : α[X]) • (1 : Matrix n n α[X]) + A.map C) = (-A).charpoly` proved by `rw [charpoly, charmatrix]; congr 1; ext i j; by_cases h : i = j <;> simp [h, sub_eq_add_neg]`, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261006-2f4333","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.prod","line":14,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-namespace-in-docstring","claim":"The module docstring (lines 14-24) names `QuadraticForm.prod`, `QuadraticForm.pi`, `QuadraticForm.Equivalent.prod`/`.pi`, `QuadraticForm.nonneg_prod_iff`/`nonneg_pi_iff` and `QuadraticForm.posDef_prod_iff`/`posDef_pi_iff`. None of these constants exist: since the QuadraticForm -> QuadraticMap generalisation they are all `QuadraticMap.*`. `prod`'s own docstring (line 52) still says it constructs a 'quadratic form', but it builds a `QuadraticMap R (M₁ × M₂) P`.","fix":"Rename every `QuadraticForm.` reference in the module docstring to `QuadraticMap.` and say 'quadratic map' in the docstring of `prod`.","ev":"batch0/probe2.lean: `#eval show CoreM Unit from do for n in [``QuadraticMap.prod, `QuadraticForm.prod, `QuadraticForm.Equivalent.prod, `QuadraticForm.pi, `QuadraticForm.nonneg_prod_iff, `QuadraticForm.posDef_prod_iff] do IO.println s!\"{n}: {(← getEnv).contains n}\"` prints `QuadraticMap.prod: true` and `false` for every `QuadraticForm.*` name (batch0/probe2.out).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2bc326","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.prod","line":55,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"The characteristic API of the orthogonal sum is incomplete. Functoriality exists only for isometric equivalences (`IsometryEquiv.prod`): there is no `Isometry.prodMap : (Q₁ →qᵢ Q₁') → (Q₂ →qᵢ Q₂') → (Q₁.prod Q₂ →qᵢ Q₁'.prod Q₂')`. The file provides `prodComm` and `prodProdProdComm` but no associator `IsometryEquiv.prodAssoc` (unlike `LinearEquiv.prodAssoc` and `LinearIsometryEquiv.prodAssoc`). Each one is a 3-line definition.","fix":"Add `Isometry.prodMap` (`toLinearMap := f₁.toLinearMap.prodMap f₂.toLinearMap`) and `IsometryEquiv.prodAssoc` (`toLinearEquiv := LinearEquiv.prodAssoc R _ _ _`, `map_app' _ := (add_assoc _ _ _).symm`).","ev":"batch0/probe1.lean D1 `def prodMap' (f₁ : Q₁ →qᵢ Q₁') (f₂ : Q₂ →qᵢ Q₂') : Q₁.prod Q₂ →qᵢ Q₁'.prod Q₂' where toLinearMap := f₁.toLinearMap.prodMap f₂.toLinearMap; map_app' x := congr($(f₁.map_app x.1) + $(f₂.map_app x.2))` and D2 `def prodAssoc' (Q₃ : QuadraticMap R N₁ P) : ((Q₁.prod Q₂).prod Q₃).IsometryEquiv (Q₁.prod (Q₂.prod Q₃)) where toLinearEquiv := LinearEquiv.prodAssoc R _ _ _; map_app' _ := (add_assoc _ _ _).symm` both compile. `git grep -nE 'IsometryEquiv\\.prod|Isometry\\.prod|prodAssoc' origin/master -- Mathlib | grep -i quadratic` finds only Prod.lean's own `IsometryEquiv.prod`, `prodComm` and `prodProdProdComm`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-dcc899","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.IsometryEquiv.prod","line":58,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-namespace-in-docstring","claim":"The docstring says the isometric equivalence is 'generated by `QuadraticForm.prod`', but no such constant exists (the declaration is `QuadraticMap.prod`). It also says the result is built 'from a pair of isometries', but the inputs are `IsometryEquiv`s, not `Isometry`s (`→qᵢ`).","fix":"Reword it as 'An isometric equivalence between forms generated by `QuadraticMap.prod` can be built from a pair of isometric equivalences between the left and right parts.'","ev":"batch0/probe2.lean `(← getEnv).contains `QuadraticForm.prod` = false (batch0/probe2.out); docstring text at src.lean:58-59.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-efbb67","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.IsometryEquiv.prod","line":60,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-apply-lemma","claim":"`@[simps toLinearEquiv]` generates only `prod_toLinearEquiv`, whose LHS `(e₁.prod e₂).toLinearEquiv` is not simp-normal (`coe_toLinearEquiv` pushes to the coercion). There is no `prod_apply` and no `prod_symm` lemma, so `simp` makes no progress on `e₁.prod e₂ x = (e₁ x.1, e₂ x.2)`, on `(e₁.prod e₂).symm x = (e₁.symm x.1, e₂.symm x.2)` or on `(e₁.prod e₂).toIsometry x`, although all of them hold by `rfl`. The linear analogue has `LinearEquiv.prodCongr_apply` and `LinearEquiv.prodCongr_symm`.","fix":"Add `@[simp] lemma IsometryEquiv.prod_apply … : e₁.prod e₂ x = (e₁ x.1, e₂ x.2) := rfl` and `@[simp] lemma IsometryEquiv.prod_symm … : (e₁.prod e₂).symm = e₁.symm.prod e₂.symm := rfl`.","ev":"batch0/probe1.lean C1a `example (e₁ : Q₁.IsometryEquiv Q₁') (e₂ : Q₂.IsometryEquiv Q₂') (x : M₁ × M₂) : e₁.prod e₂ x = (e₁ x.1, e₂ x.2) := by simp` -> error '`simp` made no progress' (line 29); C1c (symm) the same (line 35); C1b/C1d prove both by `rfl`; probe2 G4 `(e₁.prod e₂).toIsometry x = … := by simp` gets stuck at `(e₁.prod e₂) x = (e₁ x.1, e₂ x.2)`. batch0/Prod_fix.lean adds the two rfl lemmas, after which `simp` closes both goals; the file compiles with no errors.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7d8e81","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.IsometryEquiv.prodComm","line":121,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simps-projections","claim":"`IsometryEquiv` has no `initialize_simps_projections`, so `@[simps!]` on `prodComm` and `prodProdProdComm` generates `prodComm_toFun`/`prodProdProdComm_toFun` (misnamed: they are the `_apply` lemmas) and `prodComm_invFun`/`prodProdProdComm_invFun`. The latter have the raw projection `(prodComm Q₁ Q₂).invFun a` on the LHS, which never matches the simp-normal `(prodComm Q₁ Q₂).symm a`. As a result `simp` cannot evaluate `(prodComm Q₁ Q₂).symm x` or `(prodProdProdComm …).symm x`, and there is no `prodComm_symm : (prodComm Q₁ Q₂).symm = prodComm Q₂ Q₁` (it holds by rfl).","fix":"In IsometryEquiv.lean, add `Simps.apply`/`Simps.symm_apply` and `initialize_simps_projections IsometryEquiv (toFun → apply, invFun → symm_apply)`, so that these `@[simps!]` produce `prodComm_apply`/`prodComm_symm_apply`.","ev":"batch0/probe2.lean `#listprefix` shows that the generated lemmas are `prodComm_toFun`, `prodComm_invFun`, `prodProdProdComm_toFun` and `prodProdProdComm_invFun`; probe3 shows `prodComm_invFun : (IsometryEquiv.prodComm Q₁ Q₂).invFun a = a.swap`. probe1 C2b `example (x : M₂ × M₁) : (IsometryEquiv.prodComm Q₁ Q₂).symm x = x.swap := by simp` -> '`simp` made no progress'; probe2 G1 (prodProdProdComm symm) gives the same. batch0/Prod_fix.lean adds the projection setup; the regenerated `prodComm_apply`, `prodComm_symm_apply` and `prodProdProdComm_symm_apply` then let `simp` close both goals, and the file compiles.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7239ac","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.IsOrtho.prod","line":180,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"implicit-args-only-under-projections","claim":"The implicit `{v w : M₁ × M₂}` occur in the hypotheses only under `.1`/`.2`, so they cannot be inferred from `h₁ h₂`: forward use `have := IsOrtho.prod h₁ h₂` (or `h₁.prod h₂`) fails to elaborate without a type ascription. Stating the lemma on pairs, `(Q₁.prod Q₂).IsOrtho (a, c) (b, d)`, works forwards and still applies to goals about arbitrary `v w` (structure eta) and to `IsOrtho.inl_inr`.","fix":"Restate as `{a b : M₁} {c d : M₂} (h₁ : Q₁.IsOrtho a b) (h₂ : Q₂.IsOrtho c d) : (Q₁.prod Q₂).IsOrtho (a, c) (b, d)`.","ev":"batch1/Probe3.lean: (h₁ : Q₁.IsOrtho a b) (h₂ : Q₂.IsOrtho c d) : True := by have := IsOrtho.prod h₁ h₂; trivial  -- error: Application type mismatch: h₂ has type Q₂.IsOrtho c d but is expected to have type IsOrtho ?m.47 ?m.48.2 ?m.49.2. batch1/Probe4.lean (compiles): the pair-stated `IsOrtho.prod'` (proved by `h₁.prod h₂`) works in `have`, closes `(Q₁.prod Q₂).IsOrtho v w` from `h₁ : Q₁.IsOrtho v.1 w.1`, `h₂ : Q₂.IsOrtho v.2 w.2`, and proves `IsOrtho.inl_inr`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-8fee33","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.associated_prod","line":224,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"invertible-two-in-ring-instead-of-end","claim":"`associated_prod` assumes `[Invertible (2 : R)]`, but `associated` itself only needs `[Invertible (2 : Module.End R P)]` (Basic.lean chose that spelling precisely so that e.g. R = ℤ, N = ℝ is covered), and Basic.lean asks for such lemmas to be stated for the general `associatedHom S` (as `associated_comp` is). The lemma therefore does not apply over ℤ with values in ℚ, where `associated` is defined; the statement holds for every `associatedHom S` under the End-hypothesis with a one-line proof. (`associated_pi`, batch 2, has the same hypothesis.)","fix":"State it as `associatedHom_prod (S) ... [Invertible (2 : Module.End R P)] : associatedHom S (Q₁.prod Q₂) = (associatedHom S Q₁).compl₁₂ (.fst ..) (.fst ..) + (associatedHom S Q₂).compl₁₂ (.snd ..) (.snd ..)` (proof `rw [prod, map_add, associated_comp, associated_comp]`), keeping `associated_prod` as the `S = R` specialisation or a deprecated alias.","ev":"batch1/Probe1.lean (compiles, no warnings): theorem associatedHom_prod (S : Type*) [CommSemiring S] [Algebra S R] [Module S P] [IsScalarTower S R P] [Invertible (2 : Module.End R P)] (Q₁ : QuadraticMap R M₁ P) (Q₂ : QuadraticMap R M₂ P) : associatedHom S (Q₁.prod Q₂) = (associatedHom S Q₁).compl₁₂ (.fst R M₁ M₂) (.fst R M₁ M₂) + (associatedHom S Q₂).compl₁₂ (.snd R M₁ M₂) (.snd R M₁ M₂) := by rw [prod, map_add, associated_comp, associated_comp]; the Mathlib statement follows as `associatedHom_prod R Q₁ Q₂`; `associated'` follows as `associatedHom_prod ℤ Q₁ Q₂`; with `instance : Invertible (2 : Module.End ℤ ℚ)` (invOf := LinearMap.mulLeft ℤ (2⁻¹ : ℚ)) and `example : IsEmpty (Invertible (2 : ℤ))`, the ℤ/ℚ instance of the statement compiles via `associatedHom_prod ℤ Q₁ Q₂`, while batch1/Probe2.lean `:= QuadraticMap.associated_prod Q₁ Q₂` fails with `failed to synthesize instance of type class Invertible 2`. batch1/ProdCopy.lean: the original proof also compiles with `[Invertible (2 : Module.End R P)]` in place of `[Invertible (2 : R)]`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-f6d620","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.pi_apply_single","line":253,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"simp-cannot-evaluate-at-pi-single","claim":"`simp` cannot evaluate `pi Q (Pi.single i m)`: `pi_apply` fires and leaves `∑ j, Q j (Pi.single i m j) = Q i m`, which no simp lemma closes, and `pi_apply_single` is not `@[simp]`. A plain `@[simp]` is rejected by simpNF (LHS simplifies via `pi_apply`), but `@[simp high]` passes `#lint only simpNF` and lets `simp` close the goal. (Within the file, `anisotropic_of_pi`, `nonneg_pi_iff` and `Isometry.proj` re-derive this evaluation by hand.)","fix":"Tag `pi_apply_single` with `@[simp high]` (verified to pass simpNF) so simp evaluates `pi Q (Pi.single i m)`.","ev":"batch1/Probe2.lean: example ... (Q : ∀ i, QuadraticMap R (Mᵢ i) P) (i : ι) (m : Mᵢ i) : pi Q (Pi.single i m) = Q i m := by simp  -- error: unsolved goals ⊢ ∑ i_1, (Q i_1) (Pi.single i m i_1) = (Q i) m (same for a non-dependent family). batch1/ProdCopy.lean: with `@[simp] theorem pi_apply_single` `#lint only simpNF` reports 'Left-hand side simplifies from (QuadraticMap.pi Q) (Pi.single i m) to ∑ i_1, (Q i_1) (Pi.single i m i_1) using pi_apply'; with `@[simp high]` the same example closes `by simp` and `#lint only simpNF` passes ('All linting checks passed!').","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-3d0481","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.IsometryEquiv.pi","line":261,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-apply-simp-lemma-for-equiv-constructor","claim":"`IsometryEquiv.pi` is tagged only `@[simps toLinearEquiv]`, and `IsometryEquiv` has no `initialize_simps_projections`. So no apply or symm_apply lemma exists, and `simp` cannot evaluate the equivalence: `simp` makes no progress on the rfl-true goals `IsometryEquiv.pi e x i = e i (x i)` and `(IsometryEquiv.pi e).symm y i = (e i).symm (y i)`. `QuadraticMap.IsometryEquiv.pi_apply` does not exist. In contrast, `Isometry.single` (`@[simps!]`) is simp-evaluable. Two `@[simp]` rfl lemmas fix this, and they pass `#lint only simpNF`.","fix":"Add `@[simp] lemma IsometryEquiv.pi_apply : IsometryEquiv.pi e x i = e i (x i) := rfl` and `pi_symm_apply` (or `initialize_simps_projections IsometryEquiv` and `@[simps]`); `IsometryEquiv.prod` uses the same `@[simps toLinearEquiv]` and likely needs the same.","ev":"batch2/probe1.lean A1 (L40-41) and A3 (L46-47): `by simp` -> error `simp made no progress`; A2/A4 the same goals `:= rfl` compile; L30 `#check @QuadraticMap.IsometryEquiv.pi_apply` -> Unknown constant; A5 `Isometry.single Q i m j = Pi.single i m j := by simp` compiles. Fix: batch2/Prod_mod.lean L271-284 adds `@[simp]` `IsometryEquiv.pi_apply`/`pi_symm_apply` by rfl, Check example closes both goals by `simp`, `#lint only simpNF` -> 'Found 0 errors in 55 declarations'.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ff4fff","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.IsometryEquiv.pi","line":262,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-copied-from-prod-variant","claim":"The docstring of `IsometryEquiv.pi` was copied from `IsometryEquiv.prod`. It says the equivalence is built 'from a pair of isometries between the left and right parts', but the argument is a family `e : ∀ i, (Q i).IsometryEquiv (Q' i)` indexed by `ι`. There is no pair, and there are no left or right parts.","fix":"Reword to: 'An isometry between quadratic forms generated by `QuadraticMap.pi` can be constructed from a family of isometries between the components.'","ev":"src.lean L259-260: `/-- An isometry between quadratic forms generated by `QuadraticMap.pi` can be constructed\\nfrom a pair of isometries between the left and right parts. -/`, followed at L264 by the argument `(e : ∀ i, (Q i).IsometryEquiv (Q' i))`; the prod docstring at L58-59 has the same wording.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4e796d","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.anisotropic_of_pi","line":307,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"proof-rederives-adjacent-lemma","claim":"The 11-line proof of `anisotropic_of_pi` re-derives the file's own `pi_apply_single` inline (`Finset.sum_eq_zero` plus `by_cases j = i` with `Pi.single_eq_same`/`Pi.single_eq_of_ne`). Using that lemma and `Pi.single_eq_zero_iff`, the body is three lines. `nonneg_pi_iff`'s forward direction does the same through `convert … using 1` and `Finset.sum_eq_single_of_mem`, and is one line from `pi_apply_single`.","fix":"anisotropic_of_pi: `classical; intro i x hx; exact Pi.single_eq_zero_iff.mp (h (Pi.single i x) (by rw [pi_apply_single, hx]))`; nonneg_pi_iff forward: `fun h i x => by simpa only [pi_apply_single] using h (Pi.single i x)`.","ev":"batch2/Prod_mod.lean L321-325 (in-file replacement of anisotropic_of_pi, whole file compiles, exit 0); batch2/probe1.lean P1 (L56-59) and P2 (L62-66) compile. Note that in-file `congr_fun` resolves to `QuadraticMap.congr_fun`, hence `Pi.single_eq_zero_iff`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-e70181","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.nonneg_pi_iff","line":321,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"pi-variant-stronger-order-classes-than-prod","claim":"`nonneg_pi_iff` assumes `[PartialOrder P] [IsOrderedAddMonoid P]`. Its own proof, unchanged, compiles under `[Preorder P] [AddLeftMono P]`, the classes the prod analogue `nonneg_prod_iff` already uses: `Finset.sum_nonneg` needs only `Preorder` and `AddLeftMono`. Antisymmetry is never used.","fix":"State `nonneg_pi_iff` with `[Preorder P] [AddLeftMono P]` (dropping the re-bound `{P} [AddCommMonoid P] [Module R P]`).","ev":"batch2/probe1.lean G1 (L70-80): `theorem nonneg_pi_iff' [Preorder P] [AddLeftMono P] : (∀ x, 0 ≤ pi Q x) ↔ ∀ i x, 0 ≤ Q i x` with the file's proof verbatim compiles; batch2/Prod_mod.lean L327 makes the change in-file and the whole file (incl. posDef_pi_iff, which rewrites with it) compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d0a3da","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.Ring.associated_pi","line":365,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"invertible-two-in-ring-instead-of-module-end","claim":"`associated_pi` assumes `[Invertible (2 : R)]`. `associated` itself, and Basic.lean's documented convention ('We spell the condition as `[Invertible (2 : Module.End R N)]` … available in more cases than … `Invertible (2 : R)`, e.g. when `R = ℤ` and `N = ℝ`'), need only `[Invertible (2 : Module.End R P)]`. Under that hypothesis the file's proof compiles verbatim. The original therefore cannot rewrite `associated (pi Q)` for `Q : Fin 2 → QuadraticMap ℤ ℚ ℚ` (there is no instance `Invertible (2 : ℤ)`), but the weakened lemma can. The weakened `@[simp]` lemma still fires under `[Invertible (2 : R)]`, through Basic.lean's instance.","fix":"Replace `[Invertible (2 : R)]` by `[Invertible (2 : Module.End R P)]` in `associated_pi` (and likewise `associated_prod`).","ev":"batch2/probe1.lean G3 (L105-109) `associated_pi'` under `[Invertible (2 : Module.End R P)]`, file's proof verbatim, compiles; G5: `IsEmpty (Invertible (2 : ℤ))` compiles, a local `Invertible (2 : Module.End ℤ ℚ)` compiles, `associated_pi' Q` for `Q : Fin 2 → QuadraticMap ℤ ℚ ℚ` compiles, `QuadraticMap.Ring.associated_pi Q` -> 'failed to synthesize Invertible 2' (L140). batch2/Prod_mod.lean L370 in-file change, Check example under `[Invertible (2 : R)]` closes `associated (pi Q) = …` by `simp`; file exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-678806","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.tmul","line":97,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-claims-scoped-notation","claim":"The docstring of `tmul` says \"The localized notations are `m ⊗ₜ n` and `m ⊗ₜ[R] n`, accessed by `open scoped TensorProduct`\". But the `infixl ... ⊗ₜ` (L102) and `notation ... ⊗ₜ[R]` (L105) declarations are not `scoped`, so both are global and parse with no `open`. Only the type notation `M ⊗[R] N` is scoped. The sentence is left over from Mathlib 3's `localized` notation.","fix":"Reword it to say that `m ⊗ₜ n` and `m ⊗ₜ[R] n` are global notations (only `M ⊗[R] N` needs `open scoped TensorProduct`), or else make them `scoped[TensorProduct]`.","ev":"-- hunts/tensor-defs/batch0/p1_basic.lean, no `open` of any kind:\nvariable {R M N : Type*} [CommSemiring R] [AddCommMonoid M] [AddCommMonoid N] [Module R M] [Module R N]\nexample (m : M) (n : N) : m ⊗ₜ[R] n = TensorProduct.tmul R m n := rfl\nexample (m : M) (n : N) : (m ⊗ₜ n : TensorProduct R M N) = TensorProduct.tmul R m n := rfl\n-- both compile; by contrast p2_fail.lean `example : Type _ := M ⊗[R] N` fails (expected token) without the open","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-87a135","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.induction_on","line":143,"sev":"MINOR","status":"confirmed","cat":"hygiene","pattern":"linter-disabled-without-in","claim":"`set_option linter.unusedVariables false` at L143 has no `in`, so it switches the unused-variables linter off from L143 to `end Module` (L442), about 300 lines and every later declaration in the file, not just the deprecated lemma whose `zero` binder it was meant to silence. Measured: it masks no other warning today, but it would hide any future one.","fix":"Write `set_option linter.unusedVariables false in` directly before the deprecated `induction_on`.","ev":"-- hunts/tensor-defs/batch0/copy_nolinter.lean = src.lean minus L143, compiled with Mathlib's leanOptions (-DautoImplicit=false -DmaxSynthPendingDepth=3 -Dweak.linter.mathlibStandardSet=true): the only warning is\n--   copy_nolinter.lean:145:5: Variable name `zero` is not explicitly referenced.\n-- hunts/tensor-defs/batch0/copy_fixed.lean (`set_option linter.unusedVariables false in`) compiles with no output.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-03533a","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.induction_on","line":144,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"deprecation-message-wrong-target","claim":"The deprecation message says \"Use `TensorProduction.inductionOn` instead\". There is no `TensorProduction` namespace, so the message points users at a name that does not exist.","fix":"Change the message to \"Use `TensorProduct.inductionOn` instead\".","ev":"-- hunts/tensor-defs/batch0/p2_fail.lean\n#check TensorProduction.inductionOn\n-- error(lean.unknownIdentifier): Unknown identifier `TensorProduction.inductionOn`\n-- p1_basic.lean: `#check @TensorProduct.induction_on` warns \"has been deprecated: Use `TensorProduction.inductionOn` instead\"","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-594a43","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.induction_on","line":145,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"deprecated-alias-not-drop-in","claim":"The deprecated `induction_on` kept for compatibility lost `@[elab_as_elim]` when #43481 moved the attribute to `inductionOn`. Old call sites that do not use `induction ... using` now fail with an elaboration error instead of a deprecation warning, e.g. `TensorProduct.induction_on x (by simp) h hadd` or `refine x.induction_on ?_ ?_ ?_`: the motive is no longer inferred. #43481 itself had to rewrite 84 such lines in Mathlib. So the shim is not a drop-in replacement for downstream code.","fix":"Tag the deprecated lemma `@[elab_as_elim, deprecated ...]` so old term-mode/`refine` callers keep compiling with only a warning until the alias is deleted.","ev":"-- hunts/tensor-defs/batch0/p2_fail.lean (imports Mathlib.LinearAlgebra.TensorProduct.Defs)\nset_option linter.deprecated false in\nexample (f g : M ⊗[R] N →+ P) (h : ∀ m n, f (m ⊗ₜ n) = g (m ⊗ₜ n)) (x : M ⊗[R] N) :\n    f x = g x :=\n  TensorProduct.induction_on x (by simp) h (fun x y hx hy => by simp [hx, hy])\n-- error: `simp` made no progress (motive not inferred)\nset_option linter.deprecated false in\nexample ... := by\n  refine x.induction_on ?_ ?_ ?_   -- error: Type mismatch `?m.57 x` vs `f x = g x`\n-- the same calls against `TensorProduct.inductionOn` (minus the zero step) compile, and both calls compile\n-- in hunts/tensor-defs/batch0/copy_fixed.lean (src.lean with `@[elab_as_elim, deprecated ...]` on induction_on); outputs in p2_fail.out / copy_fixed.out (empty).\n-- measured: `git show 70a23a7be9 | grep '^-' | grep induction_on | grep -v 'using ...induction_on'` = 84 lines rewritten.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-fc1b78","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.CompatibleSMul","line":175,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"mixin-class-too-strong-typeclass","claim":"`CompatibleSMul R R' M N` binds `[Monoid R'] [DistribMulAction R' M] [DistribMulAction R' N]`, but its only field `(r • m) ⊗ₜ n = m ⊗ₜ[R] (r • n)` uses just `SMul R' M` and `SMul R' N`; the same over-strong binders are carried by its default instance `CompatibleSMul.isScalarTower` and by the restated lemma `smul_tmul`. Mathlib's other scalar mixins (`IsScalarTower`, `SMulCommClass`, `IsCentralScalar`) take bare `SMul`. With `[SMul R' M] [SMul R' N]` the whole file compiles, `CompatibleSMul R R M N` and `CompatibleSMul R ℕ M N` are still inferred, and `smul_tmul` applies to an action that is only an `SMul`. (Downstream files such as Basic.lean's `CompatibleSMul.int`/`.unit` were not rebuilt; the single overlappingInstances warning in the probe comes from the `omit` scaffolding, the final `#check` signatures carry no `DistribMulAction`.)","fix":"Take `[SMul R' M] [SMul R' N]` (no `Monoid R'`) in `CompatibleSMul`, `CompatibleSMul.isScalarTower` and `smul_tmul`, restructuring the section variables instead of using `omit`.","ev":"hunts/tensor-defs/batch1/c1_compatsmul_smul.lean (diff: c1_compatsmul_smul.diff; output: c1_compatsmul_smul.lean.out, EXIT=0)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-43b1aa","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.CompatibleSMul","line":175,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-docstring-lemma-list","claim":"The docstring says the class is \"only needed if `TensorProduct.smul_tmul`, `TensorProduct.smul_tmul'`, or `TensorProduct.tmul_smul` is used\", but `smul_tmul'` (L303, `r • m ⊗ₜ[R] n = (r • m) ⊗ₜ n := rfl`) takes no `CompatibleSMul` argument: `#check @TensorProduct.smul_tmul'` shows only `[SMulCommClass R R' M]`.","fix":"Drop `TensorProduct.smul_tmul'` from the list in the docstring.","ev":"#check @TensorProduct.smul_tmul'  -- in hunts/tensor-defs/batch1/checks.lean; output: ∀ ... [inst_7 : SMulCommClass R R' M] (r : R') (m : M) (n : N), r • m ⊗ₜ[R] n = (r • m) ⊗ₜ[R] n","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-39bce5","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.leftHasSMul","line":223,"sev":"MINOR","status":"confirmed","cat":"correctness","pattern":"instance-diamond-not-reducibly-defeq","claim":"The ℕ-action diamond on `M ⊗[R] N` is not reducibly defeq at the level of bundled structures: `instMulActionNatOfAddMonoid` vs `TensorProduct.leftDistribMulAction.toMulAction`, the synthesized `DistribMulAction ℕ (M ⊗[R] N)` (= `leftDistribMulAction`) vs `(inferInstance : Module ℕ _).toDistribMulAction` (= `AddCommMonoid.toNatModule`'s), and `AddCommMonoid.toNatModule` vs `TensorProduct.leftModule` all fail `with_reducible_and_instances rfl` (they pass plain `rfl`, and the `SMul ℕ` level passes). The isDefEq trace shows why: `leftHasSMul` is `id ⟨fun r => ⇑((addConGen …).lift (SMul.aux r) …)⟩`; at the transparency used for the `toSMul` field the `id` is unfolded and the coercion's domain is `(addConGen (Eqv R M N)).Quotient`, so `fun x => NSMul.nsmul n x =?= ⇑(lift …)` fails on `M ⊗[R] N =?= (addConGen (TensorProduct.Eqv R M N)).Quotient`. Dropping `id` and binding `(x : M ⊗[R] N)` explicitly makes all five diamond checks pass and the file compile (this also needs the term-mode `addMonoid` proofs). The `id` is unexplained and load-bearing: removing it alone breaks `addMonoid`. In probes, `rw`, `simp only` and `with_reducible exact` across the diamond still succeeded, so no user-facing breakage was observed; downstream files were not rebuilt with the fix.","fix":"Define the action as `⟨fun r (x : M ⊗[R] N) => ((addConGen _).lift (SMul.aux r) _) x⟩` without `id` (with `addMonoid`'s fields as `nsmul_zero := TensorProduct.zero_smul`, `nsmul_succ n x := by rw [TensorProduct.add_smul, TensorProduct.one_smul]`) and add the ℕ-module diamond to MathlibTest/InstanceDiamonds.","ev":"control (fails): hunts/tensor-defs/batch1/c9c_control.lean / c9c_control.lean.out (3 errors: MulAction, DistribMulAction, Module ℕ), e.g.\nexample : (inferInstance : DistribMulAction ℕ (M ⊗[R] N)) =\n    (inferInstance : Module ℕ (M ⊗[R] N)).toDistribMulAction := by\n  with_reducible_and_instances rfl  -- Tactic `rfl` failed\ntrace: hunts/tensor-defs/batch1/diamond4.out; fix (all pass, EXIT=0): hunts/tensor-defs/batch1/c9_noid_binder.lean (diff: c9_noid_binder.diff); `id` alone removed (breaks addMonoid): hunts/tensor-defs/batch1/c9b_noid_only.lean.out; no practical rw/simp failure: hunts/tensor-defs/batch1/diamond_rw.lean, diamond_simp.lean","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c819a9","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.leftHasSMul","line":223,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"instance-too-strong-typeclass","claim":"Well-definedness of the action only uses `smul_zero`, `smul_add` and `smul_comm` on `M`, so `leftHasSMul` (and the protected `smul_zero`, `smul_add` proved from it) need only `[DistribSMul R' M] [SMulCommClass R R' M]`; the `Monoid R'` and `DistribMulAction R' M` binders are unused. With that signature the whole file compiles and `SMul R (M ⊗[R] N)` is still reducibly defeq to `Module.toSMul`. (Downstream not rebuilt.)","fix":"State `leftHasSMul`, `TensorProduct.smul_zero` and `TensorProduct.smul_add` under `[DistribSMul R' M] [SMulCommClass R R' M]`.","ev":"hunts/tensor-defs/batch1/c2_lefthassmul_distribsmul.lean (diff: c2_lefthassmul_distribsmul.diff; EXIT=0)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-367193","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.zero_smul","line":250,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"repeated-have-instead-of-lemma","claim":"`zero_smul`, `one_smul`, `add_smul` (and `leftDistribMulAction`, L290) each open with the same `have : ∀ (r : _) (m : M) (n : N), r • m ⊗ₜ[R] n = (r • m) ⊗ₜ n := fun _ _ _ => rfl` (L251, 257, 263, 290). This is exactly `smul_tmul'` (L303, `rfl`), which needs only `leftHasSMul`; moving `smul_tmul'` to just after the `SMul R` instance and rewriting with it removes all four copies, and the file compiles.","fix":"Move `smul_tmul'` above `TensorProduct.zero_smul` and replace the four local `have`s with it.","ev":"hunts/tensor-defs/batch1/c5_no_haves.lean (diff: c5_no_haves.diff; EXIT=0)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-e3b06a","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.smul_tmul_smul","line":311,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"scalar-lemma-not-generalised-to-compatible-smul","claim":"Stated only for scalars r s : R, while its companions smul_tmul / tmul_smul in the same file are stated for any R' with [CompatibleSMul R R' M N]. The identical proof (simp_rw [smul_tmul, tmul_smul, mul_smul]) proves it for any monoid R' with [DistribMulAction R' N] [CompatibleSMul R R' M N], covering e.g. units of R and ℕ; the R case is recovered by instance search, and both Mathlib consumers' rewrite patterns (simp only [← smul_tmul_smul] in Contraction.lean, simp only [sum_tmul, smul_tmul_smul] in CanonicalTensor.lean) still work.","fix":"State it as `theorem smul_tmul_smul [DistribMulAction R' N] [CompatibleSMul R R' M N] (r s : R') (m : M) (n : N) : (r • m) ⊗ₜ[R] (s • n) = (r * s) • m ⊗ₜ[R] n` with the unchanged proof.","ev":"batch2/Probe1.lean (G1): theorem smul_tmul_smul_gen [DistribMulAction R' N] [CompatibleSMul R R' M N] (r s : R') (m : M) (n : N) : (r • m) ⊗ₜ[R] (s • n) = (r * s) • m ⊗ₜ[R] n := by simp_rw [smul_tmul, tmul_smul, mul_smul]; example (r s : R) .. := smul_tmul_smul_gen r s m n; example (u v : Rˣ) .. := smul_tmul_smul_gen u v m n; example (a b : ℕ) .. := smul_tmul_smul_gen a b m n; plus both consumer patterns. Also batch2/SrcEdit.lean (src copy with the generalised lemma in place) compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2282b2","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.instIsCentralScalar","line":325,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass-on-instance","claim":"The IsCentralScalar instance asks for [Semiring R''] [Module R'' M] [Module R''ᵐᵒᵖ M], but only a monoid acting distributively is used: the instance holds verbatim for [Monoid R'] [DistribMulAction R' M] [DistribMulAction R'ᵐᵒᵖ M] [IsCentralScalar R' M] (SMulCommClass R R'ᵐᵒᵖ M comes from SMulCommClass.op_right). As stated, instance search fails for a monoid G with these hypotheses, although the R'-action on M ⊗[R] N (leftDistribMulAction) exists for monoids.","fix":"Replace the binders by `[DistribMulAction R'ᵐᵒᵖ M] [IsCentralScalar R' M] : IsCentralScalar R' (M ⊗[R] N)` (same proof); the semiring/module case is still found by inferInstance.","ev":"batch2/Probe4.lean: example {G} [Monoid G] [DistribMulAction G M] [DistribMulAction Gᵐᵒᵖ M] [SMulCommClass R G M] [IsCentralScalar G M] : IsCentralScalar G (M ⊗[R] N) := inferInstance -- fails to synthesize with the current instance. batch2/Probe1.lean (G2) proves `instance isCentralScalar_gen [DistribMulAction R'ᵐᵒᵖ M] [IsCentralScalar R' M] : IsCentralScalar R' (M ⊗[R] N)` with the original proof; batch2/SrcEdit.lean has it in place and checks the old Semiring/Module case by inferInstance.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-52d438","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.smulCommClass_left","line":338,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-symmetric-instance","claim":"The right-factor companion is missing: isScalarTower_left has isScalarTower_right, but there is no smulCommClass_right anywhere in Mathlib (git grep), so with commuting actions on N (and the CompatibleSMul hypotheses that isScalarTower_right uses) instance search cannot find SMulCommClass R' R'₂ (M ⊗[R] N), while the IsScalarTower analogue is found.","fix":"Add `instance smulCommClass_right [SMulCommClass R' R'₂ N] : SMulCommClass R' R'₂ (M ⊗[R] N)` next to isScalarTower_right (same variables), proved by induction with `rw [← tmul_smul, ← tmul_smul, ← tmul_smul, ← tmul_smul, smul_comm]`.","ev":"batch2/Probe3.lean: example [DistribMulAction R'₂ N] [DistribMulAction R' N] [CompatibleSMul R R'₂ M N] [CompatibleSMul R R' M N] [SMulCommClass R' R'₂ N] : SMulCommClass R' R'₂ (M ⊗[R] N) := inferInstance -- failed to synthesize (the IsScalarTower analogue in the same file succeeds). The instance itself compiles in batch2/Probe1.lean (G3, smulCommClass_right_probe) and in place in batch2/SrcEdit.lean.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-600ff5","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.span_tmul_eq_top","line":418,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"special-case-of-equally-easy-general-statement","claim":"The proof uses only `subset_span` and `add_mem`, never scalars, so the same proof gives `Submodule.span S {pure tensors} = ⊤` for every semiring S with `[Module S (M ⊗[R] N)]` (with no scalar-tower assumption), and even `AddSubmonoid.closure {pure tensors} = ⊤`. Only the S = R case is stated, so Tower.lean:840 and :852 (`Submodule.baseChange_eq_span`, `baseChange_top`) get the A-span through `span_eq_top_of_span_eq_top R A _ (span_tmul_eq_top R ..)`.","fix":"Add (or generalise to) a version for `Submodule.span S` over any `S` with `[Module S (M ⊗[R] N)]`, with the same proof, and use it in Tower.lean.","ev":"example {S : Type*} [Semiring S] [Module S (M ⊗[R] N)] :\n    Submodule.span S { t : M ⊗[R] N | ∃ m n, m ⊗ₜ n = t } = ⊤ :=\n  Submodule.eq_top_iff'.2 fun t => t.inductionOn (fun m n => Submodule.subset_span ⟨m, n, rfl⟩)\n    fun _ _ => Submodule.add_mem _\nexample : AddSubmonoid.closure { t : M ⊗[R] N | ∃ m n, m ⊗ₜ n = t } = ⊤ :=\n  eq_top_iff.2 fun t _ => t.inductionOn (fun m n => AddSubmonoid.subset_closure ⟨m, n, rfl⟩)\n    fun _ _ => AddSubmonoid.add_mem _\n-- hunts/tensor-defs/batch3/probe4.lean (the file's own proof also compiles verbatim for general S: probe1.lean P4)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ae00ea","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.exists_eq_tmul_of_forall","line":432,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"explicit-args-determined-by-later-explicit-arg","claim":"`variable (R M N)` (L415) makes R, M, N explicit, although `x : M ⊗[R] N` determines them, so `exists_eq_tmul_of_forall x h` does not elaborate and every call needs `exists_eq_tmul_of_forall _ _ _ x h`. The lemma has had no consumer anywhere in Mathlib since it was added in #5766 (2023, d8f68396c1, which itself never used it).","fix":"Make R M N implicit (`variable {R M N} in`), or delete the unused lemma.","ev":"example (x : M ⊗[R] N)\n    (h : ∀ (m₁ m₂ : M) (n₁ n₂ : N), ∃ m n, m₁ ⊗ₜ n₁ + m₂ ⊗ₜ n₂ = m ⊗ₜ[R] n) :\n    ∃ m n, x = m ⊗ₜ n := exists_eq_tmul_of_forall x h\n-- hunts/tensor-defs/batch3/probe5.lean: error 'Application type mismatch: The argument x has type M ⊗[R] N but is expected to have type Type ?u'; the `_ _ _ x h` form compiles (probe1.lean P5). git grep exists_eq_tmul_of_forall origin/master: 1 hit (its definition).","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-9c8186","file":"Mathlib/LinearAlgebra/Transvection/Basic.lean","decl":"LinearEquiv.mem_transvections","line":231,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `LinearEquiv.mem_transvections` (LinearAlgebra.Transvection.Basic), `LinearEquiv.transvection_mem_transvections` (LinearAlgebra.Transvection.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file: @[simp] mem_transvections (hfv explicit) and transvection_mem_transvections {hfv} both prove `transvection hfv ∈ transvections R V` by `⟨f, v, hfv, rfl⟩`. The descriptive name matches transvection_mem_dilatransvections, and `mem_transvections` reads like the iff (which is mem_transvections_iff). Move @[simp] and deprecate mem_transvections.","fix":"Deprecate `LinearEquiv.mem_transvections` in favour of `LinearEquiv.transvection_mem_transvections`.","ev":"dupscan/Check.lean: `example := (@LinearEquiv.transvection_mem_transvections : type_of% @LinearEquiv.mem_transvections)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"unsure","astraS":"A2 (dup2 item 33, rating MINOR): Explicit `hfv` supports `have hm := mem_transvections hfv` without an expected target, whereas the implicit version needs specialization through named arguments or context. Consolidation is reasonable, but the desired binder interface deserves an explicit decision.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-ac23ce","file":"Mathlib/LinearAlgebra/UnitaryGroup.lean","decl":"Matrix.UnitaryGroup.inv_apply","line":159,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Matrix.UnitaryGroup.inv_apply` (LinearAlgebra.UnitaryGroup), `Matrix.UnitaryGroup.inv_val` (LinearAlgebra.UnitaryGroup) state exactly the same thing (Lean-checked). Reviewer: Adjacent @[simp] rfl lemmas, `⇑A⁻¹` and `↑A⁻¹` are the same `Subtype.val` term (CoeFun instance is `A.val`); Lean-3 coe_fn/coe port artefact, neither name used. Keep `inv_val`, deprecate `inv_apply`.","fix":"Deprecate `Matrix.UnitaryGroup.inv_apply` in favour of `Matrix.UnitaryGroup.inv_val`.","ev":"dupscan/Check.lean: `example := (@Matrix.UnitaryGroup.inv_val : type_of% @Matrix.UnitaryGroup.inv_apply)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 36, rating MAJOR): Both express the same matrix-valued inverse identity; there is no pointwise-inverse interpretation or distinct simplification rule.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-11ed83","file":"Mathlib/LinearAlgebra/UnitaryGroup.lean","decl":"Matrix.UnitaryGroup.mul_apply","line":163,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Matrix.UnitaryGroup.mul_apply` (LinearAlgebra.UnitaryGroup), `Matrix.UnitaryGroup.mul_val` (LinearAlgebra.UnitaryGroup) state exactly the same thing (Lean-checked). Reviewer: The CoeFun instance is `coe A := A.val` (line 129), so `⇑(A * B)` elaborates to the same Subtype.val as `↑(A * B)`. mul_apply and mul_val are adjacent @[simp] rfl lemmas, a Lean 3 coe_fn/coe port artifact; inv_ and one_ pairs exist too. Deprecate mul_apply.","fix":"Deprecate `Matrix.UnitaryGroup.mul_apply` in favour of `Matrix.UnitaryGroup.mul_val`.","ev":"dupscan/Check.lean: `example := (@Matrix.UnitaryGroup.mul_val : type_of% @Matrix.UnitaryGroup.mul_apply)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 34, rating MAJOR): Despite its name, `mul_apply` is a whole-function equality, not an entrywise lemma with matrix-index arguments. It adds no application-specific behavior.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-7f1977","file":"Mathlib/LinearAlgebra/UnitaryGroup.lean","decl":"Matrix.UnitaryGroup.one_apply","line":167,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Matrix.UnitaryGroup.one_apply` (LinearAlgebra.UnitaryGroup), `Matrix.UnitaryGroup.one_val` (LinearAlgebra.UnitaryGroup) state exactly the same thing (Lean-checked). Reviewer: Adjacent @[simp] rfl lemmas; `⇑(1 : unitaryGroup n α)` and `↑(1 : unitaryGroup n α)` elaborate to the same `Subtype.val` term because the CoeFun instance (line 70) is `coe A := A.val`, so the `_apply` copy is a Lean-3 coe_fn/coe port artefact. Neither name is used anywhere; keep `one_val`, deprecate `one_apply` (same for `inv_`/`mul_` pairs).","fix":"Deprecate `Matrix.UnitaryGroup.one_apply` in favour of `Matrix.UnitaryGroup.one_val`.","ev":"dupscan/Check.lean: `example := (@Matrix.UnitaryGroup.one_val : type_of% @Matrix.UnitaryGroup.one_apply)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 35, rating MAJOR): `one_apply` has no row or column arguments and provides exactly the same matrix equality and simp behavior as `one_val`.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-e07300","file":"Mathlib/Logic/Encodable/Basic.lean","decl":"Encodable.encodek₂","line":201,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Encodable.decode₂_encode` (Logic.Encodable.Basic), `Encodable.encodek₂` (Logic.Encodable.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file, 17 lines apart, both `decode₂ α (encode a) = some a`, proved separately. Keep the @[simp] descriptive `decode₂_encode`, deprecate `encodek₂` (Lean-3 name mirroring the `encodek` field, ~5 uses).","fix":"Deprecate `Encodable.encodek₂` in favour of `Encodable.decode₂_encode`.","ev":"dupscan/Check.lean: `example := (@Encodable.encodek₂ : type_of% @Encodable.decode₂_encode)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 37, rating MINOR): `decode₂_encode` is the clearer canonical simp name, although `encodek₂` mirrors the established `encodek` vocabulary. Treat this as low-priority compatibility cleanup.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-bc9ef7","file":"Mathlib/Logic/Equiv/Basic.lean","decl":"Equiv.piComm","line":155,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"convenience-interface-defined-twice","claim":"`Equiv.piComm` (Logic/Equiv/Basic.lean:155) and `Equiv.functionSwap` (Logic/Equiv/Defs.lean:689) are both `Function.swap` as an equivalence, built separately (equal by `rfl`); Astra: different simp/grind interfaces justify both names, but one should forward to the other.","fix":"Define `piComm` via `functionSwap`, keeping its binders and simp API.","ev":"dupscan/defs/probe2.lean: `Equiv.functionSwap α β γ = Equiv.piComm γ := rfl` compiles (import Mathlib), exit 0. Found by dupscan/DefEqScan.lean (same type, defeq bodies).","evr":"compiles","astraV":"disagrees","astraS":"**ITEM 3: VERDICT: disagrees** These have materially different public automation interfaces: - `functionSwap` takes explicit `α β` and generates whole-function equations, in both directions, registered for `simp` and `grind`. - `piComm` infers `α β`, generates a fully applied forward equation, and has the structural `[simp]` theorem `piComm_symm`. Thus definitional equality does not make a bare rename behavior-preserving. Both are equally general over `Sort*`; the distinction is the interface. Keep **`functionSwap` as the implementation in `Defs`**, with **`piComm` as a forwarding definition preserving its binders and simplification API**. Tw","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-d36bce","file":"Mathlib/Logic/Equiv/Option.lean","decl":"Equiv.optionSubtype_symm_apply_apply_coe","line":214,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Equiv.optionSubtype_symm_apply_apply_some` (Logic.Equiv.Option), `Equiv.optionSubtype_symm_apply_apply_coe` (Logic.Equiv.Option) state exactly the same thing (Lean-checked). Reviewer: Adjacent, both @[simp] rfl lemmas. The Option coercion is `some`, so `_apply_coe` duplicates `_apply_some`. Keep `_some` and deprecate `_coe`, which has 1 use in NumberField/Units/Regulator.","fix":"Deprecate `Equiv.optionSubtype_symm_apply_apply_coe` in favour of `Equiv.optionSubtype_symm_apply_apply_some`.","ev":"dupscan/Check.lean: `example := (@Equiv.optionSubtype_symm_apply_apply_coe : type_of% @Equiv.optionSubtype_symm_apply_apply_some)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 38, rating MAJOR): The coercion introduces exactly `some`, so it does not require a second matching pattern or normalization lemma.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-374177","file":"Mathlib/Logic/Equiv/Option.lean","decl":"Equiv.optionEquivSumPUnit_coe","line":269,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Equiv.optionEquivSumPUnit_some` (Logic.Equiv.Option), `Equiv.optionEquivSumPUnit_coe` (Logic.Equiv.Option) state exactly the same thing (Lean-checked). Reviewer: Adjacent @[simp] rfl lemmas. The Option coercion is `some`, so `_coe` duplicates `_some`. Deprecate `_coe`.","fix":"Deprecate `Equiv.optionEquivSumPUnit_coe` in favour of `Equiv.optionEquivSumPUnit_some`.","ev":"dupscan/Check.lean: `example := (@Equiv.optionEquivSumPUnit_coe : type_of% @Equiv.optionEquivSumPUnit_some)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 39, rating MAJOR): The `_some`/`_none` constructor family already covers the API; `_coe` supplies no additional simp behavior.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-fce39e","file":"Mathlib/Logic/Function/Conjugate.lean","decl":"Function.Semiconj₂.isAssociative_right","line":173,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-sibling-lemma","claim":"`Semiconj₂` transfers associativity (`isAssociative_right/left`) and idempotence (`isIdempotent_right/left`) along surjective/injective maps, but not commutativity: there is no `Std.Commutative` analogue anywhere in Mathlib. It is a 2-line proof in the same shape as `isAssociative_right`.","fix":"Add `Semiconj₂.commutative_right [Std.Commutative ga] (h) (h_surj : Surjective f) : Std.Commutative gb` and `commutative_left`.","ev":"probe1.lean: both lemmas compile; `git grep 'Semiconj₂.*Std.Commutative\\|isCommutative_right'` finds nothing.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-aacc31","file":"Mathlib/Logic/Godel/GodelBetaFunction.lean","decl":"Nat.coprime_mul_succ","line":52,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"general-material-wrong-file","claim":"`Nat.coprime_mul_succ`, `m - n ∣ a → Coprime (n * a + 1) (m * a + 1)`, is a general public number-theory lemma. It sits in `Logic/Godel/GodelBetaFunction.lean` with no docstring, so it is undiscoverable from `Data/Nat/GCD`. Its name describes neither the divisibility hypothesis nor the `+ 1` shape. Its only use is the private `pairwise_coprime_coprimes` in this file.","fix":"Move it to `Mathlib/Data/Nat/GCD/Basic.lean` with a docstring (and a more descriptive name, e.g. `coprime_mul_add_one_of_sub_dvd`), leaving a deprecated alias.","ev":"git grep: the only uses of `coprime_mul_succ` are L52 (definition) and L85 (private `pairwise_coprime_coprimes`).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4fec1d","file":"Mathlib/Logic/Godel/GodelBetaFunction.lean","decl":"Nat.unbeta","line":93,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-overstates","claim":"`unbeta` is documented as 'Inverse of Gödel's Beta Function' and compared with `Encodable.encodeList`, but it is not injective, so no decoder can recover the list from its code: `unbeta [2] = unbeta [2, 2] = 38`, and `beta 38 i = 2` for all `i < 5`. It is only a right inverse on indices below a length supplied separately (which is exactly what `beta_unbeta_coe` states). Separately, `beta`'s docstring writes `(Encodable.decodeList)[i]`, which does not typecheck (`decodeList : ℕ → Option (List α)`).","fix":"Say 'a code `c` with `beta c i = l[i]` for `i < l.length` (the length is not recoverable)', and describe the comparison with `decodeList` in prose.","ev":"-- hunts/godel-beta/P.lean: `#eval (Nat.unbeta [2], Nat.unbeta [2, 2])` prints `(38, 38)`; `example : Nat.unbeta [2] = Nat.unbeta [2, 2] := by decide +kernel` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-9a042b","file":"Mathlib/Logic/Relation.lean","decl":"Relation.EqvGen.eqvGen_mono","line":862,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Relation.EqvGen.mono` (Logic.Relation), `Relation.EqvGen.eqvGen_mono` (Logic.Relation) state exactly the same thing (Lean-checked). Reviewer: Same namespace, 14 lines apart: `r ≤ p → EqvGen r ≤ EqvGen p`, one by induction and one by term-mode recursion. Keep `EqvGen.mono`, which matches ReflGen/TransGen/ReflTransGen.mono and is used externally. Deprecate the stuttering `EqvGen.eqvGen_mono`, which has 4 internal uses.","fix":"Deprecate `Relation.EqvGen.eqvGen_mono` in favour of `Relation.EqvGen.mono`.","ev":"dupscan/Check.lean: `example := (@Relation.EqvGen.eqvGen_mono : type_of% @Relation.EqvGen.mono)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 40, rating MAJOR): The second recursive proof introduces no different interface or attribute; `mono` also matches the other relation-closure APIs.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-c622d4","file":"Mathlib/MeasureTheory/Constructions/Cylinders.lean","decl":"MeasureTheory.measurable_cylinderEvents_lambda","line":431,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `Measurable.of_eval` (MeasureTheory.MeasurableSpace.Constructions), `MeasureTheory.measurable_cylinderEvents_lambda` (MeasureTheory.Constructions.Cylinders) have exactly the same statement (Lean-checked), so `MeasureTheory.measurable_cylinderEvents_lambda` does not state what its name promises and the intended lemma is missing. Reviewer: Misstated lemma: despite its name, `measurable_cylinderEvents_lambda` concludes plain `Measurable f` for the product σ-algebra (no `cylinderEvents Δ`) with the same proof `measurable_pi_iff.mpr hf`, so it duplicates `Measurable.of_eval`. It is unused. Keep `Measurable.of_eval`; deprecate it, or restate it as `(hf : ∀ i ∈ Δ, ...) : Measurable[_, cylinderEvents Δ] f`. Astra rates it CRITICAL (a lemma weaker than or unrelated to its name).","fix":"Restate `MeasureTheory.measurable_cylinderEvents_lambda` as its name says (keep `Measurable.of_eval`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@MeasureTheory.measurable_cylinderEvents_lambda : type_of% @Measurable.of_eval)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 24, rating CRITICAL): The full product σ-algebra is `cylinderEvents univ`, so the current name has a defensible special-case reading. However, the surrounding API explicitly concerns arbitrary `Δ`. Correct: `(hf : ∀ i ∈ Δ, Measurable fun a ↦ f a i) : Measurable[_, cylinderEvents Δ] f`. **This implication already exists as the reverse direction of `measurable_cylinderEvents_iff`**; the missing piece is the correctly stated wrapper. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/MeasureTheory/Constructions/Cylinders.lean#L404-L433)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-f68bfe","file":"Mathlib/MeasureTheory/Constructions/Cylinders.lean","decl":"MeasureTheory.measurable_uniqueElim_cylinderEvents","line":448,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `MeasureTheory.measurable_uniqueElim_cylinderEvents` (MeasureTheory.Constructions.Cylinders), `measurable_uniqueElim` (MeasureTheory.MeasurableSpace.Constructions) have exactly the same statement (Lean-checked), so `MeasureTheory.measurable_uniqueElim_cylinderEvents` does not state what its name promises and the intended lemma is missing. Reviewer: `measurable_uniqueElim_cylinderEvents` is a verbatim copy of `measurable_uniqueElim` (@[fun_prop]), with the same statement over the default pi σ-algebra and the same proof. Despite its name it never mentions cylinderEvents, and it has no uses. Delete it or restate it with `Measurable[_, cylinderEvents _]`. Nearby `measurable_cylinderEvents_lambda` has the same smell.","fix":"Restate `MeasureTheory.measurable_uniqueElim_cylinderEvents` as its name says (keep `measurable_uniqueElim`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@measurable_uniqueElim : type_of% @MeasureTheory.measurable_uniqueElim_cylinderEvents)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 28, rating MAJOR): The context supports an omitted target σ-algebra, but the existing product-measurability statement is actually stronger than measurability into any `cylinderEvents Δ`. Correct wrapper: `Measurable[_, cylinderEvents Δ] (uniqueElim : X (default : ι) → ∀ i, X i)`. It already follows from `measurable_uniqueElim` using `Measurable.mono` and `cylinderEvents_le_pi`; no mathematical fact is missing. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/MeasureTheory/Constructions/Cylinders.lean#L415-L450)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-4d1063","file":"Mathlib/MeasureTheory/Function/LpSeminorm/ChebyshevMarkov.lean","decl":"MemLp.meas_ge_lt_top'_enorm","line":68,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"specialisation-reproved","claim":"`Integrable.measure_enorm_ge_lt_top` (MeasureTheory/Function/L1Space/Integrable.lean:663) re-derives the `p = 1` case of `MemLp.meas_ge_lt_top'_enorm` from `meas_ge_le_mul_pow_eLpNorm_enorm` in 7 lines; it is `(memLp_one_iff_integrable.2 hf).meas_ge_lt_top'_enorm one_ne_zero one_ne_top hε.ne' (by simp [hε'])`.","fix":"Prove `Integrable.measure_enorm_ge_lt_top` from `MemLp.meas_ge_lt_top'_enorm`.","ev":"hunts/chebyshev-markov/probe1.lean (B): the one-term proof of the `Integrable` statement compiles, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-44c60b","file":"Mathlib/MeasureTheory/Function/LpSeminorm/ChebyshevMarkov.lean","decl":"MemLp.meas_ge_lt_top'_enorm","line":70,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"hypothesis-implied-by-others","claim":"The hypothesis `hε' : ε = ∞ → μ {x | ‖f x‖ₑ = ⊤} = 0` of `MemLp.meas_ge_lt_top'_enorm` is automatic: for `MemLp f p μ` with `p ≠ 0, ∞`, `∫ ‖f‖ₑ ^ p.toReal < ∞` forces `‖f x‖ₑ < ∞` a.e., so `μ {x | ‖f x‖ₑ = ⊤} = 0`. Every caller must discharge a hypothesis the other assumptions already imply.","fix":"Prove `MemLp.measure_enorm_eq_top : μ {x | ‖f x‖ₑ = ⊤} = 0` (5 lines via `ae_lt_top'`) and drop `hε'` (deprecating the old signature).","ev":"hunts/chebyshev-markov/probe1.lean (A): `MemLp.measure_enorm_eq_top` (from `ae_lt_top'` on `‖f‖ₑ ^ p.toReal` and `lintegral_rpow_enorm_lt_top_of_eLpNorm_lt_top`) and `MemLp.meas_ge_lt_top'_enorm'` without `hε'` compile, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-d5f529","file":"Mathlib/MeasureTheory/Function/LpSeminorm/ChebyshevMarkov.lean","decl":"MemLp.meas_ge_lt_top'","line":77,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`MemLp.meas_ge_lt_top'` and `MemLp.meas_ge_lt_top` assume `[NormedAddCommGroup E]`, but neither commutativity nor separation is used: both hold for `[SeminormedAddGroup E]`, via `meas_ge_lt_top'_enorm` (Astra A1 item 2).","fix":"Weaken the section variable to `[SeminormedAddGroup E]`.","ev":"hunts/chebyshev-markov/probe1.lean (E): both statements for `[SeminormedAddGroup G]` compile from `MemLp.meas_ge_lt_top'_enorm`, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-7873da","file":"Mathlib/MeasureTheory/Function/LpSeminorm/Monotonicity.lean","decl":"MeasureTheory.MemLp.of_le_mul'","line":231,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `MeasureTheory.MemLp.of_le_mul'` (MeasureTheory.Function.LpSeminorm.Monotonicity), `MeasureTheory.MemLp.of_enorm_le_mul` (MeasureTheory.Function.LpSeminorm.Monotonicity) state exactly the same thing (Lean-checked). Reviewer: Same file, identical enorm statement with c : ℝ≥0 (proved via two different eLpNorm lemmas). of_enorm_le_mul sits next to of_nnnorm_le_mul; of_le_mul' is a later copy. Both unused; deprecate of_le_mul'.","fix":"Deprecate `MeasureTheory.MemLp.of_le_mul'` in favour of `MeasureTheory.MemLp.of_enorm_le_mul`.","ev":"dupscan/Check.lean: `example := (@MeasureTheory.MemLp.of_enorm_le_mul : type_of% @MeasureTheory.MemLp.of_le_mul')` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 41, rating MAJOR): Unlike neighboring norm variants, these both use the same extended norm and finite nonnegative multiplier. The prime marks no remaining generalization.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-8a37ca","file":"Mathlib/MeasureTheory/Function/LpSeminorm/SMul.lean","decl":"MeasureTheory.MemLp.const_mul'","line":104,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `MeasureTheory.MemLp.const_mul` (MeasureTheory.Function.LpSeminorm.SMul), `MeasureTheory.MemLp.const_mul'` (MeasureTheory.Function.LpSeminorm.SMul) state exactly the same thing (Lean-checked). Reviewer: Both are `{f : α → 𝕜} … : MemLp (fun x => c * f x) p μ := hf.const_smul c` over [NormedRing 𝕜]. The primed one sits in the ENormSMulClass section but never uses ε, so it adds nothing. It has no uses; deprecate it.","fix":"Deprecate `MeasureTheory.MemLp.const_mul'` in favour of `MeasureTheory.MemLp.const_mul`.","ev":"dupscan/Check.lean: `example := (@MeasureTheory.MemLp.const_mul' : type_of% @MeasureTheory.MemLp.const_mul)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 42, rating MAJOR): The generalized section contributes no parameters to this declaration, and the primed theorem even invokes the same unprimed scalar-multiplication result.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-334507","file":"Mathlib/MeasureTheory/Group/Arithmetic.lean","decl":"Finset.measurable_prod","line":766,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `Finset.measurable_fun_prod` (MeasureTheory.Group.Arithmetic), `Finset.measurable_prod` (MeasureTheory.Group.Arithmetic) have exactly the same statement (Lean-checked), so `Finset.measurable_prod` does not state what its name promises and the intended lemma is missing. Reviewer: Adjacent lemmas with identical statement (`Measurable fun a ↦ ∏ i ∈ s, f i a`) and identical proof. In the List/Multiset/Finset.aemeasurable family `_prod` is the `Measurable (∏ ...)` form and `_fun_prod` the pointwise form, so Finset.measurable_prod (and its to_additive measurable_sum) should be restated as `Measurable (∏ i ∈ s, f i)` or deprecated.","fix":"Restate `Finset.measurable_prod` as its name says (keep `Finset.measurable_fun_prod`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@Finset.measurable_prod : type_of% @Finset.measurable_fun_prod)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 2, rating MAJOR): The broad name accurately describes product measurability, and `Finset.prod_apply` connects the two intended forms. Nevertheless, the surrounding family consistently distinguishes the function-valued product from its pointwise expression. Correct `measurable_prod` to conclude `Measurable (∏ i ∈ s, f i)`, retaining the hypotheses. This repairs an API form, not missing mathematical content. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/MeasureTheory/Group/Arithmetic.lean#L802-L864)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-35318f","file":"Mathlib/MeasureTheory/Group/Arithmetic.lean","decl":"Finset.measurable_sum","line":825,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `Finset.measurable_fun_sum` (MeasureTheory.Group.Arithmetic), `Finset.measurable_sum` (MeasureTheory.Group.Arithmetic) have exactly the same statement (Lean-checked), so `Finset.measurable_sum` does not state what its name promises and the intended lemma is missing. Reviewer: This is a misstatement. `Finset.measurable_prod` is a verbatim copy, statement and proof, of `Finset.measurable_fun_prod` (pointwise `fun a ↦ ∏ i ∈ s, f i a`). By analogy with Finset.aemeasurable_prod and List/Multiset.measurable_prod, it should state `Measurable (∏ i ∈ s, f i)`. Restate it and fix its 1 use in Probability/Distributions/Gaussian/Multivariate.","fix":"Restate `Finset.measurable_sum` as its name says (keep `Finset.measurable_fun_sum`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@Finset.measurable_sum : type_of% @Finset.measurable_fun_sum)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 32, rating MAJOR): This is the generated additive consequence of item 2, not an independent source defect. The current statement does accurately express finite-sum measurability, but the sibling convention calls for `Measurable (∑ i ∈ s, f i)` under `measurable_sum`, while `measurable_fun_sum` retains the pointwise lambda. Fixing the multiplicative declaration generates that distinction. [Generating declarations](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/MeasureTheory/Group/Arithmetic.lean#L824-L864)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-fb5090","file":"Mathlib/MeasureTheory/Integral/IntervalIntegral/TrapezoidalRule.lean","decl":"trapezoidal_error","line":43,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-misnames-quantity","claim":"`trapezoidal_error f N a b := trapezoidal_integral f N a b - ∫ x in a..b, f x` is the *signed* error, but its docstring calls it 'the absolute error' (in numerical analysis the absolute error is `|approx - exact|`); e.g. it equals `-1` for `f = 1`, `N = 0` on `[0, 1]`. The docstring of `trapezoidal_error_symm` then says 'the absolute error … does not change when the endpoints are swapped', while the theorem it documents states that the (signed) error changes sign: `trapezoidal_error f N a b = -trapezoidal_error f N b a`.","fix":"Call it 'the (signed) error' in both docstrings, and say in `trapezoidal_error_symm` that the error changes sign (so its absolute value is unchanged).","ev":"hunts/trapezoidal/probe1.lean P3 `trapezoidal_error (fun _ ↦ 1) 0 0 1 = -1` compiles; L43 docstring 'The absolute error of trapezoidal integration.'; L61 docstring vs L63 statement. Exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-4960f0","file":"Mathlib/MeasureTheory/Integral/IntervalIntegral/TrapezoidalRule.lean","decl":"trapezoidal_integral_symm","line":49,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-hypothesis","claim":"Five lemmas assume `N_nonzero : 0 < N` that they do not need: `trapezoidal_integral_symm`, `trapezoidal_error_symm`, `sum_trapezoidal_integral_adjacent_intervals`, `trapezoidal_integral_ext` and `sum_trapezoidal_error_adjacent_intervals` all hold at `N = 0` (the rule is `(b - a) / 0 * … = 0` there, so both sides agree; the `ext` lemma reduces to `0 + T₁ = T₁`). Only the error bounds genuinely need `0 < N` (at `N = 0` they would claim `|∫ f| ≤ 0`).","fix":"Drop `N_nonzero` from the five lemmas (case-split `N = 0` by `simp [trapezoidal_integral]`).","ev":"hunts/trapezoidal/probe1.lean P1: all five statements without `0 < N` compile; P2 shows the error bound fails at `N = 0` (`f = 1` on `[0, 1]`). Exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-de10db","file":"Mathlib/MeasureTheory/Integral/IntervalIntegral/TrapezoidalRule.lean","decl":"trapezoidal_integral_one","line":77,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-wrong-term","claim":"The docstring of `trapezoidal_integral_one` calls the single-trapezoid formula `(b - a) / 2 * (f a + f b)` 'the \"midpoint rule\"'. The midpoint rule is `(b - a) * f ((a + b) / 2)`, a different quadrature (e.g. for `x ↦ x ^ 2` on `[0, 1]` they give `1/2` and `1/4`); the formula is the (simple) trapezoidal rule.","fix":"Replace '(the \"midpoint rule\")' by '(the simple trapezoidal rule)'.","ev":"hunts/trapezoidal/probe1.lean P4: `trapezoidal_integral (fun x ↦ x ^ 2) 1 0 1 ≠ (1 - 0) * ((0 + 1) / 2) ^ 2` by `norm_num [trapezoidal_integral_one]` compiles. Exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-dd6858","file":"Mathlib/MeasureTheory/Integral/IntervalIntegral/TrapezoidalRule.lean","decl":"trapezoidal_error_le","line":232,"sev":"MINOR","status":"suspected","cat":"generality","pattern":"hypothesis-stronger-than-classical","claim":"Astra argues (not formalised here) that the error bound's hypotheses are stronger than the classical estimate needs: `h_ddf` requires `derivWithin f [[a, b]]` to be differentiable at the endpoints, whereas continuity of `f` on the closed interval, twice differentiability in the interior and an interior bound on `f''` suffice; e.g. `f x = x² sin (log x)` (`f 0 = 0`) on `[0, 1]` has `|f''| ≤ 4` inside but `f'` has no right derivative at `0`. Separately, the construction and the algebraic lemmas would work for vector-valued `f : ℝ → E` (normed space), and the file lacks basic locality/linearity/affine-exactness API (`trapezoidal_integral_congr`, `_add`, `_smul`, exactness on affine maps), which users must currently get by unfolding the sum.","fix":"Weaken `h_ddf` to interior twice-differentiability with continuity on `[[a, b]]`, generalise the codomain, and add the basic algebraic API.","ev":"Suspected: Astra's A1 items 7, 19, 20 (paper arguments); `git grep trapezoidal -- Mathlib` finds only this file, so the API lemmas do not exist elsewhere; no Lean proof of the weakened bound was attempted.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-e413a6","file":"Mathlib/MeasureTheory/Measure/Content.lean","decl":"MeasureTheory.Content.innerContent_mono'","line":224,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `MeasureTheory.Content.innerContent_mono` (MeasureTheory.Measure.Content), `MeasureTheory.Content.innerContent_mono'` (MeasureTheory.Measure.Content) state exactly the same thing (Lean-checked). Reviewer: Identical statement and proof (`biSup_mono fun _ hK => hK.trans h2`) 80 lines apart in the same file. The first carries the docstring and about 7 uses; the primed copy has 1 use. Deprecate innerContent_mono'.","fix":"Deprecate `MeasureTheory.Content.innerContent_mono'` in favour of `MeasureTheory.Content.innerContent_mono`.","ev":"dupscan/Check.lean: `example := (@MeasureTheory.Content.innerContent_mono' : type_of% @MeasureTheory.Content.innerContent_mono)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 44, rating MAJOR): Both provide precisely the same unbundled monotonicity interface; the prime signifies no bundled variant or different assumptions.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-e49e94","file":"Mathlib/MeasureTheory/Measure/OpenPos.lean","decl":"IsOpen.measure_zero_iff_eq_empty","line":77,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `IsOpen.measure_eq_zero_iff` (MeasureTheory.Measure.OpenPos), `IsOpen.measure_zero_iff_eq_empty` (MeasureTheory.Measure.OpenPos) state exactly the same thing (Lean-checked). Reviewer: Same file; measure_zero_iff_eq_empty is proved from measure_eq_zero_iff and differs only in μ being implicit (after `variable {μ ν}`); one use (l.83). Keep the explicit-μ one, which sits in the measure_pos_iff family.","fix":"Deprecate `IsOpen.measure_zero_iff_eq_empty` in favour of `IsOpen.measure_eq_zero_iff`.","ev":"dupscan/Check.lean: `example := (@IsOpen.measure_zero_iff_eq_empty : type_of% @IsOpen.measure_eq_zero_iff)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup2 item 43, rating MINOR): The [implicit-measure wrapper](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/MeasureTheory/Measure/OpenPos.lean#L69-L83) enables expressions such as `hU.measure_zero_iff_eq_empty.mp hzero` with the measure inferred. Keeping that convenience as a thin wrapper is defensible.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-49925a","file":"Mathlib/MeasureTheory/Measure/ProbabilityMeasure.lean","decl":"MeasureTheory.ProbabilityMeasure.coeFn_comp_toFiniteMeasure_eq_coeFn","line":194,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `MeasureTheory.ProbabilityMeasure.coeFn_comp_toFiniteMeasure_eq_coeFn` (MeasureTheory.Measure.ProbabilityMeasure), `MeasureTheory.ProbabilityMeasure.coeFn_toFiniteMeasure` (MeasureTheory.Measure.ProbabilityMeasure) state exactly the same thing (Lean-checked). Reviewer: Both are @[simp] rfl lemmas stating `⇑ν.toFiniteMeasure = ⇑ν`, 9 lines apart. Keep the short conventional name and deprecate the mathlib3-era `coeFn_comp_toFiniteMeasure_eq_coeFn` (5 uses). toFiniteMeasure_apply versus toFiniteMeasure_apply_eq_apply (l.186/198) looks like a similar duplicate.","fix":"Deprecate `MeasureTheory.ProbabilityMeasure.coeFn_comp_toFiniteMeasure_eq_coeFn` in favour of `MeasureTheory.ProbabilityMeasure.coeFn_toFiniteMeasure`.","ev":"dupscan/Check.lean: `example := (@MeasureTheory.ProbabilityMeasure.coeFn_toFiniteMeasure : type_of% @MeasureTheory.ProbabilityMeasure.coeFn_comp_toFiniteMeasure_eq_coeFn)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 46, rating MAJOR): The long name does not express an additional composition-level identity; both declarations simplify the same function coercion.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-58ede2","file":"Mathlib/MeasureTheory/Measure/ProbabilityMeasure.lean","decl":"MeasureTheory.ProbabilityMeasure.toFiniteMeasure_apply_eq_apply","line":198,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `MeasureTheory.ProbabilityMeasure.toFiniteMeasure_apply_eq_apply` (MeasureTheory.Measure.ProbabilityMeasure), `MeasureTheory.ProbabilityMeasure.toFiniteMeasure_apply` (MeasureTheory.Measure.ProbabilityMeasure) state exactly the same thing (Lean-checked). Reviewer: Same file, 12 lines apart: both are rfl proofs of `μ.toFiniteMeasure s = μ s`. One is @[simp] `_apply_eq_apply`; the other is plain `_apply`, next to @[simp] coeFn_toFiniteMeasure, which already covers it for simp. Neither is used. Keep toFiniteMeasure_apply and deprecate `_apply_eq_apply`.","fix":"Deprecate `MeasureTheory.ProbabilityMeasure.toFiniteMeasure_apply_eq_apply` in favour of `MeasureTheory.ProbabilityMeasure.toFiniteMeasure_apply`.","ev":"dupscan/Check.lean: `example := (@MeasureTheory.ProbabilityMeasure.toFiniteMeasure_apply : type_of% @MeasureTheory.ProbabilityMeasure.toFiniteMeasure_apply_eq_apply)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 45, rating MAJOR): These are identical application lemmas, and the retained function-coercion simp rule already covers applications. No distinct pointwise simplification capability disappears.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-68ed48","file":"Mathlib/MeasureTheory/Measure/Real.lean","decl":"MeasureTheory.measureReal_restrict_apply₀'","line":114,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `MeasureTheory.measureReal_restrict_apply₀'` (MeasureTheory.Measure.Real), `MeasureTheory.Measure.restrict_apply₀'` (MeasureTheory.Measure.Restrict) have exactly the same statement (Lean-checked), so `MeasureTheory.measureReal_restrict_apply₀'` does not state what its name promises and the intended lemma is missing. Reviewer: measureReal_restrict_apply₀' is mis-stated: it states `μ.restrict s t = μ (t ∩ s)` (no `.real`), i.e. Measure.restrict_apply₀', whereas its neighbour measureReal_restrict_apply' states `(μ.restrict s).real t = μ.real (t ∩ s)`. Unused. Restate with `.real`. Astra rates it CRITICAL (a lemma weaker than or unrelated to its name).","fix":"Restate `MeasureTheory.measureReal_restrict_apply₀'` as its name says (keep `MeasureTheory.Measure.restrict_apply₀'`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@MeasureTheory.Measure.restrict_apply₀' : type_of% @MeasureTheory.measureReal_restrict_apply₀')` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 6, rating CRITICAL): The existing equality is stronger information from which the real-valued equality follows, but it concerns the wrong codomain for this explicitly named family. Correct: `(hs : NullMeasurableSet s μ) : (μ.restrict s).real t = μ.real (t ∩ s)`. Apply `congrArg ENNReal.toReal` to `Measure.restrict_apply₀' hs`; no finiteness assumption is needed. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/MeasureTheory/Measure/Real.lean#L97-L119)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261006-e85c67","file":"Mathlib/MeasureTheory/Measure/ResolventTransform.lean","decl":"MeasureTheory.resolventTransform","line":100,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"Assumptions are stronger than used. The definition section (`resolventTransform` and its four lemmas) needs only `[CommSemiring 𝕜] [NormedSpace ℝ A] [Algebra 𝕜 A]`, not `[NormedField 𝕜] [NormedAlgebra ℝ A] [NormedAlgebra 𝕜 A]`; the derivative section needs `[OpensMeasurableSpace 𝕜]`, not `[BorelSpace 𝕜]` — a copy with both changes compiles. Astra further reports (untested): `integrable_resolvent` does not need `[CompleteSpace A] [SecondCountableTopology A] [MeasurableSpace A] [BorelSpace A]`; `[HereditarilyLindelofSpace 𝕜]` follows from the isometric embedding into a second-countable A; `measurable_resolvent` and the norm bound do not need a nontrivially normed field.","fix":"Weaken the section variables as above.","ev":"-- hunts/resolvent/ProbeGen.lean: Definition section `[CommSemiring 𝕜] [NormedRing A] [NormedSpace ℝ A] [Algebra 𝕜 A]`, Deriv section `[OpensMeasurableSpace 𝕜]` — whole file compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-093d2f","file":"Mathlib/MeasureTheory/Measure/ResolventTransform.lean","decl":"MeasureTheory.resolventTransform","line":106,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"junk-value-presented-as-fact","claim":"The docs present `resolventTransform` as the Stieltjes/Cauchy transform without its junk conventions. At poles the kernel is 0 (`resolventTransform (dirac 0) 0 = 0` over ℝ); a non-integrable kernel gives 0 (so the transform is not additive in μ: T(vol|(0,1)) 0 = 0, T(δ₁) 0 = 1, T(sum) 0 = 0); an incomplete A gives 0 identically. The module summary of `hasDerivAt_resolventTransform` drops `IsFiniteMeasure μ` (without it the derivative formula fails: μ = vol|[1,∞), a = 0), the `RCLike A` restriction, and says `μ.support` where the theorem uses `algebraMap 𝕜 A '' μ.support`. Typos: `∂u` for `∂μ`, 'Stieljes'. The main theorems have no docstrings.","fix":"Document the integrable domain and the zero conventions; restate the summary with the actual hypotheses; fix the typos; add theorem docstrings.","ev":"open spectrum in\nexample : MeasureTheory.resolventTransform (MeasureTheory.Measure.dirac (0 : ℝ)) (0 : ℝ) = 0 := by\n  simp [resolvent]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b16073","file":"Mathlib/MeasureTheory/Measure/ResolventTransform.lean","decl":"MeasureTheory.hasDerivAt_resolventTransform","line":131,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"`hasDerivAt_resolventTransform` ends with `… |>.2`, discarding the integrability of the derivative kernel `fun x ↦ resolvent a x ^ 2` that `hasDerivAt_integral_of_dominated_loc_of_deriv_le` proves; `analyticOn_resolventTransform` proves analyticity near every point but exports only `AnalyticOn` (not `AnalyticOnNhd`). The closedness of `algebraMap 𝕜 A '' μ.support` is re-proved three times instead of once.","fix":"Export `integrable_resolvent_sq` and an `AnalyticOnNhd` version; factor out `isClosed_algebraMap_image_support`.","ev":"-- ResolventTransform.lean:178  `... (by fun_prop) h_deriv |>.2`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-897ecf","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition","line":59,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-literal-formula-wrong","claim":"Loose documentation. (1) The docstring and the module docstring (L24) say 'a Jordan decomposition *of a measurable space*'; it is a pair of mutually singular finite measures *on* `α`, i.e. the Jordan decomposition of the signed measure `posPart - negPart`. (2) The module docstring says `j` decomposes `s` if `s = j.posPart - j.negPart`. In Lean that is `Measure`'s truncated subtraction, which for any Jordan decomposition equals `j.posPart` (proved below), so the literal formula is wrong. The intended `j.posPart.toSignedMeasure - j.negPart.toSignedMeasure` is `j.toSignedMeasure`. (3) The field docstrings lack full stops. (Astra's blind pass, item 3, independently flags the literal formula as misleading.)","fix":"Reword to 'a pair of mutually singular finite measures on `α`' and write `s = j.toSignedMeasure` (not `s = j.posPart - j.negPart`) in the module docstring, ending the field docstrings with full stops.","ev":"-- hunts/vm-jordan/batch0/probe3.lean (compiles; imports JordanSub)\nexample (j : JordanDecomposition α) : j.posPart - j.negPart = j.posPart := by\n  have h := Measure.toJordanDecomposition_toSignedMeasure_sub (μ := j.posPart) (ν := j.negPart)\n  have h2 : (j.posPart.toSignedMeasure - j.negPart.toSignedMeasure).toJordanDecomposition = j :=\n    JordanDecomposition.toJordanDecomposition_toSignedMeasure j\n  rw [h2] at h\n  exact (congrArg JordanDecomposition.posPart h).symm","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-00059b","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.instSMul","line":86,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"non-defeq-instance-diamond","claim":"Non-defeq instance diamond on `SMul ℝ≥0 (JordanDecomposition α)`. Because the file also declares `instSMulReal : SMul ℝ (JordanDecomposition α)` (L91), Mathlib's generic `NNReal.instSMulOfReal : [SMul ℝ M] → SMul ℝ≥0 M` (Mathlib/Basic/NNReal/Defs.lean:258, `c • m := (c : ℝ) • m`) already provides an `SMul ℝ≥0` instance. With `instSMul` erased, `#synth SMul ℝ≥0 (JordanDecomposition α)` returns `NNReal.instSMulOfReal`. The hand-written `instSMul` (`⟨r • j.posPart, r • j.negPart, _⟩`) is not defeq to it, at either reducible-and-instances or default transparency: the generic one unfolds to the classical `if 0 ≤ (r : ℝ) then … else …` of `instSMulReal`. The two agree only propositionally (`coe_smul`). `r • j` elaborates to `instSMul`, so generic lemmas stated for the derived instance do not fire. `NNReal.smul_def r j : r • j = (r : ℝ) • j` is rejected with a type mismatch that differs only in the instance, and `rw [NNReal.smul_def]` reports no occurrence of `?c • ?x` in `r • j = ↑r • j`. No open upstream PR (gh search 'JordanDecomposition smul', 'toJordanDecomposition', 'instSMulOfReal diamond'). Astra's targeted refutation (A2.answer.md) agrees it is a genuine non-defeq diamond on operation data but rates it MINOR: API/instance hygiene with an existing workaround (`coe_smul`), not a wrong statement or an exact duplicate definition; graded MINOR under the lane's calibration.","fix":"Delete `instSMul` so that `SMul ℝ≥0` is the inherited `NNReal.instSMulOfReal`, define `instSMulReal` through a plain `def nnsmul` scaling both parts, and reprove `smul_posPart`/`smul_negPart`/`real_smul_def`/`real_smul_nonneg`/`real_smul_neg` in one line each (`coe_smul` becomes `rfl`); the rest of the file compiles unchanged.","ev":"-- hunts/vm-jordan/batch0/probe2.lean (output probe2.out), probe1.lean (probe1.out)\nattribute [-instance] MeasureTheory.JordanDecomposition.instSMul in\n#synth SMul ℝ≥0 (JordanDecomposition α)   -- NNReal.instSMulOfReal\nexample : (instSMul : SMul ℝ≥0 (JordanDecomposition α)) = NNReal.instSMulOfReal := by\n  with_reducible_and_instances rfl   -- error: not definitionally equal\nexample : (instSMul : SMul ℝ≥0 (JordanDecomposition α)) = NNReal.instSMulOfReal := by\n  rfl                                -- error: not definitionally equal\n-- propositionally equal (compiles):\nexample : (instSMul : SMul ℝ≥0 (JordanDecomposition α)) = NNReal.instSMulOfReal := by\n  have e1 : (instSMul : SMul ℝ≥0 (JordanDecomposition α)) = ⟨fun r j => instSMul.smul r j⟩ := rfl\n  have e2 : (NNReal.instSMulOfReal : SMul ℝ≥0 (JordanDecomposition α)) =\n      ⟨fun r j => NNReal.instSMulOfReal.smul r j⟩ := rfl\n  rw [e1, e2]; congr 1; funext r j; exact (coe_smul j r).symm\n-- consequence (both fail):\nexample (r : ℝ≥0) (j : JordanDecomposition α) : r • j = (r : ℝ) • j := NNReal.smul_def r j  -- Type mismatch (instSMulOfReal vs instSMul)\nexample (r : ℝ≥0) (j : JordanDecomposition α) : r • j = (r : ℝ) • j := by rw [NNReal.smul_def]  -- did not find ?c • ?x\n-- fix verified: hunts/vm-jordan/batch0/fixed_diamond.lean (src.lean minus instSMul, plus `nnsmul`) compiles with no errors or warnings (fixed_diamond.out empty)","evr":"fails-as-expected","astraV":"agrees","astraS":"A2: genuine non-defeq SMul ℝ≥0 diamond (instSMul vs NNReal.instSMulOfReal via instSMulReal); rated MINOR (instance hygiene, workaround coe_smul); adopt the nnsmul refactor.","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-8f3950","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.instSMul","line":86,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"lawless-smul-instance","claim":"`instSMul` is a bare `SMul ℝ≥0` with no lawful structure. `MulAction ℝ≥0 (JordanDecomposition α)` holds (`one_smul`, `mul_smul` follow by `ext1 <;> simp`), but it is not provided, so `smul_smul`/`one_smul` are unavailable on Jordan decompositions. There is currently no consumer in Mathlib.","fix":"After fixing the diamond (finding 0) add `MulAction ℝ` (which yields `MulAction ℝ≥0` via `NNReal`'s compHom instance), or meanwhile the two-line `MulAction ℝ≥0` on `instSMul`.","ev":"-- hunts/vm-jordan/batch0/probe2.lean P7 (compiles)\nexample : MulAction ℝ≥0 (JordanDecomposition α) where\n  one_smul j := by ext1 <;> simp\n  mul_smul r s j := by ext1 <;> simp [mul_smul]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-a3bc46","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.instSMulReal","line":91,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-real-scalar-compat-lemma","claim":"The real scalar action has no compatibility lemma with `toSignedMeasure`. Only the ℝ≥0 version `JordanDecomposition.toSignedMeasure_smul` (L162) exists, plus the reverse-direction `SignedMeasure.toJordanDecomposition_smul_real`. `(r • j).toSignedMeasure = r • j.toSignedMeasure` for `r : ℝ` is absent from Mathlib (`git grep toSignedMeasure_smul` finds only the ℝ≥0 versions in Jordan.lean:162 and Operations.lean:91). It is a one-liner via the equivalence.","fix":"Add `theorem toSignedMeasure_smul_real (r : ℝ) : (r • j).toSignedMeasure = r • j.toSignedMeasure` next to `toSignedMeasure_smul`.","ev":"-- hunts/vm-jordan/batch0/probe2.lean P6b/P6c (compile)\nexample (r : ℝ) (j : JordanDecomposition α) :\n    (r • j).toSignedMeasure = r • j.toSignedMeasure := by\n  conv_lhs => rw [← toJordanDecomposition_toSignedMeasure j,\n    ← SignedMeasure.toJordanDecomposition_smul_real, SignedMeasure.toSignedMeasure_toJordanDecomposition]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-3f19c0","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.real_smul_neg","line":129,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"strict-inequality-hypothesis-weakenable","claim":"The hypothesis `hr : r < 0` is stronger than needed: `r • j = -((-r).toNNReal • j)` also holds at r = 0 (both sides are the zero decomposition), so `r ≤ 0` suffices. The lemma has no consumers in Mathlib.","fix":"Weaken `hr : r < 0` to `hr : r ≤ 0` (and rename to `real_smul_of_nonpos`); the r = 0 case is `ext1 <;> simp [real_smul_def]`.","ev":"example (j : JordanDecomposition α) (r : ℝ) (hr : r ≤ 0) : r • j = -((-r).toNNReal • j) := by\n  rcases hr.lt_or_eq with hr | rfl\n  · exact real_smul_neg j r hr\n  · ext1 <;> simp [real_smul_def]   -- hunts/vm-jordan/batch1/Probe.lean P2a","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-852c6e","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.real_smul_posPart_neg","line":140,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"strict-inequality-hypothesis-weakenable","claim":"The hypothesis `hr : r < 0` is stronger than needed: `(r • j).posPart = (-r).toNNReal • j.negPart` also holds at r = 0 (both sides are 0), so `r ≤ 0` suffices. Its 3 consumers (Jordan.lean:446, Lebesgue.lean:110 and :333) all have `hr : r < 0` and would pass `hr.le`. The same applies to the sibling `real_smul_negPart_neg` (batch 2).","fix":"Weaken `hr : r < 0` to `hr : r ≤ 0` (rename `real_smul_posPart_of_nonpos`) and pass `hr.le` at the three call sites.","ev":"example (j : JordanDecomposition α) (r : ℝ) (hr : r ≤ 0) :\n    (r • j).posPart = (-r).toNNReal • j.negPart := by\n  rcases hr.lt_or_eq with hr | rfl\n  · exact real_smul_posPart_neg j r hr\n  · simp [real_smul_def]\nexample (j : JordanDecomposition α) : ((0 : ℝ) • j).posPart = (-(0 : ℝ)).toNNReal • j.negPart := by\n  simp [real_smul_def]   -- hunts/vm-jordan/batch1/Probe.lean P2b, P2c","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-a2000d","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.real_smul_negPart_neg","line":144,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"strict-hypothesis-where-nonstrict-suffices","claim":"The hypothesis `hr : r < 0` is stronger than needed: `(r • j).negPart = (-r).toNNReal • j.posPart` also holds at `r = 0` (both sides are `0`), so the lemma holds for all `r ≤ 0`. The weakened statement keeps the same one-line proof for `r < 0` plus `simp [real_smul_def]` for `r = 0`. Consumers (Jordan.lean L450, Lebesgue.lean L113 and L336) only need `hr.le`.","fix":"Take `hr : r ≤ 0` (proof: `rcases hr.lt_or_eq with hr | rfl`, old proof, then `simp [real_smul_def]`) and pass `hr.le` at the three call sites.","ev":"hunts/vm-jordan/batch2/probe1.lean L11-19 (`example (j) (r : ℝ) (hr : r ≤ 0) : (r • j).negPart = (-r).toNNReal • j.posPart := by rcases hr.lt_or_eq with hr | rfl; · exact j.real_smul_negPart_neg r hr; · simp [real_smul_def]`), and the weakened declaration itself in hunts/vm-jordan/batch2/src_edit.lean (diff vs src.lean in hunts/vm-jordan/batch2/src_edit.diff; compiled with the prompt's -D flags: no errors or warnings, `#lint only simpNF` passes, `#print axioms` shows no sorryAx; negative control with a broken proof does error)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-3997d3","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.toSignedMeasure","line":149,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-apply-lemma","claim":"The definition has no evaluation lemma `j.toSignedMeasure i = j.posPart.real i - j.negPart.real i` for measurable `i`. Every proof unfolds the definition and then applies `Measure.toSignedMeasure_sub_apply`. In this file that pattern occurs 9 times (L154, L159-160 twice, L164-165 twice, L178, L183, L366, L381) plus the `grind` hint list at L476. RadonNikodym.lean L37-38 also unfolds `JordanDecomposition.toSignedMeasure` and then rewrites with `_root_.sub_apply` and `toSignedMeasure_apply_measurable` twice.","fix":"Add `theorem toSignedMeasure_apply_measurable {i} (hi : MeasurableSet i) : j.toSignedMeasure i = j.posPart.real i - j.negPart.real i := toSignedMeasure_sub_apply hi` and use it in place of the unfold-then-`toSignedMeasure_sub_apply` chains.","ev":"Added as `toSignedMeasure_apply_of_measurableSet` and used in `exists_compl_positive_negative` in hunts/vm-jordan/batch2/src_edit.lean (diff vs src.lean in hunts/vm-jordan/batch2/src_edit.diff; compiled with the prompt's -D flags: no errors or warnings, `#lint only simpNF` passes, `#print axioms` shows no sorryAx; negative control with a broken proof does error); occurrence count by `grep -n toSignedMeasure_sub_apply src.lean`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-67224f","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.toSignedMeasure_zero","line":152,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`(0 : JordanDecomposition α).toSignedMeasure = 0` is a normal-form equation but is not `@[simp]`, so `simp` cannot prove it. Its consumer `SignedMeasure.toJordanDecomposition_zero` (L423) has to write `simp [toSignedMeasure_zero]`. The `Measure` counterpart `Measure.toSignedMeasure_zero` is `@[simp]`.","fix":"Mark it `@[simp]` and shorten `toJordanDecomposition_zero` to `simp`.","ev":"hunts/vm-jordan/batch2/probe1.lean L22-24 (`fail_if_success simp` succeeds on the statement); with `@[simp]` added, hunts/vm-jordan/batch2/src_edit.lean (diff vs src.lean in hunts/vm-jordan/batch2/src_edit.diff; compiled with the prompt's -D flags: no errors or warnings, `#lint only simpNF` passes, `#print axioms` shows no sorryAx; negative control with a broken proof does error): simpNF lint clean and `toJordanDecomposition_zero` closes by plain `simp`","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-463976","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.toSignedMeasure_neg","line":157,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`(-j).toSignedMeasure = -j.toSignedMeasure` is not `@[simp]`, so `simp` cannot prove it. Its consumer `SignedMeasure.toJordanDecomposition_neg` (L428) has to write `simp [toSignedMeasure_neg]`.","fix":"Mark it `@[simp]` and shorten `toJordanDecomposition_neg` to `simp`.","ev":"hunts/vm-jordan/batch2/probe1.lean L26-28 (`fail_if_success simp` succeeds); with `@[simp]` added, hunts/vm-jordan/batch2/src_edit.lean (diff vs src.lean in hunts/vm-jordan/batch2/src_edit.diff; compiled with the prompt's -D flags: no errors or warnings, `#lint only simpNF` passes, `#print axioms` shows no sorryAx; negative control with a broken proof does error): simpNF lint clean and `toJordanDecomposition_neg` closes by plain `simp`","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-10302c","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.toSignedMeasure_smul","line":162,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`(r • j).toSignedMeasure = r • j.toSignedMeasure` (r : ℝ≥0) is not `@[simp]`, although `Measure.toSignedMeasure_smul` is. `simp` cannot prove it, and `SignedMeasure.toJordanDecomposition_smul` (L433) has to write `simp [toSignedMeasure_smul]`.","fix":"Mark it `@[simp]` and shorten `toJordanDecomposition_smul` to `simp`.","ev":"hunts/vm-jordan/batch2/probe1.lean L30-33 (`fail_if_success simp` succeeds); with `@[simp]` added, hunts/vm-jordan/batch2/src_edit.lean (diff vs src.lean in hunts/vm-jordan/batch2/src_edit.diff; compiled with the prompt's -D flags: no errors or warnings, `#lint only simpNF` passes, `#print axioms` shows no sorryAx; negative control with a broken proof does error): simpNF lint clean and `toJordanDecomposition_smul` closes by plain `simp`","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-d94572","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.toJordanDecomposition","line":200,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-value-on-canonical-input","claim":"No lemma computes the Jordan decomposition on its most basic input, a finite measure: `μ.toSignedMeasure.toJordanDecomposition = ⟨μ, 0, MutuallySingular.zero_right⟩` (equivalently `.posPart = μ`, `.negPart = 0`). `simp` cannot prove it, and `exact?` finds nothing for the `posPart` form. The `@[simp]` lemma `toJordanDecomposition_toSignedMeasure_sub` (JordanSub.lean) does not fire with `ν = 0`, because `simp` first rewrites `(0 : Measure α).toSignedMeasure` to `0`. The lemma is one line from `toJordanDecomposition_eq`.","fix":"Add `@[simp] Measure.toSignedMeasure_toJordanDecomposition (μ) [IsFiniteMeasure μ] : μ.toSignedMeasure.toJordanDecomposition = ⟨μ, 0, .zero_right⟩ := toJordanDecomposition_eq (by simp [JordanDecomposition.toSignedMeasure])`, or posPart/negPart forms.","ev":"hunts/vm-jordan/batch2/probe1.lean L60-69 (`fail_if_success simp` succeeds; one-line proof via `toJordanDecomposition_eq` compiles) and L85-87 (`exact?` could not close `μ.toSignedMeasure.toJordanDecomposition.posPart = μ`); `git grep` on origin/master finds no such lemma","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-428c50","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.subset_positive_null_set","line":246,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-measurableset-hypothesis-junk-zero","claim":"The hypothesis `hv : MeasurableSet v` is redundant: the conclusion `s v = 0` holds trivially for non-measurable `v` because a vector measure is 0 off measurable sets. (`hu` and `hw` are genuinely needed: without `hu` the hypothesis `0 ≤[u] s` is vacuous, and without `hw` the hypothesis `s w = 0` can be the junk value.)","fix":"Drop `hv` and split on `MeasurableSet v` inside the proof, using `VectorMeasure.not_measurable` in the non-measurable case; update the two in-file callers.","ev":"example (hu : MeasurableSet u) (hw : MeasurableSet w) (hsu : 0 ≤[u] s) (hw₁ : s w = 0)\n    (hw₂ : w ⊆ u) (hwt : v ⊆ w) : s v = 0 := by\n  by_cases hv : MeasurableSet v\n  · exact subset_positive_null_set hu hv hw hsu hw₁ hw₂ hwt\n  · exact VectorMeasure.not_measurable s hv\n-- in hunts/vm-jordan/batch3/Jordan3.lean lines 526-531, compiled with the prompt's lake env lean flags","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-aa0751","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.subset_negative_null_set","line":259,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-measurableset-hypothesis-junk-zero","claim":"The hypothesis `hv : MeasurableSet v` is redundant: `s v = 0` is automatic when `v` is not measurable.","fix":"Drop `hv` (case split on `MeasurableSet v` inside the proof), matching the fix for `subset_positive_null_set`.","ev":"example (hu : MeasurableSet u) (hw : MeasurableSet w) (hsu : s ≤[u] 0) (hw₁ : s w = 0)\n    (hw₂ : w ⊆ u) (hwt : v ⊆ w) : s v = 0 := by\n  by_cases hv : MeasurableSet v\n  · exact subset_negative_null_set hu hv hw hsu hw₁ hw₂ hwt\n  · exact VectorMeasure.not_measurable s hv\n-- in hunts/vm-jordan/batch3/Jordan3.lean lines 533-538","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-b59115","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.of_sdiff_eq_zero_of_symmDiff_eq_zero_positive","line":271,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"stronger-hypothesis-than-used","claim":"`of_sdiff_eq_zero_of_symmDiff_eq_zero_positive` assumes `u` and `v` are positive sets (`0 ≤[u] s`, `0 ≤[v] s`), but only `0 ≤ s (u \\ v)` and `0 ≤ s (v \\ u)` are used: from `s (u ∆ v) = s (u \\ v) + s (v \\ u) = 0` and nonnegativity both terms vanish. The current lemma is the special case obtained from `nonneg_of_zero_le_restrict`. The `negative` version is the same with `≤ 0`; Astra also notes the `of_inter_eq_of_symmDiff_eq_zero_*` pair only needs sign conditions on the two difference sets.","fix":"State the lemma with `(h₁ : 0 ≤ s (u \\ v)) (h₂ : 0 ≤ s (v \\ u))` (and dually for the negative version), deriving the positive-set forms as corollaries.","ev":"hunts/vm-jordan/astra/probe.lean A12of_sdiff (hypotheses `0 ≤ s (u \\ v)`, `0 ≤ s (v \\ u)`) compiles, and the original statement is recovered from it. Exit 0. Raised by Astra's A1 pass (item 12).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-d2f16a","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.toSignedMeasure_injective","line":346,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"duplicated-have-block","claim":"The proof is 52 lines (src.lean:347-398), and 30 of them are two copy-pasted 15-line blocks `hμ₁`/`hμ₂` that differ only in `j₁,S` vs `j₂,T`. One local `key` lemma (using `measure_sdiff_null` and `measure_mono_null`) halves it to 26 lines.","fix":"Factor `hμ₁`/`hμ₂` into one local `have key` (or a private lemma) as in the evidence, replacing src.lean:347-385.","ev":"  have key {j : JordanDecomposition α} {S i : Set α} (hS : MeasurableSet S) (hi : MeasurableSet i)\n      (h₁ : j.posPart S = 0) (h₂ : j.negPart Sᶜ = 0) :\n      j.posPart.real i = j.toSignedMeasure (i ∩ Sᶜ) := by\n    rw [toSignedMeasure, toSignedMeasure_sub_apply (hi.inter hS.compl), ← Set.sdiff_eq,\n      measureReal_def, measureReal_def, measureReal_def, measure_sdiff_null h₁,\n      measure_mono_null (Set.sdiff_subset_compl i S) h₂, ENNReal.toReal_zero, sub_zero]\n  refine eq_of_posPart_eq_posPart ?_ hj\n  ext1 i hi\n  rw [← measureReal_eq_measureReal_iff, key hS₁ hi hS₄ hS₅, key hT₁ hi hT₄ hT₅, ← hj]\n  exact of_inter_eq_of_symmDiff_eq_zero_positive hS₁.compl hT₁.compl hi hS₃ hT₃ hST₁\n-- replaces the duplicated blocks; whole proof now hunts/vm-jordan/batch3/Jordan3.lean lines 334-359 (26 lines), compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-ca9a21","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.toSignedMeasure_injective","line":346,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"injective-without-inj-iff","claim":"The injectivity lemma has no `@[simp]` iff companion `toSignedMeasure_inj : j₁.toSignedMeasure = j₂.toSignedMeasure ↔ j₁ = j₂` (cf. `Measure.toSignedMeasure_eq_toSignedMeasure_iff` for measures); it is absent from Mathlib and `simp` cannot prove it.","fix":"Add `@[simp] theorem toSignedMeasure_inj {j₁ j₂ : JordanDecomposition α} : j₁.toSignedMeasure = j₂.toSignedMeasure ↔ j₁ = j₂ := toSignedMeasure_injective.eq_iff`.","ev":"-- compiles (Jordan3.lean:540-543):\nexample {j₁ j₂ : JordanDecomposition α} :\n    j₁.toSignedMeasure = j₂.toSignedMeasure ↔ j₁ = j₂ :=\n  toSignedMeasure_injective.eq_iff\n-- fails as expected (Jordan3.lean:548: `simp` made no progress):\nexample {j₁ j₂ : JordanDecomposition α} :\n    j₁.toSignedMeasure = j₂.toSignedMeasure ↔ j₁ = j₂ := by\n  simp\n-- git grep -nE \"toSignedMeasure_inj([^e]|$)|toSignedMeasure_injective\\.eq_iff\" origin/master -- Mathlib  => no hits (exit 1)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-655ca2","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.toJordanDecomposition_zero","line":421,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"Not tagged @[simp]: plain `simp` makes no progress on `(0 : SignedMeasure α).toJordanDecomposition = 0` or on `(0 : SignedMeasure α).toJordanDecomposition.posPart = 0`, so consumers pass it by hand (totalVariation_zero at L467: `simp [totalVariation, toJordanDecomposition_zero]`).","fix":"Tag `toJordanDecomposition_zero` with @[simp] (passes simpNF).","ev":"hunts/vm-jordan/batch4/Probe1.lean P1a/P1e: `example : (0 : SignedMeasure α).toJordanDecomposition = 0 := by simp` -> error: `simp` made no progress (same for `.posPart = 0`); with the attribute added (hunts/vm-jordan/batch4/SimpCopy.lean: @[simp] on toJordanDecomposition_zero/_neg/_smul/_smul_real, then `#lint only simpNF`) the file compiles and simpNF reports 'All linting checks passed'","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-292cd2","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.toJordanDecomposition_neg","line":425,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"Not tagged @[simp] although it is a clean push-the-negation-out rewrite: plain `simp` makes no progress on `(-s).toJordanDecomposition = -s.toJordanDecomposition`, and consumers pass it explicitly (Jordan.lean L470 `simp [totalVariation, toJordanDecomposition_neg, add_comm]`, Lebesgue.lean L309 `simp [singularPart, toJordanDecomposition_neg]`, plus `rw` at Lebesgue.lean L88/L91).","fix":"Tag `toJordanDecomposition_neg` with @[simp] (passes simpNF; then `(-s).toJordanDecomposition.posPart = s.toJordanDecomposition.negPart` is closed by `simp`).","ev":"hunts/vm-jordan/batch4/Probe1.lean P1b: `example (s : SignedMeasure α) : (-s).toJordanDecomposition = -s.toJordanDecomposition := by simp` -> `simp` made no progress; P2 with `attribute [local simp]` closes it and `(-s).totalVariation = s.totalVariation` by `simp [totalVariation, add_comm]`; with the attribute added (hunts/vm-jordan/batch4/SimpCopy.lean: @[simp] on toJordanDecomposition_zero/_neg/_smul/_smul_real, then `#lint only simpNF`) the file compiles and simpNF reports 'All linting checks passed'","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-00df8d","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.toJordanDecomposition_smul","line":430,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"Not tagged @[simp]: plain `simp` makes no progress on `(r • s).toJordanDecomposition = r • s.toJordanDecomposition` (r : ℝ≥0); Lebesgue.lean rewrites with it by hand four times (L97, L100, L317, L319).","fix":"Tag `toJordanDecomposition_smul` with @[simp] (passes simpNF, confluent with `JordanDecomposition.coe_smul`).","ev":"hunts/vm-jordan/batch4/Probe1.lean P1c: `example (s : SignedMeasure α) (r : ℝ≥0) : (r • s).toJordanDecomposition = r • s.toJordanDecomposition := by simp` -> `simp` made no progress; P2 confluence: with local simp, `((r : ℝ) • s).toJordanDecomposition = r • s.toJordanDecomposition := by simp` compiles; with the attribute added (hunts/vm-jordan/batch4/SimpCopy.lean: @[simp] on toJordanDecomposition_zero/_neg/_smul/_smul_real, then `#lint only simpNF`) the file compiles and simpNF reports 'All linting checks passed'","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-5700d5","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.toJordanDecomposition_smul_real","line":441,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"Not tagged @[simp]: plain `simp` makes no progress on `(r • s).toJordanDecomposition = r • s.toJordanDecomposition` for `r : ℝ`.","fix":"Tag `toJordanDecomposition_smul_real` with @[simp] (passes simpNF together with the ℝ≥0 version).","ev":"hunts/vm-jordan/batch4/Probe1.lean P1d: `example (s : SignedMeasure α) (r : ℝ) : (r • s).toJordanDecomposition = r • s.toJordanDecomposition := by simp` -> `simp` made no progress; with the attribute added (hunts/vm-jordan/batch4/SimpCopy.lean: @[simp] on toJordanDecomposition_zero/_neg/_smul/_smul_real, then `#lint only simpNF`) the file compiles and simpNF reports 'All linting checks passed'","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-3f5713","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.totalVariation","line":460,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"duplicate-definition-bridged","claim":"`SignedMeasure.totalVariation` is a second, non-definitional definition of `VectorMeasure.variation` at V = ℝ (Variation/Defs.lean L51 `noncomputable def variation (μ : VectorMeasure X V) : Measure X`), bridged by `SignedMeasure.totalVariation_eq_variation : μ.totalVariation = μ.variation` (Variation/SignedMeasure.lean L64). The two carry parallel APIs: `totalVariation_zero`/`totalVariation_neg` (L466/L469) are one-line consequences of `variation_zero`/`variation_neg`, `totalVariation_smul` is missing while `variation_smul` exists, `IsFiniteMeasure s.variation` is missing while this file has it for `totalVariation`, and the TODO at L513 ('Generalize to vector measures once total variation on vector measures is defined') is now actionable. Kept MINOR because the duplication is bridged and documented in Variation/SignedMeasure.lean; no open upstream PR unifies them (gh search 'totalVariation').","fix":"Make `VectorMeasure.variation` canonical for signed measures (prove `variation = posPart + negPart` of the Jordan decomposition, add the `IsFiniteMeasure` instance, deprecate `totalVariation` and its zero/neg lemmas), or at least cross-reference the two in the docstrings.","ev":"hunts/vm-jordan/batch4/Probe1.lean P4: `example (s : SignedMeasure α) : s.totalVariation = s.variation := s.totalVariation_eq_variation` compiles; `:= rfl` fails (Type mismatch); `example (s : SignedMeasure α) : IsFiniteMeasure s.variation := inferInstance` fails to synthesize; hunts/vm-jordan/batch4/Probe2.lean: `(0 : SignedMeasure α).totalVariation = 0 := by rw [totalVariation_eq_variation, VectorMeasure.variation_zero]` and `(-s).totalVariation = s.totalVariation := by rw [totalVariation_eq_variation, totalVariation_eq_variation, VectorMeasure.variation_neg]` compile","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-8c2ee5","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.totalVariation","line":460,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"Missing characteristic API: no `totalVariation_apply`/`totalVariation_def`, so 10 proofs unfold the definition by hand (`rw [totalVariation, Measure.add_apply, …]` / `Measure.coe_add` / `measureReal_add_apply` at Jordan.lean L480, L491, L508, L511, L521, L524, L539, Lebesgue.lean L140, Variation/SignedMeasure.lean L37, L70); and no `totalVariation_smul` although the scalar law is one line (`variation_smul` exists for the general notion).","fix":"Add `totalVariation_apply` (`s.totalVariation i = s⁺ i + s⁻ i`, by `Measure.add_apply ..`) and `totalVariation_smul` (ℝ≥0, and `‖r‖₊ •` for ℝ), and use them at the unfolding sites.","ev":"hunts/vm-jordan/batch4/Probe1.lean P4: `#check @SignedMeasure.totalVariation_smul` / `_apply` / `_def` -> Unknown constant; `example (s : SignedMeasure α) (r : ℝ) : (r • s).totalVariation = ‖r‖₊ • s.totalVariation := by simp only [totalVariation_eq_variation, VectorMeasure.variation_smul]` compiles; hunts/vm-jordan/batch4/GolfCopy.lean adds `theorem totalVariation_apply (s : SignedMeasure α) (i : Set α) : s.totalVariation i = s.toJordanDecomposition.posPart i + s.toJordanDecomposition.negPart i := Measure.add_apply ..` and `theorem totalVariation_smul (s : SignedMeasure α) (r : ℝ≥0) : (r • s).totalVariation = r • s.totalVariation := by simp [totalVariation, toJordanDecomposition_smul, smul_add]` (exit 0)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-3f8b34","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.totalVariation_zero","line":466,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`totalVariation_zero` is not `@[simp]` (nor is `toJordanDecomposition_zero`), so `simp` cannot prove `(0 : SignedMeasure α).totalVariation = 0`, whereas the counterpart `VectorMeasure.variation_zero` (Variation/Basic.lean:156) is `@[simp]`; tagging it locally works without looping.","fix":"Tag `totalVariation_zero` with `@[simp]`.","ev":"hunts/vm-jordan/batch5/probe1.lean section P1: `example : (0 : SignedMeasure α).totalVariation = 0 := by fail_if_success simp; exact SignedMeasure.totalVariation_zero` plus the `attribute [local simp]` example closed by `simp`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-e9e25f","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.totalVariation_neg","line":469,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`totalVariation_neg` is not `@[simp]` (`simp` fails on `(-s).totalVariation = s.totalVariation`), unlike `VectorMeasure.variation_neg` (Variation/Basic.lean:309, `@[simp]`); its scalar sibling `totalVariation_smul` is missing from Mathlib (no hit for `totalVariation_smul` in `git grep origin/master -- Mathlib`) although the ℝ≥0 form is one `simp` call from `toJordanDecomposition_smul`.","fix":"Tag `totalVariation_neg` `@[simp]` and add `totalVariation_smul (r : ℝ≥0) : (r • s).totalVariation = r • s.totalVariation`.","ev":"hunts/vm-jordan/batch5/probe1.lean sections P1-P2: `fail_if_success simp; exact SignedMeasure.totalVariation_neg s`; `example (s) (r : ℝ≥0) : (r • s).totalVariation = r • s.totalVariation := by simp [SignedMeasure.totalVariation, SignedMeasure.toJordanDecomposition_smul, smul_add]`; real form `‖r‖₊ • _` via `totalVariation_eq_variation` + `VectorMeasure.variation_smul`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-5337f8","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.null_of_totalVariation_zero","line":478,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-iff","claim":"Only one direction is provided; the converse/iff `s.totalVariation u = 0 ↔ ∀ t ⊆ u, s t = 0` (for measurable `u`, the analogue of `VectorMeasure.variation_apply_eq_zero`, Variation/Basic.lean:205) is missing, so the same `rw [totalVariation, Measure.add_apply, hpos, hneg, toMeasureOfZeroLE_apply …, toMeasureOfLEZero_apply …]; simp [h _ Set.inter_subset_right]` block is repeated four times (L491-495, L521-523, L524-527, L539-541).","fix":"Add `totalVariation_apply_eq_zero_iff (hu : MeasurableSet u) : s.totalVariation u = 0 ↔ ∀ t ⊆ u, s t = 0` and use it in the three characterisation proofs.","ev":"hunts/vm-jordan/batch5/probe1.lean section P4: `theorem totalVariation_apply_eq_zero_iff' (s : SignedMeasure α) {u : Set α} (hu : MeasurableSet u) : s.totalVariation u = 0 ↔ ∀ t ⊆ u, s t = 0` (6-line proof) and a 5-line reproof of `mutuallySingular_iff` from it","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-67f99d","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.absolutelyContinuous_ennreal_iff","line":486,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"special-case-of-vector-measure-statement","claim":"The statement is the `V = ℝ` case (via `totalVariation_eq_variation`) of `v ≪ᵥ μ ↔ v.variation ≪ μ.ennrealToMeasure` for every vector measure `v` into a `T2` `ENormedAddCommMonoid`, which has an equally short proof from `variation_apply_eq_zero`/`enorm_measure_le_variation`; Mathlib has no such general form (no `variation ≪`/`≪ᵥ … variation` characterisation in `git grep`), and complex measures only get the re/im form `ComplexMeasure.absolutelyContinuous_ennreal_iff : c ≪ᵥ μ ↔ c.re ≪ᵥ μ ∧ c.im ≪ᵥ μ`.","fix":"Add `VectorMeasure.absolutelyContinuous_ennreal_iff_variation` in Variation/Basic.lean and note this lemma as its signed-measure specialisation.","ev":"hunts/vm-jordan/batch5/probe1.lean section P5: `theorem VectorMeasure.absolutelyContinuous_ennreal_iff_variation' (v : VectorMeasure α V) (μ : VectorMeasure α ℝ≥0∞) : v ≪ᵥ μ ↔ v.variation ≪ μ.ennrealToMeasure` (7 lines), the SignedMeasure statement re-derived from it, and the ComplexMeasure instance","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-3306a4","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.totalVariation_absolutelyContinuous_iff","line":500,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"reprovable-by-existing-lemma","claim":"The 9-line tactic proof is exactly `Measure.AbsolutelyContinuous.add_left_iff` (AbsolutelyContinuous.lean:116, `μ₁ + μ₂ ≪ ν ↔ μ₁ ≪ ν ∧ μ₂ ≪ ν`), already imported; the sibling `totalVariation_mutuallySingular_iff` is proved the same way by `Measure.MutuallySingular.add_left_iff`.","fix":"Replace the proof with `Measure.AbsolutelyContinuous.add_left_iff`.","ev":"hunts/vm-jordan/batch5/probe1.lean section P3: `example (s : SignedMeasure α) (μ : Measure α) : s.totalVariation ≪ μ ↔ s.toJordanDecomposition.posPart ≪ μ ∧ s.toJordanDecomposition.negPart ≪ μ := Measure.AbsolutelyContinuous.add_left_iff`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-fe7528","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.mutuallySingular_iff","line":514,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"special-case-of-vector-measure-statement","claim":"The statement is the `V = W = ℝ` case (via `totalVariation_eq_variation`) of `μ ⟂ᵥ ν ↔ μ.variation ⟂ₘ ν.variation` for vector measures into any `T2` `ENormedAddCommMonoid`s (codomains may differ), now provable in 8 lines since `VectorMeasure.variation` exists; Mathlib lacks the general form, which is exactly what the TODO above the lemma asks for.","fix":"Add `VectorMeasure.mutuallySingular_iff_variation` to Variation/Basic.lean and resolve the TODO by pointing to it.","ev":"hunts/vm-jordan/batch5/probe1.lean section P5: `theorem VectorMeasure.mutuallySingular_iff_variation' (μ : VectorMeasure α V) (ν : VectorMeasure α W) : μ ⟂ᵥ ν ↔ μ.variation ⟂ₘ ν.variation` and `example (s t : SignedMeasure α) : s ⟂ᵥ t ↔ s.totalVariation ⟂ₘ t.totalVariation := by rw [totalVariation_eq_variation, totalVariation_eq_variation]; exact VectorMeasure.mutuallySingular_iff_variation' s t`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-a895a0","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.mutuallySingular_ennreal_iff","line":533,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"special-case-of-vector-measure-statement","claim":"The statement is the `V = ℝ` case of `v ⟂ᵥ μ ↔ v.variation ⟂ₘ μ.ennrealToMeasure` for any vector measure `v`, a one-line corollary of the general `⟂ᵥ`/variation characterisation and `VectorMeasure.variation_eq_ennrealToMeasure`; Mathlib lacks the general form.","fix":"Add `VectorMeasure.mutuallySingular_ennreal_iff_variation` in Variation/Basic.lean alongside the general `mutuallySingular_iff_variation`.","ev":"hunts/vm-jordan/batch5/probe1.lean section P5: `theorem VectorMeasure.mutuallySingular_ennreal_iff_variation' (v : VectorMeasure α V) (μ : VectorMeasure α ℝ≥0∞) : v ⟂ᵥ μ ↔ v.variation ⟂ₘ μ.ennrealToMeasure := by rw [mutuallySingular_iff_variation', variation_eq_ennrealToMeasure]` and the SignedMeasure statement re-derived from it","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-e7d27f","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.mutuallySingular_ennreal_iff","line":533,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-measure-form-lemma","claim":"All four consumers (Lebesgue.lean L144, L215, L251-253, L277) apply it at `μ.toENNRealVectorMeasure` for a `Measure μ` and then immediately rewrite `VectorMeasure.ennrealToMeasure_toENNRealVectorMeasure` (L251-253 even needs `change _ ⟂ₘ VectorMeasure.equivMeasure.toFun …`); the `Measure`-form `s ⟂ᵥ μ.toENNRealVectorMeasure ↔ s.totalVariation ⟂ₘ μ` is missing.","fix":"Add `mutuallySingular_toENNRealVectorMeasure_iff : s ⟂ᵥ μ.toENNRealVectorMeasure ↔ s.totalVariation ⟂ₘ μ` and use it in Lebesgue.lean.","ev":"hunts/vm-jordan/batch5/probe2.lean: `theorem mutuallySingular_toENNRealVectorMeasure_iff' … := by rw [SignedMeasure.mutuallySingular_ennreal_iff, VectorMeasure.ennrealToMeasure_toENNRealVectorMeasure]` and the `change`-free replacement of Lebesgue L249-253","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-0a3782","file":"Mathlib/MeasureTheory/VectorMeasure/Integral.lean","decl":"MeasureTheory.VectorMeasure.transpose_add","line":155,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `MeasureTheory.VectorMeasure.transpose_add` (MeasureTheory.VectorMeasure.Integral), `MeasureTheory.VectorMeasure.transpose_add_vectorMeasure` (MeasureTheory.VectorMeasure.Integral) state exactly the same thing (Lean-checked). Reviewer: Same file, same statement `(μ + ν).transpose B = μ.transpose B + ν.transpose B`, both `by simp [transpose]`. The later block names add, neg, sub and finsetSum systematically with `_vectorMeasure`/`_cbm` suffixes. Keep the @[simp] `_vectorMeasure` lemma and deprecate the earlier non-simp `transpose_add`; neither has uses.","fix":"Deprecate `MeasureTheory.VectorMeasure.transpose_add` in favour of `MeasureTheory.VectorMeasure.transpose_add_vectorMeasure`.","ev":"dupscan/Check.lean: `example := (@MeasureTheory.VectorMeasure.transpose_add_vectorMeasure : type_of% @MeasureTheory.VectorMeasure.transpose_add)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 48, rating MAJOR): The systematic suffix distinguishes linearity in the vector-measure argument from linearity in the bilinear map, while preserving the desired simp rule.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-381f71","file":"Mathlib/MeasureTheory/VectorMeasure/Order.lean","decl":"MeasureTheory.Measure.toSignedMeasure_restrict_eq_restrict_toSignedMeasure","line":353,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `MeasureTheory.Measure.toSignedMeasure_restrict_eq_restrict_toSignedMeasure` (MeasureTheory.VectorMeasure.Order), `MeasureTheory.VectorMeasure.restrict_toSignedMeasure` (MeasureTheory.VectorMeasure.Operations) state exactly the same thing (Lean-checked). Reviewer: Same [IsFiniteMeasure μ] statement `μ.toSignedMeasure.restrict s = (μ.restrict s).toSignedMeasure`. VectorMeasure/Order imports Operations; the Order copy uses explicit μ s binders and has 4 uses in JordanSub.lean. Keep the lower one and deprecate the long name.","fix":"Deprecate `MeasureTheory.Measure.toSignedMeasure_restrict_eq_restrict_toSignedMeasure` in favour of `MeasureTheory.VectorMeasure.restrict_toSignedMeasure`.","ev":"dupscan/Check.lean: `example := (@MeasureTheory.VectorMeasure.restrict_toSignedMeasure : type_of% @MeasureTheory.Measure.toSignedMeasure_restrict_eq_restrict_toSignedMeasure)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup2 item 47, rating MINOR): The [Measure-namespace theorem](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/MeasureTheory/VectorMeasure/Order.lean#L333-L356) supports `μ.toSignedMeasure_restrict_eq_restrict_toSignedMeasure s hs`, unlike the `VectorMeasure` spelling. Replace its proof with the lower theorem while preserving the method interface.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-6dc86d","file":"Mathlib/MeasureTheory/VectorMeasure/Relations.lean","decl":"MeasureTheory.VectorMeasure.AbsolutelyContinuous","line":45,"sev":"MINOR","status":"confirmed","cat":"correctness","pattern":"definition-nonstandard-in-unused-generality","claim":"`VectorMeasure.AbsolutelyContinuous v w` is `∀ s, w s = 0 → v s = 0`. For a nonnegative reference measure this is the usual notion, but the definition accepts any vector measure `w`, and for signed `w` cancellation makes it a different, stronger relation than absolute continuity (`|w|`-null sets are `v`-null). With `w = δ_true − δ_false` and `v = δ_true` on `Bool`: `¬ v ≪ᵥ w` (as `w univ = 0`, `v univ = 1`), although `v` vanishes on every `w`-null set; and `v = w.restrict {true}`, so even a restriction of `w` is not `≪ᵥ w`. Graded MINOR, not MAJOR/CRITICAL: every use of `≪ᵥ` in Mathlib (RadonNikodym, WithDensity, Jordan, Complex, Variation) has an `ℝ≥0∞` reference measure, where the definition is standard, so no stated theorem is false. Flagged to the user as a candidate for escalation.","fix":"Either document that for signed/vector-valued `w` this is the zero-set relation (not absolute continuity), or restrict `w` to `VectorMeasure α ℝ≥0∞` / define via `w.ennrealVariation`.","ev":"probe2.lean (compiles, linter warnings only): `¬ v ≪ᵥ w`; `∀ s, (∀ t ⊆ s, w t = 0) → v s = 0`; `w.restrict {true} = v`. `git grep '≪ᵥ'`: all 7 uses outside Relations.lean take an ℝ≥0∞ reference.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-4d9079","file":"Mathlib/MeasureTheory/VectorMeasure/Relations.lean","decl":"MeasureTheory.VectorMeasure.AbsolutelyContinuous.map","line":105,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"measurespace-for-measurablespace","claim":"`AbsolutelyContinuous.map` assumes `[MeasureSpace β]` (a σ-algebra plus a chosen `volume` measure), but `VectorMeasure.map` and the proof only need `[MeasurableSpace β]`. With a bare `MeasurableSpace β`, `h.map f` fails to synthesize `MeasureSpace β`; the same proof compiles under `[MeasurableSpace β]`.","fix":"Replace `[MeasureSpace β]` by `[MeasurableSpace β]`.","ev":"probe1.lean `map'` (with `[MeasurableSpace β]`, original proof) compiles; L20 `h.map f` under `[MeasurableSpace β]` → failed to synthesize `MeasureSpace β`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-3bb0a0","file":"Mathlib/MeasureTheory/VectorMeasure/Relations.lean","decl":"MeasureTheory.VectorMeasure.MutuallySingular.symm","line":151,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`MutuallySingular.symm` is not tagged `@[symm]` and the unconditional `MutuallySingular.zero_left/zero_right` and `AbsolutelyContinuous.zero` are not `@[simp]`, unlike their `Measure` counterparts: the `symm` tactic fails on `w ⟂ᵥ v` (\"No applicable symmetry lemma\") and `simp` makes no progress on `v ⟂ᵥ 0`.","fix":"Tag `MutuallySingular.symm` `@[symm]` and the three zero lemmas `@[simp]`.","ev":"Copy.lean appended examples: `symm` → No applicable symmetry lemma found; `v ⟂ᵥ (0 : VectorMeasure α N) := by simp` → simp made no progress.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-556bb5","file":"Mathlib/MeasureTheory/VectorMeasure/Relations.lean","decl":"MeasureTheory.VectorMeasure.MutuallySingular.zero_left","line":159,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-interaction-lemma","claim":"The file never relates its two relations: there is no vector-measure analogue of `Measure.eq_zero_of_absolutelyContinuous_of_mutuallySingular` (`v ≪ᵥ w → v ⟂ᵥ w → v = 0`), although it is a 5-line proof from `of_union` (needs `[T2Space M] [ContinuousAdd M]`).","fix":"Add `VectorMeasure.eq_zero_of_absolutelyContinuous_of_mutuallySingular`.","ev":"probe1.lean final `example` compiles (one deprecation warning for `Set.inter_union_diff`).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-0a43af","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.sum_finpartition","line":46,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"general-lemma-in-specialised-file","claim":"General VectorMeasure/Finpartition lemma with nothing to do with variation (the statement mentions only `VectorMeasure`, `Finpartition` and `Subtype MeasurableSet`; the proof is `of_biUnion_finset` + `Finpartition.sup_parts_apply`). It lives in Variation/Basic.lean, whose only use of it is `iSup_sum_finpartition_parts` (L432). It compiles verbatim importing only `Mathlib.MeasureTheory.Measure.PreVariation`; `VectorMeasure.Basic` alone lacks `Finpartition`.","fix":"Move it to a general file: PreVariation.lean (already imports Finpartition and VectorMeasure.Operations), or VectorMeasure/Basic.lean next to `of_biUnion_finset` if that file can take the Finpartition import.","ev":"pointer: hunts/vm-variation/batch0/probe3.lean (import Mathlib.MeasureTheory.Measure.PreVariation only; restates and reproves `sum_finpartition` verbatim as `sum_finpartition'`), output in probe3.out (no errors)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-96164e","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.variation_apply","line":57,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-apply-lemma","claim":"`variation_apply` only restates the definition by `rfl` (in Mathlib terms it is a `_def` lemma). The characteristic formula on measurable sets, `μ.variation s = ⨆ P : Finpartition ⟨s, hs⟩, ∑ p ∈ P.parts, ‖μ p‖ₑ`, is missing. As a result the file re-derives it with the same four-lemma chain `simp only [variation_apply, preVariation(_apply), ennrealToMeasure_apply hs, ennrealPreVariation_apply]` 7 times (L79, L93, L118, L151, L170, L342, L443).","fix":"Add `variation_apply_of_measurableSet` (iSup formula), and possibly `variation_apply_eq_preVariationFun`, then replace the seven unfolding chains with it.","ev":"theorem variation_apply_of_measurableSet (μ : VectorMeasure X V) {s : Set X}\n    (hs : MeasurableSet s) :\n    μ.variation s =\n      ⨆ P : Finpartition (⟨s, hs⟩ : Subtype MeasurableSet), ∑ p ∈ P.parts, ‖μ p‖ₑ := by\n  simp only [variation_apply, preVariation, ennrealToMeasure_apply hs, ennrealPreVariation_apply,\n    preVariationFun_apply _ hs]\n-- hunts/vm-variation/batch0/probe1.lean (P3); occurrence count measured with `grep -n ennrealToMeasure_apply src.lean` -> lines 79,93,118,151,170,342,444","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-da86c5","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.variation_apply","line":57,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-enorm-typeclass","claim":"Too strong a typeclass, inherited from the definition. `variation` (Defs.lean L51), `isSigmaSubadditiveSetFun_enorm`, and therefore `variation_apply`, require `[ENormedAddCommMonoid V]`, but positive definiteness (`enorm_eq_zero`) is never used. With `ENormedAddCommMonoid` replaced by `ESeminormedAddCommMonoid`, Defs.lean plus Basic.lean L36–195 compile unchanged except `absolutelyContinuous`, which genuinely needs definiteness. That covers every batch-0 lemma in section Basic: variation_apply, ennrealVariation_apply, le_variation, exists_lt_sum_of_lt_variation, exists_variation_le_add('), enorm_measure_le_variation, variation_zero, variation_apply_le_of_forall_enorm_le, variation_le_of_forall_enorm_le, variation_add_le. The variation with respect to a continuous seminorm is standard. Root cause is out of this file (Defs.lean).","fix":"Generalise `variation`/`ennrealVariation`/`isSigmaSubadditiveSetFun_enorm` in Defs.lean to `ESeminormedAddCommMonoid`, and put `ENormedAddCommMonoid` only on the lemmas that need definiteness (e.g. `absolutelyContinuous`, `variation_eq_zero`).","ev":"pointer: hunts/vm-variation/batch0/seminormed.lean = Defs.lean body + src.lean L36–195 with `[ENormedAddCommMonoid V]` -> `[ESeminormedAddCommMonoid V]`; output hunts/vm-variation/batch0/seminormed.out: exactly one error, at `absolutelyContinuous` (goal `μ s = 0` from `‖μ s‖ₑ = 0`), as expected (control); everything else compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-33c2bd","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.le_variation","line":65,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-measurability-hypothesis","claim":"The hypothesis `hs : MeasurableSet s` is redundant. `μ.variation` is a `Measure`, so `variation s = variation (toMeasurable _ s)`, and the measurable case applied to `toMeasurable` gives the general one. With the general form, `enorm_measure_le_variation` becomes `simpa using μ.le_variation (P := {E}) ..` with no measurability case split. One external consumer (WithDensityVec.lean:315) passes `hs`.","fix":"Drop `hs` (prove the measurable case as now and conclude via `measure_toMeasurable`), then update WithDensityVec.lean:315.","ev":"theorem le_variation_noMeas (μ : VectorMeasure X V) {s : Set X} {P : Finset (Set X)}\n    (hP₁ : ∀ t ∈ P, t ⊆ s) (hP₂ : (P : Set (Set X)).PairwiseDisjoint id) :\n    ∑ p ∈ P, ‖μ p‖ₑ ≤ μ.variation s :=\n  (μ.le_variation (measurableSet_toMeasurable _ s)\n    (fun t ht => (hP₁ t ht).trans (subset_toMeasurable _ _)) hP₂).trans_eq (measure_toMeasurable s)\n\nexample (μ : VectorMeasure X V) (E : Set X) : ‖μ E‖ₑ ≤ μ.variation E := by\n  simpa using μ.le_variation_noMeas (P := {E}) (by simp) (by simp)\n-- hunts/vm-variation/batch0/probe1.lean (P1, P1b)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c90114","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.exists_variation_le_add'","line":114,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"duplicated-proof-block","claim":"Repeated reasoning. The 14-line `refine ⟨P.parts.map (Function.Embedding.subtype _), ?_, ?_, ?_, ?_⟩ …` block (L123–136) is a verbatim copy of L98–111 in `exists_lt_sum_of_lt_variation`, preceded by the same `simp only` unfolding. The lemma follows from `exists_lt_sum_of_lt_variation` in four lines.","fix":"Derive it from `exists_lt_sum_of_lt_variation` with `a := μ.variation s - ε` (case `variation s = 0`: `P = ∅`), or factor the Finpartition→Finset conversion into a lemma.","ev":"example (μ : VectorMeasure X V) {s : Set X} (hs : MeasurableSet s)\n    {ε : ℝ≥0∞} (hε : 0 < ε) (hμ : μ.variation s ≠ ∞) :\n    ∃ (P : Finset (Set X)), (∀ t ∈ P, t ⊆ s) ∧ ((P : Set (Set X)).PairwiseDisjoint id) ∧\n      (∀ t ∈ P, MeasurableSet t) ∧ μ.variation s ≤ ∑ p ∈ P, ‖μ p‖ₑ + ε := by\n  rcases eq_or_ne (μ.variation s) 0 with h0 | h0\n  · exact ⟨∅, by simp [h0]⟩\n  obtain ⟨P, h₁, h₂, h₃, h₄⟩ :=\n    μ.exists_lt_sum_of_lt_variation hs (ENNReal.sub_lt_self hμ h0 hε.ne')\n  exact ⟨P, h₁, h₂, h₃, tsub_le_iff_right.1 h₄.le⟩\n-- hunts/vm-variation/batch0/probe1.lean (P2); duplication measured: `diff <(sed -n 98,111p src.lean) <(sed -n 123,136p src.lean)` is empty","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-cc1e57","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.absolutelyContinuous","line":160,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"uninformative-name-shadows-def","claim":"The full name `MeasureTheory.VectorMeasure.absolutelyContinuous` does not describe the conclusion `μ ≪ᵥ μ.ennrealVariation` (no mention of `ennrealVariation`; `μ.absolutelyContinuous` reads as 'μ is absolutely continuous'). It differs only in case from the definition `MeasureTheory.VectorMeasure.AbsolutelyContinuous` (Relations.lean:45). The sibling lemma `absolutelyContinuous_variation_transpose` (Integral.lean:179) follows the convention.","fix":"Rename to `absolutelyContinuous_ennrealVariation` with a deprecated alias.","ev":"#check @MeasureTheory.VectorMeasure.AbsolutelyContinuous  -- the def (VectorMeasure α M → VectorMeasure α N → Prop)\n#check @MeasureTheory.VectorMeasure.absolutelyContinuous  -- ∀ μ, μ ≪ᵥ μ.ennrealVariation\n-- hunts/vm-variation/batch0/probe1.lean (P6), output probe1.out","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-14a420","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.variation_le_of_forall_enorm_le","line":185,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-iff-characterisation","claim":"The minimality characterisation is only provided in one direction. `μ.variation` is the least measure dominating `‖μ ·‖ₑ` on measurable sets (Rudin RCA 6.2–6.3), but the iff `μ.variation ≤ m ↔ ∀ E, MeasurableSet E → ‖μ E‖ₑ ≤ m E` is missing. It is a one-liner from `enorm_measure_le_variation` and this lemma. Not in Mathlib (`git grep 'variation_le_iff'` finds nothing).","fix":"Add `variation_le_iff` next to `variation_le_of_forall_enorm_le`.","ev":"theorem variation_le_iff {μ : VectorMeasure X V} {m : Measure X} :\n    μ.variation ≤ m ↔ ∀ E, MeasurableSet E → ‖μ E‖ₑ ≤ m E :=\n  ⟨fun h E _ => (enorm_measure_le_variation μ E).trans (h E), variation_le_of_forall_enorm_le⟩\n-- hunts/vm-variation/batch0/probe1.lean (P5)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-3e8a98","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.variation_finsetSum_le","line":196,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"manual-induction-reproves-le-sum-of-subadditive","claim":"The 7-line `Finset.induction_on` proof reproves the special case of Mathlib's `Finset.le_sum_of_subadditive` (Mathlib/Algebra/Order/BigOperators/Group/Finset.lean:97, `@[to_additive le_sum_of_subadditive] theorem le_prod_of_submultiplicative [IsOrderedMonoid N] (f : M → N) (h_one : f 1 ≤ 1) (h_mul : ∀ x y, f (x * y) ≤ f x * f y) (s : Finset ι) (g : ι → M) : f (∏ i ∈ s, g i) ≤ ∏ i ∈ s, f (g i)`), applicable because `Measure X` is an `IsOrderedAddMonoid` (Mathlib/MeasureTheory/Measure/CompleteLattice.lean:61) and `variation_zero`/`variation_add_le` are the two hypotheses.","fix":"Replace the proof by the term `le_sum_of_subadditive _ variation_zero.le (fun _ _ ↦ variation_add_le) _ _`.","ev":"In a copy of src.lean (hunts/vm-variation/batch1/src_edit.lean, compiled with -DautoImplicit=false -DmaxSynthPendingDepth=3 -Dlinter.mathlibStandardSet=true, no errors or warnings):\nlemma variation_finsetSum_le [ContinuousAdd V] {ι} (s : Finset ι) (μ : ι → VectorMeasure X V) :\n    (∑ i ∈ s, μ i).variation ≤ ∑ i ∈ s, (μ i).variation :=\n  le_sum_of_subadditive _ variation_zero.le (fun _ _ ↦ variation_add_le) _ _","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7220e8","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.variation_add_le","line":200,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"The file provides `IsFiniteMeasure` instances for the variation of `restrict`, `map`, `smul`, `dirac` and finite spaces, but none for `0`, `μ + ν`, `-μ` or `μ - ν`, although `variation_zero`, `variation_add_le`, `variation_neg` and `variation_sub_le` make each one line. `infer_instance` fails on all four.","fix":"Add the four instances (`isFiniteMeasure_of_le _ variation_add_le`, `variation_sub_le`, and rewrites by `variation_neg`/`variation_zero`).","ev":"-- hunts/vm-variation/lead/P.lean section C: `infer_instance` fails for `(μ + ν).variation`, `(-μ).variation`, `(μ - ν).variation`, `(0 : VectorMeasure X V).variation` (4 synthInstanceFailed); the one-line proofs compile.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-952115","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.instIsFiniteMeasureVariationRestrict","line":248,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"The instance `[IsFiniteMeasure μ.variation] : IsFiniteMeasure (μ.restrict s).variation` asks for global finiteness, but its own proof (`isFiniteMeasure_of_le _ variation_restrict_le`) needs only `IsFiniteMeasure (μ.variation.restrict s)`. A consumer works around this: `VectorMeasure.setIntegral_const` (SetIntegral.lean:331) assumes `[IsFiniteMeasure (μ.variation.restrict s)]` and rebuilds the instance by hand (`have : IsFiniteMeasure (μ.restrict s).variation := by rwa [variation_restrict hs]`).","fix":"State the instance with `[IsFiniteMeasure (μ.variation.restrict s)]` (the global case still follows via `Restrict.isFiniteMeasure`), and drop the manual `have` in `setIntegral_const`.","ev":"-- hunts/vm-variation/lead/P.lean section A: `example [IsFiniteMeasure (μ.variation.restrict s)] : IsFiniteMeasure (μ.restrict s).variation := by infer_instance` fails (synthInstanceFailed); the same statement `:= isFiniteMeasure_of_le _ variation_restrict_le` compiles.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-20161c","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasurableEmbedding.variation_map","line":262,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"proves-equality-where-monotonicity-suffices","claim":"The proof spends 7 lines (a nested `have` using `variation_apply_eq_zero`, `measure_union` and two `grind` calls) proving the equality `(μ.map φ).variation s = (μ.map φ).variation (s ∩ range φ)`, but only `≥` is used, and that is `measure_mono inter_subset_left`; dropping the detour shortens the proof from 15 to 8 lines.","fix":"Replace the `s \\ range φ` block by monotonicity, e.g. `grw [← measure_mono (μ := (μ.map φ).variation) (inter_subset_left (t := range φ)), ← hφ.comap_preimage]` before the `variation_le_of_forall_enorm_le` step.","ev":"In hunts/vm-variation/batch1/src_edit.lean (whole file compiles with Mathlib's options, no warnings):\ntheorem _root_.MeasurableEmbedding.variation_map (hφ : MeasurableEmbedding φ) :\n    (μ.map φ).variation = μ.variation.map φ := by\n  refine le_antisymm variation_map_le (Measure.le_iff.2 fun s hs ↦ ?_)\n  rw [hφ.map_apply]\n  grw [← measure_mono (μ := (μ.map φ).variation) (inter_subset_left (t := range φ)),\n    ← hφ.comap_preimage]\n  refine Measure.le_iff'.1 (variation_le_of_forall_enorm_le fun t ht ↦ ?_) _\n  rw [hφ.comap_apply]\n  refine le_of_eq_of_le ?_ (enorm_measure_le_variation _ _)\n  rw [map_apply _ hφ.measurable (hφ.measurableSet_image.2 ht), preimage_image_eq _ hφ.injective]\n(a calc version is in probe1.lean P3)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-8b4a94","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.variation_smul_le","line":314,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"The private `variation_smul_le` assumes `[NormedField 𝕜] [NormedSpace 𝕜 V]`, but the inequality holds for any `[SeminormedRing R] [Module R V] [IsBoundedSMul R V]`, where the equality `variation_smul` fails. For example, with componentwise multiplication on ℝ×ℝ, c = (1,0) and μ = dirac x (0,1), the left side is 0 and the right side is 1. As the `norm_smul_le` analogue it should be public. The finite-variation instance at L333 is stated with the same field assumptions, so it misses normed-ring scalars. For `A` a `NormedRing`, `IsFiniteMeasure (c • μ).variation` for `μ : VectorMeasure X A`, `c : A` is not found, and it follows at once from the generalised lemma via `isFiniteMeasure_of_le`.","fix":"Make `variation_smul_le` public over `[SeminormedRing R] [Module R V] [IsBoundedSMul R V]` (proof: add `enorm_smul_le` to the `grw`) and derive the L333 instance as `isFiniteMeasure_of_le _ variation_smul_le` under the same assumptions.","ev":"hunts/vm-variation/batch2/srcsmul.lean (generalised `variation_smul_le` + instance compile; NormedRing-scalar examples compile); hunts/vm-variation/batch2/P5.lean (against the audited file: `example {A} [NormedRing A] (μ : VectorMeasure X A) (c : A) [IsFiniteMeasure μ.variation] : IsFiniteMeasure (c • μ).variation := inferInstance` → failed to synthesize)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b96434","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.variation_smul","line":320,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`variation_smul` assumes `[NormedField 𝕜] [NormedSpace 𝕜 V]`, but the equality holds for any `[SeminormedRing R] [Module R V] [NormSMulClass R V]`. A direct proof (pull `‖c‖ₑ` out of each partition sum, then `ENNReal.mul_iSup`) needs no inverse, and in the `ENormedAddCommMonoid` setting gives `(c • μ).variation = ‖c‖ₑ • μ.variation` for any `[ENormSMulClass R V]`. Natural cases the current statement misses: quaternion scalars (`ℍ` is a `NormedDivisionRing`, not a `NormedField`) and `ℝ≥0`-scaling of `ℝ≥0∞`-valued vector measures. The 10-line inverse-trick proof and its private helper become unnecessary.","fix":"Add `variation_smul_enorm` (ENormSMulClass, Basic section, 4-line direct proof) and state `variation_smul` for `[SeminormedRing R] [Module R V] [NormSMulClass R V]` as `by rw [variation_smul_enorm, enorm_eq_nnnorm]; rfl`.","ev":"hunts/vm-variation/batch2/P1.lean (compiles: `variation_smul_enorm` + the file's statement over SeminormedRing/NormSMulClass + ℍ and ℝ≥0/ℝ≥0∞ examples); hunts/vm-variation/batch2/P1fail.lean (`#synth NormedField ℍ` fails); hunts/vm-variation/batch2/srcsmul.lean (edited copy of src.lean with the generalised lemmas, compiles with linters, no warnings)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6f07bc","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.variation_smul","line":320,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`variation_smul` is not `@[simp]`, though its siblings `variation_zero`, `variation_neg` and `variation_dirac` are, its right side is the natural normal form, and both downstream uses call it as `simp [variation_smul]` (Integral.lean:488, :523). Plain `simp` makes no progress on `(c • μ).variation = ‖c‖₊ • μ.variation`; with the attribute, simp closes the pointwise and iterated-smul forms without looping.","fix":"Tag `variation_smul` with `@[simp]`.","ev":"hunts/vm-variation/batch2/P2.lean (A1: `example ... : (c • μ).variation = ‖c‖₊ • μ.variation := by simp` → `simp` made no progress; A2: with `attribute [local simp] variation_smul`, `simp` proves `(c • μ).variation s = ‖c‖₊ * μ.variation s` and `(c • d • μ).variation = (‖c‖₊ * ‖d‖₊) • μ.variation`)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-f8a9c1","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.SignedMeasure.exists_subset_lt_enorm_apply_of_lt_variation","line":362,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"long-proof-duplicated-blocks","claim":"The declaration is 58 lines (L362–419) with a 55-line proof. The positive block `I` and the negative block `J` (17 lines each) are near-copies, and each uses a brittle `rw [A, abs_of_nonneg]; rw [← A]` dance. Through the Hahn–Jordan decomposition (`toJordanDecomposition_spec` and `totalVariation_eq_variation`, both in Variation/SignedMeasure.lean) the same statement takes 17 proof lines: variation s = ‖μ (p ∩ s)‖ₑ + ‖μ (pᶜ ∩ s)‖ₑ, then pick the larger piece. The lemma is signed-measure-specific, so it fits Variation/SignedMeasure.lean. Its consumer Semivariation.lean would then need that import.","fix":"Move the lemma to Variation/SignedMeasure.lean and prove it via the Hahn–Jordan decomposition, or at least factor the duplicated I/J blocks into one helper applied to μ and −μ.","ev":"hunts/vm-variation/batch2/P3.lean (F: the 17-line Hahn–Jordan proof of the exact statement compiles, importing Mathlib.MeasureTheory.VectorMeasure.Variation.SignedMeasure); length measured with awk on src.lean L362–419 = 58 lines","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-48b988","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.iSup_sum_finpartition_parts","line":430,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"specialised-simp-wrapper","claim":"`iSup_sum_finpartition_parts` is a `@[simp]` wrapper of `sum_finpartition` plus `iSup_const`, specialised to `ℝ≥0∞`. If the general `sum_finpartition` is tagged `@[simp]` (a good simp lemma: `s` and `hs` come from `P`'s type), plain `simp` proves it. Its only use is through `preVariationFun_apply_of_ennreal` into `variation_eq_ennrealToMeasure`, and that theorem is a 2-line `ext; simp [..., sum_finpartition]` without either helper.","fix":"Tag `sum_finpartition` with `@[simp]` and drop `iSup_sum_finpartition_parts`, using `simp [sum_finpartition]` at its one use.","ev":"hunts/vm-variation/batch2/P4.lean (H: with `attribute [local simp] sum_finpartition`, `simp` proves the statement); hunts/vm-variation/batch2/P2.lean (C1: `variation_eq_ennrealToMeasure` by `ext s hs; simp [variation_apply, preVariation_apply, ennrealPreVariation_apply, ennrealToMeasure_apply hs, preVariationFun_apply _ hs, sum_finpartition]`; C2: the statement by `simp [sum_finpartition]`)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-0d38df","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.variation_eq_ennrealToMeasure","line":441,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`variation_eq_ennrealToMeasure` is not `@[simp]`, although `ennrealVariation_eq_self` is. Without it, `simp` cannot show `μ.toENNRealVectorMeasure.variation = μ` for a measure μ, or `μ.variation s = μ s` for measurable s and `μ : VectorMeasure X ℝ≥0∞`. With it, both close by `simp`.","fix":"Tag `variation_eq_ennrealToMeasure` with `@[simp]`.","ev":"hunts/vm-variation/batch2/P4.lean (G1: `example (μ : Measure X) : μ.toENNRealVectorMeasure.variation = μ := by simp` → `simp` made no progress; G2: compiles with `attribute [local simp] variation_eq_ennrealToMeasure`); hunts/vm-variation/batch2/P2.lean (C3 fails, C4 compiles)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2ca006","file":"Mathlib/NumberTheory/AlmostPrime.lean","decl":"Nat.IsAlmostPrime","line":40,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-instance","claim":"`IsAlmostPrime`, `IsAtMostAlmostPrime` (and so `IsSemiprime`) have no `Decidable` instances: `#synth DecidablePred (IsAlmostPrime 2)` fails and `example : IsSemiprime 6 := by decide` fails, although both are `n ≠ 0 ∧ Ω n = k` / `≤ k` with decidable parts.","fix":"`instance : Decidable (IsAlmostPrime k n) := inferInstanceAs (Decidable (n ≠ 0 ∧ Ω n = k))`, likewise for `IsAtMostAlmostPrime`.","ev":"import Mathlib.NumberTheory.AlmostPrime\nopen Nat\n#synth DecidablePred (IsAlmostPrime 2)   -- error: failed to synthesize\nexample : IsSemiprime 6 := by decide     -- error: failed to synthesize Decidable (IsSemiprime 6)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-553893","file":"Mathlib/NumberTheory/AlmostPrime.lean","decl":"Nat.IsSemiprime","line":51,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"`IsSemiprime` is introduced but no declaration mentions it: there is no characterisation `IsSemiprime n ↔ ∃ p q, p.Prime ∧ q.Prime ∧ n = p * q` (provable in six lines from `List.length_eq_two`, `Nat.prime_of_mem_primeFactorsList`, `Nat.prod_primeFactorsList`), and the constructors `Prime.mul_isAlmostPrime_two` / `sq_isAlmostPrime_two` state `IsAlmostPrime 2` so a search for 'semiprime' finds nothing. `IsAtMostAlmostPrime` also lacks `mono` (`k ≤ l → … k n → … l n`).","fix":"Add `isSemiprime_iff`, state the two constructors with `IsSemiprime`, and add `IsAtMostAlmostPrime.mono`.","ev":"example {n : ℕ} (h : IsSemiprime n) : ∃ p q : ℕ, p.Prime ∧ q.Prime ∧ n = p * q := by\n  have hc : n.primeFactorsList.length = 2 := h.2\n  obtain ⟨p, q, hf⟩ := List.length_eq_two.mp hc\n  refine ⟨p, q, ?_, ?_, ?_⟩\n  · exact Nat.prime_of_mem_primeFactorsList (n := n) (by simp [hf])\n  · exact Nat.prime_of_mem_primeFactorsList (n := n) (by simp [hf])\n  · simpa [hf] using (Nat.prod_primeFactorsList h.1).symm","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-41e709","file":"Mathlib/NumberTheory/AlmostPrime.lean","decl":"Nat.isAlmostPrime_zero_iff","line":56,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"The simp API covers index 0 and 1 of `IsAlmostPrime` but not argument 0 or 1, nor `IsAtMostAlmostPrime` at all: `simp` makes no progress on `¬ IsAlmostPrime k 0`, `IsAlmostPrime k 1 ↔ k = 0`, or `IsAtMostAlmostPrime k 1`.","fix":"Add `@[simp]` lemmas `not_isAlmostPrime_zero`, `isAlmostPrime_one_right_iff`, `not_isAtMostAlmostPrime_zero`, `isAtMostAlmostPrime_one`, `isAtMostAlmostPrime_zero_iff`.","ev":"example (k : ℕ) : ¬ IsAlmostPrime k 0 := by simp          -- `simp` made no progress\nexample (k : ℕ) : IsAtMostAlmostPrime k 1 := by simp      -- `simp` made no progress\nexample (k : ℕ) : IsAlmostPrime k 1 ↔ k = 0 := by simp    -- `simp` made no progress","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a7d890","file":"Mathlib/NumberTheory/AlmostPrime.lean","decl":"Nat.Prime.sq_isAlmostPrime_two","line":92,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"special-case-of-general","claim":"`Prime.sq_isAlmostPrime_two : IsAlmostPrime 2 (p ^ 2)` is the r = 2 case of `IsAlmostPrime r (p ^ r)` (one line from `cardFactors_apply_prime_pow`), itself a case of `IsAlmostPrime k n → IsAlmostPrime (r * k) (n ^ r)` (from `cardFactors_pow`); neither general form is in the file.","fix":"Add `Prime.isAlmostPrime_pow` and `IsAlmostPrime.pow`; keep the square as a corollary.","ev":"example {p : ℕ} (hp : p.Prime) (r : ℕ) : IsAlmostPrime r (p ^ r) :=\n  ⟨pow_ne_zero _ hp.ne_zero, ArithmeticFunction.cardFactors_apply_prime_pow hp⟩\nexample {k n : ℕ} (h : IsAlmostPrime k n) (r : ℕ) : IsAlmostPrime (r * k) (n ^ r) := by\n  refine ⟨pow_ne_zero _ h.1, ?_⟩\n  rw [ArithmeticFunction.cardFactors_pow, h.2]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-0743e4","file":"Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean","decl":"(file)","line":11,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-names-missing-decl","claim":"The module docstring names the second main result `dirichletLSeries_eulerProduct` 'with variants `dirichletLSeries_eulerProduct_hasProd` and `dirichletLSeries_eulerProduct_tprod`', but no such declarations exist in Mathlib (not even deprecated aliases): the theorems are `DirichletCharacter.LSeries_eulerProduct(_hasProd/_tprod)`. The docstring also omits the file's other results (`LSeries_changeLevel`, the `exp_log` variants, `eulerProduct_log_eq_LSeries`, `LSeries_eq_exp_LSeries`, `log_riemannZeta_eq`).","fix":"Use the current names and list the remaining results.","ev":"Measured: `grep -rn dirichletLSeries_eulerProduct Mathlib` finds only the module docstring (L22-23); the declarations are `DirichletCharacter.LSeries_eulerProduct*` (L106-131).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-f91b35","file":"Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean","decl":"tsum_dirichletSummand","line":79,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"unneeded-hypothesis","claim":"`tsum_dirichletSummand` assumes `1 < s.re`, but the identity `∑' n, dirichletSummandHom χ hs n = L ↗χ s` needs only `s ≠ 0` (convergence plays no role; the proof is the same `simp only` with `LSeries.term_of_ne_zero' hs`). Astra also notes `summable_*Summand` restate `LSeries` summability API and that `LSeries_changeLevel`'s `hs` is formally removable via the junk value 0 outside `1 < s.re` (not recorded: a junk-value strengthening, not mathematical generality) (Astra A1 items 1, 3, 8).","fix":"Take `(hs : s ≠ 0)` in `tsum_dirichletSummand` (and likewise `tsum_riemannZetaSummand` if its proof allows).","ev":"hunts/euler-dirichlet/probe1.lean: the statement with only `hs : s ≠ 0` compiles by the original `simp only` proof.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261006-4dd5f1","file":"Mathlib/NumberTheory/FundamentalDiscriminant.lean","decl":"(module docstring)","line":10,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-claims-more","claim":"The module docstring says fundamental discriminants 'are exactly the discriminants of quadratic fields', but `IsFundamentalDiscr 1` holds. Including 1 is a standard convention, but no quadratic field has discriminant 1; Mathlib proves `2 < |discr K|` for degree > 1 (`NumberField.abs_discr_gt_two`). The gloss 'not a proper square multiple of a smaller discriminant' is also inaccurate for negative D: -12 = 2²·(-3) is excluded although -3 > -12 (it is |·| that is smaller), and it says nothing about 0, which the definition excludes.","fix":"Say 'the discriminants of quadratic fields, together with 1'; state primitivity as 'no D = f²e with f ≥ 2 and e ≡ 0, 1 mod 4'.","ev":"example : Int.IsFundamentalDiscr 1 := by\n  simpa using (Int.isFundamentalDiscr_four_mul_add_one (m := 0)).2 squarefree_one","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-cc3444","file":"Mathlib/NumberTheory/FundamentalDiscriminant.lean","decl":"Int.IsFundamentalDiscr","line":39,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-instance","claim":"There is no `DecidablePred Int.IsFundamentalDiscr` instance, so `decide` cannot check `IsFundamentalDiscr (-4)` and finsets cannot be filtered by it, although `isFundamentalDiscr_iff_squarefree` plus `Int.squarefree_natAbs` and the `Nat` squarefree decision procedure make it decidable.","fix":"Add `instance : DecidablePred IsFundamentalDiscr` via `decidable_of_iff _ isFundamentalDiscr_iff_squarefree.symm`.","ev":"import Mathlib.NumberTheory.FundamentalDiscriminant\n#synth DecidablePred Int.IsFundamentalDiscr\n-- error: failed to synthesize","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-23fb30","file":"Mathlib/NumberTheory/FundamentalDiscriminant.lean","decl":"Int.isFundamentalDiscr_iff_forall_prime","line":82,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reprovable-from-existing-api","claim":"The proof rebuilds 'an odd square is 1 mod 4' from `Int.sq_emod_four` and `Int.odd_iff.mp hp.natCast`; `Int.sq_emod_four_eq_one_of_odd hp.natCast` (same imported file) states it directly and the file still compiles with it.","fix":"`rw [hD, Int.mul_emod, Int.sq_emod_four_eq_one_of_odd hp.natCast, one_mul, Int.emod_emod] at h₁`.","ev":"-- hunts/fund-discr/ProbeCopy.lean: src with that rewrite (and `simp only` instead of `simp +contextual only`) compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7b34a7","file":"Mathlib/NumberTheory/FundamentalDiscriminant.lean","decl":"Int.isFundamentalDiscr_four_mul_add_one","line":96,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`isFundamentalDiscr_four_mul_add_one` and `isFundamentalDiscr_four_mul` are the natural normal-form rewrites for the two shapes `4 * m + 1` and `4 * m` but are not `@[simp]`: `simp` makes no progress on either iff, and closes both once they are local simp lemmas.","fix":"Tag both `@[simp]`.","ev":"example (m : ℤ) : Int.IsFundamentalDiscr (4 * m + 1) ↔ Squarefree (4 * m + 1) := by simp\n-- error: `simp` made no progress (same for `4 * m`); both pass with\n-- attribute [local simp] Int.isFundamentalDiscr_four_mul_add_one Int.isFundamentalDiscr_four_mul","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-5ff3b5","file":"Mathlib/NumberTheory/ModularForms/LFunction.lean","decl":"ModularForm.L","line":135,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-drops-hypothesis","claim":"`L` is documented as 'the L-series of a modular form (without its Archimedean Γ-factor)', but it is `Λ · (2π)^s / Γ(s)`, which by `hasSum_L` equals `h ^ s · ∑ aₙ n⁻ˢ` with h the cusp width: for h ≠ 1 (e.g. Γ(N), h = N) it is h^s times the usual L-series, a normalization the docstring does not mention; `Λ` is likewise called 'the L-series … including its Γ-factor' rather than the completed L-function.","fix":"State `L f s = h ^ s * ∑ aₙ / n ^ s` for Re s large and call Λ the completed L-function.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-3bbebc","file":"Mathlib/NumberTheory/ModularForms/RamanujanFormula.lean","decl":"Derivative.normalizedDerivOfComplex_D2","line":73,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"general-material-wrong-file","claim":"`normalizedDerivOfComplex_D2 : D (D2 γ) = fun z ↦ -(γ 1 0)² / denom γ z²` is an elementary derivative computation needing nothing from the dimension formula or Ramanujan's identities, yet it lives in `RamanujanFormula.lean`, so it is unavailable to files importing only `ModularForms.Derivative`, where its ingredients are.","fix":"Move it to `Mathlib/NumberTheory/ModularForms/Derivative.lean` (or the E2 file).","ev":"import Mathlib.NumberTheory.ModularForms.Derivative\n#check Derivative.normalizedDerivOfComplex_D2   -- unknown constant","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-007a6d","file":"Mathlib/NumberTheory/ModularForms/RamanujanFormula.lean","decl":"Derivative.normalizedDerivOfComplex_D2","line":73,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reprovable-from-existing-api","claim":"Two local steps rebuild existing API. `hcomp` in `normalizedDerivOfComplex_D2` redoes the `ofComplex`-near-ℍ argument with `filter_upwards [isOpen_upperHalfPlaneSet.mem_nhds …]`, which is `UpperHalfPlane.eventuallyEq_coe_comp_ofComplex`. `heq` in `serreDerivativeOne_E2_slash` calls `grind` on what is a direct specialisation of `serreDerivative_slash_equivariant`. Both replacements compile.","fix":"`simpa [D2, Function.comp_def, div_eq_mul_inv] using (eventuallyEq_coe_comp_ofComplex z.im_pos).fun_comp (fun w : ℂ ↦ 2 * π * I * (γ 1 0 : ℂ) / denom γ w)`; `simpa using serreDerivative_slash_equivariant (k := 2) E2_mdifferentiable (γ := γ)`.","ev":"-- hunts/ramanujan/ProbeA.lean (hcomp via eventuallyEq_coe_comp_ofComplex) and ProbeB.lean (heq via simpa) both compile","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4a68a7","file":"Mathlib/NumberTheory/ModularForms/RamanujanFormula.lean","decl":"Derivative.serreDerivativeOneE2","line":118,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"general-material-private","claim":"The file proves that the weight-1 Serre derivative `∂₁ E₂` of the quasi-modular `E₂` is a weight-4 modular form (`serreDerivativeOne_E2_slash`, `serreDerivativeOneE2`), a standard fact of independent use, but both are `private`. The rank-one dimension argument `serreDerivative_eq_smul` is also private, and it works verbatim for any `Γ` with `[Γ.HasDetOne]`.","fix":"Make `serreDerivativeOneE2` (and its slash lemma) public; optionally expose the dimension argument for general Γ.","ev":"-- RamanujanFormula.lean: `private lemma serreDerivativeOne_E2_slash`, `private def serreDerivativeOneE2 : ModularForm 𝒮ℒ 4`, `private lemma serreDerivative_eq_smul`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-e51766","file":"Mathlib/NumberTheory/ModularForms/RamanujanFormula.lean","decl":"Derivative.serreDerivative_E₂","line":135,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"name-casing","claim":"`serreDerivative_E₂` and `normalizedDerivOfComplex_E₂` spell the constant with a Unicode subscript, but the declaration is `EisensteinSeries.E2` and its API uses `E2` (`E2_slash_action`, `E2_mdifferentiable`, `tendsto_E2_atImInfty`), so `…_E2` finds nothing. (`E₄`/`E₆` do match their constants.)","fix":"Rename to `serreDerivative_E2` / `normalizedDerivOfComplex_E2`.","ev":"#check @EisensteinSeries.E2\n#check @Derivative.serreDerivative_E₂   -- statement mentions `E2`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-400a75","file":"Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean","decl":"Units.mem","line":58,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"general-fact-inlined-in-special-proof","claim":"`Units.mem` inlines a general fact with no Mathlib name: in a number field of unit rank 0 every unit is torsion (L58-65 rebuild it from `exist_unique_eq_mul_prod` by emptying the product over `Fin (rank K)`). Stated as `NumberField.Units.mem_torsion_of_rank_eq_zero (h : rank K = 0) (u) : u ∈ torsion K` it has a 3-line proof and applies to every imaginary quadratic field.","fix":"Add `NumberField.Units.mem_torsion_of_rank_eq_zero` to Units/DirichletTheorem.lean and use it at L58-65.","ev":"hunts/cyclo-three/probe1.lean: `NumberField.Units.mem_torsion_of_rank_eq_zero` proved by `obtain ⟨⟨x, e⟩, hxu, -⟩ := exist_unique_eq_mul_prod _ u; have : IsEmpty (Fin (rank K)) := by rw [h]; infer_instance; simp [hxu]` compiles, exit 0; grep finds no rank-zero/torsion lemma under Mathlib/NumberTheory.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-1b3810","file":"Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean","decl":"eq_one_or_neg_one_of_unit_of_congruent","line":81,"sev":"MINOR","status":"confirmed","cat":"hygiene","pattern":"set-option-masks-missing-simp-lemma","claim":"The three `set_option backward.isDefEq.respectTransparency.types false in` (on `lambda_sq` L81, `eta_sq` L90, `eq_one_or_neg_one_of_unit_of_congruent` L96) compensate for a missing simp lemma: Mathlib has `IsPrimitiveRoot.coe_toInteger : hζ.toInteger.1 = ζ` (Cyclotomic/Basic.lean:191) but no `algebraMap (𝓞 K) K hζ.toInteger = ζ`, which is the form `ext`/`simp` produce. Without the option and without that lemma, `simpa using hζ.isRoot_cyclotomic _` fails (`ζ ^ 2 + ζ + 1 = 0` vs `algebraMap (𝓞 K) K hζ.toInteger ^ 2 + … = 0`) and `ext; simp` at L124 leaves `↑⋯.toInteger = algebraMap (𝓞 K) K hζ.toInteger ^ 2`; with the lemma (`rfl`, tagged `@[simp]`) all three proofs compile with no `set_option`.","fix":"Add `@[simp] lemma IsPrimitiveRoot.algebraMap_toInteger (hζ : IsPrimitiveRoot ζ k) : algebraMap (𝓞 K) K hζ.toInteger = ζ := rfl` next to `coe_toInteger` and delete the three `set_option` lines (and the now unused `RingOfIntegers.neg_mk` at L117).","ev":"Module-mode copies of the file: hunts/cyclo-three/m0.lean (verbatim, exit 0); m1.lean (the three `set_option` lines deleted) fails at L86 and L92 with the type mismatch quoted and at L121 with an unsolved goal; m3.lean (m1 plus `@[simp] lemma IsPrimitiveRoot.algebraMap_toInteger' … := by rfl`) compiles, exit 0, with only `RingOfIntegers.neg_mk` reported unused. Non-module probe1.lean agrees: with `@[simp] IsPrimitiveRoot.algebraMap_toInteger' … := rfl`, `lambda_sq'`, `eta_sq'` and `eq_one_or_neg_one_of_unit_of_congruent'` compile without any `set_option` (exit 0). Without the lemma (first run of probe1 and probe2.lean) `lambda_sq'`/`eta_sq'` fail with the type mismatch quoted, and the third theorem fails at `ext; simp` with the unsolved goal quoted.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-256e38","file":"Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean","decl":"lambda_sq","line":83,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"private-bridge-lemma","claim":"The module docstring states the Kummer-type result for units congruent to an integer 'modulo `3`', but only the `λ ^ 2` form exists, and the bridge `λ ^ 2 = -3 * η` is `private`, so callers cannot pass between the two. With `lambda_sq` public, `λ ^ 2 ∣ a ↔ 3 ∣ a` is a one-line `rw [lambda_sq hζ, Units.mul_right_dvd, neg_dvd]` (Astra A1 item 2).","fix":"Make `lambda_sq` public, add `lambda_sq_dvd_iff_three_dvd`, and state the modulo-3 corollary of `eq_one_or_neg_one_of_unit_of_congruent`.","ev":"hunts/cyclo-three/m3.lean (module mode): `example (a : 𝓞 K) : λ ^ 2 ∣ a ↔ (3 : 𝓞 K) ∣ a := by rw [lambda_sq hζ, _root_.Units.mul_right_dvd, neg_dvd]` compiles inside the file, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-19ff07","file":"Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean","decl":"eta_sq_add_eta_add_one","line":156,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"special-case-of-missing-general-lemma","claim":"`η ^ 2 + η + 1 = 0` (and with it `eta_sq`, `lambda_sq`) holds for a primitive cube root of unity in any domain, a one-liner from `IsPrimitiveRoot.geom_sum_eq_zero`; Mathlib has no such general lemma (grep for `ζ ^ 2 + ζ + 1 = 0` finds nothing), so this file proves the 𝓞 K versions through `hζ.isRoot_cyclotomic` and coercions (Astra A1 item 3).","fix":"Add `IsPrimitiveRoot.sq_add_self_add_one (hz : IsPrimitiveRoot z 3) : z ^ 2 + z + 1 = 0` for `[CommRing R] [IsDomain R]` in RootsOfUnity and specialise.","ev":"hunts/cyclo-three/m3.lean: `example {R} [CommRing R] [IsDomain R] {z : R} (hz : IsPrimitiveRoot z 3) : z ^ 2 + z + 1 = 0 := by simpa [Finset.sum_range_succ, add_comm, add_left_comm, add_assoc] using hz.geom_sum_eq_zero (by decide : 1 < 3)` compiles, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-08f1f1","file":"Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean","decl":"cube_sub_one_eq_mul","line":161,"sev":"MINOR","status":"suspected","cat":"reuse","pattern":"hand-rolled-factorisation","claim":"`cube_sub_one_eq_mul` re-derives by hand a case of the factorisation `X_pow_sub_C_eq_prod` (FieldTheory/KummerExtension.lean); the homogeneous form `x ^ 3 - y ^ 3 = (x - y) * (x - η * y) * (x - η ^ 2 * y)` is missing, and FLT/Three.lean (around L300) expands the same algebra again for a sum of cubes (Astra A1 item 4; not compiled here, and the import cost of KummerExtension was not measured).","fix":"State the homogeneous factorisation once and derive `cube_sub_one_eq_mul` and the FLT/Three use from it.","ev":"Suspected: Astra A1 item 4; not compiled.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261006-305a3f","file":"Mathlib/NumberTheory/NumberField/DirichletDensity.lean","decl":"NumberField.Set.primeIdealZetaSum","line":54,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"The basic facts that justify the definition are missing: summability of ∑_p N(p)^{-s} and positivity of the denominator for s > 1, `HasDirichletDensity univ 1`, density 0 for finite sets, `HasDirichletDensity.unique`; and simp support (`primeIdealZetaSum ∅ s = 0`, `hasDirichletDensity_empty` is not simp).","fix":"Add the listed lemmas (the finite-set result needs `Tendsto (primeIdealZetaSum univ) (𝓝[>] 1) atTop`).","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-0164ca","file":"Mathlib/NumberTheory/NumberField/DirichletDensity.lean","decl":"NumberField.Set.primeIdealZetaSum_le_card_of_finite","line":68,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-drops-hypothesis","claim":"The docstring and the module's Main-results entry state the bound `∑_{p ∈ S} N(p)^{-s} ≤ #S` for every finite S without the theorem's hypothesis `0 ≤ s`, which is necessary (for a singleton {p} and s = -1 the sum is N(p) > 1); `primeIdealZetaSum` itself does not say it is 0 when the series is not summable (e.g. at s = 0 for infinite S), nor that 'partial' means restricted to S.","fix":"Add 'for s ≥ 0' in both places; document the tsum junk value of `primeIdealZetaSum`.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-3f7e03","file":"Mathlib/NumberTheory/NumberField/DirichletDensity.lean","decl":"NumberField.Set.HasDirichletDensity","line":82,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"unexposed-definition-no-api","claim":"`HasDirichletDensity` is a `def` in a `public section` without `@[expose]` and has no characterisation lemma, so in any importing module it cannot be converted to or from its defining `Tendsto` statement (`exact h` is a type mismatch and `unfold HasDirichletDensity` fails): downstream code cannot prove that any set has a Dirichlet density, except `∅` via `hasDirichletDensity_empty`.","fix":"Add `hasDirichletDensity_iff : S.HasDirichletDensity δ ↔ Tendsto … (𝓝[>] 1) (𝓝 δ)` (or `@[expose]` the def).","ev":"module\npublic import Mathlib.NumberTheory.NumberField.DirichletDensity\n…\nexample (h : S.HasDirichletDensity δ) : Tendsto (fun s : ℝ ↦ S.primeIdealZetaSum s / primeIdealZetaSum (Set.univ : Set (HeightOneSpectrum (𝓞 K))) s) (𝓝[>] 1) (𝓝 δ) := by exact h   -- error: Type mismatch\n(and the converse; `unfold HasDirichletDensity at h` -- error: failed to unfold)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-92125c","file":"Mathlib/NumberTheory/Padics/Measure/AmiceTransform.lean","decl":"AbstractMeasure.invTransform_apply","line":141,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"general-material-private","claim":"`invTransform_apply` exposes `invTransform F f` as a `tsum`, but the summability of that series (`invTransformSummable`) is private, so downstream users manipulating the sum must re-prove convergence; a public `hasSum_invTransform` is missing.","fix":"Make the summability public as `hasSum_invTransform : HasSum (fun i ↦ mahlerEquiv f i * F.coeff i) (invTransform F f)`.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-4aa8fb","file":"Mathlib/NumberTheory/Padics/Measure/AmiceTransform.lean","decl":"AbstractMeasure.amiceTransform_invTransform","line":145,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"The Kronecker-delta formula for the Mahler coefficients of a Mahler basis function, `PadicInt.mahlerEquiv ℤ_[p] (mahler n) i = if i = n then 1 else 0`, is buried as a local `have` here; it is basic Mahler-basis API and holds as a one-line `simp`.","fix":"Export it from NumberTheory/Padics/MahlerBasis.lean as a `@[simp]` lemma and use it here.","ev":"example (n i : ℕ) : PadicInt.mahlerEquiv ℤ_[p] (mahler n) i = if i = n then 1 else 0 := by\n  simp [PadicInt.mahlerEquiv_apply, ← fwdDiff_iter_choose_zero n i, fwdDiff_iter_eq_sum_shift, mahler_natCast_eq]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-68267a","file":"Mathlib/NumberTheory/Padics/Measure/AmiceTransform.lean","decl":"AbstractMeasure.amiceTransformEquiv","line":158,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"simp-set-not-confluent","claim":"The inverse has no public equations: there is no `amiceTransformEquiv_symm_apply` (`e.symm F = invTransform F` fails by `rfl` in another module, the body being unexposed) and no `invTransform_amiceTransform`; worse, `simp` turns the goal `e.symm (e μ) = μ` into the unsolvable `e.symm (amiceTransform μ) = μ`, because the `@[simp]` `amiceTransformEquiv_apply` rewrites the inner application before `LinearEquiv.symm_apply_apply` can fire.","fix":"Add `@[simp] amiceTransformEquiv_symm_apply : e.symm F = invTransform F` and `@[simp] invTransform_amiceTransform` (= `injective_amiceTransform (amiceTransform_invTransform _)`); make `amiceTransform_invTransform` simp.","ev":"module\npublic import Mathlib.NumberTheory.Padics.Measure.AmiceTransform\nexample (μ : D(ℤ_[p], ℤ_[p])) :\n    (AbstractMeasure.amiceTransformEquiv (p := p)).symm (AbstractMeasure.amiceTransformEquiv μ) = μ := by\n  simp\n-- error: unsolved goals ⊢ amiceTransformEquiv.symm (amiceTransform μ) = μ\nexample (F : ℤ_[p]⟦X⟧) : amiceTransformEquiv.symm F = invTransform F := by rfl  -- error: rfl failed","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-3d680e","file":"Mathlib/NumberTheory/Padics/Measure/Basic.lean","decl":"AbstractMeasure","line":40,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-docstring","claim":"The module docstring describes an abstract measure as 'an R-linear functional on continuous maps X → R' with R 'a normed ring', but the definition is a *continuous* R-linear map C(X, R) →L[R] E into a module E, for any topological commutative ring R (no norm anywhere in the file); the `AbstractMeasure` docstring likewise speaks of the 'default (norm) topology', which is not a norm topology in this generality.","fix":"Module doc: 'a continuous R-linear map C(X, R) → E, for R a topological commutative ring and E a topological R-module'; drop '(norm)'.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-5e2f7a","file":"Mathlib/NumberTheory/Padics/Measure/Basic.lean","decl":"AbstractMeasure.isAddApply","line":64,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-instance","claim":"The type synonym re-registers only `IsAddApply` and `IsSMulApply R`, not `IsZeroApply`, `IsNegApply`, `IsSubApply` or `IsSMulApply ℕ/ℤ` (all present on `C(X, R) →L[R] E`), so `simp` cannot evaluate `(0 : AbstractMeasure X R E) f = 0` or `(-μ) f = -μ f` ('simp made no progress').","fix":"Add the missing `Is*Apply` instances next to `isAddApply`.","ev":"#synth IsZeroApply D(Unit, ℝ) C(Unit, ℝ) ℝ  -- failed to synthesize (also IsNegApply, IsSubApply, IsSMulApply ℕ)\nexample (f : C(X, R)) : (0 : AbstractMeasure X R E) f = 0 := by simp  -- simp made no progress","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-632464","file":"Mathlib/NumberTheory/Padics/Measure/Basic.lean","decl":"AbstractMeasure.instModule","line":75,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"The ContinuousSMul section (`Module`, `isSMulApply`, `toCLMEquiv`, `map`, `arrowCongrLeft`, …) assumes `[ContinuousSMul R E]`; `[ContinuousConstSMul R E]` suffices, as for `ContinuousLinearMap.module`.","fix":"Replace the section variable by `[ContinuousConstSMul R E]`.","ev":"example [ContinuousConstSMul R E] : Module R (AbstractMeasure X R E) :=\n  inferInstanceAs (Module R (C(X, R) →L[R] E))","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-b33874","file":"Mathlib/NumberTheory/Padics/Measure/Basic.lean","decl":"AbstractMeasure.map","line":105,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reprovable-from-existing-api","claim":"`map f` is, by `rfl`, the existing `ContinuousLinearMap.lcomp E (f.compCLM R R)` rebuilt as a structure literal.","fix":"Define `map f := (f.compCLM R R).lcomp E`.","ev":"example [ContinuousSMul R E] (f : C(X, Y)) (μ : AbstractMeasure X R E) :\n    map f μ = ((f.compCLM R R).lcomp E : (C(X, R) →L[R] E) →ₗ[R] (C(Y, R) →L[R] E)) μ := rfl","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-21abec","file":"Mathlib/NumberTheory/Padics/Measure/Basic.lean","decl":"AbstractMeasure.contractSndCLM","line":194,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"`contractSndCLM` and `contractFstCLM` have no evaluation or coercion lemma, and their bodies are not exposed, so from any other module nothing relates them to `contractSnd`/`contractFst`: `contractSndCLM ν f = contractSnd ν f` fails by `rfl` in a `module` file importing this one.","fix":"Add `@[simp] coe_contractSndCLM` / `contractSndCLM_apply` (and the Fst versions) proved by `rfl` in this file.","ev":"module\npublic import Mathlib.NumberTheory.Padics.Measure.Basic\n...\nexample (ν : D(Y, R)) (f : C(X × Y, R)) : contractSndCLM ν f = contractSnd ν f := by rfl\n-- error: Tactic rfl failed: (contractSndCLM ν) f is not definitionally equal to (contractSnd ν) f","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-644247","file":"Mathlib/NumberTheory/Padics/Measure/Basic.lean","decl":"AbstractMeasure.prodMk_eq_prodMk'","line":254,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-hypothesis","claim":"`prodMk_eq_prodMk'` assumes `[T2Space Y]` only to get `LocallyCompactSpace Y`; with `[LocallyCompactSpace Y]` in its place (weaker, given `CompactSpace Y`) the proof goes through unchanged, since `denseRange_tensorHom` needs no separation on Y.","fix":"Replace `[T2Space Y]` by `[LocallyCompactSpace Y]`.","ev":"example [CompactSpace X] [CompactSpace Y] [T2Space X] [LocallyCompactSpace Y]\n    [TotallyDisconnectedSpace X] [T0Space R] (μ : D(X, R)) (ν : D(Y, R)) :\n    prodMk μ ν = prodMk' μ ν := by <the file's proof, unchanged>","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-b2fc75","file":"Mathlib/NumberTheory/Padics/Measure/Monoid.lean","decl":"AbstractMeasure.instCommRing","line":17,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-drops-hypothesis","claim":"The module docstring says 'if G is abelian and compact, then D(G, R) is a commutative ring', and the CommMonoid section says 'compact, Hausdorff, and commutative', but the `CommRing` instance also needs `[TotallyDisconnectedSpace G]` and `[T0Space R]` (i.e. G profinite): the Fubini lemma `prodMk_eq_prodMk'` it uses needs a totally disconnected factor. The docs claim commutativity for e.g. the circle group, which the file does not prove. The module overview also omits Hausdorffness. Without [T0Space R] the advertised claim can fail (Astra: G = ∏ℕ F₂, R = F₂ with the indiscrete topology, ultrafilter-evaluation functionals whose two iterated integrals of an indicator differ).","fix":"Say 'if G is a commutative profinite monoid (and R is T0)' in both places.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-a6b66c","file":"Mathlib/NumberTheory/Padics/Measure/Monoid.lean","decl":"AbstractMeasure.monoidAlgebraHom_single","line":131,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"special-case-of-general","claim":"`monoidAlgebraHom_single` fixes the coefficient to 1; the same one-line `simp [monoidAlgebraHom]` proves `monoidAlgebraHom (.single g r) = r • dirac R g` for every `r`.","fix":"State it for arbitrary `r : R`.","ev":"example (g : G) (r : R) : monoidAlgebraHom (.single g r) = r • dirac R g := by\n  simp [monoidAlgebraHom]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-366756","file":"Mathlib/NumberTheory/Padics/Measure/Monoid.lean","decl":"AbstractMeasure.instModuleContinuousMap","line":139,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-instance","claim":"The convolution action `Module D(G, R) C(G, R)` comes without its compatibility with the R-module structures: `IsScalarTower R D(G, R) C(G, R)` (and `SMulCommClass`) cannot be synthesized, though both follow from the R-bilinearity of `convolveFunRight`.","fix":"Register `IsScalarTower R D(G, R) C(G, R)` and `SMulCommClass R D(G, R) C(G, R)`.","ev":"variable [Monoid G] [ContinuousMul G] [LocallyCompactSpace G]\n#synth IsScalarTower R D(G, R) C(G, R)  -- failed to synthesize","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-12a454","file":"Mathlib/NumberTheory/Padics/Measure/Topology.lean","decl":"AbstractMeasure.WeakTopology","line":41,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`WeakTopology` assumes `[NormedAddCommGroup E]` (and the section declares an unused `[ContinuousSMul R E]`), but the induced topology needs only `[AddCommGroup E] [TopologicalSpace E]`, the assumptions under which `AbstractMeasure X R E` itself makes sense.","fix":"Use `[AddCommGroup E] [TopologicalSpace E]` in the Weak section.","ev":"variable [AddCommGroup E] [TopologicalSpace E] [CommRing R] [Module R E] [TopologicalSpace R] [IsTopologicalRing R]\ndef WeakTopology' : TopologicalSpace (AbstractMeasure X R E) :=\n  .induced (fun μ f ↦ μ f) inferInstance","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-21e028","file":"Mathlib/NumberTheory/Padics/Measure/Topology.lean","decl":"AbstractMeasure.StrongTopology","line":49,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-claims-more","claim":"`StrongTopology` is documented as 'the topology induced by the norm', but the section's `[CompactSpace X]` is unused and so dropped from the exported definition: for non-compact X (e.g. X = ℕ discrete) C(X, R) is not normed and the topology is bounded convergence, which is not normable there.","fix":"Document it as the topology of bounded convergence, which is the operator-norm topology when X is compact.","ev":"#check @AbstractMeasure.StrongTopology\n-- {X R E} [TopologicalSpace X] [NontriviallyNormedField R] [NormedAddCommGroup E] [NormedSpace R E] → TopologicalSpace (AbstractMeasure X R E)   (no CompactSpace X)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-2530cf","file":"Mathlib/NumberTheory/Padics/Measure/Topology.lean","decl":"AbstractMeasure.StrongTopology","line":49,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`StrongTopology` assumes `[NontriviallyNormedField R] [NormedAddCommGroup E] [NormedSpace R E]`, but the bounded-convergence topology it inherits needs only `[NormedField R]` and a topological additive group E with `[Module R E]`.","fix":"Weaken the section variables.","ev":"variable {X R E : Type*} [TopologicalSpace X] [NormedField R]\n  [AddCommGroup E] [TopologicalSpace E] [IsTopologicalAddGroup E] [Module R E]\nnoncomputable def strongTopology' : TopologicalSpace (AbstractMeasure X R E) :=\n  inferInstanceAs (TopologicalSpace (C(X, R) →L[R] E))","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261007-7374a8","file":"Mathlib/NumberTheory/Padics/PadicIntegers.lean","decl":"PadicInt.norm_int_lt_one_iff_dvd","line":302,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `PadicInt.norm_int_lt_one_iff_dvd` (NumberTheory.Padics.PadicIntegers), `PadicInt.norm_intCast_lt_one_iff` (NumberTheory.Padics.PadicIntegers) state exactly the same thing (Lean-checked). Reviewer: Same file: norm_int_lt_one_iff_dvd (k explicit) vs @[simp] norm_intCast_lt_one_iff ({z}). The latter matches Padic.norm_intCast_lt_one_iff naming. Deprecate norm_int_lt_one_iff_dvd.","fix":"Deprecate `PadicInt.norm_int_lt_one_iff_dvd` in favour of `PadicInt.norm_intCast_lt_one_iff`.","ev":"dupscan/Check.lean: `example := (@PadicInt.norm_intCast_lt_one_iff : type_of% @PadicInt.norm_int_lt_one_iff_dvd)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 49, rating MINOR): The modern `intCast` name is preferable, but explicit versus implicit integer arguments make this a small API migration; explicit specialization becomes `(z := k)`.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-275c33","file":"Mathlib/NumberTheory/PrimeCounting.lean","decl":"(file)","line":29,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-describes-other-statement","claim":"The module docstring describes `Nat.primeCounting'_add_le` as: 'all numbers greater than `k` and not coprime to `k` are not prime, and so only at most `φ(k)/k` fraction of the numbers from `k` to `n` are prime'. The theorem is about a second modulus `a < k`: `π' (k + n) ≤ π' k + φ a * (n / a + 1)`, i.e. numbers ≥ k not coprime to `a` are not prime, on the window `[k, k + n)`. The docstring's version (modulus `k` itself, window up to `n`) is a different bound from the one proved, and as a density claim it is false: `[30, 32)` has prime density 1/2 > φ(30)/30 = 8/30 (Astra A1 item 1).","fix":"Say: for `0 < a < k`, primes in `[k, k + n)` are coprime to `a`, so at most `φ a * (n / a + 1)` of them.","ev":"Measured: module docstring L29-31 vs statement L265-266 (`{a k : ℕ} (h0 : a ≠ 0) (h1 : a < k)`, bound `Nat.totient a * (n / a + 1)`).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-5198e4","file":"Mathlib/NumberTheory/PrimeCounting.lean","decl":"primeCounting'","line":51,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"Missing characteristic API: no successor formulas `π' (n + 1) = π' n + if n.Prime then 1 else 0` / `π (n + 1) = …`, no inclusive `π (nth Prime n) = n + 1` (only the strict `primeCounting'_nth_eq`), and `mem_primesBelow`, `mem_primesLE`, `primesBelow_card_eq_primeCounting'` are not `@[simp]` though the adjacent `primesLE_card_eq_primeCounting` is (Astra A1 items 3, 5). Astra also suggests `a.primeFactors ⊆ primesBelow k` instead of `a < k` in `primeCounting'_add_le` (not checked in Lean).","fix":"Add `primeCounting'_succ`, `primeCounting_succ`, `primeCounting_nth_eq`; tag the membership and card lemmas `@[simp]`.","ev":"hunts/prime-counting/probe1.lean: both formulas compile as one-liners (`Nat.count_succ`, `Nat.count_nth_succ_of_infinite`).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-73b61d","file":"Mathlib/Order/Basic.lean","decl":"Ne.lt_of_le'","line":1,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `lt_of_ne_of_le'` (Order.Defs.PartialOrder), `Ne.lt_of_le'` (Order.Basic) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: Both are to_dual-generated: `lt_of_ne_of_le` and the dot-notation twin `Ne.lt_of_le` (Order/Basic, `@[to_dual lt_of_le']`) both have the proof `flip lt_of_le_of_ne`. The fix is `@[to_dual lt_of_le'] alias Ne.lt_of_le := lt_of_ne_of_le`.","fix":"Declare `Ne.lt_of_le'` as an `alias` of `lt_of_ne_of_le'`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-782385","file":"Mathlib/Order/Basic.lean","decl":"Ne.lt_of_le","line":206,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `lt_of_ne_of_le` (Order.Defs.PartialOrder), `Ne.lt_of_le` (Order.Basic) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: `Ne.lt_of_le` is the intended dot-notation twin of `lt_of_ne_of_le` (both proved `flip lt_of_le_of_ne`, both @[to_dual]); it should be `@[to_dual lt_of_le'] alias Ne.lt_of_le := lt_of_ne_of_le` like the neighbouring `LE.le.lt_of_ne` alias.","fix":"Declare `Ne.lt_of_le` as an `alias` of `lt_of_ne_of_le`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-fa34e6","file":"Mathlib/Order/Basic.lean","decl":"min_rec","line":390,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `min_rec` (Order.Basic), `min_ind` (Order.Defs.LinearOrder) state exactly the same thing (Lean-checked). Reviewer: min_rec (Order/Basic, `p` variable) and min_ind (Order/Defs/LinearOrder, `motive`; dual max_ind carries elab_as_elim) are the same eliminator with no comment. min_rec is used only to prove min_rec'. Keep the lower-level min_ind and deprecate min_rec/max_rec.","fix":"Deprecate `min_rec` in favour of `min_ind`.","ev":"dupscan/Check.lean: `example := (@min_ind : type_of% @min_rec)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup2 item 50, rating MINOR): The [`to_dual existing` registration](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Order/Defs/LinearOrder.lean#L134-L143) gives both `_ind` lemmas `elab_as_elim`, whereas `_rec` uses ordinary motive inference. The `@` comparison bypasses this real elaboration distinction.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-b60947","file":"Mathlib/Order/Category/BddLat.lean","decl":"BddLat.hom_id","line":92,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `BddLat.hom_id` (Order.Category.BddLat), `Lat.hom_id` (Order.Category.Lat) have exactly the same statement (Lean-checked), so `BddLat.hom_id` does not state what its name promises and the intended lemma is missing. Reviewer: This is a copy-paste bug. `BddLat.hom_id` is stated for `{X : Lat}` and `LatticeHom.id`, so it is literally Lat.hom_id. The same bug affects BddLat.id_apply, hom_comp and comp_apply (l.95-104), which are all stated for Lat. Restate them for BddLat and BoundedLatticeHom instead of deprecating them. Astra rates it CRITICAL (a lemma weaker than or unrelated to its name).","fix":"Restate `BddLat.hom_id` as its name says (keep `Lat.hom_id`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@Lat.hom_id : type_of% @BddLat.hom_id)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 27, rating CRITICAL): The identity belongs to the wrong category and the RHS to the wrong bundled-hom type. Correct: `{X : BddLat} : (𝟙 X : X ⟶ X).hom = BoundedLatticeHom.id _`. The category instance immediately above explicitly constructs this bounded lattice homomorphism, so `rfl` supplies the intended statement. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Order/Category/BddLat.lean#L68-L100)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-0f956a","file":"Mathlib/Order/Category/BddLat.lean","decl":"BddLat.id_apply","line":95,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `Lat.id_apply` (Order.Category.Lat), `BddLat.id_apply` (Order.Category.BddLat) have exactly the same statement (Lean-checked), so `BddLat.id_apply` does not state what its name promises and the intended lemma is missing. Reviewer: This is a copy-paste bug. BddLat.lean's hom_id/id_apply/hom_comp/comp_apply are stated for `X : Lat` instead of `BddLat`, verbatim copies of Lat.lean. Keep Lat.id_apply and restate BddLat.id_apply for BddLat (BoundedLatticeHom). Astra rates it CRITICAL (a lemma weaker than or unrelated to its name).","fix":"Restate `BddLat.id_apply` as its name says (keep `Lat.id_apply`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@BddLat.id_apply : type_of% @Lat.id_apply)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 12, rating CRITICAL): Forgetting a bounded lattice to a lattice does not make this a statement about identity morphisms in `BddLat`. Correct: `(X : BddLat) (x : X) : (𝟙 X : X ⟶ X) x = x`. The general `CategoryTheory.id_apply` already covers the intended result, but this specialized wrapper has the wrong binder. [BddLat source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Order/Category/BddLat.lean#L58-L104), [general theorem](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/ConcreteCategory/Basic.lean#L163-L169)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-e8b8cb","file":"Mathlib/Order/Category/BddLat.lean","decl":"BddLat.hom_comp","line":99,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `Lat.hom_comp` (Order.Category.Lat), `BddLat.hom_comp` (Order.Category.BddLat) have exactly the same statement (Lean-checked), so `BddLat.hom_comp` does not state what its name promises and the intended lemma is missing. Reviewer: This is a copy-paste bug. BddLat.hom_comp is stated for `{X Y Z : Lat}`, a verbatim copy of Lat.hom_comp. Restate it for BddLat (`(f ≫ g).hom = g.hom.comp f.hom` with BoundedLatticeHom). Astra rates it CRITICAL (a lemma weaker than or unrelated to its name).","fix":"Restate `BddLat.hom_comp` as its name says (keep `Lat.hom_comp`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@BddLat.hom_comp : type_of% @Lat.hom_comp)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 14, rating CRITICAL): The declaration concerns `LatticeHom` composition, whereas the surrounding category uses `BoundedLatticeHom`. Correct: `{X Y Z : BddLat} (f : X ⟶ Y) (g : Y ⟶ Z) : (f ≫ g).hom = g.hom.comp f.hom`. The forgetful functor explains the relationship, but does not repair the specialized statement. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Order/Category/BddLat.lean#L58-L104)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-a0f2e4","file":"Mathlib/Order/Category/BddLat.lean","decl":"BddLat.comp_apply","line":103,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `BddLat.comp_apply` (Order.Category.BddLat), `Lat.comp_apply` (Order.Category.Lat) have exactly the same statement (Lean-checked), so `BddLat.comp_apply` does not state what its name promises and the intended lemma is missing. Reviewer: Copy-paste bug in BddLat.lean: `BddLat.comp_apply` quantifies over `{X Y Z : Lat}` (as do `BddLat.hom_id`, `id_apply`, `hom_comp` at 92-100), so it is literally `Lat.comp_apply`. Keep `Lat.comp_apply`; restate the BddLat lemmas over `BddLat` rather than deprecating. Astra rates it CRITICAL (a lemma weaker than or unrelated to its name).","fix":"Restate `BddLat.comp_apply` as its name says (keep `Lat.comp_apply`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@Lat.comp_apply : type_of% @BddLat.comp_apply)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 22, rating CRITICAL): Arbitrary `BddLat` morphisms are not the `Lat` morphisms quantified over here. Correct: `{X Y Z : BddLat} (f : X ⟶ Y) (g : Y ⟶ Z) (x : X) : (f ≫ g) x = g (f x)`. General `CategoryTheory.comp_apply` already supplies the desired fact; the category-specific wrapper is still misstated. [BddLat source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Order/Category/BddLat.lean#L92-L104), [general theorem](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/ConcreteCategory/Basic.lean#L163-L169)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-310bd1","file":"Mathlib/Order/Defs/Unbundled.lean","decl":"Equivalence.isEquiv","line":220,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `IsEquiv.of_equivalence` (Order.Defs.Unbundled), `Equivalence.isEquiv` (Order.Defs.Unbundled) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: Same file: `Equivalence r → IsEquiv α r` appears at line 66 (target-namespace form, used as `.of_equivalence` in equivalence_iff_isEquiv) and at line 220 (dot-notation form `h.isEquiv`, part of the Equivalence.stdRefl/stdSymm/isTrans family). Both forms are intended, so one should be an `alias`.","fix":"Declare `Equivalence.isEquiv` as an `alias` of `IsEquiv.of_equivalence`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-3ba0b0","file":"Mathlib/Order/Filter/Basic.lean","decl":"Filter.NeBot.nonempty","line":439,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Filter.nonempty_of_neBot` (Order.Filter.Basic), `Filter.NeBot.nonempty` (Order.Filter.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file: `(f : Filter α) [NeBot f] → Nonempty α` is proved twice. NeBot.nonempty takes NeBot as an instance argument, so `hf.nonempty` dot notation cannot work, and it is unused. Keep nonempty_of_neBot (about 7 uses) and deprecate NeBot.nonempty.","fix":"Deprecate `Filter.NeBot.nonempty` in favour of `Filter.nonempty_of_neBot`.","ev":"dupscan/Check.lean: `example := (@Filter.NeBot.nonempty : type_of% @Filter.nonempty_of_neBot)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup2 item 51, rating MINOR): Lean’s [field elaborator](https://github.com/leanprover/lean4/blob/v4.35.0-rc4/src/Lean/Elab/App.lean#L1727-L1794) can supply named instance parameters: `hf.nonempty` supplies `hf` and allows `f` to be inferred. The reviewer’s reason for rejecting the proof-method interface is incorrect.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-806dea","file":"Mathlib/Order/Fin/Basic.lean","decl":"Fin.succAbove_inj","line":198,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Fin.succAbove_right_inj` (Data.Fin.SuccPred), `Fin.succAbove_inj` (Order.Fin.Basic) state exactly the same thing (Lean-checked). Reviewer: `p.succAbove i = p.succAbove j ↔ i = j` in Data/Fin/SuccPred (imported by Order/Fin/Basic via Data.Fin.Embedding/Rev) and again as @[simp] succAbove_inj in Order/Fin/Basic. Keep the lower one (fits succAbove_right_injective), move @[simp] there and deprecate succAbove_inj.","fix":"Deprecate `Fin.succAbove_inj` in favour of `Fin.succAbove_right_inj`.","ev":"dupscan/Check.lean: `example := (@Fin.succAbove_inj : type_of% @Fin.succAbove_right_inj)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 42, rating MAJOR): Moving `simp` to the lower theorem preserves the same cancellation rule while making it available earlier. No order-specific hypothesis or attribute requires the second declaration. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Order/Fin/Basic.lean#L195).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-e0fd85","file":"Mathlib/Order/Hom/Basic.lean","decl":"OrderHomClass.mono","line":170,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `OrderHomClass.mono` (Order.Hom.Basic), `OrderHomClass.monotone` (Order.Hom.Basic) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: `OrderHomClass.mono` is an intended short-name twin of `OrderHomClass.monotone` (mirroring `OrderHom.mono`/`OrderHom.monotone` at 237/240) but re-proves `fun _ _ => map_rel f`. An alias can carry the attribute: `@[gcongr] protected alias mono := monotone`.","fix":"Declare `OrderHomClass.mono` as an `alias` of `OrderHomClass.monotone`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-bf0796","file":"Mathlib/Order/Hom/BoundedLattice.lean","decl":"SupBotHom.id_toFun","line":244,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `SupBotHom.id_toFun` (Order.Hom.BoundedLattice), `SupBotHom.id_apply` (Order.Hom.BoundedLattice) state exactly the same thing (Lean-checked). Reviewer: `SupBotHom.id_toFun` comes from `simps!` on SupBotHom.id (l.243-245) and duplicates the manual `id_apply`. Sibling TopHom, SupHom, LatticeHom and BoundedLatticeHom have no simps on `id` and a @[simp] id_apply. Remove simps! and make id_apply @[simp].","fix":"Deprecate `SupBotHom.id_toFun` in favour of `SupBotHom.id_apply`.","ev":"dupscan/Check.lean: `example := (@SupBotHom.id_apply : type_of% @SupBotHom.id_toFun)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 1, rating MAJOR): `id_apply` can supply the generated lemma’s simp behavior under the conventional name. Apply the attribute change to the `InfTopHom` dual too.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-79cc0c","file":"Mathlib/Order/Hom/Lex.lean","decl":"RelIso.sumLexComplLeft_symm_apply","line":53,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `RelIso.sumLexComplLeft_apply` (Order.Hom.Lex), `RelIso.sumLexComplLeft_symm_apply` (Order.Hom.Lex) have exactly the same statement (Lean-checked), so `RelIso.sumLexComplLeft_symm_apply` does not state what its name promises and the intended lemma is missing. Reviewer: This is a copy-paste bug. The @[simp] sumLexComplLeft_symm_apply has the same statement as sumLexComplLeft_apply (`sumLexComplLeft r x a = Equiv.sumCompl (r · x) a`) instead of a `.symm` statement; sumLexComplRight_symm_apply at line 69 has the same bug. Restate both as `(sumLexCompl… r x).symm a = (Equiv.sumCompl …).symm a`. Astra rates it CRITICAL (a lemma weaker than or unrelated to its name).","fix":"Restate `RelIso.sumLexComplLeft_symm_apply` as its name says (keep `RelIso.sumLexComplLeft_apply`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@RelIso.sumLexComplLeft_symm_apply : type_of% @RelIso.sumLexComplLeft_apply)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 18, rating CRITICAL): The current lemma describes the forward function and even infers its argument in the forward domain. Correct, for `a : α`: `(sumLexComplLeft r x).symm a = (Equiv.sumCompl (r · x)).symm a`. The definition supplies this inverse directly; the copied forward statement does not expose it. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Order/Hom/Lex.lean#L35-L54)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-fe2c5c","file":"Mathlib/Order/Hom/Lex.lean","decl":"RelIso.sumLexComplRight_symm_apply","line":73,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `RelIso.sumLexComplRight_apply` (Order.Hom.Lex), `RelIso.sumLexComplRight_symm_apply` (Order.Hom.Lex) have exactly the same statement (Lean-checked), so `RelIso.sumLexComplRight_symm_apply` does not state what its name promises and the intended lemma is missing. Reviewer: Copy-paste bug: `sumLexComplRight_symm_apply` restates `sumLexComplRight r x a = ...` (no `.symm`), so it is a verbatim copy of `sumLexComplRight_apply`; `sumLexComplLeft_symm_apply` at line 53 has the same bug. Keep `_apply`; restate the `_symm_apply` lemmas about `(sumLexComplRight r x).symm`. Astra rates it CRITICAL (a lemma weaker than or unrelated to its name).","fix":"Restate `RelIso.sumLexComplRight_symm_apply` as its name says (keep `RelIso.sumLexComplRight_apply`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@RelIso.sumLexComplRight_symm_apply : type_of% @RelIso.sumLexComplRight_apply)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 25, rating CRITICAL): The inverse must undo both the complement equivalence and the sum swap. Correct, for `a : α`: `(sumLexComplRight r x).symm a = ((Equiv.sumCompl (r x)).symm a).swap`. Merely adding `.symm` without restoring `.swap` gives the wrong ordering of summands. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Order/Hom/Lex.lean#L56-L74)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-13b7af","file":"Mathlib/Order/Interval/Finset/Basic.lean","decl":"Finset.Ioi_nonempty","line":338,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Finset.Ioi_nonempty` (Order.Interval.Finset.Basic), `Finset.nonempty_Ioi` (Order.Interval.Finset.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file, about 10 lines apart. nonempty_Ioi fits the nonempty_Icc/Ico/Ioc/Ioo/Ici family and has the Aesop alias. Ioi_nonempty is the @[simp] outlier and is never referenced by name. Move simp to nonempty_Ioi and deprecate Ioi_nonempty.","fix":"Deprecate `Finset.Ioi_nonempty` in favour of `Finset.nonempty_Ioi`.","ev":"dupscan/Check.lean: `example := (@Finset.nonempty_Ioi : type_of% @Finset.Ioi_nonempty)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 2, rating MAJOR): `nonempty_Ioi` fits the existing Finset nonemptiness family; transferring `[simp]` preserves automation and the existing Aesop alias.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-629331","file":"Mathlib/Order/Interval/Finset/Basic.lean","decl":"Finset.nonempty_Iio","line":412,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Finset.Iio_nonempty` (Order.Interval.Finset.Basic), `Finset.nonempty_Iio` (Order.Interval.Finset.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file, 11 lines apart, both `(Iio a).Nonempty ↔ ¬ IsMin a`, one @[simp] and one not, no comment. `Set.Iio_nonempty` (Order/Interval/Set/Basic.lean:398) is the iff and `nonempty_X` is reserved for the unconditional form (`Finset.nonempty_Iic` at 411), so keep `Iio_nonempty` and deprecate `nonempty_Iio`, rebuilding the `Aesop.nonempty_Iio_of_not_isMin` alias from the kept lemma.","fix":"Deprecate `Finset.nonempty_Iio` in favour of `Finset.Iio_nonempty`.","ev":"dupscan/Check.lean: `example := (@Finset.nonempty_Iio : type_of% @Finset.Iio_nonempty)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup3 item 3, rating MAJOR): The naming premise is false: [Finset.nonempty_Icc/Ico/Ioc](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Order/Interval/Finset/Basic.lean#L58) are iff lemmas. Consolidate, but prefer `nonempty_Iio` for consistency with that family and its Aesop aliases.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-c0bea1","file":"Mathlib/Order/Interval/Finset/Nat.lean","decl":"Finset.range_add_eq_union","line":233,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Finset.range_add` (Algebra.Group.Nat.Range), `Finset.range_add_eq_union` (Order.Interval.Finset.Nat) state exactly the same thing (Lean-checked). Reviewer: `range (a + b) = range a ∪ (range b).map (addLeftEmbedding a)` proved twice (via `Multiset.range_add_eq_union` and via `Ico` unions) in two files; Order/Interval/Finset/Nat is higher in the import graph. Keep `Finset.range_add` (lower), deprecate `Finset.range_add_eq_union` (one use, AP/Three/Defs.lean:432).","fix":"Deprecate `Finset.range_add_eq_union` in favour of `Finset.range_add`.","ev":"dupscan/Check.lean: `example := (@Finset.range_add_eq_union : type_of% @Finset.range_add)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 21, rating MAJOR): The interval-based proof adds no distinct result or automation behavior. Keeping the theorem available lower in the import graph is preferable.","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":""},{"id":"RT-20261007-b6bd6e","file":"Mathlib/Order/Interval/Set/SuccPred.lean","decl":"Set.Ico_succ_right_eq_Icc","line":113,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Set.Ico_succ_right_eq_Icc` (Order.Interval.Set.SuccPred), `Order.Ico_succ_right` (Order.SuccPred.Basic) state exactly the same thing (Lean-checked). Reviewer: `Set.Ico_succ_right_eq_Icc` (2025 Set/SuccPred file) re-proves `Order.Ico_succ_right` (@[simp], in SuccPred/Basic, which the Set file imports), and their `_of_not_isMax` versions are also parallel. Keep the older, lower Order lemma and deprecate the Set copy, or turn it into an alias if the Finset-synced naming is wanted.","fix":"Deprecate `Set.Ico_succ_right_eq_Icc` in favour of `Order.Ico_succ_right`.","ev":"dupscan/Check.lean: `example := (@Order.Ico_succ_right : type_of% @Set.Ico_succ_right_eq_Icc)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 4, rating MINOR): Take the offered nondeprecated-alias option: the file explicitly requires Set/Finset API synchronization, which supports retaining the Set spelling. A separate proof is unnecessary.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-f8f989","file":"Mathlib/Order/Interval/Set/SuccPred.lean","decl":"Set.Ioo_succ_right_eq_Ioc","line":117,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Order.Ioo_succ_right` (Order.SuccPred.Basic), `Set.Ioo_succ_right_eq_Ioc` (Order.Interval.Set.SuccPred) state exactly the same thing (Lean-checked). Reviewer: Both say `Ioo a (succ b) = Ioc a b` in a NoMaxOrder succ order. Set.Ioo_succ_right_eq_Ioc in the 2025 Set/SuccPred file re-develops the @[simp] Order.Ioo_succ_right, and the Set file imports SuccPred/Basic. Keep the Order version and deprecate the Set one, or make it an alias.","fix":"Deprecate `Set.Ioo_succ_right_eq_Ioc` in favour of `Order.Ioo_succ_right`.","ev":"dupscan/Check.lean: `example := (@Set.Ioo_succ_right_eq_Ioc : type_of% @Order.Ioo_succ_right)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 10, rating MINOR): Use the offered alias alternative: `Set.Ioo_succ_right_eq_Ioc` has a clear role alongside its Finset counterpart and neighboring interval equalities.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-5be435","file":"Mathlib/Order/Interval/Set/SuccPred.lean","decl":"Set.Ioi_pred_eq_Ici_of_not_isMin","line":160,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Order.Ioi_pred_of_not_isMin` (Order.SuccPred.Basic), `Set.Ioi_pred_eq_Ici_of_not_isMin` (Order.Interval.Set.SuccPred) state exactly the same thing (Lean-checked). Reviewer: to_dual images of Order.Iio_succ_of_not_isMax (SuccPred/Basic) and Set.Iio_succ_eq_Iic_of_not_isMax (Interval/Set/SuccPred, which imports it): same statement. Keep the Order versions (as in the Iio_succ group) and deprecate the Set copies.","fix":"Deprecate `Set.Ioi_pred_eq_Ici_of_not_isMin` in favour of `Order.Ioi_pred_of_not_isMin`.","ev":"dupscan/Check.lean: `example := (@Set.Ioi_pred_eq_Ici_of_not_isMin : type_of% @Order.Ioi_pred_of_not_isMin)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup3 item 7, rating MINOR): The corresponding Finset theorem actually uses this Set name, and the name fits the documented synchronization policy. Sharing the Order proof while preserving the Set alias and dual mapping is preferable.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-ee03ab","file":"Mathlib/Order/Interval/Set/SuccPred.lean","decl":"Set.Iio_succ_eq_Iic_of_not_isMax","line":160,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Order.Iio_succ_of_not_isMax` (Order.SuccPred.Basic), `Set.Iio_succ_eq_Iic_of_not_isMax` (Order.Interval.Set.SuccPred) state exactly the same thing (Lean-checked). Reviewer: Both say `¬IsMax a → Iio (succ a) = Iic a` (both @[to_dual]). The 2025 Set/SuccPred file re-proves it in namespace Set; its header asks to stay in sync with the Finset files but does not mention the Order.* originals. Keep the Order version (imported by the Set file) and deprecate Set.Iio_succ_eq_Iic_of_not_isMax, or make it an alias.","fix":"Deprecate `Set.Iio_succ_eq_Iic_of_not_isMax` in favour of `Order.Iio_succ_of_not_isMax`.","ev":"dupscan/Check.lean: `example := (@Set.Iio_succ_eq_Iic_of_not_isMax : type_of% @Order.Iio_succ_of_not_isMax)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 9, rating MINOR): The offered alias alternative respects the documented Set/Finset naming policy. Preserve the Set name and its dual while eliminating the independent proof.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-60e943","file":"Mathlib/Order/Interval/Set/SuccPred.lean","decl":"Set.Iio_succ_eq_Iic","line":170,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Order.Iio_succ` (Order.SuccPred.Basic), `Set.Iio_succ_eq_Iic` (Order.Interval.Set.SuccPred) state exactly the same thing (Lean-checked). Reviewer: Same `[LinearOrder][SuccOrder][NoMaxOrder]` statement `Iio (succ a) = Iic a`; the Set-namespace copy in Order/Interval/Set/SuccPred.lean (which imports SuccPred/Basic) re-proves the older @[simp] Order lemma with no comment. Deprecate Set.Iio_succ_eq_Iic (and its to_dual Set.Ioi_pred_eq_Ici).","fix":"Deprecate `Set.Iio_succ_eq_Iic` in favour of `Order.Iio_succ`.","ev":"dupscan/Check.lean: `example := (@Set.Iio_succ_eq_Iic : type_of% @Order.Iio_succ)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup3 item 6, rating MINOR): The Set name belongs to the explicitly synchronized Set/Finset interval family. Preserve it and its dual as supported aliases of the Order results.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-11594e","file":"Mathlib/Order/Interval/Set/SuccPred.lean","decl":"Set.Ioi_pred_eq_Ici","line":170,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Order.Ioi_pred` (Order.SuccPred.Basic), `Set.Ioi_pred_eq_Ici` (Order.Interval.Set.SuccPred) state exactly the same thing (Lean-checked). Reviewer: to_dual images of Order.Iio_succ (simp) and Set.Iio_succ_eq_Iic. Same duplication as the Iio_succ group: keep the Order lemma, deprecate the Set copy.","fix":"Deprecate `Set.Ioi_pred_eq_Ici` in favour of `Order.Ioi_pred`.","ev":"dupscan/Check.lean: `example := (@Set.Ioi_pred_eq_Ici : type_of% @Order.Ioi_pred)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup3 item 8, rating MINOR): `Set.Ioi_pred_eq_Ici` supplies the Set counterpart of `Finset.Ioi_pred_eq_Ici` in the synchronized interval API. Retain that spelling as an alias.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-8b9a1a","file":"Mathlib/Order/Lattice.lean","decl":"Ne.inf_lt_or_inf_lt","line":1,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `inf_lt_left_or_right` (Order.Lattice), `Ne.inf_lt_or_inf_lt` (Order.Lattice) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: Both are @[to_dual] images of `left_or_right_lt_sup (h : a ≠ b)` and its dot-notation twin `Ne.lt_sup_or_lt_sup`, which are proved separately with the same proof idea. Declare `Ne.lt_sup_or_lt_sup` as an alias of left_or_right_lt_sup. Only the Ne. form is used, in Order/Cover.","fix":"Declare `Ne.inf_lt_or_inf_lt` as an `alias` of `inf_lt_left_or_right`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-f0a030","file":"Mathlib/Order/Lattice.lean","decl":"Ne.lt_sup_or_lt_sup","line":142,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `left_or_right_lt_sup` (Order.Lattice), `Ne.lt_sup_or_lt_sup` (Order.Lattice) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: Ne.lt_sup_or_lt_sup is the dot-notation twin (`hab.lt_sup_or_lt_sup`, used in Order/Cover.lean:188) of left_or_right_lt_sup, re-proved with the same one-line proof (both with to_dual). Fix: alias.","fix":"Declare `Ne.lt_sup_or_lt_sup` as an `alias` of `left_or_right_lt_sup`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-fca53f","file":"Mathlib/Order/Preorder/Finsupp.lean","decl":"Finsupp.coe_strictMono","line":62,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `Finsupp.coe_mono` (Order.Preorder.Finsupp), `Finsupp.coe_strictMono` (Order.Preorder.Finsupp) have exactly the same statement (Lean-checked), so `Finsupp.coe_strictMono` does not state what its name promises and the intended lemma is missing. Reviewer: This is a misstatement. `coe_strictMono` states `Monotone (Finsupp.toFun …)` and is therefore a copy of coe_mono; it should state `StrictMono`, and `fun _ _ ↦ id` still works because coe_lt_coe is .rfl. DFinsupp.coe_strictMono (Data/DFinsupp/Order.lean:78) has the identical bug. Astra rates it CRITICAL (a lemma weaker than or unrelated to its name).","fix":"Restate `Finsupp.coe_strictMono` as its name says (keep `Finsupp.coe_mono`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@Finsupp.coe_strictMono : type_of% @Finsupp.coe_mono)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 31, rating CRITICAL): The theorem asserts non-strict monotonicity despite its explicit `strictMono` name. Correct: `StrictMono (Finsupp.toFun : (ι →₀ M) → ι → M) := fun _ _ ↦ id`. As with DFinsupp, the order embedding already supplies strict monotonicity, but that does not make this weaker named statement appropriate. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Order/Preorder/Finsupp.lean#L34-L62)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-ef55b9","file":"Mathlib/Order/RelIso/Basic.lean","decl":"RelIso.apply_eq_iff_eq","line":665,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `RelIso.eq_iff_eq` (Order.RelIso.Basic), `RelIso.apply_eq_iff_eq` (Order.RelIso.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file, `f a = f b ↔ a = b` proved twice (`f.injective.eq_iff` vs `EquivLike.apply_eq_iff_eq f`). `RelIso.eq_iff_eq` mirrors `RelEmbedding.eq_iff_eq` and is used via dot notation on order isos (e.g. Order/Atoms.lean:937); `RelIso.apply_eq_iff_eq` has no uses. Deprecate `apply_eq_iff_eq`.","fix":"Deprecate `RelIso.apply_eq_iff_eq` in favour of `RelIso.eq_iff_eq`.","ev":"dupscan/Check.lean: `example := (@RelIso.apply_eq_iff_eq : type_of% @RelIso.eq_iff_eq)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup3 item 5, rating MINOR): `apply_eq_iff_eq` follows the standard Equiv/EquivLike spelling, while `eq_iff_eq` follows RelEmbedding. Keeping both names through an alias supports two established interfaces.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-ef052b","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"upperClosure_anti","line":109,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-gcongr-monotonicity","claim":"upperClosure has no @[gcongr] monotonicity lemma: upperClosure_anti is a bundled `Antitone`, so `gcongr` makes no progress on `upperClosure t ≤ upperClosure s` (nor on the coerced `↑(upperClosure s) ⊆ ↑(upperClosure t)`) from `s ⊆ t`. Its only consumer (Analysis/Normed/Order/UpperLower.lean:236) feeds `upperClosure_anti subset_closure` to `closure_minimal` as a Set inclusion through the defeq of the reversed UpperSet order. Comparable closure_mono lemmas (Topology/Closure.lean:247, Algebra/Ring/Subring/Basic.lean:506, Algebra/Field/Subfield/Basic.lean:319, ModelTheory/Substructures.lean:262) are @[gcongr].","fix":"Add an unbundled `@[gcongr] theorem upperClosure_le_upperClosure (h : s ⊆ t) : upperClosure t ≤ upperClosure s := upperClosure_anti h` (verified: compiles and makes `gcongr` close the goal).","ev":"hunts/upperlower-closure/batch1/probe_fail.lean part (A): `example (h : s ⊆ t) : upperClosure t ≤ upperClosure s := by gcongr` and `example (h : s ⊆ t) : (upperClosure s : Set α) ⊆ upperClosure t := by gcongr` both give \"`gcongr` did not make progress\"; the fix is checked in hunts/upperlower-closure/batch1/src_copy.lean (the gcongr examples there compile). A coe-level @[gcongr] lemma is rejected (\"Not all varying arguments are free variables\"), so the fix must be at the UpperSet level.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-bc437e","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"lowerClosure_mono","line":112,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-gcongr-monotonicity","claim":"lowerClosure has no @[gcongr] monotonicity lemma: lowerClosure_mono is a bundled `Monotone`, so `gcongr` makes no progress on `lowerClosure s ≤ lowerClosure t` (nor on `↑(lowerClosure s) ⊆ ↑(lowerClosure t)`) from `s ⊆ t`; the only consumer (Analysis/Normed/Order/UpperLower.lean:242) uses it as a Set inclusion via defeq. Comparable closure_mono lemmas elsewhere in Mathlib are @[gcongr].","fix":"Add an unbundled `@[gcongr] theorem lowerClosure_le_lowerClosure (h : s ⊆ t) : lowerClosure s ≤ lowerClosure t := lowerClosure_mono h` (verified: compiles and makes `gcongr` close the goal).","ev":"hunts/upperlower-closure/batch1/probe_fail.lean part (A): `example (h : s ⊆ t) : lowerClosure s ≤ lowerClosure t := by gcongr` and the coerced form both give \"`gcongr` did not make progress\"; fix checked in hunts/upperlower-closure/batch1/src_copy.lean.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-f40ace","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"upperClosure_union","line":132,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-insert-simp-lemma","claim":"There is no upperClosure_insert / lowerClosure_insert. upperClosure_union and upperClosure_singleton are simp, but set literals are `insert a s`, not `{a} ∪ s`, so `simp` makes no progress on `upperClosure {a, b} = UpperSet.Ici a ⊓ UpperSet.Ici b` (or its lowerClosure dual). No current Mathlib consumer needs it.","fix":"Add `@[to_dual (attr := simp)] theorem upperClosure_insert (a : α) (s : Set α) : upperClosure (insert a s) = UpperSet.Ici a ⊓ upperClosure s := by rw [insert_eq, upperClosure_union, upperClosure_singleton]` (verified to compile; it also generates lowerClosure_insert).","ev":"hunts/upperlower-closure/batch1/probe_fail.lean part (B): `example (a b : α) : upperClosure {a, b} = UpperSet.Ici a ⊓ UpperSet.Ici b := by simp` gives \"`simp` made no progress\" (same for the lowerClosure dual); with the added lemma both examples compile in hunts/upperlower-closure/batch1/src_copy.lean.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-847caa","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"IsLowerSet.disjoint_upperClosure_left","line":174,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"non-confluent-simp-set","claim":"The four @[simp] disjointness lemmas (`IsLowerSet.disjoint_upperClosure_left/right` and their generated duals `IsUpperSet.disjoint_lowerClosure_left/right`) are not confluent on `Disjoint ↑(upperClosure s) ↑(lowerClosure t)`: `IsLowerSet.disjoint_upperClosure_left` (with the lower set `lowerClosure t`) rewrites it to `Disjoint s ↑(lowerClosure t)`, while `IsUpperSet.disjoint_lowerClosure_right` (with the upper set `upperClosure s`) rewrites it to `Disjoint ↑(upperClosure s) t`; simp takes the second route, and the two results are equal but neither simplifies, so `simp` cannot prove an instance of its own simp lemma. The hypothesis-free statement joining them, `Disjoint ↑(upperClosure s) t ↔ Disjoint s ↑(lowerClosure t)`, is missing from Mathlib, and this lemma is a one-line corollary of it.","fix":"Add the hypothesis-free `disjoint_upperClosure_left_iff : Disjoint ↑(upperClosure s) t ↔ Disjoint s ↑(lowerClosure t)` and a simp lemma fixing one normal form for `Disjoint ↑(upperClosure s) ↑(lowerClosure t)` (e.g. `↔ ∀ a ∈ s, ∀ b ∈ t, ¬a ≤ b`).","ev":"hunts/upperlower-closure/batch2/Probe3.lean (F1 block):\nexample (s t : Set α) :\n    Disjoint (↑(upperClosure s) : Set α) ↑(lowerClosure t) ↔ Disjoint s ↑(lowerClosure t) := by\n  simp -- unsolved goal: Disjoint ↑(upperClosure s) t ↔ Disjoint s ↑(lowerClosure t)\nexample (s t : Set α) :\n    Disjoint (↑(upperClosure s) : Set α) ↑(lowerClosure t) ↔ Disjoint s ↑(lowerClosure t) :=\n  (LowerSet.lower _).disjoint_upperClosure_left  -- compiles: it IS an instance of the simp lemma\ntheorem disjoint_upperClosure_left_iff' (s t : Set α) :\n    Disjoint (↑(upperClosure s) : Set α) t ↔ Disjoint s ↑(lowerClosure t) := by\n  simp only [Set.disjoint_left, SetLike.mem_coe, mem_upperClosure, mem_lowerClosure]\n  exact ⟨fun h a ha ⟨b, hb, hab⟩ ↦ h ⟨a, ha, hab⟩ hb,\n    fun h x ⟨a, ha, hax⟩ hx ↦ h ha ⟨x, hx, hax⟩⟩  -- compiles\nexample {s t : Set α} (ht : IsLowerSet t) :\n    Disjoint (↑(upperClosure s) : Set α) t ↔ Disjoint s t := by\n  rw [disjoint_upperClosure_left_iff', ht.lowerClosure]  -- compiles","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-c82bcc","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"IsAntichain.minimal_mem_upperClosure_iff_mem","line":195,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"special-case-of-missing-general-lemma","claim":"Special case of a missing, equally easy general lemma: in any partial order, with no antichain hypothesis, Minimal (· ∈ upperClosure s) x ↔ Minimal (· ∈ s) x. The batch lemma is then `minimal_mem_upperClosure_iff.trans hs.minimal_mem_iff` (IsAntichain.minimal_mem_iff, Mathlib/Order/Antichain.lean:261), and its forward direction `Minimal (· ∈ upperClosure s) x → x ∈ s` needs no antichain hypothesis. PartialOrder itself is needed: the indiscrete preorder on Bool is a counterexample.","fix":"Add `minimal_mem_upperClosure_iff : Minimal (· ∈ upperClosure s) x ↔ Minimal (· ∈ s) x` (and its maximal/lowerClosure dual) and derive the antichain lemma from it with `IsAntichain.minimal_mem_iff`.","ev":"hunts/upperlower-closure/batch3/probe1.lean section A: `theorem minimal_mem_upperClosure_iff' : Minimal (· ∈ upperClosure s) x ↔ Minimal (· ∈ s) x` (5-line proof) and `example (hs : IsAntichain (· ≤ ·) s) : Minimal (· ∈ upperClosure s) x ↔ x ∈ s := minimal_mem_upperClosure_iff'.trans hs.minimal_mem_iff`; preorder counterexample in probe2.lean","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-f327de","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"IsAntichain.maximal_mem_lowerClosure_iff_mem","line":203,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"special-case-of-missing-general-lemma","claim":"Dual special case of the missing general lemma Maximal (· ∈ lowerClosure s) x ↔ Maximal (· ∈ s) x (any partial order, no antichain hypothesis); the batch lemma is `maximal_mem_lowerClosure_iff.trans hs.maximal_mem_iff`. (Writing it by hand rather than with @[to_dual] is justified: @[to_dual] would produce the hypothesis `IsAntichain (fun x1 x2 ↦ x2 ≤ x1) s`, see src_v2.lean.)","fix":"Derive it from a general `maximal_mem_lowerClosure_iff` (the order dual of `minimal_mem_upperClosure_iff`) and `IsAntichain.maximal_mem_iff`.","ev":"hunts/upperlower-closure/batch3/probe1.lean section A: `theorem maximal_mem_lowerClosure_iff' : Maximal (· ∈ lowerClosure s) x ↔ Maximal (· ∈ s) x := minimal_mem_upperClosure_iff' (α := αᵒᵈ)` and `example (hs : IsAntichain (· ≤ ·) s) : Maximal (· ∈ lowerClosure s) x ↔ x ∈ s := maximal_mem_lowerClosure_iff'.trans hs.maximal_mem_iff`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-da9d4a","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"upperClosure_eq_bot","line":214,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"restates-existing-lemma-via-missing-characterisation","claim":"`upperClosure s = ⊥` is exactly `IsCoinitial s` (Mathlib/Order/Bounds/Defs.lean, available here) in any preorder, by simp; that characterisation is missing. With it, the generated dual `lowerClosure_eq_top (hs : ¬BddAbove s) : lowerClosure s = ⊤` is `IsCofinal.of_not_bddAbove` (Mathlib/Order/Cofinal.lean:153, `theorem IsCofinal.of_not_bddAbove {s : Set α} (h : ¬ BddAbove s) : IsCofinal s`), and `upperClosure_eq_bot` is that lemma at αᵒᵈ. Cofinal.lean is not currently imported by this file.","fix":"Add `@[to_dual] upperClosure_eq_bot_iff_isCoinitial : upperClosure s = ⊥ ↔ IsCoinitial s` (Preorder) and derive `upperClosure_eq_bot`/`lowerClosure_eq_top` from `IsCofinal.of_not_bddAbove` by importing the light Mathlib.Order.Cofinal.","ev":"hunts/upperlower-closure/batch3/probe1.lean section B: `theorem upperClosure_eq_bot_iff_isCoinitial' [Preorder α] {s : Set α} : upperClosure s = ⊥ ↔ IsCoinitial s := by simp [← UpperSet.coe_eq_univ, eq_univ_iff_forall, IsCoinitial]`; `example [LinearOrder α] {s : Set α} (hs : ¬ BddAbove s) : lowerClosure s = ⊤ := lowerClosure_eq_top_iff_isCofinal'.2 (IsCofinal.of_not_bddAbove hs)`; `example [LinearOrder α] {s : Set α} (hs : ¬ BddBelow s) : upperClosure s = ⊥ := upperClosure_eq_bot_iff_isCoinitial'.2 (IsCofinal.of_not_bddAbove (α := αᵒᵈ) hs)`; probe3.lean shows Cofinal.lean is not in the import closure","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-953364","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"upperClosure_eq_bot","line":214,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"typeclass-stronger-than-needed","claim":"`upperClosure_eq_bot` and `upperClosure_eq_bot_iff` (and the generated `lowerClosure_eq_top`, `lowerClosure_eq_top_iff`) assume `[LinearOrder α]`, but use only totality of `≤`: `upperClosure_eq_bot` holds for any `[Preorder α] [Std.Total (α := α) (· ≤ ·)]`, and the forward direction of the iff holds in any `[Preorder α] [NoBotOrder α]`. Total preorders that are not partial orders (e.g. ℤ × Bool ordered by the first coordinate) are excluded for no reason.","fix":"State `upperClosure_eq_bot` for `[Preorder α] [Std.Total (α := α) (· ≤ ·)]` (proof: `not_bddBelow_iff'` plus `total_of`), and split the iff so its forward direction needs only `[Preorder α] [NoBotOrder α]`.","ev":"hunts/upperlower-closure/main/probe_total.lean: (A) `upperClosure s = ⊥` from `¬ BddBelow s` under `[Preorder α] [Std.Total (α := α) (· ≤ ·)]`; (B) `upperClosure s = ⊥ → ¬ BddBelow s` under `[Preorder α] [NoBotOrder α]`; (C) ℤ × Bool lifted along `Prod.fst` is a total preorder that is not antisymmetric. All compile at 4e77f237dc2 (`lake env lean`, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-e3bf28","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"upperClosure_eq_bot_iff","line":218,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"restates-existing-lemma-via-missing-characterisation","claim":"Up to the missing preorder-level characterisation `lowerClosure s = ⊤ ↔ IsCofinal s`, the generated dual `lowerClosure_eq_top_iff [NoMaxOrder α] : lowerClosure s = ⊤ ↔ ¬BddAbove s` is `not_bddAbove_iff_isCofinal` (Mathlib/Order/Cofinal.lean:166, `theorem not_bddAbove_iff_isCofinal [NoMaxOrder α] {s : Set α} : ¬ BddAbove s ↔ IsCofinal s`), and the source lemma is that one at αᵒᵈ. Its hypotheses are otherwise right: LinearOrder is needed for ← (ℤ × ℤ counterexample), NoMinOrder for → ({0} in ℕ).","fix":"State `upperClosure_eq_bot_iff_isCoinitial` (preorder) and obtain this iff as `.trans (not_bddAbove_iff_isCofinal (α := αᵒᵈ)).symm`, with the dual from `not_bddAbove_iff_isCofinal`.","ev":"hunts/upperlower-closure/batch3/probe1.lean section B: `example [LinearOrder α] [NoMaxOrder α] {s : Set α} : lowerClosure s = ⊤ ↔ ¬ BddAbove s := lowerClosure_eq_top_iff_isCofinal'.trans not_bddAbove_iff_isCofinal.symm` and `example [LinearOrder α] [NoMinOrder α] {s : Set α} : upperClosure s = ⊥ ↔ ¬ BddBelow s := upperClosure_eq_bot_iff_isCoinitial'.trans (not_bddAbove_iff_isCofinal (α := αᵒᵈ)).symm`; necessity counterexamples in probe2.lean","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-f06ff4","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"UpperSet.sdiff","line":230,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-mem-simp-lemma","claim":"Missing characteristic API. There is no `mem_sdiff`, although every other UpperSet/LowerSet operation has one (mem_sup_iff, mem_inf_iff, mem_compl_iff, mem_Ici_iff, mem_map, mem_upperClosure), so `simp` cannot rewrite `x ∈ s.sdiff t`; in-file proofs work around this by unfolding (`simp [sdiff, erase]`) or by going through coercions. The universal property that the docstring asserts, `s.sdiff t ≤ u ↔ s ≤ u ∧ Disjoint ↑u t`, is true (a 2-line proof) but nowhere stated. Same for the generated LowerSet.sdiff.","fix":"Add `@[to_dual (attr := simp)] lemma mem_sdiff : x ∈ s.sdiff t ↔ x ∈ s ∧ x ∉ lowerClosure t := .rfl` and `@[to_dual] lemma sdiff_le_iff : s.sdiff t ≤ u ↔ s ≤ u ∧ Disjoint (u : Set α) t`.","ev":"hunts/upperlower-closure/batch3/probe1.lean section D: `example : x ∈ s.sdiff t ↔ x ∈ s ∧ x ∉ lowerClosure t := by simp` fails with unsolved goal `x ∈ s.sdiff t ↔ x ∈ s ∧ ∀ x_1 ∈ t, ¬x ≤ x_1`; section C proves it by `Iff.rfl` and proves `UpperSet.sdiff_le_iff'`","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-3d1f34","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"UpperSet.erase","line":236,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-mem-simp-lemma","claim":"Missing characteristic API. There is no `mem_erase`, so `simp` makes no progress on `x ∈ s.erase a` (for both UpperSet and the generated LowerSet.erase). The universal property `s.erase a ≤ u ↔ s ≤ u ∧ a ∉ u` behind the docstring is also not stated.","fix":"Add `@[to_dual (attr := simp)] lemma mem_erase : x ∈ s.erase a ↔ x ∈ s ∧ ¬ x ≤ a := .rfl` and `erase_le_iff : s.erase a ≤ u ↔ s ≤ u ∧ a ∉ u`.","ev":"hunts/upperlower-closure/batch3/probe1.lean section D: `example : x ∈ s.erase a ↔ x ∈ s ∧ ¬ x ≤ a := by simp` and `example {s : LowerSet α} : x ∈ s.erase a ↔ x ∈ s ∧ ¬ a ≤ x := by simp` both fail with `simp made no progress`; section C proves the first by `Iff.rfl` and proves `UpperSet.erase_le_iff'`","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-1f603f","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"UpperSet.lt_sdiff_left","line":261,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"to-dual-name-clashes-root-unprotected","claim":"The to_dual of `UpperSet.lt_sdiff_left` is `LowerSet.sdiff_lt_left`, which shares its name with the root lemma `sdiff_lt_left : x \\ y < x ↔ ¬ Disjoint y x` (Mathlib/Order/BooleanAlgebra/Basic.lean:233) but is not protected (measured: protected=false), unlike the file's other root-clashing names `sdiff_eq_left` and `sdiff_idem`, which are protected on both sides. Under `open LowerSet` (Mathlib/Order/Birkhoff.lean:56 opens it file-wide) the root lemma can no longer be used in `rw`/`simp`: both fail with 'Ambiguous term', even for a GeneralizedBooleanAlgebra goal.","fix":"Mark `lt_sdiff_left` `protected`; to_dual propagates it, so `LowerSet.sdiff_lt_left` becomes protected too (checked in the file copy).","ev":"-- hunts/upperlower-closure/batch4/probe2.lean\nimport Mathlib.Order.UpperLower.Closure\nopen LowerSet in\nexample {β : Type*} [GeneralizedBooleanAlgebra β] (x y : β) : x \\ y < x ↔ ¬ Disjoint y x := by\n  rw [sdiff_lt_left]   -- error: Ambiguous term sdiff_lt_left (_root_ vs LowerSet)\nopen LowerSet in\nexample {β : Type*} [GeneralizedBooleanAlgebra β] (x y : β) : x \\ y < x ↔ ¬ Disjoint y x := by\n  simp only [sdiff_lt_left]   -- error: Ambiguous term; simp made no progress\n-- control: `rw [sdiff_eq_left]` under the same `open LowerSet` works (it is protected).\n-- fix: hunts/upperlower-closure/batch4/Closure_b4.lean:263-264 `protected lemma lt_sdiff_left`; the same `rw [sdiff_lt_left]` then compiles and `isProtected LowerSet.sdiff_lt_left = true`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-499169","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"UpperSet.sdiff_inf_upperClosure","line":276,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"hypothesis-stronger-than-conclusion-needs","claim":"The hypothesis `hst : ∀ b ∈ s, ∀ c ∈ t, b ≤ c → b ∈ t` (t is downward closed inside s, copied from `IsUpperSet.sdiff` in Basic.lean, where it is needed) is stronger than this conclusion needs: `s.sdiff t ⊓ upperClosure t = s ↔ t ⊆ s ∧ ∀ b ∈ s, ∀ c ∈ t, b ≤ c → ∃ d ∈ t, d ≤ b` (i.e. `s ∩ lowerClosure t ⊆ upperClosure t`), proved with the same five-line proof. It is too strong even in ℕ: s = ⊥ (= univ), t = {0, 2} satisfies the conclusion but not `hst` (b = 1, c = 2). At t = {a} the weak form is exactly `Minimal (· ∈ s) a`, so the generalisation also gives the right `erase_inf_Ici`. No iff form exists. Consumers: only `upperClosure_inf_sdiff` and `erase_inf_Ici` in this file; the dual `LowerSet.sdiff_sup_lowerClosure` has none.","fix":"Weaken `hst` to `∀ b ∈ s, ∀ c ∈ t, b ≤ c → ∃ d ∈ t, d ≤ b` and add `sdiff_inf_upperClosure_eq_iff` (both @[to_dual]); old call sites pass `fun b hb c hc hbc ↦ ⟨b, hst b hb c hc hbc, le_rfl⟩`.","ev":"-- hunts/upperlower-closure/batch4/probe1.lean (G4, G4', G4'', G5), all compile\ntheorem sdiff_inf_upperClosure' (hts : t ⊆ s) (hst : ∀ b ∈ s, ∀ c ∈ t, b ≤ c → ∃ d ∈ t, d ≤ b) :\n    s.sdiff t ⊓ upperClosure t = s := by\n  refine ge_antisymm (le_inf le_sdiff_left <| le_upperClosure.2 hts) fun a ha ↦ ?_\n  by_cases hat : a ∈ lowerClosure t\n  · obtain ⟨c, hc, hac⟩ := hat\n    exact subset_union_right (hst a ha c hc hac)\n  · exact subset_union_left ⟨ha, hat⟩\ntheorem sdiff_inf_upperClosure_eq_iff :\n    s.sdiff t ⊓ upperClosure t = s ↔ t ⊆ s ∧ ∀ b ∈ s, ∀ c ∈ t, b ≤ c → ∃ d ∈ t, d ≤ b := by\n  refine ⟨fun h => ⟨fun x hx => ?_, fun b hb c hc hbc => ?_⟩, fun h => sdiff_inf_upperClosure' h.1 h.2⟩\n  · rw [SetLike.mem_coe, ← h, mem_inf_iff]; exact Or.inr (subset_upperClosure hx)\n  · rw [← h, mem_inf_iff] at hb\n    rcases hb with hb | hb\n    · exact absurd ⟨c, hc, hbc⟩ hb.2\n    · exact hb\nexample : ¬ (∀ b ∈ (⊥ : UpperSet ℕ), ∀ c ∈ ({0, 2} : Set ℕ), b ≤ c → b ∈ ({0, 2} : Set ℕ)) ∧\n    (⊥ : UpperSet ℕ).sdiff {0, 2} ⊓ upperClosure {0, 2} = ⊥ := by\n  constructor\n  · intro h\n    have := h 1 UpperSet.mem_bot 2 (by simp) (by decide)\n    simp at this\n  · exact UpperSet.sdiff_inf_upperClosure' (by simp) (fun b _ c _ _ => ⟨0, by simp, Nat.zero_le b⟩)\n-- in-file version with @[to_dual] on all of them: hunts/upperlower-closure/batch4/Closure_b4.lean:278-321 (compiles; duals LowerSet.sdiff_sup_lowerClosure(_eq_iff) generated with the dual hypothesis `∃ d ∈ t, b ≤ d`)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-f2bc95","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"UpperSet.upperClosure_inf_sdiff","line":286,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"hypothesis-stronger-than-conclusion-needs","claim":"The commuted form of `sdiff_inf_upperClosure` carries the same too-strong `hst : ∀ b ∈ s, ∀ c ∈ t, b ≤ c → b ∈ t`; it holds under `∀ b ∈ s, ∀ c ∈ t, b ≤ c → ∃ d ∈ t, d ≤ b`, which is also necessary (see the iff for `sdiff_inf_upperClosure`). Same ℕ counterexample (s = ⊥, t = {0, 2}). No consumers (nor of the dual `LowerSet.lowerClosure_sup_sdiff`).","fix":"Weaken `hst` as in `sdiff_inf_upperClosure`; the `rw [inf_comm, sdiff_inf_upperClosure hts hst]` proof is unchanged.","ev":"hunts/upperlower-closure/batch4/Closure_b4.lean:297-299 (compiles):\n@[to_dual]\nlemma upperClosure_inf_sdiff (hts : t ⊆ s) (hst : ∀ b ∈ s, ∀ c ∈ t, b ≤ c → ∃ d ∈ t, d ≤ b) :\n    upperClosure t ⊓ s.sdiff t = s := by rw [inf_comm, sdiff_inf_upperClosure hts hst]\n-- necessity and the ℕ counterexample: see hunts/upperlower-closure/batch4/probe1.lean G4'/G5","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-e0b855","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"UpperSet.erase_inf_Ici","line":290,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"partial-order-minimality-in-preorder","claim":"Stated for a Preorder, but `ha : a ∈ s` plus `has : ∀ b ∈ s, b ≤ a → b = a` is the partial-order spelling of minimality and is strictly stronger in a preorder; the conclusion needs exactly `Minimal (· ∈ s) a`: `s.erase a ⊓ Ici a = s ↔ Minimal (· ∈ s) a` holds in any preorder (proved). Counterexample to necessity: two-point indiscrete preorder, s = ⊥, a = true (conclusion holds, `has` fails at b = false). The only consumer, the dual `LowerSet.erase_sup_Iic` in Mathlib/Order/Birkhoff.lean:80, already holds a `Maximal (· ∈ s) a` from `Set.Finite.exists_maximal` and has to convert it with `le_imp_eq_iff_le_imp_ge'`; with a `Maximal` hypothesis the call is just `erase_sup_Iic ha` (compiled). No iff form exists.","fix":"Take `(ha : Minimal (· ∈ s) a)` (dual: `Maximal`) and add `erase_inf_Ici_eq_iff`, both from the generalised `sdiff_inf_upperClosure_eq_iff`; simplify the Birkhoff call accordingly.","ev":"-- hunts/upperlower-closure/batch4/probe1.lean (G1, G2, G3, G6), all compile\ntheorem UpperSet.erase_inf_Ici_eq_iff [Preorder α] {s : UpperSet α} {a : α} :\n    s.erase a ⊓ Ici a = s ↔ Minimal (· ∈ s) a := by\n  simp only [← SetLike.coe_set_eq, coe_inf, coe_erase, coe_Ici, Set.ext_iff, Set.mem_union,\n    Set.mem_sdiff, SetLike.mem_coe, LowerSet.coe_Iic, Set.mem_Iic, Set.mem_Ici, Minimal]\n  constructor\n  · intro h\n    have ha : a ∈ s := (h a).1 (Or.inr le_rfl)\n    exact ⟨ha, fun b hb hba => ((h b).2 hb).resolve_left fun h' => h'.2 hba⟩\n  · rintro ⟨ha, hmin⟩ b\n    constructor\n    · rintro (⟨hb, -⟩ | hab)\n      · exact hb\n      · exact s.upper hab ha\n    · intro hb\n      by_cases hba : b ≤ a\n      · exact Or.inr (hmin hb hba)\n      · exact Or.inl ⟨hb, hba⟩\ndef Indisc := Bool\ninstance : Preorder Indisc := Preorder.lift (fun _ : Indisc => ())\nexample : ∃ (s : UpperSet Indisc) (a : Indisc), a ∈ s ∧ ¬ (∀ b ∈ s, b ≤ a → b = a) ∧\n    s.erase a ⊓ UpperSet.Ici a = s := by\n  refine ⟨⊥, (true : Indisc), UpperSet.mem_bot, fun h => ?_, ?_⟩\n  · exact Bool.false_ne_true (h (false : Indisc) UpperSet.mem_bot (le_refl ()))\n  · exact UpperSet.erase_inf_Ici_eq_iff.2 ⟨UpperSet.mem_bot, fun _ _ _ => le_refl ()⟩\n-- G6: Birkhoff's `LowerSet.supIrred_iff_of_finite` reproved with the Maximal form: \n--   obtain ⟨a, ha⟩ := (s : Set α).toFinite.exists_maximal (LowerSet.coe_nonempty.2 hs.ne_bot)\n--   exact ⟨a, (hs.2 <| LowerSet.erase_sup_Iic_eq_iff.2 ha).resolve_left (LowerSet.erase_lt.2 ha.prop).ne⟩\n-- in-file version: hunts/upperlower-closure/batch4/Closure_b4.lean:301-316, `erase_inf_Ici (ha : Minimal (· ∈ s) a)` derived from `sdiff_inf_upperClosure_eq_iff`, duals `LowerSet.erase_sup_Iic (ha : Maximal (· ∈ s) a)` generated (compiles)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-e45047","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"UpperSet.Ici_inf_erase","line":294,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"partial-order-minimality-in-preorder","claim":"The commuted form of `erase_inf_Ici` carries the same too-strong pair `ha : a ∈ s`, `has : ∀ b ∈ s, b ≤ a → b = a`; in a preorder `Minimal (· ∈ s) a` is necessary and sufficient (same indiscrete-preorder counterexample). No consumers (nor of the dual `LowerSet.Iic_sup_erase`).","fix":"Take `(ha : Minimal (· ∈ s) a)` as in `erase_inf_Ici`; the `rw [inf_comm, erase_inf_Ici ha]` proof is unchanged.","ev":"hunts/upperlower-closure/batch4/Closure_b4.lean:310-312 (compiles):\n@[to_dual]\nlemma Ici_inf_erase (ha : Minimal (· ∈ s) a) : Ici a ⊓ s.erase a = s := by\n  rw [inf_comm, erase_inf_Ici ha]\n-- dual generated: LowerSet.Iic_sup_erase : Maximal (fun x ↦ x ∈ s) a → LowerSet.Iic a ⊔ s.erase a = s\n-- necessity and counterexample: hunts/upperlower-closure/batch4/probe1.lean G1/G3","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-75f6d8","file":"Mathlib/Order/UpperLower/CompleteLattice.lean","decl":"LowerSet.coe_map_apply","line":346,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `LowerSet.coe_map` (Order.UpperLower.CompleteLattice), `LowerSet.coe_map_apply` (Order.UpperLower.CompleteLattice) state exactly the same thing (Lean-checked). Reviewer: Same file, both rfl and both @[to_dual]: coe_map_apply (`map f s = f '' s`, coerced) and coe_map (`(map f s : Set β) = f '' s`, norm_cast). The comment at line 344 explains why coe_map_apply replaces simps, not why it duplicates coe_map. Keep coe_map, add simp, and deprecate coe_map_apply (the UpperSet pair is in another part).","fix":"Deprecate `LowerSet.coe_map_apply` in favour of `LowerSet.coe_map`.","ev":"dupscan/Check.lean: `example := (@LowerSet.coe_map_apply : type_of% @LowerSet.coe_map)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 11, rating MAJOR): The comment explains replacing generated lemmas with handwritten ones; it supplies no reason for separate simp and norm_cast copies. Put both attributes on `coe_map`, moving it earlier as needed and preserving dualization.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-075714","file":"Mathlib/Order/UpperLower/CompleteLattice.lean","decl":"UpperSet.coe_map_apply","line":346,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `UpperSet.coe_map` (Order.UpperLower.CompleteLattice), `UpperSet.coe_map_apply` (Order.UpperLower.CompleteLattice) state exactly the same thing (Lean-checked). Reviewer: `coe_map` (@[norm_cast]) and `coe_map_apply` (@[simp], a hand-written stand-in for a simps lemma per the l.344 comment) are both rfl proofs of `↑(map f s) = f '' s`, mirrored to LowerSet by to_dual. A single @[simp, norm_cast] lemma suffices. Keep coe_map and deprecate coe_map_apply, which has no uses.","fix":"Deprecate `UpperSet.coe_map_apply` in favour of `UpperSet.coe_map`.","ev":"dupscan/Check.lean: `example := (@UpperSet.coe_map_apply : type_of% @UpperSet.coe_map)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 12, rating MAJOR): A single `[simp, norm_cast]` theorem supplies both registered behaviors. The handwritten simps substitute has no additional normalization role here.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-5db6c6","file":"Mathlib/Probability/Decision/BayesEstimator.lean","decl":"(module docstring)","line":22,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-claims-more","claim":"The module docstring says a Bayes estimator 'can be written as a measurable function x ↦ argmin_y P†π(x)[θ ↦ ℓ θ y] for (P ∘ₘ π)-almost every x', but only the converse is proved (an argmin estimator is Bayes), and the stated direction is false in general: randomized estimators can be Bayes (constant loss, uniform choice of action), and with infinite Bayes risk every estimator is Bayes. The lower-integral reading of `∫⁻ x, ⨅ y, …` (the infimum need not be measurable) and the attainment hypothesis missing from the measurable-selection TODO are also undocumented.","fix":"State the proved direction: a measurable posterior minimiser defines a deterministic Bayes estimator; note the lower-integral convention and that selection needs the infimum to be attained.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-1db523","file":"Mathlib/Probability/Decision/BayesEstimator.lean","decl":"ProbabilityTheory.IsBayesEstimator","line":103,"sev":"MINOR","status":"confirmed","cat":"correctness","pattern":"predicate-missing-standing-assumption","claim":"`IsBayesEstimator ℓ P κ π := avgRisk ℓ P κ π = bayesRisk ℓ P π` does not require κ to be a Markov kernel, although an estimator is a Markov kernel and `bayesRisk` is the infimum over Markov kernels only. Non-estimators therefore qualify: the zero kernel whenever the Bayes risk is 0 (proved in Lean for 0-1 loss on Bool with a noiseless observation), and, with positive Bayes risk, a sub-probability kernel such as ½·δ_b on an action b of loss 2 when the best action has loss 1 (risk 1 = Bayes risk, while its normalisation δ_b has risk 2). No consumer depends on it yet; the only producer (`IsArgminEstimator.kernel`) is Markov.","fix":"Make it `IsMarkovKernel κ ∧ avgRisk … = bayesRisk …` (or a structure), or document that it is only meaningful for Markov κ.","ev":"example : IsBayesEstimator (fun θ y : Bool ↦ if θ = y then (0 : ℝ≥0∞) else 1)\n    (Kernel.id : Kernel Bool Bool) (0 : Kernel Bool Bool) (Measure.dirac true) := by\n  have h0 : avgRisk (fun θ y : Bool ↦ if θ = y then (0 : ℝ≥0∞) else 1) Kernel.id 0 (Measure.dirac true) = 0 := by simp [avgRisk]\n  have hB : bayesRisk (fun θ y : Bool ↦ if θ = y then (0 : ℝ≥0∞) else 1) Kernel.id (Measure.dirac true) = 0 := by\n    refine le_antisymm ?_ bot_le\n    refine (bayesRisk_le_avgRisk _ _ (Kernel.id : Kernel Bool Bool) _).trans (le_of_eq ?_)\n    simp [avgRisk, Kernel.id_apply]\n  rw [IsBayesEstimator, h0, hB]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-78edd9","file":"Mathlib/Probability/Distributions/Bernoulli.lean","decl":"ProbabilityTheory.bernoulliMeasure","line":43,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-claims-more","claim":"The module and definition docstrings (inherited by the `Ber(x, y, p)` notation) say the measure 'gives mass `p` to `{x}` and `1 - p` to `{y}`'. That is false when x = y (`Ber(0, 0, 0) {0} = 1`, not 0), and also for distinct points that the σ-algebra does not separate (indiscrete `Bool`: both singletons get mass 1). The definition is right; the docstring should state the mixture `p • δₓ + (1 - p) • δ_y`. The two `hasLaw_indicator_*` theorems also share one copied docstring.","fix":"Describe it as `p • dirac x + (1 - p) • dirac y`; qualify the singleton masses (x ≠ y, measurable singletons); give the second hasLaw theorem its own docstring.","ev":"example : Ber((0 : ℕ), 0, (0 : I)) {0} = 1 := by simp","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b8a287","file":"Mathlib/Probability/Distributions/Bernoulli.lean","decl":"ProbabilityTheory.bernoulliMeasure","line":43,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"Missing basic API: there is no symmetry lemma `Ber(x, y, p) = Ber(y, x, σ p)` (one `simp` line); the measurable-map version `map_bernoulliMeasure'` is not `@[simp]` (so `simp [hf]` makes no progress on `Ber(x, y, p).map f = Ber(f x, f y, p)`, unlike `map_dirac'`); and there are no evaluation lemmas for arbitrary (non-measurable) sets under `[MeasurableSingletonClass X]`.","fix":"Add `bernoulliMeasure_comm`/`_swap`, tag `map_bernoulliMeasure'` `@[simp]`, add `MeasurableSingletonClass` apply lemmas without `hs`.","ev":"example (x y : X) (p : I) : Ber(x, y, p) = Ber(y, x, σ p) := by\n  simp [bernoulliMeasure_def, add_comm]   -- compiles\nexample (x y : X) {f : X → Y} (hf : Measurable f) (p : I) :\n    Ber(x, y, p).map f = Ber(f x, f y, p) := by simp [hf]   -- error: simp made no progress","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-519c85","file":"Mathlib/Probability/Distributions/Bernoulli.lean","decl":"ProbabilityTheory.map_bernoulliMeasure","line":150,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-hypothesis","claim":"Several hypotheses are unnecessary: `map_bernoulliMeasure` needs no `[MeasurableSingletonClass Y]` (any f is a.e. equal to `f a` under `dirac a`); `bernoulliMeasure_apply_of_mem_of_mem` and its real version need no `hs : MeasurableSet s` (a Dirac measure gives 1 to any set containing its point); `eq_bernoulliMeasure` needs only `h1` and `h2` (`h3`, `h4` follow by complements in the probability measure μ). Astra also notes `[DecidablePred (· ∈ s)]` in the apply lemmas can be `[Decidable (x ∈ s)] [Decidable (y ∈ s)]` (not tested).","fix":"Drop the target singleton instance, `hs` in the both-atoms lemmas, and `h3 h4` (keep a four-case version only if wanted as `ext`).","ev":"example [MeasurableSingletonClass X] (x y : X) (f : X → Y) (p : I) :\n    Ber(x, y, p).map f = Ber(f x, f y, p) := by\n  have hd (a : X) : (dirac a).map f = dirac (f a) := by\n    calc (dirac a).map f = (dirac a).map (fun _ ↦ f a) := Measure.map_congr (ae_eq_dirac f)\n      _ = dirac (f a) := by simp\n  simp only [bernoulliMeasure_def]\n  rw [AEMeasurable.map_add₀ (aemeasurable_dirac.smul_measure _)\n    (aemeasurable_dirac.smul_measure _), Measure.map_smul, Measure.map_smul, hd, hd]\n  all_goals exact aemeasurable_dirac\nexample (x y : X) (p : I) {s : Set X} (hx : x ∈ s) (hy : y ∈ s) : Ber(x, y, p) s = 1 := by\n  simp [bernoulliMeasure_def, hx, hy, ← ENNReal.coe_add]\n-- and eq_bernoulliMeasure from h1 h2 only: hunts/bernoulli/Probe3.lean compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-94d131","file":"Mathlib/Probability/Distributions/Binomial.lean","decl":"(file)","line":13,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-describes-other-statement","claim":"The module docstring misdescribes the file: (1) it says `Bin(n, p)` is 'the cardinal of a random subset `U` of `Set.Iic n`', but `binomial n p := setBer(Iio n, p).map ncard` uses `Iio n` (n trials); a subset of `Iic n` (n + 1 elements) would give `Bin(n + 1, p)`; (2) it says the file 'computes their expectation and variance', but only the expectation (`integral_of_hasLaw_binomial`) is proved; there is no binomial variance result anywhere in Mathlib; (3) it calls `ProbabilityTheory.binomial` the 'Binomial distribution on an arbitrary semiring', but it is a `Measure ℕ` (the semiring version is the notation `Bin(R, n, p)`).","fix":"Say `Set.Iio n`; drop 'and variance' (or prove it); describe `binomial` as a measure on `ℕ`.","ev":"Measured: module docstring L13-29 vs `binomial` L56 (`setBer(Iio n, p)`); `grep -i variance` finds only the docstring; `grep -rn 'variance.*Bin(' Mathlib` finds nothing.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-7802bd","file":"Mathlib/Probability/Distributions/Binomial.lean","decl":"map_cast_binomial_eq_sum_dirac","line":129,"sev":"MINOR","status":"suspected","cat":"generality","pattern":"too-strong-typeclass","claim":"Astra A1 items 2, 4-9 (not compiled): `map_cast_binomial_eq_sum_dirac` should not need `[MeasurableSingletonClass R]` (`Measure.map` of a finite sum of Diracs along a measurable cast); the `integrable_*` lemmas assume more structure on the target than needed; `binomial_zero` is not `@[simp]`; no lemmas for the endpoints `p = 0`/`p = 1`; `binomial_singleton` repeats the `ENNReal.ofReal_toReal` conversion; `binomial_eq_sum_dirac` re-does a finite atomic decomposition; `binomial_nat` and `integral_of_hasLaw_binomial` break the file's own naming convention (`map_cast_binomial`).","fix":"Drop `MeasurableSingletonClass R` where possible; add `@[simp]` and the endpoint lemmas; rename per the stated convention.","ev":"Suspected: Astra A1 items 2, 4-9 (probes not run).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-9ea944","file":"Mathlib/Probability/Distributions/SetBernoulli.lean","decl":"setBernoulli","line":44,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"The defining properties of `setBer(u, p)` are not exposed: there is no one-point marginal law `setBer(u, p).map (fun s ↦ i ∈ s) = Ber(i ∈ u, False, p)`, no `setBer(u, p) {s | i ∈ s} = p` / `= 0` lemma, and no independence statement (`iIndepFun` of the membership indicators, or an `IsSetBernoulli` wrapper), so users must unfold the definition into `infinitePi` to use the advertised behaviour; the marginal follows in two lines from `infinitePi_map_eval`.","fix":"Add `map_mem_setBernoulli`/`setBernoulli_mem` (marginals) and an independence lemma via `iIndepFun_infinitePi`, plus `IsSetBernoulli` wrappers.","ev":"hunts/set-bernoulli/probe2.lean A6map_mem (`setBer(u, p).map (fun s ↦ i ∈ s) = Ber(i ∈ u, False, p)`, via `setBernoulli_eq_map`, `map_map`, `infinitePi_map_eval`) compiles. Exit 0. Raised by Astra's A1 pass (item 6).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-770bf9","file":"Mathlib/Probability/Distributions/SetBernoulli.lean","decl":"setBernoulli_ae_subset","line":76,"sev":"MINOR","status":"suspected","cat":"generality","pattern":"typeclass-stronger-than-needed","claim":"Astra argues (not formalised here) that the remaining countability assumptions are also stronger than needed: `setBernoulli_ae_subset`, `setBernoulli_apply_eq_apply_subsets` and `IsSetBernoulli.ae_subset` need only `(uᶜ).Countable` (only excluded coordinates contribute exceptional events), and for finite `u` the atom formulas `setBernoulli_singleton`/`setBernoulli_real_singleton` hold for every `ι` (as outer-measure values). Countability cannot be dropped entirely from `ae_subset` (see the docs finding) nor from the `ncard` pushforwards (`ncard` may fail to be a.e.-measurable).","fix":"Restate the support lemmas under `(uᶜ).Countable` and the finite-`u` atom formulas without `Countable ι`, if the proofs go through.","ev":"Suspected: Astra's A1 items 4-5 give paper arguments; no Lean proof was attempted (the current proofs go through `measure_iUnion_null_iff` over `ι` and `Measure.infinitePi_singleton`).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-3473e8","file":"Mathlib/Probability/Distributions/SetBernoulli.lean","decl":"setBernoulli_singleton_of_not_subset","line":90,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-typeclass-from-section","claim":"`setBernoulli_singleton_of_not_subset` (`¬ s ⊆ u → setBer(u, p) {s} = 0`) sits in `section Countable`, but one excluded coordinate suffices: pick `i ∈ s \\ u`; then `{s} ⊆ {t | i ∈ t}`, a measurable cylinder of measure `0`, with no countable union involved. The general version holds for every index type (e.g. `ι = ℝ`); the null-cylinder fact `setBer(u, p) {s | i ∈ s} = 0` for `i ∉ u` is itself missing as a lemma.","fix":"Prove it outside `section Countable` from a new lemma `setBernoulli_mem_eq_zero (hi : i ∉ u) : setBer(u, p) {s | i ∈ s} = 0`.","ev":"hunts/set-bernoulli/probe2.lean A3mem_null and A3singleton_of_not_subset (no `Countable ι`) compile; applied at `ι = ℝ`. Exit 0. Raised by Astra's A1 pass (item 3).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-914f81","file":"Mathlib/Probability/Distributions/SetBernoulli.lean","decl":"map_ncard_setBernoulli_singleton","line":143,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-bridge-lemma","claim":"The file computes the point masses of `setBer(u, p).map Set.ncard` for finite `u` (the binomial pmf), and `Binomial.lean` defines `Bin(n, p) := setBer(Iio n, p).map ncard`, but no lemma identifies `setBer(u, p).map Set.ncard` with `Bin(u.ncard, p)` for a general finite `u`; users of a set-Bernoulli law on, say, the edges of a graph must redo the `ext_of_singleton` argument.","fix":"Add `map_ncard_setBernoulli (hu : u.Finite) : setBer(u, p).map Set.ncard = Bin(u.ncard, p)` to `Binomial.lean` (it imports this file).","ev":"hunts/set-bernoulli/probe1.lean P2 `P2map_ncard_setBernoulli` compiles in two lines (`Measure.ext_of_singleton`, `map_ncard_setBernoulli_singleton`, `binomial_singleton`); `#check ProbabilityTheory.map_ncard_setBernoulli` fails (`#guard_msgs (drop error)`). Exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-1d67c5","file":"Mathlib/Probability/Distributions/SetBernoulli.lean","decl":"setBernoulli_empty","line":150,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-typeclass-from-section","claim":"`setBernoulli_empty : setBer(∅, p) = dirac ∅` sits in `section Countable` and so assumes `[Countable ι]`, but it holds for every index type by the same one-line `simp [setBernoulli_eq_map]` that proves its siblings `setBernoulli_zero`/`setBernoulli_one` (with `u = ∅` every factor `Ber(i ∈ ∅, False, p)` is `dirac False`). The current statement excludes e.g. `ι = ℝ`.","fix":"Move `setBernoulli_empty` before `section Countable` and prove it by `simp [setBernoulli_eq_map]`.","ev":"hunts/set-bernoulli/probe1.lean P1 `P1setBernoulli_empty` (no `Countable ι`) compiles and is applied at `ι = ℝ`. Exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261013-795f06","file":"Mathlib/Probability/Independence/ZeroOne.lean","decl":"Kernel.measure_eq_zero_or_one_of_indepSet_self","line":59,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"unsynthesizable-pi-instance-binder","claim":"`Kernel.measure_eq_zero_or_one_of_indepSet_self` and `…_of_indep_self` take the instance binder `[h : ∀ a, IsFiniteMeasure (κ a)]`, used nowhere else in Mathlib. Typeclass search does not fill it for `condExpKernel μ m` (an `IsMarkovKernel`), so `condExp_eq_zero_or_one_of_condIndepSet_self` needs a manual `have` under '-- TODO: Why is not inferred?'. With Mathlib's usual `[IsFiniteKernel κ]` the instance is found and the workaround disappears; the pointwise-finite generality stays available through the primed `ae` lemma.","fix":"Use `[IsFiniteKernel κ]` in both lemmas (proof: `…_self' (ae_of_all μα fun _ ↦ inferInstance) h_indep`) and delete the TODO and the `have`.","ev":"hunts/zero-one/copyA.lean: deleting the TODO `have` fails with 'failed to synthesize ∀ (a : Ω), IsFiniteMeasure ((condExpKernel μ m) a)'. hunts/zero-one/copyE.lean: with `[IsFiniteKernel κ]` in both lemmas and the `have` deleted, the file compiles with the Mathlib linter set, exit 0. `grep '∀ a, IsFiniteMeasure (κ a)]' Mathlib` matches only this file.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-1819a4","file":"Mathlib/Probability/Independence/ZeroOne.lean","decl":"measure_eq_zero_or_one_of_indepSet_self","line":70,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"The self-independence 0-1 lemmas assume the whole measure finite (`[IsFiniteMeasure μ]`; for kernels, every or almost every `κ a` finite), but only finiteness of the one event is used: from `measure_eq_zero_or_one_or_top_of_indepSet_self`, `μ t ≠ ∞` rules out the last case. Example (Astra): `μ = ∞ • dirac false` on `Bool`, `t = {true}` is self-independent with `μ t = 0` but `μ` is not finite.","fix":"Add `measure_eq_zero_or_one_of_indepSet_self_of_ne_top (h_indep) (ht : μ t ≠ ∞)` and the kernel version with `∀ᵐ a ∂μα, κ a t ≠ ∞`; keep the typeclass versions as wrappers.","ev":"hunts/zero-one/probe_astra.lean (A4): `IndepSet t t μ → μ t ≠ ∞ → μ t = 0 ∨ μ t = 1` compiles in three lines from `measure_eq_zero_or_one_or_top_of_indepSet_self`, exit 0. The kernel analogue is the same argument under `filter_upwards` (not compiled separately).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-776a13","file":"Mathlib/Probability/Independence/ZeroOne.lean","decl":"condExp_eq_zero_or_one_of_condIndepSet_self","line":80,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"detour-through-kernel-representation","claim":"The conditional self-independence law goes through `condExpKernel`, `ae_of_ae_trim`, the instance workaround and `ENNReal.toReal`, although `condIndepSet_iff` already gives `μ⟦t ∩ t | m⟧ =ᵐ μ⟦t | m⟧ * μ⟦t | m⟧`, from which `q = q * q` and `mul_eq_left₀` finish.","fix":"`filter_upwards [(condIndepSet_iff m hm t t ht ht μ).mp h_indep] with ω hω` then split on `μ⟦t | m⟧ ω = 0` and use `(mul_eq_left₀ h0).mp` after `simp only [Set.inter_self, Pi.mul_apply] at hω`.","ev":"hunts/zero-one/probe_astra.lean (A8): the statement proved by this six-line route compiles, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-8f5bd0","file":"Mathlib/Probability/Independence/ZeroOne.lean","decl":"Kernel.indep_iSup_limsup","line":174,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"hypotheses-encode-simpler-condition","claim":"The abstract law's filter interface takes a predicate `p`, `hf : ∀ t, p t → tᶜ ∈ f`, a family `ns : β → Set ι`, `hns : Directed (· ≤ ·) ns`, `hnsp : ∀ a, p (ns a)` and `hns_univ : ∀ n, ∃ a, n ∈ ns a`, but together these say no more than `f ≤ cofinite`: they imply it (cover each `n`, so `{n}ᶜ ∈ f`, then `le_cofinite_iff_compl_singleton_mem`), and `f ≤ cofinite` alone suffices (take `p := Set.Finite` and `ns := (↑) : Finset ι → Set ι`). In particular `Directed` is never needed.","fix":"Add (or restate as) `Kernel.indep_iSup_limsup_of_le_cofinite (h_le) (h_indep) (hf : f ≤ cofinite)` and the matching `indep_limsup_self`/zero-one-law versions; derive the current forms from them with `le_cofinite_iff_compl_singleton_mem`.","ev":"hunts/zero-one/probe_astra.lean: `A5_indep_iSup_limsup_of_le_cofinite` (hypothesis `f ≤ cofinite` only) and `A5_le_cofinite_of_cover` (the original hypotheses imply `f ≤ cofinite`) compile, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-1dfbea","file":"Mathlib/Probability/Independence/ZeroOne.lean","decl":"condExp_zero_or_one_of_measurableSet_limsup","line":238,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"duplicated-proof-argument","claim":"The abstract conditional 0-1 law re-derives the kernel-to-`condExp` conversion inline (`ae_of_ae_trim`, `condExpKernel_ae_eq_condExp`, `toReal` rewrites), whereas the `atTop`/`atBot` versions call `condExp_eq_zero_or_one_of_condIndepSet_self` with `condIndep_limsup_*_self`.","fix":"`condExp_eq_zero_or_one_of_condIndepSet_self hm (limsup_le_iSup.trans (iSup_le h_le) t ht_tail) ((condIndep_limsup_self hm h_le h_indep hf hns hnsp hns_univ).condIndepSet_of_measurableSet ht_tail ht_tail)`.","ev":"hunts/zero-one/copyB.lean: the file with this term-mode proof compiles with the Mathlib linter set, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-814271","file":"Mathlib/Probability/Independence/ZeroOne.lean","decl":"Kernel.indep_limsup_atTop_self","line":254,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"The `AtTop` section assumes `[SemilatticeSup ι] [NoMaxOrder ι] [Nonempty ι]` (and `AtBot` the duals), but `[Preorder ι] [NoTopOrder ι]` suffices, via `Filter.atTop_le_cofinite` (dually `atBot_le_cofinite` with `[NoBotOrder ι]`). Even with the present proofs `[Nonempty ι]` is redundant: an empty index gives `tᶜ = univ ∈ atTop`, and with a direct proof of the cofinality step the unused-section-variable linter flags `[Nonempty ι]` as unused.","fix":"State the `atTop` results under `[Preorder ι] [NoTopOrder ι]` and the `atBot` ones under `[Preorder ι] [NoBotOrder ι]`, proved from the `f ≤ cofinite` form; at minimum drop `[Nonempty ι]`.","ev":"hunts/zero-one/probe_astra.lean: `A3_kernel_indep_limsup_atTop_self` and `A3_measure_zero_or_one_atTop` compile under `[Preorder ι] [NoTopOrder ι]`, exit 0. hunts/zero-one/copyD.lean: the file with `[Nonempty ι]` removed from both sections (empty-index case split in the cofinality step) compiles with the Mathlib linter set, exit 0. hunts/zero-one/copyF.lean: with `eventually_gt_atTop` in the cofinality step the linter reports '[Nonempty ι]' unused in `Kernel.indep_limsup_atTop_self`. The `atBot` claim is the dual; only the `Nonempty` part is compiled for it (copyD).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-964142","file":"Mathlib/Probability/Independence/ZeroOne.lean","decl":"measure_zero_or_one_of_measurableSet_limsup_atTop","line":287,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"wrong-formula-in-docstring","claim":"The docstring of Kolmogorov's 0-1 law says 'The tail σ-algebra `limsup s atTop` is the same as `⋂ n, ⋃ i ≥ n, s i`'. That is set notation; it does not typecheck for σ-algebras, and read as intersections/unions of the families of sets it is false (a union of σ-algebras is not one; Astra: on `Bool × Bool` alternating the two coordinate σ-algebras, the tail sup has 16 sets, the unions 6). The correct statement is `⨅ n, ⨆ i ≥ n, s i` (`Filter.limsup_eq_iInf_iSup_of_nat` for `ℕ`).","fix":"Write '`limsup s atTop`, which for `ι = ℕ` is `⨅ n, ⨆ i ≥ n, s i` (`Filter.limsup_eq_iInf_iSup_of_nat`)'.","ev":"hunts/zero-one/probe_doc_fail.lean: `limsup s atTop = ⋂ n, ⋃ i ≥ n, s i` for `s : ℕ → MeasurableSpace Ω` fails ('s i has type MeasurableSpace Ω but is expected to have type Set ?'); hunts/zero-one/probe_doc.lean: `limsup s atTop = ⨅ n, ⨆ i ≥ n, s i := limsup_eq_iInf_iSup_of_nat` compiles, exit 0.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-6115b7","file":"Mathlib/Probability/Independence/ZeroOne.lean","decl":"Kernel.indep_limsup_atBot_self","line":310,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"order-dual-duplicate-proof","claim":"`Kernel.indep_limsup_atBot_self` repeats the 12-line proof of `Kernel.indep_limsup_atTop_self` with the order reversed; it is the `atTop` lemma on `ιᵒᵈ`.","fix":"`Kernel.indep_limsup_atTop_self (ι := ιᵒᵈ) h_le h_indep`.","ev":"hunts/zero-one/copyC.lean: the file with this one-line proof compiles with the Mathlib linter set, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261007-5c6e56","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.hasFiniteIntegral_prodMk_left","line":64,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"long-proof-one-line-from-api","claim":"The 12-line proof (L66-77) takes a `toMeasurable` detour and an a.e. filter through `ae_kernel_lt_top` that are not needed: `le_compProd_apply` already holds for arbitrary (non-measurable) `s`, and `hasFiniteIntegral_toReal_of_lintegral_ne_top` handles the `ofReal ∘ toReal` step. The whole lemma is the one-liner `hasFiniteIntegral_toReal_of_lintegral_ne_top (ne_top_of_le_ne_top h2s (le_compProd_apply _ _ _ _))`.","fix":"Replace the calc proof with `hasFiniteIntegral_toReal_of_lintegral_ne_top (ne_top_of_le_ne_top h2s (le_compProd_apply _ _ _ _))`.","ev":"hunts/kernel-integral-compprod/batch0/probe.lean theorem Probe.P1 (exact statement of hasFiniteIntegral_prodMk_left, proved by the one-liner). Exit 0; batch0/axioms.lean: P1 depends only on [propext, Classical.choice, Quot.sound].","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-44a4ae","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.integrable_kernel_prodMk_left","line":79,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"measurableset-to-nullmeasurableset","claim":"`(hs : MeasurableSet s)` can be weakened to `NullMeasurableSet s ((κ ⊗ₖ η) a)`. With `t := toMeasurable _ s`, `(κ ⊗ₖ η) a (t \\ s) = 0`, so `ae_null_of_compProd_null` makes the slices of `s` and `t` have equal `η (a, b)`-measure for a.e. `b`. The function is then a.e. equal to a measurable one. The original statement is recovered via `hs.nullMeasurableSet`. This is low priority: the lemma has no consumers in Mathlib, and the Measure.prod analogue `integrable_measure_prodMk_left` has the same restriction.","fix":"State it with `(hs : NullMeasurableSet s ((κ ⊗ₖ η) a))`, or leave it as is if Measure.prod parity is preferred.","ev":"hunts/kernel-integral-compprod/batch0/probe.lean theorem Probe.P4 (NullMeasurableSet version, 8-line proof) plus an example that recovers the original from `P4 a hs.nullMeasurableSet h2s`. Exit 0, axioms clean.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-b9d4e8","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"MeasureTheory.Integrable.integral_compProd","line":148,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-measure-level-wrapper","claim":"The partial-integral integrability lemmas `Integrable.integral_compProd`, `Integrable.integral_norm_compProd`, `Integrable.ae_of_compProd` and `AEStronglyMeasurable.integral_kernel_compProd` have no `μ ⊗ₘ κ` (Measure.compProd) counterparts. The file supplies Measure wrappers for `integrable_compProd_iff`, `integral_compProd`, `setIntegral_compProd`, `AEStronglyMeasurable.ae_of_compProd`, and for Measure.comp (`ae_integrable_of_integrable_comp`, `integrable_integral_norm_of_integrable_comp`). Downstream code therefore applies the kernel lemmas by unfolding `Measure.compProd` definitionally to `(Kernel.const Unit μ ⊗ₖ Kernel.prodMkLeft Unit κ) ()`: IntegralRNDeriv.lean:190 `hf_int.integral_compProd` with `hf_int : Integrable _ (ν ⊗ₘ η)`, and Disintegration/Integral.lean:182 `AEStronglyMeasurable.integral_kernel_compProd hf` with `hf` over `ρ.fst ⊗ₘ ρ.condKernel`.","fix":"Add `Measure.Integrable`-style wrappers for `μ ⊗ₘ κ`, e.g. `Integrable.integral_compProd_measure` or a `Measure.integrable_integral_compProd` family, proved by the kernel lemma plus `simp [Measure.compProd]`, and use them at the two defeq-abuse sites.","ev":"hunts/kernel-integral-compprod/batch0/probe.lean section `measure`: four examples, each closing the μ ⊗ₘ κ statement with the kernel lemma by defeq (`hf.integral_compProd`, `hf.integral_kernel_compProd`, `hf.ae_of_compProd`, `hf.integral_norm_compProd`), exit 0. `git grep -nP \"(Integrable|AEStronglyMeasurable)[^\\n]*⊗ₘ\" origin/master -- Mathlib` lists only the Measure lemmas named above.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-9fc5e1","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.Kernel.integral_fn_integral_add","line":163,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"stronger-hypothesis-than-used","claim":"`Kernel.integral_fn_integral_add`, `Kernel.integral_fn_integral_sub` and `Kernel.lintegral_fn_integral_sub` (the `⊗ₖ` versions) assume `Integrable f ((κ ⊗ₖ η) a)` and `Integrable g ((κ ⊗ₖ η) a)` (and s-finiteness through the section), but their proofs use only the a.e. integrability of the slices (`hf.ae_of_compProd`); the statements hold with `∀ᵐ x ∂κ a, Integrable (fun y ↦ f (x, y)) (η (a, x))` and no s-finiteness, which is strictly weaker (counting measure on ℕ with Dirac inner kernels and f(n) = n + 1). This is the same pattern as the `_comp` versions (recorded separately) and as their `Integral/Prod.lean` originals.","fix":"State the `fn` helpers with a.e. slice integrability hypotheses and derive the current forms via `Integrable.ae_of_compProd`.","ev":"hunts/kernel-integral-compprod/astra/probe.lean A7integral_fn_integral_add (slice hypotheses, no `IsSFiniteKernel`) compiles and the original statement is recovered from it via `Integrable.ae_of_compProd`. Exit 0. Raised by Astra's A1 pass (item 7).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-961fc2","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.Kernel.continuous_integral_integral","line":213,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"fubini-copy-derivable-from-comp","claim":"The 17-line proof is a third copy of the argument behind MeasureTheory.continuous_integral_integral and Kernel.continuous_integral_integral_comp. Its only consumer in Mathlib is integral_compProd (git grep), which can be proved without it (see the integral_compProd reuse finding). Given integral_compProd the statement is the one-liner 'continuous_integral.congr fun f ↦ integral_compProd (L1.integrable_coeFn f)'.","fix":"After deriving integral_compProd from Kernel.integral_comp, replace the proof by the one-liner (or deprecate the lemma).","ev":"hunts/kernel-integral-compprod/batch1/Probe2.lean, section OneLiners (compiles): example : Continuous fun f : β × γ →₁[(κ ⊗ₖ η) a] E => ∫ x, ∫ y, f (x, y) ∂η (a, x) ∂κ a :=\n  continuous_integral.congr fun f ↦ integral_compProd_via_comp (L1.integrable_coeFn f)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-4068c7","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.integral_compProd","line":231,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"fubini-copy-derivable-from-comp","claim":"The proof re-runs the whole L1-density Fubini argument (Integrable.induction plus the 8 compProd-only helpers Kernel.integral_fn_integral_add ... Kernel.continuous_integral_integral, L163-229, ~90 lines with this proof), but the statement follows in 12 lines from Kernel.integral_comp (same file, needs no s-finiteness and none of those helpers) via Kernel.compProd_apply_eq_compProd_sectR, Measure.compProd_eq_comp_prod, Measure.comp_eq_comp_const_apply, Kernel.prod_apply, Measure.dirac_prod and integral_map. A transitive-dependency walk confirms the derivation uses neither integral_compProd nor any compProd helper. The module docstring's reason for redoing the proofs ('the composition-product requires s-finiteness while the composition does not') only rules out deriving comp from compProd, not this direction. None of the 8 helpers has a consumer anywhere else in Mathlib (git grep origin/master).","fix":"Put the comp section first, prove integral_compProd from Kernel.integral_comp as in the probe, and deprecate the compProd-only scaffolding (or restate it as one-line corollaries).","ev":"hunts/kernel-integral-compprod/batch1/Probe2.lean (compiles; #uses checks in Probe2.out):\ntheorem integral_compProd_via_comp {f : β × γ → E} (hf : Integrable f ((κ ⊗ₖ η) a)) :\n    ∫ z, f z ∂(κ ⊗ₖ η) a = ∫ x, ∫ y, f (x, y) ∂η (a, x) ∂κ a := by\n  have h_eq : (κ ⊗ₖ η) a =\n      ((Kernel.id ×ₖ Kernel.sectR η a) ∘ₖ Kernel.const Unit (κ a)) () := by\n    rw [Kernel.compProd_apply_eq_compProd_sectR, Measure.compProd_eq_comp_prod,\n      Measure.comp_eq_comp_const_apply]\n  rw [h_eq] at hf ⊢\n  have h_ae := hf.ae_of_comp\n  rw [Kernel.const_apply] at h_ae\n  rw [Kernel.integral_comp hf, Kernel.const_apply]\n  refine integral_congr_ae ?_\n  filter_upwards [h_ae] with b hb\n  rw [Kernel.prod_apply, Kernel.id_apply, Kernel.sectR_apply, Measure.dirac_prod] at hb ⊢\n  exact integral_map measurable_prodMk_left.aemeasurable hb.aestronglyMeasurable\n-- #uses integral_compProd_via_comp ProbabilityTheory.integral_compProd: false\n-- #uses integral_compProd_via_comp ProbabilityTheory.Kernel.continuous_integral_integral: false\n-- #uses integral_compProd_via_comp ProbabilityTheory.Kernel.integral_integral_add': false\n-- #uses integral_compProd_via_comp ProbabilityTheory.Kernel.lintegral_fn_integral_sub: false\n-- positive control: #uses ProbabilityTheory.integral_compProd ProbabilityTheory.Kernel.continuous_integral_integral: true","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-2c4ed6","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.integral_compProd","line":231,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"missing-docstring-main-theorem","claim":"The file's main theorem (listed under 'Main statements' in the module docstring) has no docstring, while its model MeasureTheory.integral_prod carries a '**Fubini's Theorem**' docstring pointing to the integrability API (integrable_prod_iff, Integrable.integral_prod_right).","fix":"Add a '**Fubini's theorem** for the composition-product' docstring pointing to integrable_compProd_iff and Integrable.integral_compProd.","ev":"measured: grep -n '/--' src.lean returns no docstring before L231 (the file has no declaration docstrings at all); Mathlib/MeasureTheory/Integral/Prod.lean:433-437 has the integral_prod docstring.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-0f02ba","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.setIntegral_compProd","line":257,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-measurability-hypothesis","claim":"The hypothesis hs : MeasurableSet s is unnecessary. The statement holds for arbitrary s, given measurable t. The proof replaces s by toMeasurable (κ a) s: (κ a).restrict is unchanged, and ((κ ⊗ₖ η) a).restrict (s ×ˢ t) is unchanged because the defect set has a measurable section function supported on a measurable subset of toMeasurable s \\ s. ht is genuinely needed (sketch, not formalised: κ a = Lebesgue on [0,1], η (a, x) = dirac x, t non-measurable with positive outer measure; then LHS = λ*(t) > 0 while RHS = ∫ 1_t = 0, since 1_t is not AEStronglyMeasurable). Its model MeasureTheory.setIntegral_prod needs neither. Consumers carrying the extra hypothesis: setIntegral_compProd_univ_right, MeasureTheory.Measure.setIntegral_compProd, 2 uses in Kernel/Disintegration/Integral.lean. The sibling Kernel.setLIntegral_compProd (CompProd.lean:389) likely admits the same weakening; that is unchecked.","fix":"Drop hs from setIntegral_compProd (and from setIntegral_compProd_univ_right / Measure.setIntegral_compProd), proving it via toMeasurable (κ a) s as in the probe.","ev":"hunts/kernel-integral-compprod/batch1/Probe1.lean P1 (compiles, only a deprecation warning for mem_setOf_eq in the probe):\ntheorem setIntegral_compProd_noMeasS {f : β × γ → E} {s : Set β} {t : Set γ}\n    (ht : MeasurableSet t) (hf : IntegrableOn f (s ×ˢ t) ((κ ⊗ₖ η) a)) :\n    ∫ z in s ×ˢ t, f z ∂(κ ⊗ₖ η) a = ∫ x in s, ∫ y in t, f (x, y) ∂η (a, x) ∂κ a := by ... (55 lines, see file)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-582a9e","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.setIntegral_compProd_univ_right","line":265,"sev":"MINOR","status":"suspected","cat":"generality","pattern":"measurableset-hypothesis-droppable","claim":"`hs : MeasurableSet s` is probably unnecessary: the product-measure analogue `MeasureTheory.setIntegral_prod (f) {s t} (hf : IntegrableOn f (s ×ˢ t) (μ.prod ν))` has no measurability hypotheses (it goes through `Measure.prod_restrict (s t)` for arbitrary sets), and for `s ×ˢ univ = Prod.fst ⁻¹' s` with κ s-finite one can replace `s` by `toMeasurable (κ a) s` on both sides (for measurable V ⊇ s ×ˢ univ, A = {x | η (a,x) (V_x)ᶜ = 0} is measurable and contains s, so the hull minus A is κ a-null). Not proved in Lean: the kernel API (`Kernel.restrict`, `compProd_restrict`) only takes measurable sets, so the generalisation needs a new restrict lemma. The `_left` variant is not claimed (the hull of t would depend on x).","fix":"If wanted, prove `((κ ⊗ₖ η) a).restrict (s ×ˢ univ) = ((κ ⊗ₖ η) a).restrict (toMeasurable (κ a) s ×ˢ univ)` and drop `hs`.","ev":"git grep -n -A3 'theorem setIntegral_prod\\b' origin/master -- Mathlib  →  Mathlib/MeasureTheory/Integral/Prod.lean:502: theorem setIntegral_prod (f : α × β → E) {s : Set α} {t : Set β} (hf : IntegrableOn f (s ×ˢ t) (μ.prod ν)) : ∫ z in s ×ˢ t, f z ∂μ.prod ν = ∫ x in s, ∫ y in t, f (x, y) ∂ν ∂μ; versus CompProd.lean:279 compProd_restrict (hs : MeasurableSet s) (ht : MeasurableSet t). No Lean proof of the generalised statement attempted.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-2cbbf8","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.Kernel.integral_fn_integral_add_comp","line":354,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"stronger-hypothesis-than-used","claim":"The three `fn` lemmas `Kernel.integral_fn_integral_add_comp` (L354), `Kernel.integral_fn_integral_sub_comp` (L361) and `Kernel.lintegral_fn_integral_sub_comp` (L368) assume `Integrable f ((η ∘ₖ κ) a)` and `Integrable g ((η ∘ₖ κ) a)`, but their proofs only use the fibrewise consequences `hf.ae_of_comp : ∀ᵐ x ∂κ a, Integrable f (η x)` (and the same for `g`). With those weaker hypotheses the proofs go through unchanged, and the weakening is strict: for `κ = Kernel.const Unit Measure.count : Kernel Unit ℕ`, `η = Kernel.id`, `f = 1`, `f` is integrable on every fibre `η x = dirac x` but not on `(η ∘ₖ κ) () = count`. No kernel or completeness assumption is involved, so this is the only over-restriction. The same pattern is inherited from `MeasureTheory.integral_fn_integral_add`/`_sub`/`lintegral_fn_integral_sub` in `Mathlib/MeasureTheory/Integral/Prod.lean` and the compProd copies at L163-L185.","fix":"Take `(hf : ∀ᵐ x ∂κ a, Integrable f (η x)) (hg : ∀ᵐ x ∂κ a, Integrable g (η x))` and pass `hf.ae_of_comp hg.ae_of_comp` at the two call sites `integral_integral_add_comp`/`integral_integral_sub_comp` and in `continuous_integral_integral_comp`.","ev":"hunts/kernel-integral-compprod/batch3/probe.lean section P1: the weakened versions of all three lemmas compile with the original proof scripts (only `filter_upwards [hf, hg]` changed), `hf.ae_of_comp` recovers the original hypothesis, and the strictness counterexample (`Kernel.const Unit Measure.count`, `Kernel.id`, `fun _ ↦ (1 : ℝ)`) compiles. Exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-46a2b5","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.Kernel.integral_comp","line":410,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"module-docstring-wrong-name-and-statement","claim":"The module docstring (L32-33) lists this main statement as `ProbabilityTheory.integral_comp`, which does not exist (the declaration is `ProbabilityTheory.Kernel.integral_comp`, inside `namespace Kernel` at L352), and states it with lower Lebesgue integrals `∫⁻ z, f z ∂((η ∘ₖ κ) a) = ∫⁻ x, ∫⁻ y, f y ∂(η x) ∂(κ a)`, i.e. the statement of `Kernel.lintegral_comp`, not this Bochner statement (which also needs `Integrable f ((η ∘ₖ κ) a)`). The theorem itself has no docstring. Astra's blind pass adds that both advertised Bochner identities in 'Main statements' (`integral_compProd` and `integral_comp`) omit the indispensable integrability hypothesis (for non-integrable `f` the left side is the junk `0` while the iterated integral can be `1`); the docstring should say 'for integrable `f`'.","fix":"Change the bullet to `ProbabilityTheory.Kernel.integral_comp`: `∫ z, f z ∂((η ∘ₖ κ) a) = ∫ x, ∫ y, f y ∂(η x) ∂(κ a)` for integrable `f`, and give the theorem a docstring.","ev":"hunts/kernel-integral-compprod/batch4/probe1.lean (P6, L121-123): `#check @ProbabilityTheory.Kernel.integral_comp` succeeds; `#check @ProbabilityTheory.integral_comp` -> error: Unknown identifier `ProbabilityTheory.integral_comp`","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-4c2635","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.Kernel.integral_comp","line":410,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-measure-level-companion","claim":"There is no measure-level `κ ∘ₘ μ` version of this Bochner Fubini (`∫ y, f y ∂(κ ∘ₘ μ) = ∫ x, ∫ y, f y ∂κ x ∂μ`), nor of `Kernel.setIntegral_comp` or `Integrable.integral_comp`, although the file provides the measure-level integrability API for `κ ∘ₘ μ` (`Measure.integrable_comp_iff`, `Measure.ae_integrable_of_integrable_comp`, `Measure.integrable_integral_norm_of_integrable_comp`) and the `⊗ₘ` integral versions (`Measure.integral_compProd`, `Measure.setIntegral_compProd`). `git grep -F '∘ₘ μ)' origin/master -- Mathlib` finds no Bochner integral identity against `κ ∘ₘ μ` (only `lintegral` via `Measure.lintegral_bind`). Each missing lemma is 3 lines from the kernel version.","fix":"Add `Measure.integral_comp`, `Measure.setIntegral_comp` and `Measure.integrable_integral_comp` (via `Measure.comp_eq_comp_const_apply` and the kernel lemmas) next to `Measure.integral_compProd`.","ev":"example [NormedSpace ℝ E] {μ : Measure α} {κ : Kernel α β} {f : β → E}\n    (hf : Integrable f (κ ∘ₘ μ)) :\n    ∫ y, f y ∂(κ ∘ₘ μ) = ∫ x, ∫ y, f y ∂κ x ∂μ := by\n  rw [Measure.comp_eq_comp_const_apply] at hf ⊢\n  rw [Kernel.integral_comp hf]\n  simp\n-- plus the setIntegral and Integrable.integral_comp analogues: hunts/kernel-integral-compprod/batch4/probe1.lean (P2, L16-36), all compile","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-6b48f2","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"MeasureTheory.AEStronglyMeasurable.ae_of_compProd","line":453,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"typeclass-stronger-than-needed","claim":"`[NormedAddCommGroup E]` is stronger than needed: the same one-line proof works for any `[TopologicalSpace X]` codomain, as for its parent `AEStronglyMeasurable.compProd_mk_left` (L91, `{δ} [TopologicalSpace δ]`) and the product analogue `AEStronglyMeasurable.prodMk_left` (Integral/Prod.lean:145, `{f : α × β → X}`).","fix":"Replace `{E : Type*} [NormedAddCommGroup E]` by `{X : Type*} [TopologicalSpace X]`.","ev":"example {X : Type*} [TopologicalSpace X] {μ : Measure α} {κ : Kernel α β} [SFinite μ]\n    [IsSFiniteKernel κ] {f : α → β → X} (hf : AEStronglyMeasurable f.uncurry (μ ⊗ₘ κ)) :\n    ∀ᵐ x ∂μ, AEStronglyMeasurable (f x) (κ x) := by\n  simpa using hf.compProd_mk_left","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-7f4dc8","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"MeasureTheory.Measure.setIntegral_compProd","line":474,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-measurability-hypothesis","claim":"The hypothesis `hs : MeasurableSet s` is redundant. The statement holds for arbitrary `s` (with `t` measurable): `(μ ⊗ₘ κ).restrict (s ×ˢ t) = (μ ⊗ₘ κ).restrict (toMeasurable μ s ×ˢ t)`, then `Measure.restrict_toMeasurable_of_sfinite`. Compare `MeasureTheory.setIntegral_prod`, which needs no measurability of `s` or `t`. One downstream lemma, `Measure.setIntegral_condKernel` (Disintegration/Integral.lean:191), carries the hypothesis on.","fix":"Drop `hs` via a helper `(μ ⊗ₘ κ).restrict (s ×ˢ t) = (μ ⊗ₘ κ).restrict (toMeasurable μ s ×ˢ t)` for measurable `t`.","ev":"hunts/kernel-integral-compprod/batch4/probe1.lean (P4, L48-107): `theorem setIntegral_compProd_noHs ... {s : Set α} {t : Set β} (ht : MeasurableSet t) {f : α × β → E} (hf : IntegrableOn f (s ×ˢ t) (μ ⊗ₘ κ)) : ∫ x in s ×ˢ t, f x ∂(μ ⊗ₘ κ) = ∫ a in s, ∫ b in t, f (a, b) ∂(κ a) ∂μ` compiles (helper `aux_null`); `#print axioms` = [propext, Classical.choice, Quot.sound]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-56c6c1","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"MeasureTheory.Measure.integrable_compProd_snd_iff","line":486,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"typeclass-stronger-than-needed","claim":"`Measure.integrable_compProd_snd_iff` sits in a section with `[NormedAddCommGroup E]`, but its statement and proof (via `integrable_map_measure`) only need `[TopologicalSpace E] [ContinuousENorm E]`; the generalised version compiles verbatim and covers e.g. `ℝ≥0∞`-valued functions, which the current statement excludes.","fix":"Weaken the codomain assumptions of `integrable_compProd_snd_iff` to `[TopologicalSpace E] [ContinuousENorm E]`.","ev":"hunts/kernel-integral-compprod/astra/probe.lean A4integrable_compProd_snd_iff (`[TopologicalSpace E] [ContinuousENorm E]`, same proof) compiles and is applied to `g : β → ℝ≥0∞`. Exit 0. Raised by Astra's A1 pass (item 4).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261006-86ae31","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.IsRatCondKernelCDF","line":64,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-variable-mismatch","claim":"The docstring does not match the fields. It says `fun b ↦ f (a, b) x` is integrable \"for all `a : α` and `x : ℝ`\" and gives the integral condition with `Iic x`, but `f (a, b) : ℚ → ℝ` and the fields quantify over `q : ℚ` with `Iic (q : ℝ)`. It also starts lowercase (\"a function\") and drops a word (\"if is measurable\"). The module docstring entry has the same \"if is measurable\". Neither says that `κ` should be finite.","fix":"Rewrite the docstring with `q : ℚ` and `Iic (q : ℝ)`, capitalise it, fix \"if it is measurable\" (in the module docstring too), and mention that `κ` is meant to be finite.","ev":"src.lean L64-68: \"a function `f : α × β → ℚ → ℝ` ... if is measurable, if `fun b ↦ f (a, b) x` is `(ν a)`-integrable for all `a : α` and `x : ℝ` ... `∫ b in s, f (a, b) x ∂(ν a) = (κ a).real (s ×ˢ Iic x)`\" vs fields L74-76 `integrable (a : α) (q : ℚ)`, `setIntegral ... (q : ℚ) : ... (κ a).real (s ×ˢ Iic (q : ℝ))`; module doc L36-37 \"if is measurable\"","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a5383d","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.setLIntegral_stieltjesOfMeasurableRat","line":117,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"long-proof-golfable","claim":"The declaration is 55 lines, with a 51-line proof. It handles `(ν a).restrict s = 0` in a 13-line case whose only purpose is to discharge the `hμ : μ ≠ 0` hypothesis of `lintegral_iInf_directed_of_measurable` (that lemma uses `hμ` only when the index type is empty). It also has leftovers: the case hypothesis is named `hρ_zero` although no `ρ` is in scope, and `exists_rat_gt x` is invoked three times. A 19-line proof compiles, with the whole file building against it.","fix":"Replace the proof with the calc version from the probe: rewrite with `ENNReal.ofReal_iInf` and `StieltjesFunction.iInf_rat_gt_eq`, apply `lintegral_iInf_directed_of_measurable` (the zero-measure case becomes `simp [hρ]`), and finish with a real-`x` version of `Measure.iInf_rat_gt_prod_Iic`.","ev":"hunts/cdf-kernel/batch0/probe2.lean (copy of src.lean with this proof replaced by a 19-line calc; whole file compiles, `#print axioms` clean via check2.lean); original L117-171 = 55 lines vs replacement 23 lines including the statement","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6ca3fa","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.setLIntegral_stieltjesOfMeasurableRat","line":133,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"inline-reproof-of-existing-lemma","claim":"Two blocks of the proof re-prove existing results inline. (1) The 15-line `have h` (L133-147) derives `ofReal (F x) = ⨅ r : {r' : ℚ // x < r'}, ofReal (F r)` through `measure_stieltjesOfMeasurableRat_Iic` and `Monotone.measure_iInter`. That is `StieltjesFunction.iInf_rat_gt_eq` (Mathlib/MeasureTheory/Measure/Stieltjes.lean:153, `⨅ r : { r' : ℚ // x < r' }, f r = f x`) combined with `ENNReal.ofReal_iInf`, a one-line `rw`. (2) The final 8-line block (L164-171) is the real-`x` version of `Measure.iInf_rat_gt_prod_Iic`, which the same file states later (L326) only for rational `t`. A real-`t` lemma covers both, and the rational case follows in 2 lines.","fix":"Use `StieltjesFunction.iInf_rat_gt_eq` with `ENNReal.ofReal_iInf`. Generalise `Measure.iInf_rat_gt_prod_Iic` to a real `t` placed before this lemma, keep the rational version as a corollary, and call it here.","ev":"hunts/cdf-kernel/batch0/probe3.lean (F): `rw [← ENNReal.ofReal_iInf, StieltjesFunction.iInf_rat_gt_eq]` proves the `h` statement; (E): `iInf_rat_gt_prod_Iic_real` (real x) and the rational `Measure.iInf_rat_gt_prod_Iic` statement from it via `Equiv.subtypeEquivRight ... |>.iInf_congr`; probe2.lean uses both in the full file","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-da093a","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.integrable_stieltjesOfMeasurableRat","line":179,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-finiteness-instance","claim":"`[IsFiniteKernel κ]` is redundant. The current proof needs it only because it goes through `lintegral_stieltjesOfMeasurableRat` and the finiteness of `κ a (univ ×ˢ Iic x)`. Instead, for a rational `q > x`, `0 ≤ F(a,b) x ≤ F(a,b) q` holds and `F(a,·) q =ᵐ f(a,·) q` is integrable by `hf.integrable`, so `Integrable.mono'` gives the result for any `κ`, `ν`. Both in-file consumers (`setIntegral_stieltjesOfMeasurableRat`, `isCondKernelCDF_stieltjesOfMeasurableRat`) still compile, and there are no consumers outside the file.","fix":"Drop `[IsFiniteKernel κ]` and prove the lemma by domination by the value at a rational `q > x`, a 6-line proof.","ev":"hunts/cdf-kernel/batch0/probe1.lean (A): `theorem integrable_stieltjesOfMeasurableRat' (hf : IsRatCondKernelCDF f κ ν) (a : α) (x : ℝ) : Integrable (fun b ↦ stieltjesOfMeasurableRat f hf.measurable (a, b) x) (ν a) := by obtain ⟨q, hq⟩ := exists_rat_gt x; refine ((hf.integrable a q).congr (stieltjesOfMeasurableRat_ae_eq hf a q).symm).mono' ((measurable_stieltjesOfMeasurableRat hf.measurable x).comp measurable_prodMk_left).aestronglyMeasurable (ae_of_all _ fun b ↦ ?_); rw [Real.norm_of_nonneg (stieltjesOfMeasurableRat_nonneg _ _ _)]; exact (stieltjesOfMeasurableRat f hf.measurable (a, b)).mono hq.le`; probe2.lean compiles the whole file with the instance removed","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-eb0e24","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.integral_stieltjesOfMeasurableRat","line":206,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"redundant-special-case-of-general-lemma","claim":"`integral_stieltjesOfMeasurableRat hf a x` is exactly `(isCondKernelCDF_stieltjesOfMeasurableRat hf).integral a x`, with the same hypotheses ([IsFiniteKernel κ], hf), using the general `IsCondKernelCDF.integral` (L417) and `isCondKernelCDF_stieltjesOfMeasurableRat` (L434) from the same file. It has no consumer anywhere in Mathlib (git grep origin/master: only its own declaration), so it is a redundant special case. The [IsFiniteKernel κ] hypothesis itself is needed (with ν a = 0 and a κ a carrying infinite mass on every interval just above x0, the real-valued junk makes the conclusion fail), so this is a reuse finding, not a generality one.","fix":"Delete it, or move it after `isCondKernelCDF_stieltjesOfMeasurableRat` and prove it as `(isCondKernelCDF_stieltjesOfMeasurableRat hf).integral a x`.","ev":"hunts/cdf-kernel/batch1/probe1.lean section P1:\nexample [IsFiniteKernel κ] (hf : IsRatCondKernelCDF f κ ν) (a : α) (x : ℝ) :\n    ∫ b, stieltjesOfMeasurableRat f hf.measurable (a, b) x ∂(ν a)\n      = (κ a).real (univ ×ˢ Iic x) :=\n  (isCondKernelCDF_stieltjesOfMeasurableRat hf).integral a x","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b38355","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.IsRatCondKernelCDFAux","line":221,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"redundant-structure-field","claim":"The field `nonneg'` is implied by the other fields with no extra assumptions: `integrable` and `setIntegral` give `0 ≤ ∫ c in A, f (a, c) q ∂ν a = (κ a).real (…)` for every measurable A, so `ae_nonneg_of_forall_setIntegral_nonneg` yields `0 ≤ᵐ f (a, ·) q`. Dropping the field and deriving `IsRatCondKernelCDFAux.nonneg` this way leaves the whole file compiling. Under the finiteness assumptions that the only consumer (`isRatCondKernelCDF`: [IsFiniteKernel κ] [IsFiniteKernel ν]) and both constructors (CondCDF.isRatCondKernelCDFAux_preCDF, StandardBorel.isRatCondKernelCDFAux_density_Iic) work in, `mono'` (from `ae_le_of_forall_setIntegral_le` + `measureReal_mono`, needs κ finite) and `integrable` (from `measurable` + `nonneg'` + `le_one'` via `Integrable.of_bound`, needs ν finite) also follow. So every constructor must supply three derivable fields. (`le_one'` is not redundant: β = Bool, ν a = δ_true + δ_false, f(a,true) = 2F, f(a,false) = 0 satisfies all other fields.)","fix":"Remove the `nonneg'` field and derive `IsRatCondKernelCDFAux.nonneg` from `integrable` + `setIntegral` via `ae_nonneg_of_forall_setIntegral_nonneg`, and consider also deriving `mono'`/`integrable` under the finiteness hypotheses used by `isRatCondKernelCDF`.","ev":"hunts/cdf-kernel/batch1/probe1.lean sections P2 (nonneg' from integrable+setIntegral, no finiteness), P3 (mono' under [IsFiniteKernel κ]), P4 (integrable under [IsFiniteKernel ν]); hunts/cdf-kernel/batch1/copy.lean = src.lean with the `nonneg'` field deleted and\n  lemma IsRatCondKernelCDFAux.nonneg … := ae_all_iff.mpr fun q ↦ ae_nonneg_of_forall_setIntegral_nonneg (hf.integrable a q)\n    fun _ hs _ ↦ (hf.setIntegral a hs q).symm ▸ measureReal_nonneg\n(whole file compiles, exit 0)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-67d1e2","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.IsRatCondKernelCDFAux","line":221,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-omits-finiteness-junk-real","claim":"The docstring says unconditionally \"This property implies `IsRatCondKernelCDF`\", but the implication (`IsRatCondKernelCDFAux.isRatCondKernelCDF`) needs [IsFiniteKernel κ] [IsFiniteKernel ν], and without finiteness of ν it is false because of a junk value. The field `tendsto_integral_of_monotone` uses `(ν a).real univ`, which is `(∞).toReal = 0` for infinite ν a. With ν = const (∞ • dirac ()), κ = 0, f = 0, `IsRatCondKernelCDFAux` holds but `IsRatCondKernelCDF` fails, since f does not tend to 1. Also, the explanations on the two `tendsto_integral_*` fields are plain `/- -/` comments rather than `/-- -/` field docstrings, so they never reach the docs.","fix":"Say \"for finite kernels `κ` and `ν`, this property implies `IsRatCondKernelCDF`\" (noting that `(ν a).real univ` is meaningful only for finite `ν a`) and turn the two field comments into `/--` docstrings.","ev":"hunts/cdf-kernel/batch1/probe1.lean section junk (P10):\nnoncomputable def νinf : Kernel Unit Unit := Kernel.const Unit ((∞ : ℝ≥0∞) • Measure.dirac ())\nlemma νinf_real_univ : (νinf ()).real univ = 0 := by simp [νinf, Measure.real]\nexample : IsRatCondKernelCDFAux (0 : Unit × Unit → ℚ → ℝ) (0 : Kernel Unit (Unit × ℝ)) νinf where … (all fields by ae_of_all / simp / integrable_zero)\nexample : ¬ IsRatCondKernelCDF (0 : Unit × Unit → ℚ → ℝ) (0 : Kernel Unit (Unit × ℝ)) νinf := by\n  intro h; have h1 := h.tendsto_atTop_one (); … obtain ⟨b, hb⟩ := h1.exists\n  exact one_ne_zero (tendsto_nhds_unique hb tendsto_const_nhds)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-97057b","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.IsRatCondKernelCDFAux.tendsto_zero_of_antitone","line":261,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"needless-isfinitekernel","claim":"[IsFiniteKernel ν] is not needed. The proof uses it only to get `integrable_const _` for the limit function `fun _ ↦ 0`, and `integrable_zero` works for any measure. Mathematically, a decreasing nonneg sequence dominated by the integrable f(a,·)(seq 0) with integrals tending to 0 tends to 0 a.e. for any ν.","fix":"Drop `[IsFiniteKernel ν]` and replace `integrable_const _` by `integrable_zero _ _ _`.","ev":"hunts/cdf-kernel/batch1/probe1.lean P5 (theorem tendsto_zero_of_antitone' without [IsFiniteKernel ν], `refine tendsto_of_integral_tendsto_of_antitone ?_ (integrable_zero _ _ _) ?_ ?_ ?_`, rest of proof unchanged); also hunts/cdf-kernel/batch1/copy.lean (whole file compiles with the instance removed)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-9397ca","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.IsRatCondKernelCDFAux.tendsto_atBot_zero","line":293,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"needless-isfinitekernel","claim":"[IsFiniteKernel ν] is not needed. It is used only through `tendsto_zero_of_antitone`, which holds for any ν (finding on L261), and the unchanged proof compiles without the instance. By contrast, `tendsto_atTop_one` genuinely needs ν finite: in the νinf example (P10), f = 0 satisfies the structure but does not tend to 1.","fix":"Drop `[IsFiniteKernel ν]` (after dropping it from `tendsto_zero_of_antitone`).","ev":"hunts/cdf-kernel/batch1/probe1.lean P6 (theorem tendsto_atBot_zero' (hf : IsRatCondKernelCDFAux f κ ν) (a : α) : ∀ᵐ t ∂(ν a), Tendsto (f (a, t)) atBot (𝓝 0) with the original proof); also hunts/cdf-kernel/batch1/copy.lean","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c6ab29","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.IsRatCondKernelCDFAux.integrable_iInf_rat_gt","line":312,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"needless-isfinitekernel","claim":"[IsFiniteKernel ν] is not needed. For a.e. t, `0 ≤ ⨅ r : Ioi q, f (a, t) r ≤ f (a, t) (q + 1)`, and `f (a, ·) (q + 1)` is integrable by the `integrable` field, so `Integrable.mono'` gives integrability for any ν. The proof only uses finiteness to bound the eLpNorm by `ν a univ`. Its consumers `setIntegral_iInf_rat_gt` and `iInf_rat_gt_eq` (batch 2) inherit the instance.","fix":"Drop `[IsFiniteKernel ν]` and prove it by `Integrable.mono'` against `hf.integrable a (q + 1)`.","ev":"hunts/cdf-kernel/batch1/probe1.lean P7 and hunts/cdf-kernel/batch1/copy.lean:\nlemma IsRatCondKernelCDFAux.integrable_iInf_rat_gt (hf : IsRatCondKernelCDFAux f κ ν)\n    (a : α) (q : ℚ) :\n    Integrable (fun t ↦ ⨅ r : Ioi q, f (a, t) r) (ν a) := by\n  refine (hf.integrable a (q + 1)).mono'\n    (Measurable.iInf fun _ ↦ hf.measurable_right a _).aestronglyMeasurable ?_\n  filter_upwards [hf.bddBelow_range a, hf.nonneg a] with t hbdd h_nonneg\n  rw [Real.norm_eq_abs, abs_of_nonneg (le_ciInf fun r ↦ h_nonneg _)]\n  exact ciInf_le (hbdd q) ⟨q + 1, by simp⟩","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d2932f","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"MeasureTheory.Measure.iInf_rat_gt_prod_Iic","line":329,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"rational-special-case-of-real-lemma","claim":"Stated only for a rational point `t : ℚ`, but the same proof works for a real `t` (the index stays `{ r' : ℚ // t < r' }`). `setLIntegral_stieltjesOfMeasurableRat` (L164-171) re-proves that real-`t` statement inline, line for line (`Monotone.measure_iInter`, `prod_iInter`, `le_of_forall_lt_rat_imp_le`, ...). With `t : ℝ` that 8-line block becomes one `exact`, and the rational form is a 2-line corollary.","fix":"State the lemma for `t : ℝ` (keep the ℚ form as a corollary or adapt its two callers), and replace L164-171 of `setLIntegral_stieltjesOfMeasurableRat` with `exact Measure.iInf_rat_gt_prod_Iic hs x`.","ev":"hunts/cdf-kernel/batch2/src_mod.lean (a copy of src.lean, compiled with `lake env lean`, exit 0, no warnings): adds\nlemma _root_.MeasureTheory.Measure.iInf_rat_gt_prod_Iic_real {ρ : Measure (α × ℝ)}\n    [IsFiniteMeasure ρ] {s : Set α} (hs : MeasurableSet s) (t : ℝ) :\n    ⨅ r : { r' : ℚ // t < r' }, ρ (s ×ˢ Iic (r : ℝ)) = ρ (s ×ˢ Iic t) := by\n  obtain ⟨q, hq⟩ := exists_rat_gt t\n  have : Nonempty { r' : ℚ // t < r' } := ⟨⟨q, hq⟩⟩\n  rw [← Monotone.measure_iInter]\n  · rw [← prod_iInter]; congr with x : 1\n    simp only [mem_iInter, mem_Iic, Subtype.forall]\n    exact ⟨le_of_forall_lt_rat_imp_le, fun hxt q htq ↦ hxt.trans htq.le⟩\n  · exact fun r r' hrr' ↦ prod_mono_right <| by gcongr\n  · exact fun _ => (hs.prod measurableSet_Iic).nullMeasurableSet\n  · exact ⟨⟨q, hq⟩, measure_ne_top ρ _⟩\n-- in setLIntegral_stieltjesOfMeasurableRat, L164-171 replaced by:\n  exact Measure.iInf_rat_gt_prod_Iic_real hs x\n-- and the original ℚ lemma reproved as:\n  rw [← Measure.iInf_rat_gt_prod_Iic_real hs (t : ℝ)]\n  exact (Equiv.subtypeEquivRight fun r ↦ Rat.cast_lt.symm).iInf_congr fun _ ↦ rfl","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-cb0ba4","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"MeasureTheory.Measure.iInf_rat_gt_prod_Iic","line":329,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"general-lemma-in-specialised-file","claim":"A fact about an arbitrary finite measure on `α × ℝ`. The statement uses only Mathlib measure notions and the proof does not depend on kernels. It is declared as `_root_.MeasureTheory.Measure.…` inside `Probability/Kernel/Disintegration/CDFToKernel.lean`, so it cannot be found where measure-continuity lemmas live. Its consumers are this file (L359) and `CondCDF.lean:79` (`iInf_IicSnd_gt`).","fix":"Move it, in its real-`t` form, to a measure-theory file, e.g. next to `Monotone.measure_iInter` / `Real.iUnion_Iic_rat`.","ev":"measured: `git grep -n iInf_rat_gt_prod_Iic origin/master -- Mathlib` -> definition at CDFToKernel.lean:329, uses at CDFToKernel.lean:359 and CondCDF.lean:79 only; the statement mentions only `Measure`, `IsFiniteMeasure`, `MeasurableSet`, `×ˢ`, `Iic`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-76d88c","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.IsCondKernelCDF","line":402,"sev":"MINOR","status":"confirmed","cat":"correctness","pattern":"toreal-junk-in-structure-field","claim":"The field `setIntegral` compares with `(κ a).real (s ×ˢ Iic x)`, and `ENNReal.toReal ∞ = 0`, so the structure does not pin κ down when κ is infinite. `IsCondKernelCDF (fun _ ↦ cdf (dirac 0)) (Kernel.const Unit (∞ • dirac ((),0))) 0` holds, yet `0 ⊗ₖ toKernel f = 0 ≠ κ`, so f is not a conditional CDF of κ in any sense. No false theorem results: `setLIntegral`, `lintegral` and `compProd_toKernel` all assume `[IsFiniteKernel κ]`, and the probe shows that `setLIntegral` is false without it. But the structure, its docstring and its fields never say that κ must be finite; only the module header's \"two finite kernels\" does.","fix":"State in the docstring that the notion is meant for finite κ (`(κ a).real` sends `∞` to `0`), or phrase the integral condition in `ℝ≥0∞` (`∫⁻ b in s, ofReal (f (a, b) x) ∂ν a = κ a (s ×ˢ Iic x)`).","ev":"hunts/cdf-kernel/batch2/probe1.lean section (A) (compiles):\nnoncomputable def κInf : Kernel Unit (Unit × ℝ) :=\n  Kernel.const Unit (∞ • Measure.dirac (((), (0 : ℝ)) : Unit × ℝ))\nnoncomputable def fDirac : Unit × Unit → StieltjesFunction ℝ := fun _ ↦ cdf (Measure.dirac (0 : ℝ))\ntheorem isCondKernelCDF_junk : IsCondKernelCDF fDirac κInf (0 : Kernel Unit Unit) where\n  measurable _ := measurable_const\n  integrable _ _ := by rw [Kernel.zero_apply]; exact integrable_zero_measure\n  tendsto_atTop_one _ := tendsto_cdf_atTop _\n  tendsto_atBot_zero _ := tendsto_cdf_atBot _\n  setIntegral _ s _ x := by\n    rw [Kernel.zero_apply, Measure.restrict_zero, integral_zero_measure]\n    simp only [κInf, Kernel.const_apply, measureReal_def, Measure.smul_apply, smul_eq_mul,\n      ENNReal.toReal_mul, ENNReal.toReal_top, zero_mul]\nexample : (0 : Kernel Unit Unit) ⊗ₖ isCondKernelCDF_junk.toKernel fDirac ≠ κInf := ...\nexample : ¬ (∫⁻ b in univ, ENNReal.ofReal (fDirac ((), b) 0) ∂((0 : Kernel Unit Unit) ()) =\n    κInf () (univ ×ˢ Iic 0)) := ...  -- so `IsCondKernelCDF.setLIntegral` needs `[IsFiniteKernel κ]`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-bdced2","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.setLIntegral_toKernel_univ","line":483,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-forced-parameter-lemma","claim":"Since `hf.toKernel f` is Markov, the LHS `∫⁻ b in s, hf.toKernel f (a, b) univ ∂(ν a)` of `setLIntegral_toKernel_univ` (and `∫⁻ b, … univ ∂(ν a)` of `lintegral_toKernel_univ`) is just `ν a s` — `simp` rewrites it so. What these lemmas really say is that `IsCondKernelCDF f κ ν` with `κ` finite forces `ν = Kernel.fst κ` (hence `IsFiniteKernel ν`), and the file never states this characteristic fact. Both Mathlib consumers indeed use `ν = fst κ` (`isCondKernelCDF_condKernelCDF : IsCondKernelCDF (condKernelCDF κ) κ (fst κ)`, `isCondKernelCDF_condCDF : … (Kernel.const Unit ρ) (Kernel.const Unit ρ.fst)`). Also `setLIntegral_toKernel_univ` is just the `t = univ` case of `setLIntegral_toKernel_prod` once the latter is proved without it (see the reuse finding on `setLIntegral_toKernel_prod`).","fix":"Add `IsCondKernelCDF.eq_fst [IsFiniteKernel κ] (hf) : ν = Kernel.fst κ` and `IsCondKernelCDF.isFiniteKernel`, and state the univ lemmas (if kept) as `ν a s = κ a (s ×ˢ univ)`.","ev":"hunts/cdf-kernel/batch3/probeA.lean, P3/P4/P8:\nexample (hf : IsCondKernelCDF f κ ν) (a : α) (s : Set β) :\n    ∫⁻ b in s, hf.toKernel f (a, b) univ ∂(ν a) = ν a s := by simp\ntheorem IsCondKernelCDF.eq_fst' [IsFiniteKernel κ] (hf : IsCondKernelCDF f κ ν) :\n    ν = Kernel.fst κ := by\n  ext a s hs\n  rw [Kernel.fst_apply, Measure.map_apply measurable_fst hs, ← prod_univ]\n  simpa using setLIntegral_toKernel_univ hf a hs\ntheorem IsCondKernelCDF.isFiniteKernel' [IsFiniteKernel κ] (hf : IsCondKernelCDF f κ ν) :\n    IsFiniteKernel ν := by\n  rw [hf.eq_fst']; infer_instance\n-- exit 0","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-fe72a4","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.setLIntegral_toKernel_prod","line":506,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reproves-measure-ext-of-iic","claim":"The 36-line π-system induction (`MeasurableSpace.induction_on_inter` over `borel_eq_generateFrom_Iic`, with an `ENNReal` subtraction `compl` case that needs the separate 15-line `setLIntegral_toKernel_univ`) re-derives `MeasureTheory.Measure.ext_of_Iic` (Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean:522: `theorem ext_of_Iic … (μ ν : Measure α) [IsFiniteMeasure μ] (h : ∀ a, μ (Iic a) = ν (Iic a)) : μ = ν`). Applied to the finite measure `((κ a).restrict (s ×ˢ univ)).map Prod.snd` and `((ν a).restrict s).bind (fun b ↦ hf.toKernel f (a, b))` (via `Measure.bind_apply`), the lemma follows from `setLIntegral_toKernel_Iic` alone in ~10 lines, and `setLIntegral_toKernel_univ` becomes its `t = univ` instance.","fix":"Prove it by `Measure.ext_of_Iic` on the two measures in `t` (probe P7) and derive `setLIntegral_toKernel_univ` from it (or drop it).","ev":"hunts/cdf-kernel/batch3/probeA.lean, P7/P8:\ntheorem setLIntegral_toKernel_prod' [IsFiniteKernel κ] (hf : IsCondKernelCDF f κ ν)\n    (a : α) {s : Set β} (hs : MeasurableSet s) {t : Set ℝ} (ht : MeasurableSet t) :\n    ∫⁻ b in s, hf.toKernel f (a, b) t ∂(ν a) = κ a (s ×ˢ t) := by\n  have hm : AEMeasurable (fun b ↦ hf.toKernel f (a, b)) ((ν a).restrict s) :=\n    ((hf.toKernel f).measurable.comp measurable_prodMk_left).aemeasurable\n  have key {u : Set ℝ} (hu : MeasurableSet u) :\n      ((κ a).restrict (s ×ˢ univ)).map Prod.snd u = κ a (s ×ˢ u) := by\n    rw [Measure.map_apply measurable_snd hu, Measure.restrict_apply (measurable_snd hu)]\n    congr 1; ext; simp [and_comm]\n  have h : ((κ a).restrict (s ×ˢ univ)).map Prod.snd\n      = ((ν a).restrict s).bind fun b ↦ hf.toKernel f (a, b) :=\n    Measure.ext_of_Iic _ _ fun x ↦ by\n      rw [key measurableSet_Iic, Measure.bind_apply measurableSet_Iic hm,\n        setLIntegral_toKernel_Iic hf a x hs]\n  rw [← Measure.bind_apply ht hm, ← h, key ht]\nexample … : ∫⁻ b in s, hf.toKernel f (a, b) univ ∂(ν a) = κ a (s ×ˢ univ) :=\n  setLIntegral_toKernel_prod' hf a hs .univ\n-- exit 0","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-f3c1aa","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.setLIntegral_toKernel_prod","line":506,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"long-proof","claim":"Proof is 36 lines (L509-544), over the 30-line threshold, with a hand-rolled `ENNReal`-subtraction complement step (`lintegral_sub`, `measure_sdiff`, `prod_sdiff_prod`) and an `iUnion` case binder `f` that shadows the section's Stieltjes family `f`.","fix":"Replace by the ~10-line `Measure.ext_of_Iic` proof from the reuse finding.","ev":"measured: `awk 'NR>=509&&NR<=544' src.lean | wc -l` = 36; L537 `| iUnion f hf_disj hf_meas ihf =>` shadows `f : α × β → StieltjesFunction ℝ`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ce47ae","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.lintegral_toKernel_mem","line":547,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reproves-measure-ext-prod","claim":"`lintegral_toKernel_mem` is `(ν ⊗ₖ hf.toKernel f) a s = κ a s` unfolded through `Kernel.compProd_apply`, and its 61-line π-system induction over `generateFrom_prod`/`isPiSystem_prod` re-derives `MeasureTheory.Measure.ext_prod` (Mathlib/MeasureTheory/Measure/Prod.lean:613: `lemma ext_prod … {μ ν : Measure (α × β)} [IsFiniteMeasure μ] (h : ∀ {s t}, MeasurableSet s → MeasurableSet t → μ (s ×ˢ t) = ν (s ×ˢ t)) : μ = ν`). Its only consumer is `compProd_toKernel`, which follows in 4 lines from `Measure.ext_prod`, `Kernel.compProd_apply_prod` (CompProd.lean:137: `(κ ⊗ₖ η) a (s ×ˢ t) = ∫⁻ b in s, η (a, b) t ∂(κ a)`) and `setLIntegral_toKernel_prod`; `lintegral_toKernel_mem` is then two rewrites (`← Kernel.compProd_apply hs, compProd_toKernel`). The chain `lintegral_toKernel_univ` → `lintegral_toKernel_mem` exists only for this.","fix":"Prove `compProd_toKernel` by `ext a : 1; symm; refine Measure.ext_prod fun hs ht ↦ ?_; rw [Kernel.compProd_apply_prod hs ht, setLIntegral_toKernel_prod hf a hs ht]` and derive (or drop) `lintegral_toKernel_mem` from it.","ev":"hunts/cdf-kernel/batch3/probeA.lean, P5/P6:\ntheorem compProd_toKernel' [IsFiniteKernel κ] (hf : IsCondKernelCDF f κ ν) :\n    ν ⊗ₖ hf.toKernel f = κ := by\n  have := hf.isFiniteKernel'\n  ext a : 1\n  symm\n  refine Measure.ext_prod fun hs ht ↦ ?_\n  rw [Kernel.compProd_apply_prod hs ht, setLIntegral_toKernel_prod hf a hs ht]\nexample [IsFiniteKernel κ] (hf : IsCondKernelCDF f κ ν) (a : α) {s : Set (β × ℝ)}\n    (hs : MeasurableSet s) :\n    ∫⁻ b, hf.toKernel f (a, b) (Prod.mk b ⁻¹' s) ∂(ν a) = κ a s := by\n  have := hf.isFiniteKernel'\n  rw [← Kernel.compProd_apply hs, compProd_toKernel' hf]\n-- exit 0","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-77699e","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.lintegral_toKernel_mem","line":547,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"long-proof","claim":"Proof is 61 lines (L550-610), over 50 (MINOR under the Mathlib calibration); it also shadows `a : α` by `a : β` in `fun a ha` (L563) and `intro a hat₁` (L571).","fix":"Replace by the two-line derivation from `compProd_toKernel` (proved via `Measure.ext_prod`) in the reuse finding.","ev":"measured: `awk 'NR>=550&&NR<=610' src.lean | wc -l` = 61.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-64b51c","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.compProd_toKernel","line":612,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"derivable-typeclass-hypothesis","claim":"`[IsSFiniteKernel ν]` is redundant: `hf : IsCondKernelCDF f κ ν` with `[IsFiniteKernel κ]` already forces `ν = Kernel.fst κ` (from `setLIntegral_toKernel_univ`, since `hf.toKernel f` is Markov), so `IsFiniteKernel ν` is derivable and the theorem holds without the instance argument. (`[IsFiniteKernel κ]` itself is needed: with `ν a = 0` and `κ a = ∞ • δ`, `IsCondKernelCDF` holds via `ENNReal.toReal ∞ = 0` but `ν ⊗ₖ _ = 0 ≠ κ`.) Both consumers instantiate `ν = fst κ`, so the extra hypothesis is harmless there.","fix":"Drop `[IsSFiniteKernel ν]` and obtain the instance inside the proof from a new `IsCondKernelCDF.isFiniteKernel`.","ev":"hunts/cdf-kernel/batch3/probeA.lean, P4/P5: `theorem compProd_toKernel' [IsFiniteKernel κ] (hf : IsCondKernelCDF f κ ν) : ν ⊗ₖ hf.toKernel f = κ := by have := hf.isFiniteKernel'; …` (no `[IsSFiniteKernel ν]`), with `IsCondKernelCDF.isFiniteKernel'` proved from `setLIntegral_toKernel_univ` — exit 0","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-f0cafa","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.compProd_toKernel","line":612,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"missing-docstring-main-theorem","claim":"`compProd_toKernel` is the file's main theorem (listed under 'Main statements' in the module docstring and used by `Kernel.condKernel` in StandardBorel.lean) but has no docstring; Mathlib's documentation guideline requires one for major theorems.","fix":"Add a docstring, e.g. `/-- A conditional kernel CDF of a finite kernel κ with respect to ν gives a disintegration: ν ⊗ₖ hf.toKernel f = κ. -/`.","ev":"measured: src.lean L611 is `` (blank) and L612 starts `lemma compProd_toKernel` — no `/--` docstring.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-a7cd4b","file":"Mathlib/Probability/Kernel/IonescuTulcea/Maps.lean","decl":"IicProdIoc_comp_restrict₂","line":76,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `restrict₂_comp_IicProdIoc` (Probability.Kernel.IonescuTulcea.Maps), `IicProdIoc_comp_restrict₂` (Probability.Kernel.IonescuTulcea.Maps) state exactly the same thing (Lean-checked). Reviewer: Same file, identical statement `restrict₂ _ ∘ IicProdIoc a b = Prod.snd` and identical proof; only `a b` explicit vs implicit. The composition is `restrict₂ ∘ IicProdIoc`, so `IicProdIoc_comp_restrict₂` is misnamed; keep `restrict₂_comp_IicProdIoc` (matches sibling `frestrictLe₂_comp_IicProdIoc`), deprecate the other (one use, PartialTraj.lean:237).","fix":"Deprecate `IicProdIoc_comp_restrict₂` in favour of `restrict₂_comp_IicProdIoc`.","ev":"dupscan/Check.lean: `example := (@IicProdIoc_comp_restrict₂ : type_of% @restrict₂_comp_IicProdIoc)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 13, rating MAJOR): Endpoint explicitness offers modest convenience, but the discarded name describes the composition in the wrong order. The correctly named survivor provides the same result without losing automation.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-e2a228","file":"Mathlib/Probability/Kernel/Posterior.lean","decl":"(file)","line":26,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-drops-hypothesis","claim":"The module docstring advertises `posterior_comp_self : κ†μ ∘ₘ κ ∘ₘ μ = μ` and `posterior_posterior : (κ†μ)†(κ ∘ₘ μ) =ᵐ[μ] κ` without the `[IsMarkovKernel κ]` they need (for a finite non-Markov kernel the recovered prior is `μ.withDensity (fun ω ↦ κ ω univ)`; e.g. `Unit` spaces, `κ () = 2 • δ ()`), and calls the posterior 'a Markov kernel such that …' without saying it is only determined `κ ∘ₘ μ`-a.e. (arbitrary on predictive-null observations); `posterior_id`'s docstring says 'is the identity kernel' while the statement is `=ᵐ[μ]` (Astra A1 items 3, 8).","fix":"State the Markov assumption and the a.e. nature in the module docstring and in `posterior_id`'s docstring.","ev":"Measured: module docstring L26-30 vs `posterior_comp_self [IsMarkovKernel κ]` L125 and `posterior_posterior [IsMarkovKernel κ]` L177; `posterior_id` docstring L129 vs statement `=ᵐ[μ]` L130.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-4b86a6","file":"Mathlib/Probability/Kernel/Posterior.lean","decl":"posterior","line":70,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"definition-repeats-existing-body","claim":"`posterior κ μ := ((μ ⊗ₘ κ).map Prod.swap).condKernel` repeats the body of the (irreducible) `condDistrib Prod.fst Prod.snd (μ ⊗ₘ κ) = ((μ ⊗ₘ κ).map fun p ↦ (p.2, p.1)).condKernel` instead of reusing it, and no lemma connects the two, so `condDistrib`'s API (a.e. uniqueness, `compProd_map_condDistrib`, …) and the posterior API cannot be transported to each other without unfolding `condDistrib_def`. The posterior is a meaningful named concept, so this is a missing bridge, not a second construction.","fix":"Add `posterior_eq_condDistrib : κ†μ = condDistrib Prod.fst Prod.snd (μ ⊗ₘ κ)` (or define `posterior` through `condDistrib`).","ev":"hunts/posterior/probe1.lean: `posterior κ μ = condDistrib Prod.fst Prod.snd (μ ⊗ₘ κ)` by `rw [condDistrib_def]; rfl` compiles (master 4e77f237dc2); `grep condDistrib Posterior.lean` finds nothing.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-bba3ef","file":"Mathlib/Probability/Kernel/Posterior.lean","decl":"rnDeriv_posterior_ae_prod","line":233,"sev":"MINOR","status":"suspected","cat":"generality","pattern":"unneeded-hypothesis","claim":"Astra A1 item 1 (not compiled): the `h_ac : ∀ᵐ ω ∂μ, κ ω ≪ κ ∘ₘ μ` hypothesis of `rnDeriv_posterior_ae_prod`/`rnDeriv_posterior`/`rnDeriv_posterior_symm` is unnecessary (both sides are densities of the a.c. part of the same joint measure; `rnDeriv_measure_compProd_right` + `MeasurableEmbedding.rnDeriv_map` would give it without `h_ac`); example κ(ω) = ½δ_ω + ½μ on [0,1]. Also (items 2, 4-7): `Kernel.absolutelyContinuous_comp_of_absolutelyContinuous` should not need `StandardBorelSpace Ω`/`Nonempty Ω`/`CountableOrCountablyGenerated` and belongs with composition lemmas; `[IsFiniteKernel η]` in `ae_eq_posterior_of_compProd_eq` could be `[IsSFiniteKernel η]`; `deterministic_comp_posterior` could assume `[IsDeterministic κ]`; `posterior_comp_self`/`posterior_posterior` need only a.e. normalisation.","fix":"Check each generalisation in Lean; drop `h_ac` from the RN lemmas if it holds.","ev":"Suspected: Astra A1 items 1, 2, 4-7 (Lean proofs not attempted).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-bbbd22","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.evariance","line":58,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-const-simp-lemma","claim":"There is no lemma for the `evariance` of a constant. With `[IsProbabilityMeasure μ]`, `simp` makes no progress on `eVar[fun _ ↦ c; μ] = 0`, although `simp [evariance]` proves it. The covariance API has the analogues `covariance_const_left`/`_right` (@[simp]), and conditional variance has `condVar_const`.","fix":"Add `@[simp] lemma evariance_const [IsProbabilityMeasure μ] (c : ℝ) : eVar[fun _ ↦ c; μ] = 0 := by simp [evariance]`.","ev":"hunts/variance/batch0/probe1.lean lines 78-79 (`example [IsProbabilityMeasure μ] (c : ℝ) : eVar[fun _ ↦ c; μ] = 0 := by simp` -> error: `simp` made no progress) and lines 85-86 (`... := by simp [evariance]` compiles)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-43e6e6","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.evariance","line":59,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"definition-docstring-hides-measure-convention","claim":"`evariance`/`variance` and their notations are documented as the variance of a random variable, but they accept any measure and centre with the unnormalised integral `μ[X]`; outside probability measures they are not a variance: under `2 • dirac ()` the constant `1` has `Var = 2` (and translating by a constant changes the variance). The docstrings do not say that the probability-measure interpretation is intended or what happens otherwise.","fix":"Say in the docstrings that these are the variance when `μ` is a probability measure and describe the extension (centering by the unnormalised integral) otherwise.","ev":"hunts/variance/astra/probe.lean: `Var[fun _ : Unit ↦ (1 : ℝ); (2 : ℝ≥0∞) • Measure.dirac ()] = 2` by `simp [variance, evariance, …]; norm_num` compiles (exit 0). Raised by Astra's A1 pass (item 1).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-cbe9b9","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance","line":64,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-const-simp-lemma","claim":"Two pieces of characteristic `variance` API are missing. (1) There is no `variance_const`: with `[IsProbabilityMeasure μ]`, `simp` makes no progress on `Var[fun _ ↦ c; μ] = 0`, while `covariance_const_left`/`_right` and `condVar_const` exist. (2) There is no `variance_eq_zero_iff`: only the forward direction `ae_eq_integral_of_variance_eq_zero` exists. The iff follows in two lines from `evariance_eq_zero_iff`. The WIP upstream PR #26291 (Cameron-Martin, blocked, merge-conflict) adds a `variance_eq_zero_iff`.","fix":"Add `@[simp] variance_const [IsProbabilityMeasure μ] (c : ℝ) : Var[fun _ ↦ c; μ] = 0` and `variance_eq_zero_iff [IsFiniteMeasure μ] (hX : MemLp X 2 μ) : Var[X; μ] = 0 ↔ ∀ᵐ ω ∂μ, X ω = μ[X]`.","ev":"hunts/variance/batch0/probe1.lean line 76 (`example [IsProbabilityMeasure μ] (c : ℝ) : Var[fun _ ↦ c; μ] = 0 := by simp` -> `simp` made no progress); lines 82-83 (`rw [← covariance_self aemeasurable_const]; simp` compiles); lines 89-92 (`Var[X; μ] = 0 ↔ ∀ᵐ ω ∂μ, X ω = μ[X]` via `ae_eq_integral_of_variance_eq_zero` + `evariance_eq_zero_iff` compiles)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-a263a4","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.evariance_eq_top","line":111,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-finite-measure-instance","claim":"`[IsFiniteMeasure μ]` is not needed. For any measure, an a.e.-strongly-measurable `X` that is not in L² has `evariance X μ = ∞`. If `μ[X] = 0` this is immediate. If `μ[X] = c ≠ 0`, then `X` is integrable, and finite evariance would give `X - c ∈ L²`, so the constant `c` would be bounded by `2|X| + 4/|c|·(X-c)²` and hence integrable, which forces `μ` to be finite. Two downstream lemmas carry the hypothesis only because of this one and become hypothesis-free (beyond measurability): `variance_of_not_memLp` and `memLp_two_of_variance_ne_zero`. `evariance_eq_top_iff` and `evariance_lt_top_iff_memLp` still need it for their other direction.","fix":"Drop `[IsFiniteMeasure μ]` from `evariance_eq_top`, `variance_of_not_memLp` and `memLp_two_of_variance_ne_zero`, using the proof in the probe.","ev":"hunts/variance/batch0/Variance_gen.lean (a copy of src.lean with `evariance_eq_top` restated without `[IsFiniteMeasure μ]`, plus `variance_of_not_memLp` and `memLp_two_of_variance_ne_zero` without it; the whole file compiles with the prescribed -D flags); standalone version `Probe.evariance_eq_top'` in hunts/variance/batch0/probe1.lean lines 19-55","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-6a2e99","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_of_not_memLp","line":134,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-finite-measure-assumption","claim":"`[IsFiniteMeasure μ]` is redundant: for any measure, an a.e.-strongly-measurable X that is not in L² has evariance = ∞, hence Var = 0. (If X - μ[X] were in L² with μ[X] ≠ 0, X is integrable and the space is covered by two finite-measure sets, so μ is finite and X ∈ L²; if μ[X] = 0 then X - μ[X] = X.) The root over-restriction is `evariance_eq_top` (batch 0), which this lemma inherits; it is used in CovarianceBilin.lean:95 and Variance.lean:237.","fix":"Drop `[IsFiniteMeasure μ]` from `evariance_eq_top`, `variance_of_not_memLp` and `memLp_two_of_variance_ne_zero`, proving `evariance_eq_top` by the finite-measure-covering argument in the probe.","ev":"hunts/variance/batch1/Probe1.lean, section P1: `theorem evariance_eq_top' (hXm : AEStronglyMeasurable X μ) (hX : ¬MemLp X 2 μ) : evariance X μ = ∞` proved with NO finiteness assumption (if X - μ[X] ∈ L² and μ[X] ≠ 0 then X is integrable, so univ ⊆ {|μ[X]|/2 ≤ ‖X‖} ∪ {|μ[X]|/2 ≤ ‖X - μ[X]‖} has finite measure by Integrable.measure_norm_ge_lt_top and MemLp.meas_ge_lt_top, hence memLp_const_iff gives the constant in L²); then `theorem variance_of_not_memLp' (hX : AEStronglyMeasurable X μ) (hX_not : ¬ MemLp X 2 μ) : variance X μ = 0 := by simp [variance, evariance_eq_top' hX hX_not]` and `theorem memLp_two_of_variance_ne_zero' (hX : AEStronglyMeasurable X μ) (h : Var[X; μ] ≠ 0) : MemLp X 2 μ := by contrapose h; exact variance_of_not_memLp' hX h` all compile (lake env lean, no errors in P1).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-fdef78","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.memLp_two_of_variance_ne_zero","line":138,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-finite-measure-assumption","claim":"`[IsFiniteMeasure μ]` is redundant: Var[X; μ] ≠ 0 with X a.e.-strongly measurable forces MemLp X 2 μ for every measure μ (contrapositive of the generalised `variance_of_not_memLp`). Consumer: CentralLimitTheorem.lean:103.","fix":"Drop `[IsFiniteMeasure μ]` once `variance_of_not_memLp` is generalised; the proof is unchanged.","ev":"hunts/variance/batch1/Probe1.lean, section P1: `theorem evariance_eq_top' (hXm : AEStronglyMeasurable X μ) (hX : ¬MemLp X 2 μ) : evariance X μ = ∞` proved with NO finiteness assumption (if X - μ[X] ∈ L² and μ[X] ≠ 0 then X is integrable, so univ ⊆ {|μ[X]|/2 ≤ ‖X‖} ∪ {|μ[X]|/2 ≤ ‖X - μ[X]‖} has finite measure by Integrable.measure_norm_ge_lt_top and MemLp.meas_ge_lt_top, hence memLp_const_iff gives the constant in L²); then `theorem variance_of_not_memLp' (hX : AEStronglyMeasurable X μ) (hX_not : ¬ MemLp X 2 μ) : variance X μ = 0 := by simp [variance, evariance_eq_top' hX hX_not]` and `theorem memLp_two_of_variance_ne_zero' (hX : AEStronglyMeasurable X μ) (h : Var[X; μ] ≠ 0) : MemLp X 2 μ := by contrapose h; exact variance_of_not_memLp' hX h` all compile (lake env lean, no errors in P1).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-25de86","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.ofReal_variance","line":140,"sev":"MINOR","status":"suspected","cat":"api","pattern":"hypothesis-stronger-than-needed","claim":"Astra argues (not formalised here) that several results are stated under `[IsFiniteMeasure μ]` + `MemLp X 2 μ` where the primitive condition is `eVar[X; μ] ≠ ∞`: `ofReal_variance`, real Chebyshev `meas_ge_le_variance_div_sq` and `ae_eq_integral_of_variance_eq_zero` would apply to infinite measures under that condition (e.g. counting measure on ℕ with `X = 𝟙{0} - 𝟙{1}`); and the `IsZeroOrProbabilityMeasure` weakening also applies to `evariance_def'`, `variance_le_expectation_sq` and `variance_le_sq_of_bounded` (but not to `variance_le_sub_mul_sub`).","fix":"Add `eVar ≠ ∞` versions and derive the current forms; weaken the probability instance where the zero-measure case is trivial.","ev":"Suspected: Astra's A1 items 7-8 (paper arguments); not compiled here.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-876229","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.ae_eq_integral_of_variance_eq_zero","line":161,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-drops-hypothesis","claim":"Docstrings drop the L² hypothesis that the statements carry: `ae_eq_integral_of_variance_eq_zero` says 'A random variable with variance `0` is almost surely constant' (the lemma needs `MemLp X 2 μ`), `IndepFun.variance_add` says the variance of an independent sum is the sum of the variances (needs `MemLp` for both), and the module's main-results list states `IndepFun.variance_add`/`variance_sum` and real Chebyshev without `MemLp X 2 μ` (and `0 < c`). Read literally with Mathlib's convention `Var[X] = 0` for infinite variance (`variance_of_not_memLp`), these summaries are false (a heavy-tailed `X` has `Var[X] = 0` without being a.s. constant).","fix":"Say 'An `L²` random variable …' in these docstrings and add the `MemLp`/`0 < c` hypotheses to the module's main-results summaries.","ev":"Doc-only finding: L161 docstring vs L162 `(hX : MemLp X 2 μ)`; L407 docstring vs L408 `(hX : MemLp X 2 μ)`; module docstring L27-34; `variance_of_not_memLp` gives `Var[X] = 0` for measurable non-L² `X`. Raised by Astra's A1 pass (items 2-3).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-ad2385","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.ae_eq_integral_of_variance_eq_zero","line":162,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"reproves-sibling-lemma","claim":"The 8-line proof (rewrite to a Bochner integral, integral_eq_zero_iff_of_nonneg, a hand-built integrability proof via sub_sq, then simp/grind) re-derives the forward direction of `evariance_eq_zero_iff` (line 181), from which the statement follows in one line via `ofReal_variance`.","fix":"Move the lemma below `evariance_eq_zero_iff` and prove it as `(evariance_eq_zero_iff hX.aemeasurable).1 (by rw [← ofReal_variance hX, h, ENNReal.ofReal_zero])`.","ev":"hunts/variance/batch1/Probe1.lean, section P2: `example [IsFiniteMeasure μ] (hX : MemLp X 2 μ) (h : Var[X; μ] = 0) : ∀ᵐ ω ∂μ, X ω = μ[X] := (evariance_eq_zero_iff hX.aemeasurable).1 (by rw [← ofReal_variance hX, h, ENNReal.ofReal_zero])` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-16c12a","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.covariance_self","line":197,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"main-statement-listed-in-wrong-module-doc","claim":"The module docstring of Mathlib/Probability/Moments/Covariance.lean lists `covariance_self: cov[X, X; μ] = Var[X; μ]` under 'Main statements', but the lemma is declared in Variance.lean (Covariance.lean cannot state it, since it does not import `variance`). Variance.lean's own module docstring does not mention it, and the lemma has no docstring.","fix":"Move the `covariance_self` bullet from Covariance.lean's module docstring to Variance.lean's 'Main results' (or say it lives in `Mathlib.Probability.Moments.Variance`).","ev":"measured: `git grep -n covariance_self origin/master -- Mathlib/Probability/Moments/Covariance.lean` gives only line 25 (the module-doc bullet); the declaration is Variance.lean:197.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-e4bd5c","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_nonneg","line":204,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-positivity-extension","claim":"`variance` has no `positivity` extension: `positivity` fails on `0 ≤ Var[X; μ]` and on `0 < 1 + Var[X; μ]`, although `Measure.real` (a similar `ENNReal.toReal` wrapper) has one (`evalMeasureReal`). Consumers write `variance_nonneg _ _` by hand (StrongLaw.lean:433,459; Gaussian/Basic.lean:167,179,221; CentralLimitTheorem.lean:113; Fernique.lean:234).","fix":"Add a `@[positivity ProbabilityTheory.variance _ _]` extension returning `variance_nonneg`, modelled on `evalMeasureReal`.","ev":"hunts/variance/batch2/Probe1.lean P1 (lines 11-12): `example : 0 ≤ Var[X; μ] := by positivity` and `example : 0 < 1 + Var[X; μ] := by positivity` both fail with `failed to prove positivity/nonnegativity/nonzeroness`; P2 (lines 17-29): after `@[positivity ProbabilityTheory.variance _ _] meta def evalVarianceProbe : PositivityExt where eval {_ _} _zα pα? e := match pα? with | none => pure .none | some _ => do let .app (.app _ a) b ← whnfR e | throwError \"not variance\"; let p ← mkAppOptM ``ProbabilityTheory.variance_nonneg #[none, none, a, b]; pure (.nonnegative p)` both examples compile.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-8455c2","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_eq_sub","line":226,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"probability-measure-to-zero-or-probability","claim":"`[IsProbabilityMeasure μ]` can be weakened to `[IsZeroOrProbabilityMeasure μ]` (the zero-measure case closes by `simp`), as `centralMoment_one` and `cgf_zero` already do; the weaker class covers conditional measures `μ[|s]`, which are only `IsZeroOrProbabilityMeasure`.","fix":"State it with `[IsZeroOrProbabilityMeasure μ]` and split on `eq_zero_or_isProbabilityMeasure μ`.","ev":"hunts/variance/batch2/Probe1.lean P4: `lemma variance_eq_sub' [IsZeroOrProbabilityMeasure μ] (hX : MemLp X 2 μ) : Var[X; μ] = μ[X ^ 2] - μ[X] ^ 2 := by rcases eq_zero_or_isProbabilityMeasure μ with rfl | _; · simp; · exact variance_eq_sub hX` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-14045e","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_add_const","line":230,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"probability-measure-to-zero-or-probability","claim":"`[IsProbabilityMeasure μ]` can be weakened to `[IsZeroOrProbabilityMeasure μ]` (the zero measure is trivial). As stated the lemma does not apply to a conditional measure `μ[|s]`, where `failed to synthesize IsProbabilityMeasure μ[|s]`, but the weakened version does. Being a probability measure (or zero) is necessary: for `μ = 2 • dirac`, `Var[fun _ ↦ 1] = 2 ≠ 0 = Var[0]`.","fix":"Use `[IsZeroOrProbabilityMeasure μ]` and split on `eq_zero_or_isProbabilityMeasure μ` (and likewise for `variance_const_add`, `variance_sub_const`, `variance_const_sub`).","ev":"hunts/variance/batch2/Probe1.lean P4 (lines 56-81): `lemma variance_add_const' [IsZeroOrProbabilityMeasure μ] (hX : AEStronglyMeasurable X μ) (c : ℝ) : Var[fun ω ↦ X ω + c; μ] = Var[X; μ] := by rcases eq_zero_or_isProbabilityMeasure μ with rfl | _; · simp; · exact variance_add_const hX c` compiles and applies to `μ[|s]`; `variance_add_const hX c` on `μ[|s]` fails with `failed to synthesize IsProbabilityMeasure μ[|s]`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-4a2d46","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_add_const","line":230,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"Unlike its covariance counterpart `covariance_add_const_left` (Covariance.lean:88, `@[simp]` with an `Integrable` side condition), `variance_add_const` is not `@[simp]`, so `simp [hX]` makes no progress on `Var[fun ω ↦ X ω + c; μ] = Var[X; μ]` while the covariance analogue closes. With the attribute, `simp [hX]` and `simp (disch := fun_prop)` close it.","fix":"Tag `variance_add_const` `@[simp]`, matching `covariance_add_const_left`.","ev":"hunts/variance/batch2/Probe1.lean P5 line 86: `example [IsProbabilityMeasure μ] (hX : AEStronglyMeasurable X μ) (c : ℝ) : Var[fun ω ↦ X ω + c; μ] = Var[X; μ] := by simp [hX]` fails with `simp made no progress`; line 90, the covariance analogue, compiles; hunts/variance/batch2/Probe2.lean (with `attribute [local simp] variance_add_const variance_const_add`) the same `simp [hX]` compiles.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-9dbed9","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_const_add","line":243,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"probability-measure-to-zero-or-probability","claim":"As for `variance_add_const`: `[IsProbabilityMeasure μ]` can be weakened to `[IsZeroOrProbabilityMeasure μ]`, which lets the lemma apply to conditional measures `μ[|s]`.","fix":"Use `[IsZeroOrProbabilityMeasure μ]`.","ev":"hunts/variance/batch2/Probe1.lean P4: `lemma variance_const_add' [IsZeroOrProbabilityMeasure μ] (hX : AEStronglyMeasurable X μ) (c : ℝ) : Var[fun ω ↦ c + X ω; μ] = Var[X; μ] := by rcases eq_zero_or_isProbabilityMeasure μ with rfl | _; · simp; · exact variance_const_add hX c` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-f0e679","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_const_add","line":243,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`variance_const_add` is not `@[simp]`, unlike `covariance_const_add_left` (Covariance.lean:96); `simp [hX]` makes no progress on `Var[fun ω ↦ c + X ω; μ] = Var[X; μ]`.","fix":"Tag `variance_const_add` `@[simp]`, matching `covariance_const_add_left`.","ev":"hunts/variance/batch2/Probe1.lean P5 line 88: `... Var[fun ω ↦ c + X ω; μ] = Var[X; μ] := by simp [hX]` fails with `simp made no progress`; hunts/variance/batch2/Probe2.lean with the local simp attribute the same call compiles.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-48ebb3","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_fun_neg","line":247,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`variance_fun_neg` is not `@[simp]`, though its lambda LHS is simp-normal and holds with no hypotheses. Its covariance analogues `covariance_fun_neg_left/right` and `condVar_neg` are `@[simp]`. Without the tag `simp` cannot close `Var[fun ω ↦ -X ω; μ] = Var[X; μ]`. Tagging `variance_neg` alone does not cover the lambda form, because simp does not rewrite `fun ω ↦ -X ω` to `-X`. A simp-tagged copy passes `#lint only simpNF`.","fix":"Tag `variance_fun_neg` with `@[simp]`, matching `covariance_fun_neg_left`.","ev":"hunts/variance/batch3/Probe1.lean (P1, P1b, P1c): `example : Var[fun ω ↦ -X ω; μ] = Var[X; μ] := by fail_if_success simp; exact variance_fun_neg` compiles; with only `attribute [local simp] variance_neg`, `by simp` gives `simp made no progress` (line 24); `@[simp] theorem probe_variance_fun_neg ... := variance_fun_neg` + `#lint only simpNF` -> All linting checks passed","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-f0c40c","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_neg","line":252,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`variance_neg : Var[-X; μ] = Var[X; μ]` holds with no hypotheses but is not `@[simp]`, unlike `covariance_neg_left/right` (Covariance.lean) and `condVar_neg` (CondVar.lean). `simp` cannot prove it. Tagged copies pass `#lint only simpNF`, and with the tag `simp [variance_const_mul]` proves `Var[fun ω ↦ -(c * X ω); μ] = c ^ 2 * Var[X; μ]`.","fix":"Tag `variance_neg` with `@[simp]`, matching `covariance_neg_left` and `condVar_neg`.","ev":"hunts/variance/batch3/Probe1.lean (P1, P1c): `example : Var[-X; μ] = Var[X; μ] := by fail_if_success simp; exact variance_neg` compiles; `example : cov[-X, Y; μ] = -cov[X, Y; μ] := by simp` compiles; `@[simp] theorem probe_variance_neg : Var[-X; μ] = Var[X; μ] := variance_neg` + `#lint only simpNF` passes","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-1f3330","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_sub_const","line":254,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"probability-measure-instead-of-zero-or-probability","claim":"`[IsProbabilityMeasure μ]` can be weakened to `[IsZeroOrProbabilityMeasure μ]`, since the statement is trivial for `μ = 0`. Kernel fibres of an `IsZeroOrMarkovKernel` have this weaker instance, and Moments/Basic.lean already uses it (`centralMoment_one`, `cgf_zero`). It cannot be weakened to `IsFiniteMeasure`: for `μ = 2 • dirac ()`, `Var[fun _ ↦ 0 - 1; μ] ≠ Var[fun _ ↦ 0; μ]`, which was checked in Lean. The `AEStronglyMeasurable` hypothesis is needed: a non-measurable indicator gives different junk lintegrals for `X` and `X - c`. This was argued on paper, not in Lean.","fix":"State it, together with `variance_add_const` and `variance_const_add`, under `[IsZeroOrProbabilityMeasure μ]`, splitting with `eq_zero_or_isProbabilityMeasure μ`.","ev":"hunts/variance/batch3/Probe1.lean (P2, P2b): `example [IsZeroOrProbabilityMeasure μ] (hX : AEStronglyMeasurable X μ) (c : ℝ) : Var[fun ω ↦ X ω - c; μ] = Var[X; μ] := by rcases eq_zero_or_isProbabilityMeasure μ with rfl | _; · simp; · exact variance_sub_const hX c` compiles; counterexample `Var[fun _ : Unit ↦ (0 : ℝ) - 1; (2 : ℝ≥0∞) • Measure.dirac ()] ≠ Var[fun _ : Unit ↦ (0 : ℝ); (2 : ℝ≥0∞) • Measure.dirac ()]` compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-1c57e2","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_sub_const","line":254,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`variance_sub_const` is not `@[simp]`, while its covariance analogue `covariance_sub_const_left/right` (Covariance.lean, hypothesis `Integrable X μ`) is. `simp [hX]` cannot prove `Var[fun ω ↦ X ω - 3; μ] = Var[X; μ]`, but it can with the attribute, and a simp-tagged copy passes simpNF.","fix":"Tag `variance_sub_const`, and `variance_add_const`/`variance_const_add`, with `@[simp]`, matching `covariance_sub_const_left`.","ev":"hunts/variance/batch3/Probe2.lean (Q1): `example [IsProbabilityMeasure μ] (hX : AEStronglyMeasurable X μ) : Var[fun ω ↦ X ω - 3; μ] = Var[X; μ] := by fail_if_success simp [hX]; exact variance_sub_const hX 3` compiles; with `attribute [local simp] variance_sub_const`, `by simp [hX]` closes it; `#lint only simpNF` on the tagged copy passes","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-821bc2","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_const_sub","line":258,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"probability-measure-instead-of-zero-or-probability","claim":"As with `variance_sub_const`, `[IsProbabilityMeasure μ]` can be weakened to `[IsZeroOrProbabilityMeasure μ]` (the `μ = 0` case is trivial). A finite measure is not enough.","fix":"State it under `[IsZeroOrProbabilityMeasure μ]`, splitting with `eq_zero_or_isProbabilityMeasure μ`.","ev":"hunts/variance/batch3/Probe1.lean (P2): `example [IsZeroOrProbabilityMeasure μ] (hX : AEStronglyMeasurable X μ) (c : ℝ) : Var[fun ω ↦ c - X ω; μ] = Var[X; μ] := by rcases eq_zero_or_isProbabilityMeasure μ with rfl | _; · simp; · exact variance_const_sub hX c` compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-777e1a","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_const_sub","line":258,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`variance_const_sub` is not `@[simp]`, while `covariance_const_sub_left/right` is. `simp [hX]` cannot prove `Var[fun ω ↦ 3 - X ω; μ] = Var[X; μ]`, but it can with the attribute, and a simp-tagged copy passes simpNF.","fix":"Tag `variance_const_sub` with `@[simp]`, matching `covariance_const_sub_left`.","ev":"hunts/variance/batch3/Probe2.lean (Q1): `example [IsProbabilityMeasure μ] (hX : AEStronglyMeasurable X μ) : Var[fun ω ↦ 3 - X ω; μ] = Var[X; μ] := by fail_if_success simp [hX]; exact variance_const_sub hX 3` compiles; with the local simp attribute `by simp [hX]` closes it; simpNF passes on the tagged copy","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-7044d4","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_dirac","line":312,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"missing-measurable-dirac-variant","claim":"`variance_dirac` assumes `[MeasurableSingletonClass Ω]`, but `Var[X; Measure.dirac x] = 0` also holds for every measurable `X` on any measurable space. Mathlib has such companions for integrals (`integral_dirac'` with `StronglyMeasurable f`, `lintegral_dirac'` with `Measurable f`), but the variance has none. (The class cannot simply be dropped: without it and without measurability of `X`, `μ[X]` and `∫⁻` take junk/lower-integral values. This was argued on paper, not checked in Lean.)","fix":"Add `variance_dirac' (x : Ω) (hX : Measurable X) : Var[X; Measure.dirac x] = 0`, proved by `rw [variance_congr (ae_eq_dirac' hX)]; simp [variance, evariance]`.","ev":"hunts/variance/batch4/probe1.lean theorems P4a/P4b, e.g.\ntheorem P4a (x : Ω) (hX : Measurable X) : Var[X; Measure.dirac x] = 0 := by\n  rw [variance_congr (ae_eq_dirac' hX)]\n  simp [variance, evariance]\n(also added as `variance_dirac'` in hunts/variance/batch4/VarianceEdit.lean, which compiles)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-fab6b3","file":"Mathlib/Probability/Moments/Variance.lean","decl":"MeasureTheory.MeasurePreserving.variance_fun_comp","line":327,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-ae-companion","claim":"The proof uses only the a.e. content of `MeasurePreserving X μ ν` (`hX.aemeasurable`, `hX.map_eq`), so it does not need `Measurable X`. The a.e. companion is missing: HasLaw.lean has `HasLaw.covariance_comp` and `HasLaw.covariance_fun_comp`, but for the variance it has only `HasLaw.variance_eq`, which covers just the case `f = id`. There is no `HasLaw.variance_comp` or `HasLaw.variance_fun_comp` (checked with git grep).","fix":"Add `HasLaw.variance_fun_comp (hY : HasLaw Y ν μ) (hf : AEMeasurable f ν) : Var[fun ω ↦ f (Y ω); μ] = Var[f; ν]` and its `∘` form to HasLaw.lean, matching the covariance pair.","ev":"hunts/variance/batch4/probe1.lean theorem P5:\ntheorem P5 {𝓧 : Type*} {m𝓧 : MeasurableSpace 𝓧} {ν : Measure 𝓧} {Y : Ω → 𝓧}\n    (hY : HasLaw Y ν μ) {f : 𝓧 → ℝ} (hf : AEMeasurable f ν) :\n    Var[fun ω ↦ f (Y ω); μ] = Var[f; ν] := by\n  rw [← hY.map_eq, variance_map (hY.map_eq ▸ hf) hY.aemeasurable, Function.comp_def]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-12ef0b","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_map_equiv","line":333,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"equiv-where-embedding-suffices","claim":"The lemma needs `Y : Ω' ≃ᵐ Ω`, but the same one-line proof works for any `MeasurableEmbedding Y` (through `MeasurableEmbedding.lintegral_map` and `MeasurableEmbedding.integral_map`). That is the generality Mathlib uses for `integral_map` and `lintegral_map` on embeddings. `covariance_map_equiv` has the same restriction.","fix":"Add `MeasurableEmbedding.variance_map (hY : MeasurableEmbedding Y) (X : Ω → ℝ) : Var[X; μ.map Y] = Var[X ∘ Y; μ]` and derive `variance_map_equiv` as `Y.measurableEmbedding.variance_map X`. Do the same for covariance.","ev":"hunts/variance/batch4/probe1.lean theorem P2:\ntheorem P2 {Ω' : Type*} {mΩ' : MeasurableSpace Ω'} {μ : Measure Ω'} (X : Ω → ℝ) {Y : Ω' → Ω}\n    (hY : MeasurableEmbedding Y) : Var[X; μ.map Y] = Var[X ∘ Y; μ] := by\n  simp_rw [variance, evariance, hY.lintegral_map, hY.integral_map, Function.comp_apply]\n(also applied in hunts/variance/batch4/VarianceEdit.lean: variance_map_equiv := Y.measurableEmbedding.variance_map X, which compiles)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-69a3b5","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_le_expectation_sq","line":341,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"inline-rederivation-of-file-api","claim":"The proof (L343–L360, 18 lines) works out the non-L² case by hand, through `evariance_eq_lintegral_ofReal`, `integral_eq_lintegral_of_nonneg_ae`, two nested `by_cases`, and a rebuilt `MemLp` argument. The in-file lemma `variance_of_not_memLp` already gives `Var[X; μ] = 0` in that case, and with it the proof is 5 lines.","fix":"Replace the proof with `by_cases hX : MemLp X 2 μ; · rw [variance_eq_sub hX]; exact sub_le_self _ (sq_nonneg _); · rw [variance_of_not_memLp hm hX]; exact integral_nonneg fun _ ↦ sq_nonneg _`.","ev":"hunts/variance/batch4/probe1.lean theorem P3:\ntheorem P3 [IsProbabilityMeasure μ] (hm : AEStronglyMeasurable X μ) :\n    variance X μ ≤ μ[X ^ 2] := by\n  by_cases hX : MemLp X 2 μ\n  · rw [variance_eq_sub hX]\n    exact sub_le_self _ (sq_nonneg _)\n  · rw [variance_of_not_memLp hm hX]\n    exact integral_nonneg fun _ ↦ sq_nonneg _\n(also substituted in hunts/variance/batch4/VarianceEdit.lean, which compiles)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-db8cdf","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_le_expectation_sq","line":341,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"main-result-missing-docstring","claim":"The module docstring lists this lemma under 'Main results' (L27), but the declaration has no docstring of its own. L340 is blank, and it is the only main result in the list without one.","fix":"Add `/-- The variance is at most the second moment: `Var[X] ≤ 𝔼[X ^ 2]`. -/`.","ev":"src.lean L338–L341: `lemma variance_id_map …` (L338) / proof (L339) / blank (L340) / `theorem variance_le_expectation_sq [IsProbabilityMeasure μ] {X : Ω → ℝ}` (L341); no `/--` block","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-03c5a2","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.evariance_def'","line":362,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-measurability-hypothesis","claim":"The hypothesis `hX : AEStronglyMeasurable X μ` is not needed. If `X` is not a.e.-strongly measurable, then `μ[X] = 0` by `integral_undef`, and both sides reduce to `∫⁻ ω, ‖X ω‖ₑ ^ 2 ∂μ`. So the identity holds for every `X` under `[IsProbabilityMeasure μ]`.","fix":"Drop `hX` and handle the non-measurable case first with `simp [evariance, integral_undef (fun h ↦ hX h.1)]`. The lemma has no consumers in Mathlib.","ev":"hunts/variance/batch4/probe1.lean theorem P1:\ntheorem P1 [IsProbabilityMeasure μ] (X : Ω → ℝ) :\n    evariance X μ = (∫⁻ ω, ‖X ω‖ₑ ^ 2 ∂μ) - ENNReal.ofReal (μ[X] ^ 2) := by\n  by_cases hX : AEStronglyMeasurable X μ\n  · exact evariance_def' hX\n  · simp [evariance, integral_undef (fun h ↦ hX h.1)]\n(also applied to the declaration in hunts/variance/batch4/VarianceEdit.lean, which compiles)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-d4bdf0","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.IndepFun.variance_add","line":408,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-companion-lemma","claim":"There is no `IndepFun.variance_sub` / `IndepFun.variance_fun_sub` (Var[X - Y] = Var[X] + Var[Y] for independent L² X, Y). The file has the general `variance_sub`/`variance_fun_sub` and `IndepFun.variance_add`, and the missing lemma follows in one line via `IndepFun.neg_right`.","fix":"Add `IndepFun.variance_sub` (and the `fun` form) proved by `rw [sub_eq_add_neg, h.neg_right.variance_add hX hY.neg, variance_neg]`.","ev":"#check @ProbabilityTheory.IndepFun.variance_sub      -- error: Unknown constant\n#check @ProbabilityTheory.IndepFun.variance_fun_sub  -- error: Unknown constant\nexample {X Y : Ω → ℝ} (hX : MemLp X 2 μ) (hY : MemLp Y 2 μ) (h : X ⟂ᵢ[μ] Y) :\n    Var[X - Y; μ] = Var[X; μ] + Var[Y; μ] := by\n  rw [sub_eq_add_neg, h.neg_right.variance_add hX hY.neg, variance_neg]  -- compiles\n(hunts/variance/batch5/probe1.lean lines 9-15)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-f6b130","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.IndepFun.variance_sum","line":424,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-fun-variant","claim":"There is no `fun ω ↦ ∑ i ∈ s, X i ω` form (`IndepFun.variance_fun_sum`), although the file pairs `variance_sum'`/`variance_fun_sum'`, `variance_sum`/`variance_fun_sum` and `IndepFun.variance_add`/`IndepFun.variance_fun_add`. `rw [IndepFun.variance_sum hs h]` fails on that form, and callers need `convert!` plus `simp`.","fix":"Add `IndepFun.variance_fun_sum` (proof: `convert! IndepFun.variance_sum hs h; simp`).","ev":"example {ι : Type*} {X : ι → Ω → ℝ} {s : Finset ι} (hs : ∀ i ∈ s, MemLp (X i) 2 μ)\n    (h : Set.Pairwise ↑s fun i j => X i ⟂ᵢ[μ] X j) :\n    Var[fun ω ↦ ∑ i ∈ s, X i ω; μ] = ∑ i ∈ s, Var[X i; μ] := by\n  rw [IndepFun.variance_sum hs h]  -- error: did not find pattern Var[∑ i ∈ s, X i; μ]\n#check @ProbabilityTheory.IndepFun.variance_fun_sum  -- error: Unknown constant\n(hunts/variance/batch5/probe1.lean lines 17-30; the `convert! …; simp` variant compiles)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-b0dc01","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_dual_prod'","line":530,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"variance_dual_prod' does not use the section's `[NormedAddCommGroup E] [NormedSpace ℝ E]` (and the same for F). The same statement and proof compile under `[TopologicalSpace E] [AddCommGroup E] [Module ℝ E]`. Only the unprimed variance_dual_prod needs norms, for `MemLp id 2 μ`. It has one consumer (Gaussian/Basic.lean:264).","fix":"State variance_dual_prod' for topological vector spaces (`[TopologicalSpace E] [AddCommGroup E] [Module ℝ E]`) and keep the normed section for variance_dual_prod.","ev":"section TVS\nvariable {E F : Type*} [TopologicalSpace E] [AddCommGroup E] [Module ℝ E] {mE : MeasurableSpace E}\n  [TopologicalSpace F] [AddCommGroup F] [Module ℝ F] {mF : MeasurableSpace F}\n  {μ : Measure E} [IsProbabilityMeasure μ] {ν : Measure F} [IsProbabilityMeasure ν]\nlemma variance_dual_prod'_tvs {L : StrongDual ℝ (E × F)}\n    (hLμ : MemLp (L.comp (.inl ℝ E F)) 2 μ) (hLν : MemLp (L.comp (.inr ℝ E F)) 2 ν) :\n    Var[L; μ.prod ν] = Var[L.comp (.inl ℝ E F); μ] + Var[L.comp (.inr ℝ E F); ν] := by\n  have : L = fun x : E × F ↦ L.comp (.inl ℝ E F) x.1 + L.comp (.inr ℝ E F) x.2 := by\n    ext; rw [L.comp_inl_add_comp_inr]\n  rw [this, variance_add_prod hLμ hLν]\nend TVS\n(hunts/variance/batch5/probe2.lean)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261006-2a82b1","file":"Mathlib/Probability/Process/LimitProcess.lean","decl":"MeasureTheory.Filtration.limitProcess","line":163,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-claims-more","claim":"The `limitProcess` docstring says it picks g when \"g is ⨆ t, 𝓕 t-measurable (i.e. HasLimitProcess X 𝓕 P holds)\", but `HasLimitProcess` requires strong measurability, strictly stronger for non-separable codomains; the module docstring claims a strongly adapted process has a strongly measurable limit, which needs a countably generated atTop and a metrizable codomain; both cite `Submartingale.ae_tendsto_limitProcess` without its real-valued, ℕ-indexed scope; and the degenerate case atTop = ⊥ (e.g. ι empty), where every process has a limit process, is undocumented.","fix":"'strongly measurable'; qualify the module motivation; state the scope of the cited theorem.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-05665f","file":"Mathlib/Probability/Process/LimitProcess.lean","decl":"MeasureTheory.Filtration.memLp_limitProcess_of_eLpNorm_bdd","line":303,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-hypothesis","claim":"Redundant or too-narrow hypotheses: `memLp_limitProcess_of_eLpNorm_bdd`'s `hfm` (a.e.-strong measurability) follows from the finite bound `hbdd` via `aestronglyMeasurable_of_eLpNorm_ne_top`; `limitProcess_prodMk` forces both processes to take values in the same E although the same one-line proof covers `X : ι → Ω → E`, `Z : ι → Ω → F` (as `HasLimitProcess.prodMk` already does).","fix":"Drop `hfm`; generalise `limitProcess_prodMk` to two codomains.","ev":"example … (hbdd : ∀ n, eLpNorm (X n) p P ≤ R) : MemLp (limitProcess X 𝓕 P) p P :=\n  memLp_limitProcess_of_eLpNorm_bdd\n    (fun n ↦ aestronglyMeasurable_of_eLpNorm_ne_top ((hbdd n).trans_lt ENNReal.coe_lt_top).ne) hbdd\nexample … {X : ι → Ω → E} {Z : ι → Ω → F} (hX : HasLimitProcess X 𝓕 P) (hZ : HasLimitProcess Z 𝓕 P) :\n    𝓕.limitProcess (fun t ω ↦ (X t ω, Z t ω)) P =ᵐ[P] fun ω ↦ (𝓕.limitProcess X P ω, 𝓕.limitProcess Z P ω) :=\n  hX.limitProcess_comp₂ (f := fun x y ↦ (x, y)) continuous_id hZ","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-d8ebd2","file":"Mathlib/RepresentationTheory/Homological/GroupCohomology/Shapiro.lean","decl":"groupCohomology.linearYonedaObjResProjectiveResolutionIso","line":46,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`linearYonedaObjResProjectiveResolutionIso` takes a projective resolution `P` of the trivial representation but uses only its underlying complex: the identical proof gives `ChainComplex.linearYonedaObj ((resFunctor S.subtype).mapHomologicalComplex _ |>.obj C) k A ≅ C.linearYonedaObj k (coind S.subtype A)` for any chain complex `C` of G-representations (Astra notes it should even hold for any monoid hom φ). The projective-resolution packaging belongs only in `coindIso`.","fix":"State the helper for an arbitrary chain complex (ideally in `Rep`) and specialise.","ev":"noncomputable def linearYonedaObjResIso' (C : ChainComplex (Rep.{u} k G) ℕ) (A : Rep.{u} k S) :\n    ChainComplex.linearYonedaObj (((resFunctor S.subtype).mapHomologicalComplex _).obj C) k A ≅\n      C.linearYonedaObj k (coind S.subtype A) := <the file's proof, unchanged>\n-- hunts/shapiro/ProbeGen.lean compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b30d1c","file":"Mathlib/RepresentationTheory/Homological/GroupCohomology/Shapiro.lean","decl":"groupCohomology.coindIso","line":56,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"`coindIso : Hⁿ(G, Coind_S^G A) ≅ Hⁿ(S, A)` is built abstractly through resolutions, and the file proves nothing about it: no lemma identifies its forward map with the classical Shapiro map (restriction to S followed by evaluation at 1, i.e. `groupCohomology.map S.subtype (resCoindAdjunction.counit.app A) n`), no naturality in A (no `NatIso` `coindFunctor ⋙ functor k G n ≅ functor k S n`), no compatibility with `δ`, and no component simp lemmas for the helper. Mathlib has no other declaration mentioning it, so a user cannot compute with it on cocycles.","fix":"Prove `coindIso_hom_eq_map` (restriction + counit), package coefficient naturality as a NatIso, add `@[simps]` to the helper.","ev":"-- git grep 'coindIso\\b' finds only Rep.coindIso (Coinduced.lean, a different iso) besides this file's definition; no lemma has groupCohomology.coindIso in its statement","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-31f0cf","file":"Mathlib/RingTheory/AdicCompletion/RingHom.lean","decl":"(file)","line":21,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-swapped-roles","claim":"The module docstring's \"Main definitions\" entry swaps the roles of `R` and `S`: it says \"if `R` is `I`-adically complete, then a compatible family of ring maps `S →+* R ⧸ I ^ n` can be lifted to … `S →+* R`\", while `IsAdicComplete.liftRingHom` needs `S` complete and lifts `f n : R →+* S ⧸ I ^ n` to `R →+* S` (as the file's own opening paragraph says). It also cites `mk_liftRingHom_apply`, which does not exist (the lemma is `mk_liftRingHom`).","fix":"Swap `R`/`S` in the bullet and cite `mk_liftRingHom`.","ev":"Source L13–25 vs. L32–50; `git grep mk_liftRingHom_apply origin/master -- Mathlib`: only the docstring.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-e34e57","file":"Mathlib/RingTheory/AdicCompletion/RingHom.lean","decl":"IsAdicComplete.algHom_ext","line":127,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"complete-where-hausdorff-suffices","claim":"`IsAdicComplete.algHom_ext` (two algebra maps into `S` agreeing modulo every `I ^ n` are equal) assumes `[IsAdicComplete I S]` and commutative rings `R`, `A`, but only Hausdorffness is used: under `[IsHausdorff I S]`, `[CommSemiring K] [Semiring A]` it is `DFunLike.coe_injective` + `IsHausdorff.funext'`. Its current proof detours through `ofAlgEquiv`; e.g. `S = ℤ`, `I = (2)` (separated, not complete) is excluded.","fix":"Restate as `IsHausdorff.algHom_ext` under `[IsHausdorff I S]` with the 4-line proof, keeping the complete version as an alias.","ev":"probe2.lean: the `[IsHausdorff I S]`/`CommSemiring`/`Semiring` version compiles; applying `IsAdicComplete.algHom_ext` with only `[IsHausdorff I S]` fails to synthesize `IsAdicComplete I S`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-e81ff3","file":"Mathlib/RingTheory/Algebraic/Basic.lean","decl":"Algebra.IsAlgebraic.nontrivial","line":39,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Algebra.IsAlgebraic.nontrivial` (RingTheory.Algebraic.Basic), `Algebra.nontrivial_of_isAlgebraic` (RingTheory.Algebraic.Defs) state exactly the same thing (Lean-checked). Reviewer: `[Algebra.IsAlgebraic R A] → Nontrivial R` with (R A) explicit, proved in Defs and again in Basic. Keep `Algebra.nontrivial_of_isAlgebraic` (Defs, lower in the import graph), deprecate `Algebra.IsAlgebraic.nontrivial` (or move that name down to Defs if the `IsAlgebraic.nontrivial` naming family is preferred).","fix":"Deprecate `Algebra.IsAlgebraic.nontrivial` in favour of `Algebra.nontrivial_of_isAlgebraic`.","ev":"dupscan/Check.lean: `example := (@Algebra.nontrivial_of_isAlgebraic : type_of% @Algebra.IsAlgebraic.nontrivial)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 14, rating MAJOR): Both expose the same explicit parameters and typeclass assumption, with no distinguishing attributes. The theorem in `Defs` already supplies the necessary interface.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-d522c8","file":"Mathlib/RingTheory/Bialgebra/Equiv.lean","decl":"BialgEquiv.coe_coe","line":156,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `BialgEquiv.coe_toBialgHom` (RingTheory.Bialgebra.Equiv), `BialgEquiv.coe_coe` (RingTheory.Bialgebra.Equiv) state exactly the same thing (Lean-checked). Reviewer: `coe_coe` (@[simp, norm_cast]) and `coe_toBialgHom` (@[simp]) are both `⇑(e : A →ₐc[R] B) = e := rfl`, which makes two simp lemmas with the same LHS. Keep coe_toBialgHom, which matches the adjacent coe_toCoalgEquiv/coe_toAlgEquiv, and add norm_cast to it. Deprecate coe_coe; neither is used.","fix":"Deprecate `BialgEquiv.coe_coe` in favour of `BialgEquiv.coe_toBialgHom`.","ev":"dupscan/Check.lean: `example := (@BialgEquiv.coe_coe : type_of% @BialgEquiv.coe_toBialgHom)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 15, rating MAJOR): Both simplify the same coercion expression; combining `[simp, norm_cast]` on the survivor preserves their registered behavior.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-870bb8","file":"Mathlib/RingTheory/Bialgebra/Equiv.lean","decl":"BialgEquiv.coe_toCoalgEquiv","line":172,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `BialgEquiv.coe_toCoalgEquiv` (RingTheory.Bialgebra.Equiv), `BialgEquiv.coe_toAlgEquiv` (RingTheory.Bialgebra.Equiv) state exactly the same thing (Lean-checked). Reviewer: Copy-paste bug: `coe_toCoalgEquiv` states `⇑(e : A ≃ₐ[R] B) = e` (the AlgEquiv coercion) instead of `⇑(e : A ≃ₗc[R] B) = e`, making it a verbatim copy of `coe_toAlgEquiv`. Keep `coe_toAlgEquiv`; restate `coe_toCoalgEquiv` with the CoalgEquiv coercion rather than deprecating.","fix":"Deprecate `BialgEquiv.coe_toCoalgEquiv` in favour of `BialgEquiv.coe_toAlgEquiv`.","ev":"dupscan/Check.lean: `example := (@BialgEquiv.coe_toAlgEquiv : type_of% @BialgEquiv.coe_toCoalgEquiv)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 20, rating MINOR): The explicit coercion target contradicts `toCoalgEquiv`; the neighboring `coe_toAlgEquiv` removes the naming ambiguity. Correct: `⇑(e : A ≃ₗc[R] B) = e`. Both coercion routes retain the same underlying function, so this repairs the named simplification form without adding mathematical content. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/RingTheory/Bialgebra/Equiv.lean#L155-L184)","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-af2b24","file":"Mathlib/RingTheory/Bialgebra/GroupLike.lean","decl":"IsGroupLikeElem.one","line":27,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`IsGroupLikeElem.one` is not `@[simp]`, so `simp` cannot close `IsGroupLikeElem R (1 : A)` in a general bialgebra (the coalgebra file's `isGroupLikeElem_self` only covers `A = R`). `IsGroupLikeElem.mul`, `.pow` and the units lemma are the closure API, and `one` is the one proposition with no hypotheses that should simp to `True`.","fix":"Tag `IsGroupLikeElem.one` with `@[simp]`.","ev":"probe2.lean L5 `example : IsGroupLikeElem R (1 : A) := by simp` → `simp` made no progress.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-babe3a","file":"Mathlib/RingTheory/Bialgebra/GroupLike.lean","decl":"groupLikeSubmonoid","line":39,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-mem-lemma","claim":"`groupLikeSubmonoid R A` has no membership lemma: `a ∈ groupLikeSubmonoid R A ↔ IsGroupLikeElem R a` holds by `Iff.rfl`, but `simp` makes no progress on it. Nothing in Mathlib uses the submonoid, so the missing `mem_groupLikeSubmonoid` is the only way in.","fix":"Add `@[simp] lemma mem_groupLikeSubmonoid : a ∈ groupLikeSubmonoid R A ↔ IsGroupLikeElem R a := .rfl`.","ev":"probe1.lean L8 `example : a ∈ groupLikeSubmonoid R A ↔ IsGroupLikeElem R a := by simp` → `simp` made no progress; L9 `Iff.rfl` compiles.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d95810","file":"Mathlib/RingTheory/Bialgebra/GroupLike.lean","decl":"GroupLike.instCommMonoid","line":76,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"parallel-construction-no-bridge","claim":"The file builds the same monoid twice: `groupLikeSubmonoid R A` (whose coercion type `↥(groupLikeSubmonoid R A)` is already a monoid) and the structure `GroupLike R A`, with `One`, `Mul`, `Pow`, `Monoid` and `CommMonoid` instances transported by hand along `val_injective`. No `MulEquiv` connects the two (the coalgebra file's `GroupLike.valEquiv` to the subtype is a plain `Equiv`), and neither has any consumer of the other, so facts proved for one cannot be used on the other.","fix":"Either add `GroupLike.mulEquivSubmonoid : GroupLike R A ≃* groupLikeSubmonoid R A` (upgrading `valEquiv`), or derive the `GroupLike` monoid structure from the submonoid through that equivalence.","ev":"`grep -rnw 'groupLikeSubmonoid\\|valMonoidHom'` outside the file: no hits; `grep 'GroupLike R A ≃\\*'`: no hits. The only bridge is `GroupLike.valEquiv : GroupLike R A ≃ Subtype (IsGroupLikeElem R)` in `Coalgebra/GroupLike.lean:88`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-453d44","file":"Mathlib/RingTheory/DedekindDomain/AdicValuation.lean","decl":"IsDedekindDomain.HeightOneSpectrum.intValuation.map_zero'","line":101,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `IsDedekindDomain.HeightOneSpectrum.intValuationDef_zero` (RingTheory.DedekindDomain.AdicValuation), `IsDedekindDomain.HeightOneSpectrum.intValuation.map_zero'` (RingTheory.DedekindDomain.AdicValuation) state exactly the same thing (Lean-checked). Reviewer: Same file, nine lines apart, both `v.intValuationDef 0 = 0`; `intValuation.map_zero'` only mirrors the `Valuation` field name used when building `intValuation`. Keep the @[simp] `intValuationDef_zero` (fits the `intValuationDef_if_pos/neg` family), deprecate `intValuation.map_zero'` and fill the field with the kept lemma.","fix":"Deprecate `IsDedekindDomain.HeightOneSpectrum.intValuation.map_zero'` in favour of `IsDedekindDomain.HeightOneSpectrum.intValuationDef_zero`.","ev":"dupscan/Check.lean: `example := (@IsDedekindDomain.HeightOneSpectrum.intValuation.map_zero' : type_of% @IsDedekindDomain.HeightOneSpectrum.intValuationDef_zero)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup3 item 16, rating MINOR): `intValuation.map_zero'` belongs to the construction-axiom family alongside `map_one'`, `map_mul'`, and `map_add_le_max'`. Making it an alias preserves that coherent interface at negligible cost.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-57ab84","file":"Mathlib/RingTheory/DedekindDomain/AdicValuation.lean","decl":"IsDedekindDomain.HeightOneSpectrum.adicCompletion.valued_coe","line":761,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `IsDedekindDomain.HeightOneSpectrum.valuedAdicCompletion_eq_valuation'` (RingTheory.DedekindDomain.AdicValuation), `IsDedekindDomain.HeightOneSpectrum.adicCompletion.valued_coe` (RingTheory.DedekindDomain.AdicValuation) state exactly the same thing (Lean-checked). Reviewer: Same file, both prove `Valued.v (k : v.adicCompletion K) = v.valuation K k` separately (one via valued_toCompletion, one by simp), no comment. Keep the primed lemma (docstring, paired with the unprimed `r : R` version, used in LaurentSeries and FiniteAdeleRing); `adicCompletion.valued_coe` has no uses.","fix":"Deprecate `IsDedekindDomain.HeightOneSpectrum.adicCompletion.valued_coe` in favour of `IsDedekindDomain.HeightOneSpectrum.valuedAdicCompletion_eq_valuation'`.","ev":"dupscan/Check.lean: `example := (@IsDedekindDomain.HeightOneSpectrum.adicCompletion.valued_coe : type_of% @IsDedekindDomain.HeightOneSpectrum.valuedAdicCompletion_eq_valuation')` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 17, rating MAJOR): The documented, used pair for ring and field elements provides a reasonable canonical API. `adicCompletion.valued_coe` adds no distinct automation behavior.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-1cf048","file":"Mathlib/RingTheory/DedekindDomain/Ideal/Basic.lean","decl":"(module docstring)","line":13,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-drops-hypothesis","claim":"The module introduction and the `IsDedekindDomainInv` docstring say 'all fractional ideals are invertible' / 'every fractional ideal has an inverse', omitting 'nonzero' (0 is a fractional ideal and 0 * 0⁻¹ = 0). The docstring of `exists_multiset_prod_cons_le_and_prod_not_le` claims the product is made 'minimal', but the conclusion only says dropping M breaks containment (Z = {(3)}, I = M = (2) in ℤ satisfies it with a superfluous factor). Proof comments are stale: 'minimal set'/'contained in J' (it is a multiset and I), and `mul_inv_cancel_of_le_one` cites `exists_notMem_one_of_ne_bot`, a downstream lemma in Ideal/Lemmas.lean, though it uses `not_inv_le_one_of_ne_bot`; 'Main definitions' lists a theorem.","fix":"Add 'nonzero'; state the exact property about M; refresh the comments.","ev":"-- DedekindDomain/Ideal/Basic.lean:14 'all fractional ideals are invertible'; :219 'if every fractional ideal has an inverse'; :167 comment cites exists_notMem_one_of_ne_bot (defined in Ideal/Lemmas.lean:77)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d49ab1","file":"Mathlib/RingTheory/DedekindDomain/Ideal/Basic.lean","decl":"FractionalIdeal.coe_ideal_mul_inv","line":185,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"name-casing","claim":"`FractionalIdeal.coe_ideal_mul_inv` and `FractionalIdeal.one_mem_inv_coe_ideal` use the Lean 3 spelling `coe_ideal`, while the FractionalIdeal API uses `coeIdeal_*` (`coeIdeal_ne_zero`, `coeIdeal_le_coeIdeal`, …); the same split recurs in FractionalIdeal/Inverse.lean (`coe_ideal_le_self_mul_inv`, `coe_ideal_span_singleton_*`) and ClassGroup/Basic.lean.","fix":"Rename to `coeIdeal_mul_inv`, `one_mem_inv_coeIdeal` (with deprecated aliases).","ev":"-- git grep: DedekindDomain/Ideal/Basic.lean:70 one_mem_inv_coe_ideal, :185 coe_ideal_mul_inv; FractionalIdeal/Basic.lean has 26 `coeIdeal_` names","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c059f0","file":"Mathlib/RingTheory/DedekindDomain/Ideal/Basic.lean","decl":"FractionalIdeal.instPosMulReflectLEIdeal","line":372,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-instance","claim":"The file registers `PosMulReflectLE (Ideal A)` but not `MulPosReflectLE (Ideal A)` (`#synth` fails), although `PosMulReflectLE.toMulPosReflectLE` provides it, so order cancellation on ideals works on one side only. The `Ideal` instance is also declared inside `namespace FractionalIdeal` (named `FractionalIdeal.instPosMulReflectLEIdeal`).","fix":"Add `instance : MulPosReflectLE (Ideal A) := PosMulReflectLE.toMulPosReflectLE` and move both into `namespace Ideal`.","ev":"import Mathlib.RingTheory.DedekindDomain.Ideal.Basic\nvariable {A : Type*} [CommRing A] [IsDedekindDomain A]\n#synth PosMulReflectLE (Ideal A)   -- ok\n#synth MulPosReflectLE (Ideal A)   -- error: failed to synthesize","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-447074","file":"Mathlib/RingTheory/DedekindDomain/Ideal/Basic.lean","decl":"Ideal.dvdNotUnit_iff_lt","line":413,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reprovable-from-existing-api","claim":"Existing API is rebuilt: `Ideal.dvdNotUnit_iff_lt`'s 10-line term proof is `rw [← dvd_and_not_dvd_iff, Ideal.dvd_iff_le, Ideal.dvd_iff_le, lt_iff_le_not_ge]`; `mul_left_strictMono`/`mul_right_strictMono` are `strictMono_mul_right_of_pos`/`strictMono_mul_left_of_pos`; and `Ideal.strongNormalizationMonoid` duplicates an instance already found for ideals of any commutative semiring (`Ideal.uniqueUnits` + `instStrongNormalizationMonoid`). Astra also suggests `isIntegral_of_smul_mem_submodule` for the polynomial tail of `coe_ideal_mul_inv` and `Ideal.IsPrime.mul_le` in the UFM instance (untested).","fix":"Use the one-line proofs; drop the redundant normalization instance.","ev":"-- hunts/dedekind-ideal/ProbeCopy.lean: one-line dvdNotUnit_iff_lt and strictMono proofs compile\nimport Mathlib.Algebra.GCDMonoid.Basic\nimport Mathlib.RingTheory.Ideal.Operations\nexample (B : Type*) [CommSemiring B] : StrongNormalizationMonoid (Ideal B) := inferInstance  -- compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-e78e64","file":"Mathlib/RingTheory/DedekindDomain/Ideal/Basic.lean","decl":"Ideal.finiteMultiplicity","line":431,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"Several results assume Dedekind where much less is used: `Ideal.finiteMultiplicity` holds in every Noetherian domain (Krull intersection `Ideal.iInf_pow_eq_bot_of_isDomain`); `PrimeSpectrum.exists_multiset_prod_cons_le_and_prod_not_le` needs only `[IsDomain A] [IsNoetherianRing A] [Ring.DimensionLEOne A]` (a copy with that binder compiles), so it also covers non-normal domains like k[t²,t³]. Astra also notes (untested) that its `hNF : ¬IsField A` follows from `hI0`, `hIM` and maximality, and that `adjoinIntegral_eq_one_of_isUnit` holds over any localization.","fix":"State `finiteMultiplicity` for Noetherian domains (near Filtration) and weaken the prime-product lemma's binder.","ev":"example {B : Type*} [CommRing B] [IsDomain B] [IsNoetherianRing B]\n    {I J : Ideal B} (hI : I ≠ ⊤) (hJ : J ≠ ⊥) : FiniteMultiplicity I J := by\n  by_contra h\n  have hd : ∀ n : ℕ, I ^ n ∣ J := FiniteMultiplicity.not_iff_forall.mp h\n  apply hJ\n  apply eq_bot_iff.mpr\n  rw [← Ideal.iInf_pow_eq_bot_of_isDomain I hI]\n  exact le_iInf fun n => Ideal.le_of_dvd (hd n)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-39e171","file":"Mathlib/RingTheory/DividedPowers/RatAlgebra.lean","decl":"DividedPowers.OfInvertibleFactorial.dpow_null","line":73,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `DividedPowers.OfInvertibleFactorial.dpow_null` (RingTheory.DividedPowers.RatAlgebra), `DividedPowers.OfInvertibleFactorial.dpow_eq_of_notMem` (RingTheory.DividedPowers.RatAlgebra) state exactly the same thing (Lean-checked). Reviewer: Four lines apart with identical statement and proof (`simp [dpow, hx]`); `dpow_null` only mirrors the `DividedPowers.dpow_null` field name and is used to fill that field at lines 180/272. Keep `dpow_eq_of_notMem` (pairs with `dpow_eq_of_mem`, just renamed 2026-09-28), deprecate `dpow_null` and fill the fields with the kept lemma.","fix":"Deprecate `DividedPowers.OfInvertibleFactorial.dpow_null` in favour of `DividedPowers.OfInvertibleFactorial.dpow_eq_of_notMem`.","ev":"dupscan/Check.lean: `example := (@DividedPowers.OfInvertibleFactorial.dpow_eq_of_notMem : type_of% @DividedPowers.OfInvertibleFactorial.dpow_null)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup3 item 18, rating MINOR): `dpow_null` is the axiom-facing member of the `dpow_zero`/`dpow_one`/`dpow_mem` family and serves both constructors. Keep that interface as an alias of the computational lemma.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-e019ae","file":"Mathlib/RingTheory/Etale/Finite.lean","decl":"CommAlgCat.finite","line":46,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-instance","claim":"The object properties `finite`, `etale`, `finiteEtale` are invariant under isomorphism but no `ObjectProperty.IsClosedUnderIsomorphisms` instance is registered, so generic transport along isos (and the full-subcategory API that needs it) cannot use them.","fix":"Register the instances for `finite` and `etale` (via `Module.Finite.equiv`, `Algebra.Etale.of_equiv`); `finiteEtale` follows.","ev":"example (R : Type u) [CommRing R] : (CommAlgCat.finite.{v} R).IsClosedUnderIsomorphisms := by infer_instance\n-- failed to synthesize","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-6092d1","file":"Mathlib/RingTheory/Etale/Finite.lean","decl":"CommAlgCat.FiniteEtale.finiteSpec","line":126,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`finiteSpec` and the `IsArtinianRing` instance are stated over a field k, but finiteness of `PrimeSpectrum A` (and Artinianness of A) only needs an Artinian base, via `IsArtinianRing.of_finite`; e.g. `finiteSpec (ZMod 4)` is excluded for no reason.","fix":"Take `[IsArtinianRing R]` (commutative) instead of `[Field k]`.","ev":"example (R A : Type*) [CommRing R] [CommRing A] [Algebra R A] [IsArtinianRing R]\n    [Module.Finite R A] : Finite (PrimeSpectrum A) := by\n  letI : IsArtinianRing A := IsArtinianRing.of_finite R A\n  infer_instance","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261007-b31a82","file":"Mathlib/RingTheory/FiniteType.lean","decl":"RingHom.Finite.finiteType","line":222,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `RingHom.FiniteType.of_finite` (RingTheory.FiniteType), `RingHom.Finite.finiteType` (RingTheory.FiniteType) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: RingHom.Finite.finiteType is the dot-notation twin of FiniteType.of_finite, with the identical proof `@Module.Finite.finiteType _ _ _ _ f.toAlgebra hf`. There is already `alias RingHom.Finite.to_finiteType := of_finite` at line 253, so this is a third name. Make Finite.finiteType an alias and drop or deprecate one of the two dot-notation names.","fix":"Declare `RingHom.Finite.finiteType` as an `alias` of `RingHom.FiniteType.of_finite`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-c84af1","file":"Mathlib/RingTheory/Flat/Rank.lean","decl":"RingHom.finrank_comp_left_of_bijective","line":160,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-hypothesis","claim":"`RingHom.finrank_comp_left_of_bijective` assumes `h1 : f.Finite` and `h2 : f.Flat`, but `(g.comp f).finrank = f.finrank` holds for every `f` when `g` is bijective: T ≃ S as R-algebras, and `Module.rankAtStalk_eq_of_equiv` needs no hypotheses. These assumptions propagate to `Scheme.Hom.finrank_comp_left_of_isIso` in FlatRank.lean.","fix":"Drop `h1 h2`; prove by `algebraize` and `Module.rankAtStalk_eq_of_equiv (AlgEquiv.ofBijective (IsScalarTower.toAlgHom R S T) hg).toLinearEquiv`.","ev":"example {R S T : Type*} [CommRing R] [CommRing S] [CommRing T]\n    (f : R →+* S) (g : S →+* T) (hg : Function.Bijective g) (x : PrimeSpectrum R) :\n    (g.comp f).finrank x = f.finrank x := by\n  algebraize [f, g, (g.comp f)]\n  exact congrFun (Module.rankAtStalk_eq_of_equiv\n    (AlgEquiv.ofBijective (IsScalarTower.toAlgHom R S T) hg).toLinearEquiv).symm x","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":""},{"id":"RT-20261007-67bc7a","file":"Mathlib/RingTheory/HahnSeries/PowerSeries.lean","decl":"HahnSeries.coeff_toPowerSeries_symm","line":84,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `HahnSeries.toPowerSeries_symm_apply_coeff` (RingTheory.HahnSeries.PowerSeries), `HahnSeries.coeff_toPowerSeries_symm` (RingTheory.HahnSeries.PowerSeries) state exactly the same thing (Lean-checked). Reviewer: `@[simps]` on `toPowerSeries` (line 55) already generates the @[simp] `toPowerSeries_symm_apply_coeff : (toPowerSeries.symm f).coeff n = coeff n f` (used at 123/136). The manual rfl lemma `coeff_toPowerSeries_symm` states the same, is not simp, has no uses and no comment. Deprecate it, or drop `symm_apply` from simps and make the manual one simp.","fix":"Deprecate `HahnSeries.coeff_toPowerSeries_symm` in favour of `HahnSeries.toPowerSeries_symm_apply_coeff`.","ev":"dupscan/Check.lean: `example := (@HahnSeries.coeff_toPowerSeries_symm : type_of% @HahnSeries.toPowerSeries_symm_apply_coeff)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 20, rating MINOR): The generated simp lemma suffices, although the manual lemma’s implicit arguments and pairing with `coeff_toPowerSeries` provide modest API convenience. Either proposed consolidation direction is reasonable.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-20ca78","file":"Mathlib/RingTheory/Ideal/MinimalPrime/Colon.lean","decl":"exists_eq_colon_of_mem_minimalPrimes","line":32,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"long-proof","claim":"`Submodule.exists_eq_colon_of_mem_minimalPrimes` has a 66-line proof (L34-99) in one block: the existence of `n` and `J` with `I ^ n * J ≤ ann`, `¬ J ≤ I` (L40-52), the finite-product construction of `z` (L73-91) and the final minimality argument are independent steps that would read better as separate lemmas (the first is a general statement about minimal primes of an ideal in a Noetherian ring).","fix":"Extract the `key` step as a lemma about minimal primes in a Noetherian ring (`∃ n ≠ 0, ∃ J, I ^ n * J ≤ a ∧ ¬ J ≤ I` for `I ∈ a.minimalPrimes`) and the product step as a helper.","ev":"Measured: the proof spans L34-L99 (66 lines) of the audited file; profiling with `-Dprofiler=true -Dprofiler.threshold=100` reports no declaration over 100 ms, so this is a structure finding, not a speed one.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-29e30a","file":"Mathlib/RingTheory/Ideal/MinimalPrime/Colon.lean","decl":"exists_eq_colon_of_mem_minimalPrimes","line":32,"sev":"MINOR","status":"suspected","cat":"generality","pattern":"hypothesis-stronger-than-needed","claim":"Astra argues (not formalised here) that `[IsNoetherianRing R]` is stronger than needed: finite generation of the chosen prime `I` suffices (a finitely generated weakly associated prime is associated, Stacks 058A), e.g. `R = k[t, z₁, z₂, …]`, `N = (t²)`, `x = 1`, `I = (t)` is covered by an `I.FG` version but not by the current theorem. Some finiteness is necessary (`k[X₁, X₂, …]/(X₁², X₂², …)` is a counterexample without any).","fix":"Prove a version assuming `I.FG` and derive the Noetherian one.","ev":"Suspected: Astra's A1 item 1 (paper argument via ideal saturation); not formalised here.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-f38167","file":"Mathlib/RingTheory/Ideal/MinimalPrime/Colon.lean","decl":"exists_eq_colon_of_mem_minimalPrimes","line":33,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"statement-discards-witness","claim":"The proof establishes the stronger `∃ a : R, I = N.colon {a • x}` (the witness is `y • x` for a scalar `y`, L68) but the theorem exports only `∃ x' : M, I = N.colon {x'}`, so callers lose the guarantee that the witness lies in `R ∙ x` (e.g. for `M = 𝔽₂²`, `N = ⊥`, `x = (1, 0)` the weak conclusion also allows `(0, 1)`).","fix":"State the theorem as `∃ a : R, I = N.colon {a • x}` (changing the witness at L68 to `y`) and keep the current form as a one-line corollary.","ev":"hunts/minprime-colon/probe_strong.lean: the file with the conclusion `∃ a : R, I = N.colon {a • x}`, the witness `⟨y, …⟩` and the corollary `exists_eq_colon_of_mem_minimalPrimes'` (the current statement) compiles with exit 0. Raised by Astra's A1 pass (item 2).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-bb521d","file":"Mathlib/RingTheory/IntegralClosure/Algebra/Defs.lean","decl":"Algebra.isIntegral_iff","line":33,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Algebra.isIntegral_iff` (RingTheory.IntegralClosure.Algebra.Defs), `Algebra.isIntegral_def` (RingTheory.IntegralClosure.Algebra.Defs) state exactly the same thing (Lean-checked). Reviewer: `@[mk_iff] protected class Algebra.IsIntegral` generates isIntegral_iff (R and A explicit). The manual isIntegral_def five lines below states the same with implicit R and A, with no comment. Keep isIntegral_def (about 9 uses), drop `mk_iff`, and fix the single `Algebra.isIntegral_iff ..` use at line 42.","fix":"Deprecate `Algebra.isIntegral_iff` in favour of `Algebra.isIntegral_def`.","ev":"dupscan/Check.lean: `example := (@Algebra.isIntegral_def : type_of% @Algebra.isIntegral_iff)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 21, rating MINOR): `mk_iff` generates the theorem without establishing a separate automation role for that name. The explicit-versus-inferred parameter distinction makes this a small API cleanup.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-145f3e","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"(module docstring)","line":25,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-claims-more","claim":"The module overview states the universal property as `Hom_R(Ω[S⁄R], M) ≃ₗ[S] Der_R(S, M)`; it must be `Hom_S`. `linearMapEquivDerivation` itself is correctly about `Ω[S⁄R] →ₗ[S] M`, and an R-linear map out of Ω need not give a derivation: for R = ℚ, S = M = ℚ[X], the ℚ-linear F(p dX) = p' composes with d to second differentiation, which fails Leibniz.","fix":"Write `Hom_S(Ω[S⁄R], M) ≃ₗ[S] Der_R(S, M)`.","ev":"-- Kaehler/Basic.lean:25 `The isomorphism Hom_R(Ω[S⁄R], M) ≃ₗ[S] Der_R(S, M).`\n#check @KaehlerDifferential.linearMapEquivDerivation   -- (Ω[S⁄R] →ₗ[S] M) ≃ₗ[S] Derivation R S M","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c864e9","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.one_smul_sub_smul_one_mem_ideal","line":67,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"name-describes-wrong-operation","claim":"The name says `one_smul_sub_smul_one`, but the statement is about tensors: `(1 : S) ⊗ₜ[R] a - a ⊗ₜ[R] (1 : S) ∈ ideal R S`. Read literally, the name describes `1 • a - a • 1`, which is always 0. Mathlib's sibling lemma for the same expression uses `tmul`: `Algebra.FormallyUnramified.one_tmul_sub_tmul_one_mul_elem : (1 ⊗ₜ s - s ⊗ₜ 1) * elem R S = 0` (Mathlib/RingTheory/Unramified/Finite.lean:143). The name is used 9 times in Basic.lean and nowhere else.","fix":"Rename to `KaehlerDifferential.one_tmul_sub_tmul_one_mem_ideal` and keep the old name as a `@[deprecated]` alias.","ev":"src.lean:67-68: `theorem KaehlerDifferential.one_smul_sub_smul_one_mem_ideal (a : S) : (1 : S) ⊗ₜ[R] a - a ⊗ₜ[R] (1 : S) ∈ KaehlerDifferential.ideal R S`; `git grep one_smul_sub_smul_one_mem_ideal origin/master -- Mathlib` gives 10 hits, all in Kaehler/Basic.lean; `git grep one_tmul_sub_tmul_one` gives Unramified/Finite.lean:143 `lemma one_tmul_sub_tmul_one_mul_elem (s : S) : (1 ⊗ₜ s - s ⊗ₜ 1) * elem R S = 0`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6579df","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"Derivation.tensorProductTo","line":74,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reimplements-mathlib-combinator","claim":"The body rebuilds Mathlib's `LinearMap.liftBaseChange` (Mathlib/LinearAlgebra/TensorProduct/Lift.lean: `abbrev liftBaseChange (l : M →ₗ[R] N) : A ⊗[R] M →ₗ[A] N`, with `@[simp] liftBaseChange_tmul : l.liftBaseChange A (x ⊗ₜ y) = x • l y`). `D.tensorProductTo = D.toLinearMap.liftBaseChange S` holds by `rfl`. With the body replaced, the whole file still compiles.","fix":"Define `Derivation.tensorProductTo D := D.toLinearMap.liftBaseChange S`, so `tensorProductTo_tmul` becomes an instance of `LinearMap.liftBaseChange_tmul`.","ev":"batch0/probe1.lean (P1): `example (D : Derivation R S M) : D.tensorProductTo = D.toLinearMap.liftBaseChange S := rfl` and `example (D : Derivation R S M) (s t : S) : D.toLinearMap.liftBaseChange S (s ⊗ₜ t) = s • D t := by simp`, both compile. Whole-file check: batch0/KB_liftBaseChange.lean (diff in batch0/KB_liftBaseChange.diff, body := `D.toLinearMap.liftBaseChange S`) compiles. The only new diagnostic is an unused-simp-arg warning for `AlgebraTensorModule.lift_apply` in `tensorProductTo_mul`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4c10d3","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"Derivation.tensorProductTo","line":74,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`Derivation.tensorProductTo`, `tensorProductTo_tmul` and `tensorProductTo_mul` are stated under the file's `[CommRing R] [CommRing S] [AddCommGroup M]`. All three compile unchanged (same bodies and proofs) under `[CommSemiring R] [CommSemiring S] [AddCommMonoid M]`. The general version specialises back to the file's by `rfl`.","fix":"Move the three declarations into a section with `[CommSemiring R] [CommSemiring S] [Algebra R S] [AddCommMonoid M]`, ahead of the `CommRing` material.","ev":"batch0/probe5_gen.lean: `variable {R S M : Type*} [CommSemiring R] [CommSemiring S] [Algebra R S] [AddCommMonoid M] [Module R M] [Module S M] [IsScalarTower R S M]`, followed by the three declarations copied verbatim (as `Probe.tensorProductTo{,_tmul,_mul}`) and `example ... : tensorProductTo D = D.tensorProductTo := rfl`. Compiles with no errors or warnings.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-603462","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"Derivation.tensorProductTo_tmul","line":77,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-on-apply-lemma","claim":"The characteristic evaluation lemma `D.tensorProductTo (s ⊗ₜ t) = s • D t` is not `@[simp]`, so `simp` cannot evaluate `tensorProductTo` on a pure tensor. Every caller passes it by hand: Extension/Cotangent/Basic.lean:188 and :300, and Kaehler/TensorProduct.lean:171 and :194. Mathlib's equivalent `LinearMap.liftBaseChange_tmul` is `@[simp]`. Adding `@[simp]` leaves Basic.lean compiling.","fix":"Tag `Derivation.tensorProductTo_tmul` with `@[simp]` (or get it for free by defining the map via `liftBaseChange`), then drop it from the explicit simp sets.","ev":"batch0/probe2_fail.lean: `example (D : Derivation R S M) (s t : S) : D.tensorProductTo (s ⊗ₜ t) = s • D t := by simp` gives `simp made no progress`, while `by simp [Derivation.tensorProductTo_tmul]` compiles. batch0/KB_simp_tmul.lean (src plus `@[simp]`) compiles.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b48d25","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"Derivation.tensorProductTo_mul","line":80,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"brittle-rw-chain-proof","claim":"The 20-line proof is brittle. It uses `refine TensorProduct.inductionOn ... ; swap` twice, two 9-lemma `rw` chains (`add_mul, map_add, map_add, map_add, add_smul, smul_add, h₁, h₂, add_add_add_comm`), a non-terminal bare `dsimp`, and a closing `simp only` with hand-instantiated `mul_comm (x * y) x₁` and `mul_right_comm x₁ x₂`. A structural `induction ... with` proof that ends with `module` is 9 lines and compiles.","fix":"Replace the proof with the `induction x with | add => simp only [...]; abel | tmul => induction y with ... | tmul => simp only [tmul_mul_tmul, tensorProductTo_tmul, lmul'_apply_tmul, Derivation.leibniz]; module` version.","ev":"batch0/probe6_golf.lean (G1):\n  induction x with\n  | add _ _ h₁ h₂ => simp only [add_mul, map_add, h₁, h₂, add_smul, smul_add]; abel\n  | tmul x₁ x₂ =>\n    induction y with\n    | add _ _ h₁ h₂ => simp only [mul_add, map_add, h₁, h₂, add_smul, smul_add]; abel\n    | tmul y₁ y₂ =>\n      simp only [TensorProduct.tmul_mul_tmul, Derivation.tensorProductTo_tmul,\n        TensorProduct.lmul'_apply_tmul, Derivation.leibniz]\n      module","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2fced5","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.fromIdeal","line":170,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"`fromIdeal` (the quotient map `I →ₗ Ω[S⁄R]`) has no API except `fromIdeal_surjective`: no equality or kernel lemma. The cotangent API does not fire on it: `rw [Ideal.toCotangent_eq]` and `simp [Ideal.toCotangent_eq_zero]` fail on `fromIdeal` goals. As a result the file bypasses `fromIdeal` and states `DLinearMap_apply`, `D_apply`, `liftKaehlerDifferential_apply` and `D_tensorProductTo` through `(ideal R S).toCotangent`, whose codomain is `(ideal R S).Cotangent`, not `Ω[S⁄R]`. It is used only 3 times, all in this file. The missing lemma `fromIdeal_eq_iff` is one line.","fix":"Add `fromIdeal_eq_iff : fromIdeal R S x = fromIdeal R S y ↔ (x - y : S ⊗[R] S) ∈ ideal R S ^ 2 := Ideal.toCotangent_eq _` (and an `_eq_zero_iff`), and state the file's apply lemmas through `fromIdeal`.","ev":"batch0/probe7_fromIdeal.lean: `example (x y : ideal R S) : fromIdeal R S x = fromIdeal R S y ↔ (x - y : S ⊗[R] S) ∈ ideal R S ^ 2 := by rw [Ideal.toCotangent_eq]` fails with `rewrite failed: did not find (Ideal.toCotangent ?I) ?x = ...`, and `example (x : ideal R S) : fromIdeal R S x = 0 ↔ (x : S ⊗[R] S) ∈ ideal R S ^ 2 := by simp [Ideal.toCotangent_eq_zero]` gives `simp made no progress`. The one-liners `theorem fromIdeal_eq_iff ... := Ideal.toCotangent_eq _` and `theorem fromIdeal_eq_zero_iff ... := Ideal.toCotangent_eq_zero _ x` compile.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-96796e","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.DLinearMap_apply","line":185,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"statement-crosses-type-synonym","claim":"The statement equates `DLinearMap R S s : Ω[S⁄R]` with `(ideal R S).toCotangent ⟨…⟩ : (ideal R S).Cotangent`, which type-checks only by unfolding the semireducible `def KaehlerDifferential`. After `rw [DLinearMap_apply]` the goal is not type-correct at `implicit` transparency, and the next generic step fails: `rw [← map_add]` and `rw [← LinearMap.map_smul_of_tower (ideal R S).toCotangent]` both fail. This is the failure the adaptation note before `D` (lines 190–221) works around with three `backward.*` options and a `have : CompatibleSMul …`. Stated through `fromIdeal` (defeq, so still `rfl`), the same rewrites succeed. In a copy of the file, restating it this way, adding `fromIdeal_eq_iff`, and rewriting `D`'s proof through `fromIdeal` lets all three `set_option backward.*` lines and the `have` go, and the whole file compiles. (`D_apply`, line 246, in batch 1, has the same shape.)","fix":"State `DLinearMap_apply` (and `D_apply`) as `… = fromIdeal R S ⟨1 ⊗ₜ s - s ⊗ₜ 1, _⟩`, add `fromIdeal_eq_iff`, and rewrite `D`'s proof through `fromIdeal`. This removes the backward options and the adaptation note.","ev":"batch0/probe4_synonym_use.lean: U1 `example (s t : S) : DLinearMap R S s + DLinearMap R S t = DLinearMap R S (s + t) := by rw [DLinearMap_apply, DLinearMap_apply, DLinearMap_apply, ← map_add]` fails (`did not find ?f ?x + ?f ?y`; note: target not type-correct under `implicit` transparency: `(ideal R S).toCotangent ⟨…⟩ has type (ideal R S).Cotangent but is expected to have type Ω[S⁄R]`). U3 `rw [DLinearMap_apply, ← LinearMap.map_smul_of_tower (ideal R S).toCotangent]` fails the same way. U2 and U4 run the same rewrites through `DLinearMap_apply_fromIdeal (s) : DLinearMap R S s = fromIdeal R S ⟨1 ⊗ₜ s - s ⊗ₜ 1, _⟩ := rfl` and compile. Whole-file check: batch0/KB_fromIdeal.lean (diff in batch0/KB_fromIdeal.diff) drops the 3 `set_option backward.*` lines and the `CompatibleSMul` `have` from `D`, compiles, and `#print axioms KaehlerDifferential.mapBaseChange_surjective` runs at the end.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d0ddba","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.subsingleton_of_surjective","line":274,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-docstring-reference","claim":"The docstring's 'Also see `Algebra.FormallyUnramified.iff_subsingleton_kaehlerDifferential`' points to a declaration that does not exist; this docstring is the only occurrence of that name in Mathlib. The equivalence now exists as `Algebra.formallyUnramified_iff : Algebra.FormallyUnramified R A ↔ Subsingleton Ω[A⁄R]` (generated by `@[mk_iff]` on the class in Mathlib/RingTheory/Unramified/Basic.lean:56).","fix":"Replace the reference with `Algebra.formallyUnramified_iff`.","ev":"-- hunts/kaehler/batch1/probeA.lean (imports Mathlib.RingTheory.Kaehler.Basic, Mathlib.RingTheory.Unramified.Basic)\nopen Lean in\n#eval show CoreM Unit from do\n  let env ← getEnv\n  IO.println s!\"{env.contains `Algebra.FormallyUnramified.iff_subsingleton_kaehlerDifferential}\"  -- prints false\n  IO.println s!\"{env.contains `Algebra.formallyUnramified_iff}\"  -- prints true\n#check @Algebra.formallyUnramified_iff  -- ∀ R A ..., Algebra.FormallyUnramified R A ↔ Subsingleton Ω[A⁄R]\n-- git grep iff_subsingleton_kaehlerDifferential origin/master -- Mathlib: only Kaehler/Basic.lean:274","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-1cc257","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"Derivation.liftKaehlerDifferential","line":285,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"hand-assembled-def-mathlib-combinator","claim":"The 13-line tactic-mode construction (`liftQ` ∘ `restrictScalarsEquiv.symm` plus a `smul_induction_on` kernel proof) re-implements Mathlib's `Ideal.Cotangent.lift (f : I →ₗ[R] M) (hf : ∀ (x y : I), f (x * y) = 0) : I.Cotangent →ₗ[R] M` (Mathlib/RingTheory/Ideal/Cotangent.lean:234). A 3-line term-mode definition via `Ideal.Cotangent.lift` is equal to it (by `ext a; rfl`, though not `rfl` as bundled maps), keeps `liftKaehlerDifferential_apply` true by `rfl`, and the whole file compiles with it substituted.","fix":"Define `liftKaehlerDifferential D` as `Ideal.Cotangent.lift (D.tensorProductTo.comp ((ideal R S).subtype.restrictScalars S)) fun x y => by simp [Derivation.tensorProductTo_mul, RingHom.mem_ker.mp x.2, RingHom.mem_ker.mp y.2]`.","ev":"-- hunts/kaehler/batch1/probeE.lean\nnoncomputable def liftViaCotangentLift (D : Derivation R S M) : Ω[S⁄R] →ₗ[S] M :=\n  Ideal.Cotangent.lift (D.tensorProductTo.comp ((ideal R S).subtype.restrictScalars S))\n    fun x y => by\n      simp [Derivation.tensorProductTo_mul, RingHom.mem_ker.mp x.2, RingHom.mem_ker.mp y.2]\nexample (D : Derivation R S M) : liftViaCotangentLift D = D.liftKaehlerDifferential := by\n  ext a; rfl\nexample (D : Derivation R S M) (x : ideal R S) :\n    liftViaCotangentLift D ((ideal R S).toCotangent x) = D.tensorProductTo x := rfl\n-- and hunts/kaehler/batch1/v8_cotangentLift.lean (full file with this definition substituted): EXIT=0","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-546d1c","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"Derivation.liftKaehlerDifferential","line":285,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-simp-lemma","claim":"The universal-property API lacks the 'lift of a composite' lemma `(f.compDer (D R S)).liftKaehlerDifferential = f`: `simp` cannot prove it; it is reachable only as `(linearMapEquivDerivation R S).symm_apply_apply f`. With it added as `@[simp]` (proof `ext; simp`) the whole file still compiles.","fix":"Add `@[simp] theorem Derivation.liftKaehlerDifferential_compDer_D (f : Ω[S⁄R] →ₗ[S] M) : (f.compDer (D R S)).liftKaehlerDifferential = f := by ext; simp`.","ev":"-- hunts/kaehler/batch1/probeA.lean (P4)\nexample (f : Ω[S⁄R] →ₗ[S] M) : (f.compDer (D R S)).liftKaehlerDifferential = f := by\n  fail_if_success simp\n  ext; simp\n-- and hunts/kaehler/batch1/vC_api.lean (full file with the lemma added as @[simp]): EXIT=0","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c691be","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"Derivation.liftKaehlerDifferential_unique","line":317,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"proof-reinvents-mathlib-lemma","claim":"The 9-line `Submodule.span_induction` proof re-derives `LinearMap.ext_on_range {ι : Sort*} {v : ι → M} {f g : M →ₛₗ[σ₁₂] M₂} (hv : span R (Set.range v) = ⊤) (h : ∀ i, f (v i) = g (v i)) : f = g` (Mathlib/LinearAlgebra/Span/Basic.lean:863); the one-liner `LinearMap.ext_on_range (span_range_derivation R S) fun x => congr($hf x)` proves the statement, and the whole file compiles with it.","fix":"Replace the proof by `LinearMap.ext_on_range (KaehlerDifferential.span_range_derivation R S) fun x => congr($hf x)`.","ev":"-- hunts/kaehler/batch1/probeA.lean (P1)\nexample (f f' : Ω[S⁄R] →ₗ[S] M)\n    (hf : f.compDer (KaehlerDifferential.D R S) = f'.compDer (KaehlerDifferential.D R S)) :\n    f = f' :=\n  LinearMap.ext_on_range (KaehlerDifferential.span_range_derivation R S) fun x => congr($hf x)\n-- and hunts/kaehler/batch1/vC_api.lean (full file with this proof): EXIT=0","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4713a0","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"Derivation.liftKaehlerDifferential_unique","line":317,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"name-mentions-absent-constant","claim":"The name describes neither the statement nor its subject: the conclusion `f = f'` for `f f' : Ω[S⁄R] →ₗ[S] M` mentions no `liftKaehlerDifferential` (Mathlib's `lift_unique` lemmas conclude `f = lift g`), and the lemma is the `@[ext]` lemma for linear maps out of `Ω[S⁄R]`, which by convention would be named like `KaehlerDifferential.linearMap_ext` (cf. `Finsupp.lhom_ext`, `TensorProduct.ext'`). A user looking for the ext lemma of Ω will not find it under `Derivation`.","fix":"Rename to `KaehlerDifferential.linearMap_ext` and keep a deprecated alias.","ev":"#check @Derivation.liftKaehlerDifferential_unique\n-- : ∀ {R S} ... {M} ... (f f' : Ω[S⁄R] →ₗ[S] M), f.compDer (KaehlerDifferential.D R S) = f'.compDer (KaehlerDifferential.D R S) → f = f'   (hunts/kaehler/batch1/probeG.lean)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a6cef1","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"Derivation.liftKaehlerDifferential_D","line":332,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`(D R S).liftKaehlerDifferential = LinearMap.id` (the lift of the universal derivation is the identity) is a natural simp normal form but is not `@[simp]`, and `simp` cannot prove it; tagging it `@[simp]` keeps the whole file compiling.","fix":"Tag `Derivation.liftKaehlerDifferential_D` with `@[simp]`.","ev":"-- hunts/kaehler/batch1/probeA.lean (P3)\nexample : (D R S).liftKaehlerDifferential = LinearMap.id := by\n  fail_if_success simp\n  exact Derivation.liftKaehlerDifferential_D R S\n-- and hunts/kaehler/batch1/vC_api.lean (full file with @[simp] added): EXIT=0","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-8bf795","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.quotientCotangentIdealRingEquiv","line":363,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-apply-lemma","claim":"No lemma computes the equivalence: `quotientCotangentIdealRingEquiv R S (mk (mk x)) = lmul' R x` holds by `rfl` but is stated nowhere, so its only consumer `End_equiv_aux` re-derives it inline (`e₁`, by quotient induction and `rfl`) and also relies on the defeq `x = e (toAlgHom x)` via `(mul_one x).symm`.","fix":"Add `@[simp] lemma quotientCotangentIdealRingEquiv_mk (x : S ⊗[R] S) : quotientCotangentIdealRingEquiv R S (mk (mk x)) = lmul' R x := rfl` and use it in `End_equiv_aux`.","ev":"-- hunts/kaehler/batch2/probe1.lean (d)\nexample (x : S ⊗[R] S) :\n    KaehlerDifferential.quotientCotangentIdealRingEquiv R S\n      (Ideal.Quotient.mk _ (Ideal.Quotient.mk _ x)) = Algebra.TensorProduct.lmul' R x := rfl","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-055388","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.quotientCotangentIdeal","line":375,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"equiv-name-missing-equiv-suffix","claim":"An `≃ₐ[S]` is named like an ideal (`quotientCotangentIdeal`), while its `≃+*` sibling is `quotientCotangentIdealRingEquiv`; Mathlib pairs such equivalences as `…RingEquiv`/`…AlgEquiv`. The declaration has no use anywhere in Mathlib (git grep -nw quotientCotangentIdeal origin/master -- Mathlib: only its own definition).","fix":"Rename to `quotientCotangentIdealAlgEquiv` with a `@[deprecated]` alias.","ev":"#check @KaehlerDifferential.quotientCotangentIdeal  -- ... ≃ₐ[S] S (probe1.lean); git grep -nw quotientCotangentIdeal origin/master -- Mathlib → Basic.lean:375 only","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a1bc57","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.End_equiv_aux","line":381,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"aux-name-capitalised-type","claim":"`End_equiv_aux` is the only non-deprecated theorem in Mathlib whose name contains an `End_` component (the last ones, `MulEquiv.Monoid.End_apply_apply` etc., were deprecated 2026-09-10); its sibling definitions are spelled `endEquiv…`, it is a public `_aux` lemma, and its statement (R-algebra maps `S → S ⊗ S ⧸ J²` lifting the algebra map ↔ sections of `kerSquareLift`) does not involve `End` at all.","fix":"Rename to a descriptive snake_case name such as `KaehlerDifferential.mkₐ_comp_eq_toAlgHom_iff_kerSquareLift_comp_eq_id`, keeping a `@[deprecated]` alias.","ev":"git grep -nE \"^(theorem|lemma) ([A-Za-z.]*\\.)?End_[a-z]\" origin/master -- Mathlib | grep -v deprecated  →  only Mathlib/RingTheory/Kaehler/Basic.lean:381; Mathlib/Algebra/Group/Equiv/TypeTags.lean:126-133 deprecate the `…End_apply_apply` names (since 2026-09-10)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6857fb","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"instR","line":403,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"local-instance-root-namespace-leak","claim":"`local instance instR` makes only the instance attribute local: it declares a public, exposed constant `_root_.instR` (with `@[instance_reducible]`) in the root namespace, visible to every file importing Mathlib.RingTheory.Kaehler.Basic under a generic five-letter name.","fix":"Delete the instance (see the hygiene finding); if one is ever needed again, make it a `private local instance` or put it in the `KaehlerDifferential` namespace with a descriptive name.","ev":"-- hunts/kaehler/batch2/probe1.lean (a), a downstream file:\nimport Mathlib.RingTheory.Kaehler.Basic\n#check @instR\n#print instR\n-- @[instance_reducible] def instR.{u, v} : (R : Type u) → (S : Type v) → [CommRing R] → [CommRing S] → [Algebra R S] → Module R ↥(KaehlerDifferential.ideal R S).cotangentIdeal := fun R S .. => Submodule.module' (KaehlerDifferential.ideal R S).cotangentIdeal","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ce9ab6","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"instR","line":403,"sev":"MINOR","status":"confirmed","cat":"hygiene","pattern":"stale-shortcut-instance","claim":"Stale workaround: its docstring says it is 'a shortcut instance to prevent timing out. Hopefully to be removed in the future', but the file compiles unchanged without it, `endEquivDerivation'` + `endEquiv` elaborate in ~630 ms without it vs ~600 ms with it (profiler, 3 runs each; whole file 5.4 s vs 5.3 s), and the instance found without it is reducibly defeq to `Submodule.module' _`, so no type changes.","fix":"Delete lines 402-404 (`instR` and its docstring).","ev":"hunts/kaehler/batch2/copy_noinstR.lean (src.lean minus lines 402-404) compiles with no errors; hunts/kaehler/batch2/copy_orig_dprof.lean vs copy_noinstR_dprof.lean (profiler on the two consumers): 602/617/569 ms vs 628/632/633 ms; probe2.lean (j):\nexample : (inferInstance : Module R (KaehlerDifferential.ideal R S).cotangentIdeal) =\n    Submodule.module' _ := by with_reducible_and_instances rfl","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c74fe8","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.endEquivDerivation'","line":408,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"primed-name-without-unprimed","claim":"A primed name with no unprimed `endEquivDerivation` anywhere in Mathlib, and the `endEquiv` prefix misdescribes it: it is `Derivation R S Ω[S⁄R] ≃ₗ[S] Derivation R S (ideal R S).cotangentIdeal` (post-composition with `cotangentEquivIdeal`), with no endomorphisms involved.","fix":"Rename to e.g. `KaehlerDifferential.derivationEquivDerivationCotangentIdeal` (unprimed), keeping a `@[deprecated]` alias.","ev":"git grep -nE \"endEquivDerivation[^']\" origin/master -- Mathlib  → no hits; #check @KaehlerDifferential.endEquivDerivation' (probe1.lean)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a3dff8","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.endEquivAuxEquiv","line":414,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reimplements-mathlib-combinator","claim":"The body `(Equiv.refl _).subtypeEquiv (End_equiv_aux R S)` is literally Mathlib's `Equiv.subtypeEquivRight (End_equiv_aux R S)` (Mathlib/Logic/Equiv/Basic.lean:296, `def subtypeEquivRight {p q : α → Prop} (e : ∀ x, p x ↔ q x) : { x // p x } ≃ { x // q x } := subtypeEquiv (Equiv.refl _) e`); the named public wrapper has a single use, in `endEquiv`.","fix":"Use `Equiv.subtypeEquivRight (End_equiv_aux R S)` (inline in `endEquiv`, or as the body) and deprecate the wrapper.","ev":"-- hunts/kaehler/batch2/probe1.lean (f)\nexample : KaehlerDifferential.endEquivAuxEquiv R S =\n    Equiv.subtypeEquivRight (KaehlerDifferential.End_equiv_aux R S) := rfl\n-- and copy_edits.lean with the body replaced compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-646fb4","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.endEquiv","line":425,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-apply-lemma","claim":"No characteristic API: no apply/symm lemma and no `@[simps]`; its one consumer (Unramified/Basic.lean:102) uses only `.injective`. The defining formula `(endEquiv R S f).1 x = ↑(cotangentEquivIdeal (f (D x))) + mk (x ⊗ₜ 1)` holds by `rfl`, and the basic values (0 ↦ the left inclusion `x ↦ x ⊗ 1`, `LinearMap.id` ↦ the right inclusion `x ↦ 1 ⊗ x`) need unfolding four definitions to state and prove.","fix":"Add `endEquiv_apply_coe` (by `rfl`) and `endEquiv_id`/`endEquiv_zero` lemmas, or `@[simps]`.","ev":"-- hunts/kaehler/batch2/probe2.lean (i), (h); probe1.lean (c)\nexample (f : Module.End S Ω[S⁄R]) (x : S) : ((KaehlerDifferential.endEquiv R S f).1 x) =\n    (Ideal.cotangentEquivIdeal _ (f (KaehlerDifferential.D R S x)) :\n      S ⊗[R] S ⧸ KaehlerDifferential.ideal R S ^ 2) + Ideal.Quotient.mk _ (x ⊗ₜ[R] (1 : S)) := rfl\nexample (x : S) : ((KaehlerDifferential.endEquiv R S LinearMap.id).1 x) =\n    Ideal.Quotient.mk (KaehlerDifferential.ideal R S ^ 2) ((1 : S) ⊗ₜ[R] x) := by\n  change ((Ideal.cotangentEquivIdeal _ (KaehlerDifferential.D R S x) :\n      S ⊗[R] S ⧸ KaehlerDifferential.ideal R S ^ 2)) + Ideal.Quotient.mk _ (x ⊗ₜ[R] (1 : S)) = _\n  rw [KaehlerDifferential.D_apply, Ideal.cotangentEquivIdeal_apply,\n    Ideal.toCotangent_to_quotient_square, Submodule.mkQ_apply, Ideal.Quotient.mk_eq_mk,\n    ← map_add, sub_add_cancel]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-25e35a","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.kerTotal","line":504,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-docstring-signature","claim":"Stale docstring: it calls the kernel that of `Finsupp.linearCombination S Ω[S⁄R] S (KaehlerDifferential.D R S)`, the old `Finsupp.total α M R v` argument order, which no longer elaborates; the file itself uses `Finsupp.linearCombination S (KaehlerDifferential.D R S)`.","fix":"Replace with `Finsupp.linearCombination S (KaehlerDifferential.D R S)`.","ev":"-- hunts/kaehler/batch2/probe3.lean\n#check Finsupp.linearCombination S Ω[S⁄R] S (KaehlerDifferential.D R S)\n-- error: Application type mismatch: The argument Ω[S⁄R] has type Type but is expected to have type ?m.3 → ?m.4\n#check Finsupp.linearCombination S (KaehlerDifferential.D R S)  -- (S →₀ S) →ₗ[S] Ω[S⁄R]","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-dc6294","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.kerTotal_mkQ_single_algebraMap_one","line":531,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"name-describes-proof-not-statement","claim":"The statement is `(kerTotal R S).mkQ (single 1 x) = 0`; `algebraMap` does not occur in it (the name records the proof route `1 = algebraMap R S 1`). It even follows from the Leibniz relation alone (`kerTotal_mkQ_single_mul` at `1, 1`).","fix":"Rename to `kerTotal_mkQ_single_one` with a `@[deprecated]` alias (its only use is in `derivationQuotKerTotal`).","ev":"#check @KaehlerDifferential.kerTotal_mkQ_single_algebraMap_one  -- ∀ R S .. (x : S), (kerTotal R S).mkQ (Finsupp.single 1 x) = 0 (probe1.lean); hunts/kaehler/batch2/copy_edits.lean with the rename compiles; probe1.lean (e):\nexample (x : S) : (KaehlerDifferential.kerTotal R S).mkQ (Finsupp.single 1 x) = 0 := by\n  have := KaehlerDifferential.kerTotal_mkQ_single_mul R S 1 1 x\n  simp only [mul_one] at this\n  simpa using this","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a8f8e8","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.derivationQuotKerTotal_apply","line":552,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-on-apply-lemma","claim":"The `_apply` lemma of the derivation `derivationQuotKerTotal` is not `@[simp]`, so `simp` cannot evaluate `derivationQuotKerTotal R S x`; its only consumer (`derivationQuotKerTotal_lift_comp_linearCombination`) has to pass it to `simp` by hand. Marking it `@[simp]` lets plain `simp` close that proof, and the whole file still compiles.","fix":"Mark `derivationQuotKerTotal_apply` `@[simp]` and drop the explicit argument in the consumer's `simp`.","ev":"batch3/probe1.lean P5b (no simp attribute):\nexample : (KaehlerDifferential.derivationQuotKerTotal R S).liftKaehlerDifferential.comp\n      (Finsupp.linearCombination S (KaehlerDifferential.D R S)) = Submodule.mkQ _ := by\n  apply Finsupp.lhom_ext\n  intro a b\n  conv_rhs => rw [← Finsupp.smul_single_one a b, map_smul]\n  simp\n-- error: unsolved goals ⊢ b • (derivationQuotKerTotal R S) a = b • Submodule.Quotient.mk (single a 1)\nP5 (same with `attribute [local simp] derivationQuotKerTotal_apply`) compiles; batch3/ModE.lean (`@[simp]` added, consumer uses plain `simp`) compiles.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7dedea","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.quotKerTotalEquiv","line":581,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"simps-unfolds-past-quotient-lift","claim":"`@[simps!]` generates an unusable `quotKerTotalEquiv_apply`: it unfolds `Submodule.liftQ` down to `QuotientAddGroup.lift (kerTotal R S).toAddSubgroup (linearCombination S ⇑(D R S)).toAddMonoidHom ⋯ a`, with `a : (S →₀ S) ⧸ (kerTotal R S).toAddSubgroup`. `simp` (and even `simp only [quotKerTotalEquiv_apply]`) makes no progress on `quotKerTotalEquiv R S (Submodule.Quotient.mk f)`, although `= linearCombination S (D R S) f` holds by `rfl`.","fix":"Use `@[simps! symm_apply]` and add `@[simp] lemma quotKerTotalEquiv_mk (f) : quotKerTotalEquiv R S (Submodule.Quotient.mk f) = linearCombination S (D R S) f := rfl`.","ev":"batch3/probe1.lean P1 (#check shows the generated statement above); batch3/probe2.lean:\nexample (f : S →₀ S) :\n    quotKerTotalEquiv R S (Submodule.Quotient.mk f) = linearCombination S (D R S) f := by\n  simp            -- error: `simp` made no progress\nexample … := by simp only [quotKerTotalEquiv_apply]   -- error: `simp` made no progress\nexample … := rfl  -- compiles\nbatch3/ModE.lean (`@[simps! symm_apply]` + `@[simp] quotKerTotalEquiv_mk := rfl`): whole file compiles and the `simp` example closes.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-e19017","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.kerTotal_map","line":639,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-omits-hypothesis","claim":"The docstring states the spanning result unconditionally (\"Given the commutative diagram … The kernel of the presentation ⊕ₓ B dx ↠ Ω_{B/S} is spanned by …\") and never mentions the hypothesis `h : Function.Surjective (algebraMap A B)`. Without it the equation is false: with R = S = A = ℤ and B = ℚ, the left side is supported on integer indices, but `d(1/2)+d(1/2)-d(1)` lies in `kerTotal ℤ ℚ`.","fix":"Begin the docstring with \"If `A → B` is surjective, …\" (and the same in `kerTotal_map'`).","ev":"batch3/probe5.lean (compiles): example : (kerTotal ℤ ℤ).map ((mapRange.linearMap (Algebra.linearMap ℤ ℚ)).comp (lmapDomain ℤ ℤ (algebraMap ℤ ℚ))) ⊔ Submodule.span ℤ (Set.range fun x : ℤ => single (algebraMap ℤ ℚ x) (1 : ℚ)) ≠ (kerTotal ℤ ℚ).restrictScalars ℤ, proved by bounding the left side by `(supported ℚ ℚ (range (algebraMap ℤ ℚ))).restrictScalars ℤ` and exhibiting `single (1/2) 1 + single (1/2) 1 - single (1/2+1/2) 1`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-0b5348","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.kerTotal_map'","line":664,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"redundant-sup-summand","claim":"The summand `⊔ Submodule.span A (Set.range fun x ↦ .single (algebraMap R A x) 1)` is redundant. It is exactly the span of the third generator family in the definition of `kerTotal R A`, so `kerTotal R A ⊔ span … = kerTotal R A` in one term. The lemma is therefore just `(kerTotal R A).map finsupp_map = (kerTotal R B).restrictScalars A`. Its only consumer, `ker_map_of_surjective`, spends `Submodule.map_sup, Submodule.map_span, ← Set.range_comp` and `convert bot_sup_eq _; rw [Submodule.span_eq_bot]; simp` removing that summand again.","fix":"State `kerTotal_map'` as `(kerTotal R A).map finsupp_map = (kerTotal R B).restrictScalars A` and shorten `ker_map_of_surjective` accordingly.","ev":"batch3/probe1.lean P3:\nexample : KaehlerDifferential.kerTotal R S ⊔\n    Submodule.span S (Set.range fun x : R ↦ Finsupp.single (algebraMap R S x) (1 : S)) =\n      KaehlerDifferential.kerTotal R S :=\n  sup_eq_left.mpr (Submodule.span_mono Set.subset_union_right)\nbatch3/ModA.lean: `kerTotal_map''` (simplified statement) and `ker_map_of_surjective_probe` re-proved as\n  rw [ker_map, ← kerTotal_map'' R A B h, Submodule.comap_map_eq, Submodule.map_sup, ← kerTotal_eq,\n    ← Submodule.comap_bot, Submodule.map_comap_eq_of_surjective (linearCombination_surjective _ _),\n    bot_sup_eq]\nwhole file compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d4125e","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.kerTotal_map'","line":664,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-wrong-generators","claim":"The docstring says the kernel is spanned by the image of `kerTotal R A` \"and all `da` with `a : A`\", but the statement adds only `d(algebraMap R A r)` for `r : R`, and those are already in `kerTotal R A`. Taken literally the docstring is false: with A → B surjective, the A-span of the images of all `da` is all of `B →₀ B`, which is not `kerTotal R B` unless Ω[B⁄R] = 0. The docstring also omits the surjectivity hypothesis `h`.","fix":"Say \"is the image of the kernel of `⊕ₓ A dx ↠ Ω_{A/R}`, if `A → B` is surjective\" (after the api fix), or at least replace \"`da` with `a : A`\" by \"`dr` with `r : R`\".","ev":"src.lean:659-668: docstring \"… spanned by the image of the kernel of `⊕ₓ A dx ↠ Ω_{A/R}` and all `da` with `a : A`.\" vs statement `(kerTotal R A ⊔ Submodule.span A (Set.range fun x ↦ .single (algebraMap R A x) 1)).map finsupp_map = …` with `x : R`; redundancy shown by batch3/probe1.lean P3 (compiles).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-f471a1","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.map","line":684,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-typeclass-derivable-instance","claim":"The section variable `[SMulCommClass S A B]` (line 674) is redundant. Mathlib's instance `instSMulCommClass : [CommSemiring R] [CommSemiring S] [Semiring A] [Algebra R A] [Algebra S A] → SMulCommClass R S A` (Mathlib/Algebra/Algebra/Basic.lean:435) always supplies it. With the binder deleted, the whole file compiles. It is carried by `map`, `map_compDer`, `map_D` and `ker_map` (and `map_surjective_of_surjective`).","fix":"Drop `[SMulCommClass S A B]` from the `variable` line at 674.","ev":"batch3/probe2.lean: example (A B : Type*) [CommRing A] [CommRing B] [Algebra A B] [Algebra S B] : SMulCommClass S A B := by show_term infer_instance  -- finds @instSMulCommClass S A B …; batch3/ModC.lean (src.lean with line 674 reading `variable [Algebra R B] [IsScalarTower R A B] [IsScalarTower R S B]`): whole file compiles, exit 0, with -D maxSynthPendingDepth=3. batch3/probe6.lean #check shows the binder on map, map_compDer, map_D, ker_map.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-331661","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.mapBaseChange","line":745,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reprovable-from-existing-api","claim":"`mapBaseChange` is built by hand as `(TensorProduct.isBaseChange A Ω[A⁄R] B).lift (map R R A B)`. Mathlib's combinator for this is `LinearMap.liftBaseChange` (Mathlib/LinearAlgebra/TensorProduct/Lift.lean:35, `(l : M →ₗ[R] N) : A ⊗[R] M →ₗ[A] N`, already imported here), and the two maps are equal. The sibling constructions use the combinator: `cotangentComplexBaseChange` (Extension/Cotangent/Basic.lean:87) and `tensorKaehlerEquiv` (Kaehler/TensorProduct.lean). With `mapBaseChange := (map R R A B).liftBaseChange B`, `mapBaseChange_tmul` is `rfl` and the whole file compiles. The two definitions are not `rfl`-equal, so downstream files would need a rebuild, but no downstream file unfolds `mapBaseChange` (git grep).","fix":"Define `mapBaseChange := (KaehlerDifferential.map R R A B).liftBaseChange B` and prove `mapBaseChange_tmul` by `rfl`.","ev":"-- hunts/kaehler/batch4/p1_checks.lean\nexample : mapBaseChange R A B = (map R R A B).liftBaseChange B := by\n  ext x; simp\n-- and hunts/kaehler/batch4/cA_liftBaseChange.lean: src.lean with\nnoncomputable def KaehlerDifferential.mapBaseChange : B ⊗[A] Ω[A⁄R] →ₗ[B] Ω[B⁄R] :=\n  (KaehlerDifferential.map R R A B).liftBaseChange B\n-- and `mapBaseChange_tmul ... := rfl`; the whole file compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-81a2f7","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.kerCotangentToTensor","line":801,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"hand-rolled-cotangent-lift","claim":"`kerCotangentToTensor` is built as `Submodule.liftQ _ (kerToTensor R A B)` with an 8-line kernel argument (`Submodule.smul_eq_map₂`, `iSup_le_iff`, a 9-lemma `simp only`). Mathlib has the combinator `Ideal.Cotangent.lift (f : I →ₗ[R] M) (hf : ∀ x y : I, f (x * y) = 0) : I.Cotangent →ₗ[R] M` (Mathlib/RingTheory/Ideal/Cotangent.lean:234, added 2026-04 in #35593, an imported file). `Ideal.Cotangent.lift (kerToTensor R A B) _` is definitionally equal to the current definition (`rfl`), so swapping it in cannot break downstream files. Its side condition is a one-line `simp`, and `kerCotangentToTensor_toCotangent` stays `rfl`.","fix":"Define `kerCotangentToTensor := Ideal.Cotangent.lift (kerToTensor R A B) fun x y ↦ by simp [show x * y = (x : A) • y from rfl, TensorProduct.smul_tmul', ← algebraMap_eq_smul_one, RingHom.mem_ker.mp x.2]`.","ev":"-- hunts/kaehler/batch4/p1_checks.lean (compiles)\nnoncomputable def kct' : (RingHom.ker (algebraMap A B)).Cotangent →ₗ[A] B ⊗[A] Ω[A⁄R] :=\n  Ideal.Cotangent.lift (kerToTensor R A B) fun x y ↦ by\n    rw [show x * y = (x : A) • y from rfl, map_smul, kerToTensor_apply, smul_tmul',\n      ← Algebra.algebraMap_eq_smul_one, RingHom.mem_ker.mp x.2, zero_tmul]\n\nexample : kct' R A B = kerCotangentToTensor R A B := rfl\n-- and hunts/kaehler/batch4/cB_cotangentLift.lean: src.lean with the definition replaced by the `fix` (simp side condition); whole file compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-27d972","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.kerCotangentToTensor_toCotangent","line":813,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"simp-lemma-blocked-by-inner-rewrite","claim":"This `@[simp]` lemma never fires under plain `simp` when `B = A ⧸ J`, the standard surjective case. `simp` works bottom-up, so it first rewrites the explicit ideal argument of `Ideal.toCotangent (RingHom.ker (algebraMap A (A ⧸ J)))` to `RingHom.ker (Ideal.Quotient.mk J)` with the simp lemma `Ideal.Quotient.algebraMap_eq`. The LHS then no longer matches, and the goal is left stuck at `kerCotangentToTensor ℤ ℤ[X] (ℤ[X] ⧸ J) ((RingHom.ker (Ideal.Quotient.mk J)).toCotangent x) = …`. `simp only [kerCotangentToTensor_toCotangent]` works. Registering the lemma with `simp↓` (pre-order) makes plain `simp` close both the quotient case and the generic case.","fix":"Tag the lemma `@[simp↓]` (a pre-order simp lemma), so it fires before `simp` rewrites `algebraMap A (A ⧸ J)` inside the ideal.","ev":"-- hunts/kaehler/batch4/p4_simp.lean (fails as expected)\nexample (x : RingHom.ker (algebraMap ℤ[X] (ℤ[X] ⧸ J))) :\n    kerCotangentToTensor ℤ ℤ[X] (ℤ[X] ⧸ J) (Ideal.toCotangent _ x) = 1 ⊗ₜ D ℤ ℤ[X] x.1 := by\n  simp   -- unsolved goal: ... ((RingHom.ker (Ideal.Quotient.mk J)).toCotangent x) = ...; simp? reports only [Ideal.Quotient.algebraMap_eq]\n-- hunts/kaehler/batch4/p5_simp_pre.lean (compiles): after `attribute [simp↓] KaehlerDifferential.kerCotangentToTensor_toCotangent` the same `example` and the generic-A,B version both close by `simp`","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-523659","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.range_kerCotangentToTensor","line":818,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"long-proof","claim":"The proof is 41 lines (L822-862). Its hard direction does fibrewise bookkeeping by hand. It uses `Finset.sum_fiberwise_of_maps_to` over `x.support.image (algebraMap A B)` and builds an `attach`-indexed witness. It also runs a `simpa` that unfolds the definitions `Finsupp.mapDomain` and `Finsupp.sum` (L846), followed by two long `simp only` lists. It is fast: the whole declaration takes about 0.5 s cumulative under the profiler.","fix":"Split out the fibre step as a lemma (for `f ∈ ker finsupp_map` and a chosen lift `a` of `c`, `1 ⊗ₜ ∑_{i ↦ c} f i • D i ∈ range kerCotangentToTensor`), and avoid unfolding `Finsupp.mapDomain` by using `Finsupp.mapDomain_apply`-style lemmas.","ev":"-- awk 'NR>=822 && NR<=862' src.lean | wc -l  ->  41; profiler (batch4/cE0_baseline.lean): simp 114-117ms, typeclass inference 224-233ms, tactic execution 76-80ms","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4f8c05","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.mapBaseChange_surjective","line":869,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"hypothesis-stronger-than-used","claim":"The hypothesis `Function.Surjective (algebraMap A B)` is used only to get `Subsingleton Ω[B⁄A]` (via `subsingleton_of_surjective`). The same proof works under `[Subsingleton Ω[B⁄A]]`, which is in fact equivalent to the conclusion (`Surjective (mapBaseChange R A B) ↔ Subsingleton Ω[B⁄A]` compiles). The general form covers formally unramified extensions: étale algebras and localisations, where `algebraMap` is not surjective. There the current lemma cannot be applied, so `KaehlerDifferential.tensorKaehlerEquivOfFormallyEtale` (Etale/Kaehler.lean:39) re-derives surjectivity inline from `exact_mapBaseChange_map` and `Subsingleton.elim`.","fix":"Add `mapBaseChange_surjective_of_subsingleton [Subsingleton Ω[B⁄A]]` (and the iff), derive `mapBaseChange_surjective` from it, and use it in `tensorKaehlerEquivOfFormallyEtale`.","ev":"import Mathlib.RingTheory.Kaehler.Basic\nimport Mathlib.RingTheory.Unramified.Basic\n\nopen KaehlerDifferential TensorProduct\n\nvariable (R A B : Type*) [CommRing R] [CommRing A] [CommRing B] [Algebra R A] [Algebra A B]\n  [Algebra R B] [IsScalarTower R A B]\n\n/-- Same proof as `mapBaseChange_surjective`, with `Subsingleton Ω[B⁄A]` in place of\nsurjectivity of `algebraMap A B`. -/\ntheorem mapBaseChange_surjective_of_subsingleton [Subsingleton Ω[B⁄A]] :\n    Function.Surjective (mapBaseChange R A B) := by\n  rw [← LinearMap.range_eq_top, range_mapBaseChange, ← top_le_iff]\n  exact fun x _ ↦ Subsingleton.elim _ _\n\n-- the current lemma is a special case\nexample (h : Function.Surjective (algebraMap A B)) :\n    Function.Surjective (mapBaseChange R A B) :=\n  have := subsingleton_of_surjective A B h\n  mapBaseChange_surjective_of_subsingleton R A B\n\n-- and the hypothesis is in fact necessary: surjectivity of `mapBaseChange` is equivalent to it\ntheorem mapBaseChange_surjective_iff :\n    Function.Surjective (mapBaseChange R A B) ↔ Subsingleton Ω[B⁄A] := by\n  refine ⟨fun h ↦ ⟨fun x y ↦ ?_⟩, fun _ ↦ mapBaseChange_surjective_of_subsingleton R A B⟩\n  obtain ⟨x, rfl⟩ := map_surjective R A B x\n  obtain ⟨y, rfl⟩ := map_surjective R A B y\n  obtain ⟨x, rfl⟩ := h x\n  obtain ⟨y, rfl⟩ := h y\n  rw [(exact_mapBaseChange_map R A B _).mpr ⟨x, rfl⟩,\n    (exact_mapBaseChange_map R A B _).mpr ⟨y, rfl⟩]\n\n-- covers formally unramified (e.g. étale, localisation) extensions, where `algebraMap A B`\n-- need not be surjective; `Etale/Kaehler.lean` reproves this inline today\nexample [Algebra.FormallyUnramified A B] : Function.Surjective (mapBaseChange R A B) :=\n  mapBaseChange_surjective_of_subsingleton R A B\n\n-- `mapBaseChange_surjective` itself cannot be applied there:\nexample [Algebra.FormallyUnramified A B] : Function.Surjective (mapBaseChange R A B) :=\n  mapBaseChange_surjective R A B\n\n-- result: everything compiles except the last `example`, which fails as expected (type mismatch: needs `Function.Surjective ⇑(algebraMap A B)`)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-41a13b","file":"Mathlib/RingTheory/Localization/Away/AdjoinRoot.lean","decl":"Localization.awayEquivAdjoin","line":25,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"`awayEquivAdjoin` has no computation lemmas: `simp` cannot show it sends `IsLocalization.Away.invSelf r` to `AdjoinRoot.root (C r * X - 1)`, or the reverse for `.symm`. Its docstring does not say this either. The forward map also re-builds `IsLocalization.Away.liftAlgHom` by hand.","fix":"Add `@[simp] awayEquivAdjoin_invSelf` and `awayEquivAdjoin_symm_root`, and build the forward map with `IsLocalization.Away.liftAlgHom`.","ev":"-- hunts/away-adjoinroot/P2.lean: `example (r : R) : Localization.awayEquivAdjoin r (IsLocalization.Away.invSelf (S := Localization.Away r) r) = AdjoinRoot.root (C r * X - 1) := by simp` fails (`simp` made no progress).","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-96734a","file":"Mathlib/RingTheory/Localization/Away/AdjoinRoot.lean","decl":"IsLocalization.adjoin_inv","line":34,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-instance","claim":"`IsLocalization.adjoin_inv : IsLocalization.Away r (AdjoinRoot (C r * X - 1))` is a theorem, not an instance (the `r` is recoverable from the goal), so `infer_instance` cannot find it. The name also says nothing about `AdjoinRoot` (e.g. `AdjoinRoot.isLocalizationAway`).","fix":"Register it as an instance (and consider `AdjoinRoot.isLocalizationAway` as the name).","ev":"-- hunts/away-adjoinroot/P2.lean: `example (r : R) : IsLocalization.Away r (AdjoinRoot (C r * X - 1)) := by infer_instance` fails (synthInstanceFailed).","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-3a81c1","file":"Mathlib/RingTheory/Localization/Away/AdjoinRoot.lean","decl":"instance@L55","line":55,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"redundant-instance","claim":"The final instance `Algebra.FiniteType R (Localization.Away f)` (for `[Algebra.FiniteType R S]`) is redundant. With only `Localization.Away.Basic` and `Localization.InvSubmonoid` imported, i.e. without this file, `infer_instance` already finds it through `IsLocalization.instFiniteTypeLocalizationOfFGSubtypeMemSubmonoid`. Graded MINOR: it is a redundant Prop-valued instance, not a data diamond.","fix":"Delete the instance.","ev":"-- hunts/away-adjoinroot/P1.lean (imports only Away.Basic and InvSubmonoid): `example [CommRing R] [CommRing S] [Algebra R S] [Algebra.FiniteType R S] (f : S) : Algebra.FiniteType R (Localization.Away f) := by infer_instance` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-81500f","file":"Mathlib/RingTheory/Localization/Basic.lean","decl":"IsLocalization.self","line":344,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `IsLocalization.self` (RingTheory.Localization.Basic), `IsLocalization.of_le_isUnit` (RingTheory.Localization.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file, both `M ≤ IsUnit.submonoid R → IsLocalization M R`; `IsLocalization.self` is proved again via `isLocalization_of_algEquiv`/`atUnits`. Keep `of_le_isUnit` (rename target of deprecated `at_units`, 4 uses), deprecate `IsLocalization.self` (2 uses in FractionRing.lean).","fix":"Deprecate `IsLocalization.self` in favour of `IsLocalization.of_le_isUnit`.","ev":"dupscan/Check.lean: `example := (@IsLocalization.of_le_isUnit : type_of% @IsLocalization.self)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 22, rating MAJOR): `self` has no special registration requiring its name, and the earlier theorem already constructs precisely the required localization instance.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-5c512b","file":"Mathlib/RingTheory/MvPolynomial/MonomialOrder.lean","decl":"MonomialOrder.Monic.of_subsingleton","line":139,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `MonomialOrder.monic_of_subsingleton` (RingTheory.MvPolynomial.MonomialOrder), `MonomialOrder.Monic.of_subsingleton` (RingTheory.MvPolynomial.MonomialOrder) state exactly the same thing (Lean-checked). Reviewer: Same file: `[Subsingleton R] → m.Monic p` appears at line 139 as @[nontriviality] Monic.of_subsingleton (implicit f) and at line 928 as @[simp, nontriviality] monic_of_subsingleton (explicit p). The attribute is duplicated and neither is used. Keep monic_of_subsingleton (mirrors Polynomial.monic_of_subsingleton) and deprecate Monic.of_subsingleton.","fix":"Deprecate `MonomialOrder.Monic.of_subsingleton` in favour of `MonomialOrder.monic_of_subsingleton`.","ev":"dupscan/Check.lean: `example := (@MonomialOrder.Monic.of_subsingleton : type_of% @MonomialOrder.monic_of_subsingleton)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 24, rating MAJOR): Consolidate, but move the retained lemma earlier using the direct proof: [Monic.mul and Monic.pow](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/RingTheory/MvPolynomial/MonomialOrder.lean#L519) invoke `nontriviality` before line 928. Counting named references misses this tactic dependency.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-892781","file":"Mathlib/RingTheory/MvPolynomial/MonomialOrder.lean","decl":"MonomialOrder.le_degree_of_mem_support","line":856,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `MonomialOrder.le_degree_of_mem_support` (RingTheory.MvPolynomial.MonomialOrder), `MonomialOrder.le_degree` (RingTheory.MvPolynomial.MonomialOrder) state exactly the same thing (Lean-checked). Reviewer: Same file: `le_degree_of_mem_support (ha : a ∈ p.support) : a ≼[m] m.degree p` re-proves `le_degree`, which is about 600 lines earlier. Deprecate the later, unused lemma.","fix":"Deprecate `MonomialOrder.le_degree_of_mem_support` in favour of `MonomialOrder.le_degree`.","ev":"dupscan/Check.lean: `example := (@MonomialOrder.le_degree : type_of% @MonomialOrder.le_degree_of_mem_support)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 26, rating MAJOR): The later theorem adds no attribute, stronger conclusion, or distinct application interface. The existing `le_degree` already handles it directly.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-78e24a","file":"Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean","decl":"MvPolynomial.sum_weightedHomogeneousComponent","line":445,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `MvPolynomial.sum_weightedHomogeneousComponent` (RingTheory.MvPolynomial.WeightedHomogeneous), `MvPolynomial.finsum_weightedHomogeneousComponent` (RingTheory.MvPolynomial.WeightedHomogeneous) state exactly the same thing (Lean-checked). Reviewer: Both state `(finsum fun m => weightedHomogeneousComponent w m φ) = φ`; the `finsum_` version just rewrites with `sum_`, and no deprecation links them. Keep the accurate `finsum_` name, because the statement is a finsum and unweighted sum_homogeneousComponent is a Finset sum. Deprecate `sum_` after updating the module doc, the l.373 docstring and the 1 use at l.676.","fix":"Deprecate `MvPolynomial.sum_weightedHomogeneousComponent` in favour of `MvPolynomial.finsum_weightedHomogeneousComponent`.","ev":"dupscan/Check.lean: `example := (@MvPolynomial.finsum_weightedHomogeneousComponent : type_of% @MvPolynomial.sum_weightedHomogeneousComponent)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 25, rating MINOR): `finsum_weightedHomogeneousComponent` already delegates to the other theorem, so this resembles an intended naming alias written manually. Keeping the accurate name is reasonable, with modest benefit.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-459a92","file":"Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean","decl":"MvPolynomial.weightedHomogeneousComponent_eq_self","line":509,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `MvPolynomial.IsWeightedHomogeneous.weightedHomogeneousComponent_same` (RingTheory.MvPolynomial.WeightedHomogeneous), `MvPolynomial.weightedHomogeneousComponent_eq_self` (RingTheory.MvPolynomial.WeightedHomogeneous) state exactly the same thing (Lean-checked). Reviewer: Same file: `IsWeightedHomogeneous w p m → weightedHomogeneousComponent w m p = p` is proved at line 468 (ext/split_ifs) and re-added at line 509 (`simp [weightedHomogeneousComponent_of_mem hp]`), with no comment. Keep the older dot-notation lemma (1 use) and deprecate weightedHomogeneousComponent_eq_self (unused). The reverse also works, since it matches Homogeneous' homogeneousComponent_eq_self.","fix":"Deprecate `MvPolynomial.weightedHomogeneousComponent_eq_self` in favour of `MvPolynomial.IsWeightedHomogeneous.weightedHomogeneousComponent_same`.","ev":"dupscan/Check.lean: `example := (@MvPolynomial.weightedHomogeneousComponent_eq_self : type_of% @MvPolynomial.IsWeightedHomogeneous.weightedHomogeneousComponent_same)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup3 item 23, rating MINOR): These form a reasonable proof-method/operation-name pair, and `_eq_self` matches the unweighted API. Preserve the second spelling as an alias instead of removing that access path.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-45d30a","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.isEmptyEquiv","line":54,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"commsemiring-where-semiring-suffices","claim":"isEmptyEquiv assumes [CommSemiring R], but the isomorphism and its proof (constantCoeff / C) only need a semiring of coefficients: with [Semiring R] [CommSemiring S] [Algebra S R] the same `where` block gives MvPowerSeries σ R ≃ₐ[S] R unchanged (commutes' still rfl). MvPowerSeries' ring/algebra API (Basic.lean) is stated for [Semiring A] [Algebra R A].","fix":"State it for [Semiring R] with an explicit commutative base S and [Algebra S R], i.e. MvPowerSeries σ R ≃ₐ[S] R.","ev":"hunts/mvpowerseries-equiv/batch0/Gen.lean (copy of the file truncated after the optionEquivLeft section, variables `{S σ R} [CommSemiring S] [Semiring R] [Algebra S R]`; `def isEmptyEquiv [IsEmpty σ] : MvPowerSeries σ R ≃ₐ[S] R` with the original body; `example ... [CommSemiring R] [IsEmpty σ] : MvPowerSeries σ R ≃ₐ[R] R := isEmptyEquiv R σ R`); compiles with exit 0, no messages","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-72419b","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.isEmptyEquiv","line":54,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"argument-order-differs-from-mvpolynomial-analogue","claim":"The explicit arguments are (σ R): `isEmptyEquiv σ R`, the reverse of its declared model `MvPolynomial.isEmptyAlgEquiv R σ` (the module docstring says the file is patterned after Mathlib/Algebra/MvPolynomial/Equiv.lean), and of `MvPowerSeries.finSuccEquiv R n` in the same file.","fix":"Order the explicit arguments (R σ) as in MvPolynomial.isEmptyAlgEquiv (use `variable (R σ) in` after reordering the variable binder, or name the binders explicitly).","ev":"hunts/mvpowerseries-equiv/batch0/Probe1.lean: `#check @MvPowerSeries.isEmptyEquiv` gives `(σ : Type u_1) → (R : Type u_2) → [CommSemiring R] → [IsEmpty σ] → MvPowerSeries σ R ≃ₐ[R] R`; `#check @MvPolynomial.isEmptyAlgEquiv` gives `(R : Type u_1) → (σ : Type u_2) → [CommSemiring R] → [IsEmpty σ] → MvPolynomial σ R ≃ₐ[R] R`; `#check @MvPowerSeries.finSuccEquiv` gives `(R : Type u_1) → [CommSemiring R] → (n : ℕ) → ...`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-057737","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.optionEquivLeft","line":119,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"commsemiring-where-semiring-suffices","claim":"optionEquivLeft (and every helper and lemma of its section) assumes [CommSemiring R], but the isomorphism MvPowerSeries (Option σ) R ≃ PowerSeries (MvPowerSeries σ R) needs only a semiring of coefficients: with [Semiring R] [CommSemiring S] [Algebra S R] the whole section compiles as an S-algebra isomorphism with the proofs unchanged (only `commutes'` passes `algebraMap S R r`), e.g. for matrix coefficients over ℚ. Unlike MvPolynomial (CommSemiring-only), MvPowerSeries' API is stated for Semiring coefficients.","fix":"Generalise the optionEquivLeft section to [Semiring R] with an explicit commutative base S and [Algebra S R], giving MvPowerSeries (Option σ) R ≃ₐ[S] PowerSeries (MvPowerSeries σ R).","ev":"hunts/mvpowerseries-equiv/batch0/Gen.lean (section `Semiring`, `variable {S σ R : Type*} [CommSemiring S] [Semiring R] [Algebra S R]`; optionFunLeft, coeff_coeff_optionFunLeft, optionFunLeft_monomial, optionFunLeft_mul, optionInvFunLeft, coeff_optionInvFunLeft, `def optionEquivLeft : MvPowerSeries (Option σ) R ≃ₐ[S] PowerSeries (MvPowerSeries σ R)`, coeff_coeff_optionEquivLeft, optionEquivLeft_monomial, optionEquivLeft_X_some, optionEquivLeft_X_none, optionEquivLeft_C with original proofs; plus `example {σ : Type*} : MvPowerSeries (Option σ) (Matrix (Fin 2) (Fin 2) ℚ) ≃ₐ[ℚ] PowerSeries (MvPowerSeries σ (Matrix (Fin 2) (Fin 2) ℚ)) := optionEquivLeft ℚ σ _`); compiles with exit 0, no messages","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-b0dc61","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.optionEquivLeft","line":119,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"argument-order-differs-from-mvpolynomial-analogue","claim":"The explicit arguments are (σ R): `optionEquivLeft σ R`, the reverse of the same-named model `MvPolynomial.optionEquivLeft R S₁` that the file says it is patterned after, and of `MvPowerSeries.finSuccEquiv R n`, which is defined from it in the same file. With both namespaces open, `optionEquivLeft R σ` silently means different things.","fix":"Order the explicit arguments (R σ) as in MvPolynomial.optionEquivLeft.","ev":"hunts/mvpowerseries-equiv/batch0/Probe1.lean: `#check @MvPowerSeries.optionEquivLeft` gives `(σ : Type u_1) → (R : Type u_2) → [CommSemiring R] → MvPowerSeries (Option σ) R ≃ₐ[R] PowerSeries (MvPowerSeries σ R)`; `#check @MvPolynomial.optionEquivLeft` gives `(R : Type u_1) → (S₁ : Type u_2) → [CommSemiring R] → MvPolynomial (Option S₁) R ≃ₐ[R] Polynomial (MvPolynomial S₁ R)`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-ec24f5","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.coeff_coeff_optionEquivLeft","line":130,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-symm-api-for-no-expose-equiv","claim":"optionEquivLeft is @[no_expose] and its inverse's coefficient lemma `coeff_optionInvFunLeft` is private, so the inverse direction has no API: there is no coefficient formula for `(optionEquivLeft σ R).symm f` (not provable by rfl from a downstream module), and no `@[simp]` companions `optionEquivLeft_symm_X`, `optionEquivLeft_symm_C_X`, `optionEquivLeft_symm_C_C`, which MvPolynomial.optionEquivLeft has. `simp` makes no progress on `(optionEquivLeft σ R).symm PowerSeries.X = X none`; each is a one-liner with `AlgEquiv.symm_apply_eq`.","fix":"Add `coeff_optionEquivLeft_symm : coeff x ((optionEquivLeft σ R).symm f) = coeff x.some (PowerSeries.coeff (x none) f)` and @[simp] `optionEquivLeft_symm_X`, `optionEquivLeft_symm_C_X`, `optionEquivLeft_symm_C_C`.","ev":"hunts/mvpowerseries-equiv/batch0/Probe1.lean P4: `example : (optionEquivLeft σ R).symm PowerSeries.X = X none := by simp` (and the C (X i), C (C r) versions) -> error '`simp` made no progress'; P4': same with `simp [AlgEquiv.symm_apply_eq]` compiles; P5: the symm coefficient formula `by simp` -> 'simp made no progress'; P5': `conv_rhs => rw [← (optionEquivLeft σ R).apply_symm_apply f]; rw [coeff_coeff_optionEquivLeft, optionElim_some]` compiles. hunts/mvpowerseries-equiv/batch0/ModProbe.lean (a `module` with `public import Mathlib.RingTheory.MvPowerSeries.Equiv`): the same formula `by rfl` -> 'Tactic rfl failed ... not definitionally equal'","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-15ffc4","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.finSuccEquiv","line":169,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-symm-api","claim":"`finSuccEquiv` has no `symm` API. Plain `simp` makes no progress on `(finSuccEquiv R n).symm PowerSeries.X = X 0`, on `(finSuccEquiv R n).symm (PowerSeries.C (X j)) = X j.succ`, or on `coeff (x.cons k) ((finSuccEquiv R n).symm f) = coeff x (PowerSeries.coeff k f)`. All three hold, through `AlgEquiv.symm_apply_eq` / `apply_symm_apply`. Compare `MvPolynomial.optionEquivLeft_symm_X/_symm_C_X/_symm_C_C`.","fix":"Add `@[simp]` lemmas `finSuccEquiv_symm_X`, `finSuccEquiv_symm_C_X`, `finSuccEquiv_symm_C_C` and a coefficient lemma `coeff_cons_finSuccEquiv_symm`.","ev":"hunts/mvpowerseries-equiv/batch1/Probe1.lean P4: `example : (MvPowerSeries.finSuccEquiv R n).symm PowerSeries.X = X 0 := by simp` (and the C (X j), coeff variants) give `simp made no progress`. P4': the same statements compile with `simp [AlgEquiv.symm_apply_eq]` and with `rw [← coeff_coeff_finSuccEquiv, AlgEquiv.apply_symm_apply]`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-eb368a","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.finSuccEquiv_X_zero","line":180,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"coefficient-chase-instead-of-simp","claim":"The proof is a 7–8 line coefficient chase (`ext k x; simp_rw [...]; split_ifs` into 4 cases closed by `simp`/`tauto`/`rw`), and the same block is repeated across `finSuccEquiv_X_zero`, `finSuccEquiv_X_succ` and `finSuccEquiv_C`. But `simp [finSuccEquiv]` proves `finSuccEquiv R n (X 0) = .X` in one line from the existing API (rename_X, finSuccEquiv_zero, optionEquivLeft_X_none); the MvPolynomial analogues are also one-line `simp`s.","fix":"Replace the proof by `simp [finSuccEquiv]`.","ev":"hunts/mvpowerseries-equiv/batch1/EquivCopy.lean (copy of src.lean with the proof replaced in place by `simp [finSuccEquiv]`, compiles); also hunts/mvpowerseries-equiv/batch1/Probe1.lean P1 with the lemma itself erased from the simp set (`simp [MvPowerSeries.finSuccEquiv, -MvPowerSeries.finSuccEquiv_X_zero]`).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-643de9","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.finSuccEquiv_X_succ","line":190,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"coefficient-chase-instead-of-simp","claim":"The proof is a 7–8 line coefficient chase (`ext k x; simp_rw [...]; split_ifs` into 4 cases closed by `simp`/`tauto`/`rw`), and the same block is repeated across `finSuccEquiv_X_zero`, `finSuccEquiv_X_succ` and `finSuccEquiv_C`. But `simp [finSuccEquiv]` proves `finSuccEquiv R n (X j.succ) = .C (X j)` in one line from the existing API (rename_X, finSuccEquiv_succ, optionEquivLeft_X_some); the MvPolynomial analogues are also one-line `simp`s.","fix":"Replace the proof by `simp [finSuccEquiv]`.","ev":"hunts/mvpowerseries-equiv/batch1/EquivCopy.lean (copy of src.lean with the proof replaced in place by `simp [finSuccEquiv]`, compiles); also hunts/mvpowerseries-equiv/batch1/Probe1.lean P1 with the lemma itself erased from the simp set (`simp [MvPowerSeries.finSuccEquiv, -MvPowerSeries.finSuccEquiv_X_succ]`).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-46fdfb","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.finSuccEquiv_C","line":200,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"coefficient-chase-instead-of-simp","claim":"The proof is a 7–8 line coefficient chase (`ext k x; simp_rw [...]; split_ifs` into 4 cases closed by `simp`/`tauto`/`rw`), and the same block is repeated across `finSuccEquiv_X_zero`, `finSuccEquiv_X_succ` and `finSuccEquiv_C`. But `simp [finSuccEquiv]` proves `finSuccEquiv R n (C r) = PowerSeries.C (C r)` in one line from the existing API (rename_C, optionEquivLeft_C); the MvPolynomial analogues are also one-line `simp`s.","fix":"Replace the proof by `simp [finSuccEquiv]`.","ev":"hunts/mvpowerseries-equiv/batch1/EquivCopy.lean (copy of src.lean with the proof replaced in place by `simp [finSuccEquiv]`, compiles); also hunts/mvpowerseries-equiv/batch1/Probe1.lean P1 with the lemma itself erased from the simp set (`simp [MvPowerSeries.finSuccEquiv, -MvPowerSeries.finSuccEquiv_C]`).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-de0471","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.finSuccEquiv_comp_C","line":210,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"statement-not-in-simp-normal-form","claim":"The statement is written with `(finSuccEquiv R n).symm.toRingHom`, which elaborates to `.toRingEquiv.toRingHom` and not to the coercion `(↑e : _ →+* _)` that `MvPolynomial.finSuccEquiv_comp_C_eq_C` uses. So `simp only [finSuccEquiv_comp_C]` makes no progress on the coercion form. The full `simp [finSuccEquiv_comp_C]` cannot even close the lemma's own statement: it first rewrites `toRingHom` with `RingEquiv.toRingHom_eq_coe`, then reports the lemma as unused.","fix":"State it as `((finSuccEquiv R n).symm : PowerSeries (MvPowerSeries (Fin n) R) →+* MvPowerSeries (Fin (n + 1)) R).comp (PowerSeries.C.comp C) = C`; the same proof `ext1; simp [AlgEquiv.symm_apply_eq]` works.","ev":"hunts/mvpowerseries-equiv/batch1/Probe2.lean: (c) `simp [finSuccEquiv_comp_C, -RingHom.ext_iff]` on the lemma's own statement leaves `⊢ (↑{ toEquiv := ↑(finSuccEquiv R n).symm, .. }).comp (PowerSeries.C.comp C) = C` with 'simp argument is unused'; (d) `simp only [finSuccEquiv_comp_C]` on the coercion form gives 'simp made no progress' (and `rw` gives 'did not find an occurrence of the pattern' in EquivCopy.lean); (e) the coercion form compiles with `ext1; simp [AlgEquiv.symm_apply_eq]`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-6836ea","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.isNoetherianRing","line":224,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"module-docstring-omits-main-result","claim":"The module docstring (lines 16–35) lists `isEmptyEquiv`, `optionEquivLeft`, `finSuccEquiv` and `toAdicCompletionAlgEquiv`, but not the Hilbert-basis instance `MvPowerSeries.isNoetherianRing` (or `PowerSeries.toMvPowerSeries`). The only Noetherian instance for `MvPowerSeries` thus sits in a file named `Equiv` with no mention in its header.","fix":"Add `MvPowerSeries.isNoetherianRing` (power series in finitely many variables over a Noetherian ring form a Noetherian ring) to the module docstring.","ev":"`sed -n '16,35p' src.lean | grep -ciE 'noetherian|toMvPowerSeries'` = 0; `git grep Noetherian origin/master -- Mathlib | grep -i powerseries` shows that this file holds the only `IsNoetherianRing (MvPowerSeries ..)` instance.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-fde440","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.toAdicCompletion","line":283,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-simp-evaluation-lemma","claim":"simp cannot evaluate `toAdicCompletion`. `toAdicCompletion_apply_eq_mk_truncTotal` and `toAdicCompletion_coe` are not @[simp], and there is no `evalₐ_toAdicCompletion`. `simp [toAdicCompletion]` also fails, because `AdicCompletion.evalₐ_liftAlgHom` cannot fire when simp cannot synthesise its `hf` argument. So `simp` fails on `evalₐ n (toAdicCompletion σ R p) = mk (truncTotal n p)` and on `toAdicCompletionAlgEquiv σ R ↑p = of p`, and the only consumer (AdicCompletion/Completeness.lean:216) has to pass `toAdicCompletion_coe` to simp by hand.","fix":"Add `@[simp] lemma evalₐ_toAdicCompletion : evalₐ _ n (toAdicCompletion σ R p) = Ideal.Quotient.mk _ (truncTotal n p) := rfl` and tag `toAdicCompletion_coe` @[simp].","ev":"hunts/mvpowerseries-equiv/batch2/evidence.lean E2: E2a/E2b/E2c/E2e (`simp`, `simp [toAdicCompletion]`) fail as expected; E2d (the evalₐ lemma by `rfl`) and E2f (with `attribute [local simp] toAdicCompletion_coe`, `simp` closes `toAdicCompletionAlgEquiv σ R ↑p = of p`) compile. In hunts/mvpowerseries-equiv/batch2/src_mod.lean, adding both lemmas as @[simp] compiles, and the same goals close by `simp`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-685721","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.toAdicCompletion_coe","line":305,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"one-line-from-alghom-commutes","claim":"The statement is `(toAdicCompletion σ R).commutes p` up to defeq, yet the 6-line proof needs `set_option backward.isDefEq.respectTransparency.types false`, unfolds the internals `toAdicCompletion`, `AdicCompletion.liftAlgHom` and `AdicCompletion.liftRingHom`, and re-derives `p - truncTotal n ↑p ∈ idealOfVars σ R ^ n`, which the `commutes'` field of `truncTotalAlgHom` already proves.","fix":"Replace the proof by the term `(toAdicCompletion σ R).commutes p` and drop the `set_option backward.isDefEq.respectTransparency.types false in`.","ev":"example (p : MvPolynomial σ R) : toAdicCompletion σ R p = .of (MvPolynomial.idealOfVars σ R) (MvPolynomial σ R) p := (toAdicCompletion σ R).commutes p  -- hunts/mvpowerseries-equiv/batch2/evidence.lean E1; also substituted in place (set_option removed) in hunts/mvpowerseries-equiv/batch2/src_mod.lean, where the whole file compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-ff4415","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.toAdicCompletionAlgEquiv_symm_apply","line":357,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"simp-unfolds-equiv-breaks-round-trip","claim":"The @[simp] lemmas `toAdicCompletionAlgEquiv_apply` and `toAdicCompletionAlgEquiv_symm_apply` rewrite `e` and `e.symm` into `toAdicCompletion` and the choice-built `toAdicCompletionInv` before `AlgEquiv.apply_symm_apply` or `symm_apply_apply` can fire. There are no `toAdicCompletion_toAdicCompletionInv` or `toAdicCompletionInv_toAdicCompletion` lemmas to make up for this, so `simp` cannot prove `e (e.symm f) = f` or `e.symm (e p) = p`; it is left with `toAdicCompletion σ R (toAdicCompletionInv σ R f) = f`.","fix":"Add @[simp] `toAdicCompletion_toAdicCompletionInv` and `toAdicCompletionInv_toAdicCompletion`, each a one-liner from `apply_symm_apply`/`symm_apply_apply`, or remove @[simp] from `toAdicCompletionAlgEquiv_symm_apply`.","ev":"hunts/mvpowerseries-equiv/batch2/evidence.lean E3: E3a/E3b `example : toAdicCompletionAlgEquiv σ R ((toAdicCompletionAlgEquiv σ R).symm f) = f := by simp` (and the converse) fail as expected; E3c, the same with `simp [-toAdicCompletionAlgEquiv_apply, -toAdicCompletionAlgEquiv_symm_apply]`, compiles. Adding the two round-trip lemmas in hunts/mvpowerseries-equiv/batch2/src_mod.lean makes plain `simp` close both.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-6dd579","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"PowerSeries.toMvPowerSeries","line":376,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-coeff-lemma","claim":"`toMvPowerSeries` has no coefficient lemma; a grep of Mathlib finds none. The only coefficient fact is `toMvPowerSeries_coeff_eq_zero`, which assumes `CommRing R`, `d i = 0` and `constantCoeff f = 0`. The general formula `coeff d (f.toMvPowerSeries i) = if d = single i (d i) then coeff (d i) f else 0` holds over a `CommSemiring`, takes about 10 lines from `coeff_embDomain_rename`/`coeff_rename_eq_zero`, and implies `toMvPowerSeries_coeff_eq_zero` without `CommRing`.","fix":"Add `coeff_toMvPowerSeries` (the `if` formula) and a @[simp] `coeff_single_toMvPowerSeries` over `CommSemiring R`, then derive `toMvPowerSeries_coeff_eq_zero` from them.","ev":"hunts/mvpowerseries-equiv/batch2/evidence.lean E5: `theorem coeff_single_toMvPowerSeries (f : PowerSeries R) (i : σ) (k : ℕ) : coeff (Finsupp.single i k) (f.toMvPowerSeries i) = PowerSeries.coeff k f`, `theorem coeff_toMvPowerSeries [DecidableEq σ] ... = if d = Finsupp.single i (d i) then PowerSeries.coeff (d i) f else 0`, and `toMvPowerSeries_coeff_eq_zero` restated over `[CommSemiring R]` all compile.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-932252","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"PowerSeries.subst_toMvPowerSeries","line":403,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"subst-target-not-generalised-to-algebra","claim":"The substituted family is restricted to `a : σ → MvPowerSeries τ R` (same coefficient ring as `f`); the same proof works verbatim for `a : σ → MvPowerSeries τ S` with any `[CommRing S] [Algebra R S]`, which is the generality of `PowerSeries.subst`/`MvPowerSeries.subst_comp_subst_apply` and of the polynomial analogue `MvPolynomial.aeval_toMvPolynomial (f : σ → S)`.","fix":"Add `{S : Type*} [CommRing S] [Algebra R S]` and state it for `a : σ → MvPowerSeries τ S`.","ev":"batch3/probe1.lean (P3) and batch3/modified.lean:\nvariable {σ τ : Type*} {R S : Type*} [CommRing R] [CommRing S] [Algebra R S]\nexample {f : R⟦X⟧} {i : σ} {a : σ → MvPowerSeries τ S} (ha : MvPowerSeries.HasSubst a) :\n    (f.toMvPowerSeries i).subst a = f.subst (a i) := by\n  rw [toMvPowerSeries_eq_subst, PowerSeries.subst, MvPowerSeries.subst_comp_subst_apply\n    (PowerSeries.HasSubst.const (PowerSeries.HasSubst.X _)) ha, MvPowerSeries.subst_X ha,\n    PowerSeries.subst]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-8f14e2","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"PowerSeries.toMvPowerSeries_coeff_eq_zero","line":408,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"commring-where-commsemiring-suffices","claim":"The lemma sits in `section CommRing` (line 398, `[CommRing R]`) only because its proof routes through `rename_eq_subst`/`coeff_subst`; the statement (coeff d (toMvPowerSeries i f) = 0 when d i = 0 and constantCoeff f = 0) mentions no substitution and holds verbatim over `[CommSemiring R]`, where `toMvPowerSeries` itself is defined.","fix":"Move it next to `toMvPowerSeries_inj` under `[CommSemiring R]` and prove it from `MvPowerSeries.coeff_rename_eq_zero` and `constantCoeff_rename` (or from a `coeff_toMvPowerSeries` formula).","ev":"batch3/probe1.lean (P1, P1b) and batch3/modified.lean: under `variable {R σ : Type*} [CommSemiring R]`:\nexample {f : R⟦X⟧} {i : σ} {d : σ →₀ ℕ} (hd : d i = 0) (hf : f.constantCoeff = 0) :\n    (f.toMvPowerSeries i).coeff d = 0 := by\n  rcases eq_or_ne d 0 with rfl | h0\n  · rw [toMvPowerSeries_apply, MvPowerSeries.coeff_zero_eq_constantCoeff_apply,\n      MvPowerSeries.constantCoeff_rename]\n    exact hf\n  · refine MvPowerSeries.coeff_rename_eq_zero _ _ ?_\n    rintro ⟨x, rfl⟩\n    apply h0\n    rw [Finsupp.unique_single x, Finsupp.mapDomain_single] at hd ⊢\n    simp_all","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-ec2d5b","file":"Mathlib/RingTheory/Polynomial/Basic.lean","decl":"Polynomial.coeff_restriction'","line":292,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Polynomial.coeff_restriction` (RingTheory.Polynomial.Basic), `Polynomial.coeff_restriction'` (RingTheory.Polynomial.Basic) state exactly the same thing (Lean-checked). Reviewer: These are adjacent. `↑(coeff (restriction p) n)` and `(coeff (restriction p) n).1` are both Subtype.val, so the primed lemma (proved `by simp`) is a Lean 3 coe-vs-.1 port artifact. Keep the @[simp] unprimed lemma and deprecate the primed one (1 use, at line 326).","fix":"Deprecate `Polynomial.coeff_restriction'` in favour of `Polynomial.coeff_restriction`.","ev":"dupscan/Check.lean: `example := (@Polynomial.coeff_restriction' : type_of% @Polynomial.coeff_restriction)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 27, rating MAJOR): Coercion notation and `.1` select the same projection here; the unprimed simp theorem covers the primed rewrite.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-0de771","file":"Mathlib/RingTheory/Polynomial/Selmer.lean","decl":"(file)","line":15,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-drops-hypothesis","claim":"The module docstring says 'This file proves irreducibility of the Selmer polynomials `X ^ n - X - 1`' and lists `X_pow_sub_X_sub_one_irreducible`: 'The Selmer polynomials `X ^ n - X - 1` are irreducible', with no exception and no coefficient ring. At n = 1 the polynomial is the unit -1 (not irreducible), and over ℂ it is reducible for every n ≥ 2; the theorems are for n ≠ 1 over ℤ and ℚ. `X_pow_sub_X_sub_one_irreducible_rat` is missing from Main results, neither public theorem has a docstring, and the TODO does not name the Galois group (Sₙ over ℚ).","fix":"State the results as irreducibility over ℤ and ℚ for n ≠ 1 (n = 0 gives -X), list both theorems, give each a docstring, and make the TODO say 'Galois group Sₙ over ℚ'.","ev":"hunts/selmer/probe.lean (A): `example : ¬ Irreducible (X ^ 1 - X - 1 : ℤ[X])` compiles (exit 0). Measured: source L15, L19-21; no docstring on L49 or L69.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-6c6d8b","file":"Mathlib/RingTheory/Polynomial/Selmer.lean","decl":"X_pow_sub_X_sub_one_irreducible_aux","line":33,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"overspecialised-scalar","claim":"`X_pow_sub_X_sub_one_irreducible_aux` is stated for `z : ℂ` but uses nothing complex: the same proof works verbatim over any field of characteristic zero. (Characteristic cannot be dropped: in 𝔽₄ = 𝔽₂[α], n = 2, z = α satisfies both equations.)","fix":"State it for `{K : Type*} [Field K] [CharZero K] (z : K)`, under a descriptive name (see the api finding).","ev":"hunts/selmer/probe.lean (C): the statement for `{K} [Field K] [CharZero K] (z : K)` compiles with the file's proof (shortened as in the proof finding), exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-934ee0","file":"Mathlib/RingTheory/Polynomial/Selmer.lean","decl":"X_pow_sub_X_sub_one_irreducible_aux","line":38,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"rebuilds-existing-lemma","claim":"`X_pow_sub_X_sub_one_irreducible_aux` rebuilds `pow_eq_pow_mod` with `rw [← Nat.mod_add_div n 3, pow_add, pow_mul, h3, one_pow, mul_one]` (L38); `rw [pow_eq_pow_mod n h3]` is the existing lemma.","fix":"Replace L38 by `rw [pow_eq_pow_mod n h3]`.","ev":"hunts/selmer/probe.lean (C): the proof with `rw [pow_eq_pow_mod n h3]` in place of L38 compiles, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-09141e","file":"Mathlib/RingTheory/Polynomial/Selmer.lean","decl":"X_pow_sub_X_sub_one_irreducible_rat","line":69,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"duplicated-proof-setup","claim":"`X_pow_sub_X_sub_one_irreducible_rat` repeats the `n = 0` case split, the trinomial identity `hp` and the derivation of `1 < n` from `X_pow_sub_X_sub_one_irreducible` (L70-75 vs L50-56), only to get primitivity from `trinomial_monic`. The integer polynomial is primitive for every `n` (its value at 1 is -1), so the whole proof is five lines with no case split.","fix":"Replace the proof by: `have hp : (X ^ n - X - 1 : ℤ[X]).IsPrimitive := fun a ha => isUnit_of_dvd_one (by simpa using _root_.map_dvd (evalRingHom (1 : ℤ)) ha)` then `simpa using (IsPrimitive.Int.irreducible_iff_irreducible_map_cast hp).mp (X_pow_sub_X_sub_one_irreducible hn1)`.","ev":"hunts/selmer/probe.lean (B): the five-line proof of `Irreducible (X ^ n - X - 1 : ℚ[X])` from `hn1 : n ≠ 1` compiles at 4e77f237dc2 (`lake env lean`, exit 0, no warnings).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-272ed4","file":"Mathlib/RingTheory/Polynomial/Subring.lean","decl":"Polynomial.coeff_toSubring'","line":54,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Polynomial.coeff_toSubring'` (RingTheory.Polynomial.Subring), `Polynomial.coeff_toSubring` (RingTheory.Polynomial.Subring) state exactly the same thing (Lean-checked). Reviewer: `coeff_toSubring'` uses `.1` where `coeff_toSubring` (@[simp]) uses `↑`, and both elaborate to Subtype.val. The primed lemma is just `by simp` and carries no comment. Deprecate it.","fix":"Deprecate `Polynomial.coeff_toSubring'` in favour of `Polynomial.coeff_toSubring`.","ev":"dupscan/Check.lean: `example := (@Polynomial.coeff_toSubring : type_of% @Polynomial.coeff_toSubring')` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 28, rating MAJOR): The projection spelling supplies no additional rewriting behavior, and the primed wrapper has no distinguishing attribute or interface.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-06f801","file":"Mathlib/RingTheory/RootsOfUnity/Basic.lean","decl":"rootsOfUnity.coe_mkOfPowEq","line":98,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `rootsOfUnity.coe_mkOfPowEq` (RingTheory.RootsOfUnity.Basic), `rootsOfUnity.val_mkOfPowEq_coe` (RingTheory.RootsOfUnity.Basic) state exactly the same thing (Lean-checked). Reviewer: `@[simps! coe_val]` on `mkOfPowEq` (line 93) already generates the @[simp] lemma `val_mkOfPowEq_coe : ↑↑(mkOfPowEq ζ h) = ζ` (used 3 times in KummerExtension/SpecialLinearGroup). The hand-written @[simp] `coe_mkOfPowEq` five lines later states the same thing, has no uses and no comment. Deprecate `coe_mkOfPowEq`.","fix":"Deprecate `rootsOfUnity.coe_mkOfPowEq` in favour of `rootsOfUnity.val_mkOfPowEq_coe`.","ev":"dupscan/Check.lean: `example := (@rootsOfUnity.val_mkOfPowEq_coe : type_of% @rootsOfUnity.coe_mkOfPowEq)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup3 item 29, rating MINOR): The [manual lemma](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/RingTheory/RootsOfUnity/Basic.lean#L98) permits `coe_mkOfPowEq h`, inferring `ζ`; the generated lemma retains the constructor’s explicit `ζ`. That useful inference interface and conventional `coe_` name merit an alias.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-dcde57","file":"Mathlib/RingTheory/Spectrum/Prime/IsOpenComapC.lean","decl":"AlgebraicGeometry.Polynomial.isOpenMap_comap_C","line":67,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Polynomial.isOpenMap_comap_C` (RingTheory.Spectrum.Prime.Polynomial), `AlgebraicGeometry.Polynomial.isOpenMap_comap_C` (RingTheory.Spectrum.Prime.IsOpenComapC) state exactly the same thing (Lean-checked). Reviewer: `IsOpenMap (comap C)` for R[X] is proved independently in two sibling files, neither importing the other. One is the old AlgebraicGeometry.Polynomial version via imageOfDf, with @[stacks 00FB]; the other is the newer Polynomial version, listed in its module doc and with an MvPolynomial sibling. Keep Polynomial.isOpenMap_comap_C, move the stacks tag, and deprecate the AlgebraicGeometry one.","fix":"Deprecate `AlgebraicGeometry.Polynomial.isOpenMap_comap_C` in favour of `Polynomial.isOpenMap_comap_C`.","ev":"dupscan/Check.lean: `example := (@AlgebraicGeometry.Polynomial.isOpenMap_comap_C : type_of% @Polynomial.isOpenMap_comap_C)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"unsure","astraS":"A2 (dup3 item 30, rating MINOR): The [older module](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/RingTheory/Spectrum/Prime/IsOpenComapC.lean#L8) imports only spectrum topology, while the [newer module](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/RingTheory/Spectrum/Prime/Polynomial.lean#L8) imports characteristic-polynomial and eigenspace machinery. Consolidation should preserve the lightweight proof’s availability, ideally placing the canonical name there.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-ec10b1","file":"Mathlib/RingTheory/Spectrum/Prime/Topology.lean","decl":"IsLocalRing.closed_point_mem_iff","line":1332,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `IsLocalRing.closedPoint_mem_iff` (RingTheory.Spectrum.Prime.Topology), `IsLocalRing.closed_point_mem_iff` (RingTheory.Spectrum.Prime.Topology) state exactly the same thing (Lean-checked). Reviewer: Adjacent lemmas `closedPoint R ∈ U ↔ U = ⊤`, U explicit vs implicit, proved separately. `closed_point_mem_iff` breaks lowerCamelCase for `closedPoint`. Keep `closedPoint_mem_iff`, deprecate `closed_point_mem_iff` (one use, AlgebraicGeometry/Stalk.lean:295).","fix":"Deprecate `IsLocalRing.closed_point_mem_iff` in favour of `IsLocalRing.closedPoint_mem_iff`.","ev":"dupscan/Check.lean: `example := (@IsLocalRing.closed_point_mem_iff : type_of% @IsLocalRing.closedPoint_mem_iff)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 31, rating MAJOR): The camel-case name matches `closedPoint`; the implicit-argument convenience does not justify retaining a separately proved, inconsistently named theorem.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-f2f32d","file":"Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean","decl":"Irreducible.normalizedFactors_pow","line":165,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `UniqueFactorizationMonoid.normalizedFactors_of_irreducible_pow` (RingTheory.UniqueFactorizationDomain.NormalizedFactors), `Irreducible.normalizedFactors_pow` (RingTheory.UniqueFactorizationDomain.NormalizedFactors) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: `Irreducible.normalizedFactors_pow` is the dot-notation twin of `normalizedFactors_of_irreducible_pow`, with a verbatim identical statement and proof. It has no uses, while the bar_of_foo form has 2. Make it an alias.","fix":"Declare `Irreducible.normalizedFactors_pow` as an `alias` of `UniqueFactorizationMonoid.normalizedFactors_of_irreducible_pow`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-a5a598","file":"Mathlib/RingTheory/Valuation/RankOne.lean","decl":"(file)","line":26,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-docstring","claim":"The module docstring's Main Definitions entry for `RankOne.restrict_RankOne` ends mid-sentence ('as defined in' followed by nothing). It also does not list `RankLeOne`, the base class of `RankOne`.","fix":"Finish the sentence (point to `Valuation.restrict`) and add a `RankLeOne` entry.","ev":"src L26-28: '* `RankOne.restrict_RankOne` is the `RankOne` instance for the restriction of a valuation to its\\n  image, as defined in\\n' (next line is blank).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ac8d7b","file":"Mathlib/RingTheory/Valuation/RankOne.lean","decl":"Valuation.RankLeOne","line":49,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"The embedding API (`hom`, `strictMono`) and the characterization `nonempty_rankOne_iff_mulArchimedean` live only under `RankOne`, although the data is `RankLeOne`'s. There is no `Nonempty v.RankLeOne ↔ MulArchimedean v.ValueGroup₀` (which holds without nontriviality; the existing construction works). As a result, `isRankLeOne_iff_mulArchimedean` has to case-split on nontriviality.","fix":"Add `RankLeOne.hom`/`strictMono` and `nonempty_rankLeOne_iff_mulArchimedean`, and derive the `RankOne` versions.","ev":"src L96-99: `abbrev hom := RankLeOne.hom' v` and `strictMono` sit in `namespace RankOne` under `[hv : RankOne v]`; L60 `nonempty_rankOne_iff_mulArchimedean` requires `[v.IsNontrivial]`; no `RankLeOne` analogue in Mathlib (grep).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-85a95a","file":"Mathlib/RingTheory/Valuation/RankOne.lean","decl":"Valuation.RankLeOne","line":50,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-docstring","claim":"Several docstrings still describe the pre-`ValueGroup₀` design. The field `RankLeOne.hom'` and the abbrev `RankOne.hom` say 'The inclusion morphism from `Γ₀` to `ℝ≥0`', and `RankOne`'s docstring says 'an inclusion morphism `Γ₀ → ℝ≥0`', but the map is `v.ValueGroup₀ →*₀ ℝ≥0`. Likewise, the docstrings of `zero_of_hom_zero` and `hom_eq_zero_iff` say 'x : Γ₀' for `x : v.ValueGroup₀`.","fix":"Replace `Γ₀` by `v.ValueGroup₀` (the value group of `v`) in these five docstrings.","ev":"src L50-51 `/-- The inclusion morphism from `Γ₀` to `ℝ≥0`. -/ hom' (v) : v.ValueGroup₀ →*₀ ℝ≥0`; L55 `inclusion morphism `Γ₀ → ℝ≥0``; L96-97; L103-105 and L111-113 `x : Γ₀` vs `{x : v.ValueGroup₀}`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ad0f48","file":"Mathlib/RingTheory/Valuation/RankOne.lean","decl":"Valuation.RankOne","line":54,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-overstates","claim":"The module, `RankLeOne` and `RankOne` docstrings call `v.ValueGroup₀` the valuation's 'image', but it is the group generated by the nonzero values, with zero adjoined. For `v f = 2 ^ deg f` on `ℚ[X]`, the image is `{0} ∪ {2ⁿ}` while the value group contains `1/2`. The module doc also writes `MonoidWithZeroHom.valueGroup₀` (lowercase) for `ValueGroup₀`, and `rankLeOneStruct`'s docstring ('Convert between ...') describes a one-way map.","fix":"Say 'the value group generated by the image'; fix the identifier; describe `rankLeOneStruct` as producing `RankLeOneStruct R` from a rank-one valuation.","ev":"src L23-24, L46-47, L54 ('its image (defined as `MonoidWithZeroHom.valueGroup₀ v`)'); `MonoidWithZeroHom.ValueGroup₀` in Mathlib/Algebra/GroupWithZero/Range.lean is the subgroup generated by the range; L228.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-506659","file":"Mathlib/RingTheory/Valuation/RankOne.lean","decl":"Valuation.nonempty_rankOne_iff_mulArchimedean","line":60,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"defeq-abuse","claim":"The 30-line proof builds the embedding into `ℝ≥0` by hand, and it says in a comment that it uses defeq abuse (`-- toAdd_strictMono is already in an applied form, do defeq abuse instead`, then `exact StrictMono.comp strictMono_id ...`). That makes it brittle under changes to `Multiplicative`/`Additive`.","fix":"Use `toAdd`/`ofAdd` strict-monotonicity lemmas (or an order-iso `Multiplicative ℝ ≃o ℝ≥0ˣ`-style API) instead of `strictMono_id` defeq.","ev":"src L70-73 (comment and `exact StrictMono.comp strictMono_id (f.monotone'.strictMono_of_injective hf)`); proof spans L62-90.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-459991","file":"Mathlib/RingTheory/Valuation/RankOne.lean","decl":"Valuation.RankOne.hom_eq_zero_iff","line":113,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reprovable-from-existing-api","claim":"`RankOne.hom_eq_zero_iff` is the general `map_eq_zero` (a `MonoidWithZeroHom` out of a group with zero into a nontrivial target reflects zero; already `@[simp]`), and `zero_of_hom_zero` is its `.mp`. Neither needs strict monotonicity.","fix":"Prove them as `map_eq_zero (RankOne.hom v)` (or deprecate them).","ev":"-- hunts/valuation-rankone/P2.lean: `example [RankOne v] {x : v.ValueGroup₀} : RankOne.hom v x = 0 ↔ x = 0 := map_eq_zero (RankOne.hom v)` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-bef651","file":"Mathlib/RingTheory/Valuation/RankOne.lean","decl":"Valuation.RankOne.unit","line":117,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"Several declarations assume `[RankOne v]` but use only part of it. `RankOne.nontrivial`, `RankOne.unit`, `unit_ne_one` and `ValuativeRel.isNontrivial_of_rankOne` need only nontriviality. `RankOne.rankLeOneStruct` and `ValuativeRel.isRankLeOne_of_rankOne` need only `RankLeOne`. So they are unavailable for nontrivial valuations of higher rank, and for trivial rank-≤1 valuations, respectively.","fix":"Restate them under `[v.IsNontrivial]` and `[RankLeOne v]` respectively.","ev":"-- hunts/valuation-rankone/P2.lean: `noncomputable example [v.IsNontrivial] : Γ₀ˣ := Units.mk0 (v (IsNontrivial.exists_val_nontrivial (v := v)).choose) ...` and the `RankLeOneStruct R` built from `e : RankLeOne (valuation R)` (via `RankLeOne.hom'`, `e.strictMono'`) compile.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-8aa19f","file":"Mathlib/RingTheory/Valuation/RankOne.lean","decl":"Valuation.RankOne.restrict_RankOne","line":137,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"The restriction API is over-constrained. `restrict_RankOne` and `restrict_RankOne_hom_eq` assume `[DivisionRing K]`, but the instance is built verbatim for `v : Valuation R Γ₀` over any ring. Likewise, `isNontrivial_restrict` assumes `[RankOne v]` although `[v.IsNontrivial]` suffices (via `isEquiv_restrict` and `IsEquiv.isNontrivial_iff`).","fix":"State the restriction instance and its `hom` lemma for `[Ring R]`, and `isNontrivial_restrict` for `[v.IsNontrivial]`.","ev":"-- hunts/valuation-rankone/P2.lean: `noncomputable example (v : Valuation R Γ₀) [RankOne v] : RankOne v.restrict where hom' := (RankOne.hom v).comp embedding; strictMono' := ...` over `[Ring R]` and `example [v.IsNontrivial] : v.restrict.IsNontrivial := (IsEquiv.isNontrivial_iff (isEquiv_restrict v)).mp inferInstance` compile.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a3cd3f","file":"Mathlib/RingTheory/Valuation/RankOne.lean","decl":"Valuation.RankLeOne.rankOne_of_nontrivial","line":180,"sev":"MINOR","status":"suspected","cat":"generality","pattern":"too-strong-typeclass","claim":"`rankOne_of_nontrivial` should hold over any ring: a unit `u ≠ 1` of `v.ValueGroup₀ˣ` is `v a / v b` with `v a, v b ≠ 0` (`Valuation.exists_div_eq_of_unit`), so one of `v a`, `v b` is not `1`. The proof's `restrict₀_surjective` route forces `[DivisionRing K]`. Not proved in Lean here.","fix":"Reprove via `exists_div_eq_of_unit` under `[Ring R]`.","ev":"Astra A1 sketch; src L179-198.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ad5bd4","file":"Mathlib/RingTheory/Valuation/RankOne.lean","decl":"ValuativeRel.IsRankLeOne.of_compatible_mulArchimedean","line":266,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`IsRankLeOne.of_compatible_mulArchimedean` assumes `[MulArchimedean Γ₀]` on the whole codomain, but the intrinsic `[MulArchimedean v.ValueGroup₀]` suffices. A rank-one valuation into a lexicographic `ℤ ×ₗ ℤ` (with zero adjoined) satisfies the latter but not the former.","fix":"Prove the intrinsic version via `ValueGroupWithZero.embed v` and derive the current one from it.","ev":"-- hunts/valuation-rankone/P2.lean: `example (v : Valuation R Γ₀) [v.Compatible] [MulArchimedean v.ValueGroup₀] : IsRankLeOne R := by rw [isRankLeOne_iff_mulArchimedean]; exact MulArchimedean.comap (ValueGroupWithZero.embed v).toMonoidHom (ValueGroupWithZero.embed_strictMono v)` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-9edc36","file":"Mathlib/RingTheory/ZMod/Torsion.lean","decl":"ZMod.rootsOfUnity_eq_top","line":23,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"specialised-to-zmod","claim":"`ZMod.rootsOfUnity_eq_top` (`rootsOfUnity (p - 1) (ZMod p) = ⊤`) and the `HasEnoughRootsOfUnity (ZMod p) (p - 1)` instance are stated only for `ZMod p`, but both hold for every finite field `K` with `Fintype.card K - 1`, by the same proof with `FiniteField.pow_card_sub_one_eq_one`. Mathlib has no finite-field version of either, so e.g. `GaloisField p n` gets no `HasEnoughRootsOfUnity` instance.","fix":"State both for `[Field K] [Fintype K]` (in `FieldTheory/Finite`), and recover the `ZMod p` lemma by `simpa using` the general one.","ev":"probe1.lean: `FiniteField.rootsOfUnity_eq_top'` and `instance : HasEnoughRootsOfUnity K (Fintype.card K - 1)` compile; the `ZMod p` lemma follows by `simpa`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-db6552","file":"Mathlib/SetTheory/Cardinal/Basic.lean","decl":"Cardinal.mk_lt_aleph0_iff","line":540,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Cardinal.mk_lt_aleph0_iff` (SetTheory.Cardinal.Basic), `Cardinal.lt_aleph0_iff_finite` (SetTheory.Cardinal.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file: `#α < ℵ₀ ↔ Finite α` is proved at line 421 (`simp only [lt_aleph0, mk_eq_nat_iff, …]`) and again at line 540 (`simp [← not_le, aleph0_le_mk_iff]`). Keep the earlier lt_aleph0_iff_finite (with lt_aleph0_iff_fintype/lt_aleph0_of_finite) and deprecate mk_lt_aleph0_iff. Both are well used (13 vs 16 occurrences), so the other choice is also defensible.","fix":"Deprecate `Cardinal.mk_lt_aleph0_iff` in favour of `Cardinal.lt_aleph0_iff_finite`.","ev":"dupscan/Check.lean: `example := (@Cardinal.lt_aleph0_iff_finite : type_of% @Cardinal.mk_lt_aleph0_iff)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup3 item 32, rating MINOR): Both names are established and well used, and `mk_lt_aleph0_iff` pairs naturally with `aleph0_le_mk_iff`. Sharing a proof through an alias offers better value than forcing renames.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-d87a65","file":"Mathlib/SetTheory/Cardinal/Basic.lean","decl":"Cardinal.mk_lt_aleph0","line":542,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Cardinal.lt_aleph0_of_finite` (SetTheory.Cardinal.Basic), `Cardinal.mk_lt_aleph0` (SetTheory.Cardinal.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file: `#α < ℵ₀` for [Finite α], with α explicit in one and implicit in the other, each proved from its own iff. Keep `lt_aleph0_of_finite`, which is older and has about 20 uses, and move @[simp] onto it. Deprecate `mk_lt_aleph0`, which has 1 use in FieldTheory/FinTrdeg.","fix":"Deprecate `Cardinal.mk_lt_aleph0` in favour of `Cardinal.lt_aleph0_of_finite`.","ev":"dupscan/Check.lean: `example := (@Cardinal.mk_lt_aleph0 : type_of% @Cardinal.lt_aleph0_of_finite)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup3 item 34, rating MINOR): `mk_lt_aleph0` complements `aleph0_le_mk`, and its inferred type parameter makes it convenient as a bare proof term. Keep that standard naming-family member as an alias.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-451126","file":"Mathlib/SetTheory/Cardinal/Basic.lean","decl":"Cardinal.mk_subtype_mono","line":850,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Cardinal.mk_subtype_mono` (SetTheory.Cardinal.Basic), `Cardinal.mk_subtype_le_of_subset` (SetTheory.Cardinal.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file, `(∀ x, p x → q x) → #{x // p x} ≤ #{x // q x}` proved twice (`embeddingOfSubset` vs `Embedding.subtypeMap`), differing only in ⦃x⦄ vs (x). Keep `mk_subtype_le_of_subset` (earlier, matches `mk_le_mk_of_subset`), deprecate `mk_subtype_mono` (a misnomer, since the statement is not `Monotone`; 2 uses).","fix":"Deprecate `Cardinal.mk_subtype_mono` in favour of `Cardinal.mk_subtype_le_of_subset`.","ev":"dupscan/Check.lean: `example := (@Cardinal.mk_subtype_le_of_subset : type_of% @Cardinal.mk_subtype_mono)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup3 item 33, rating MINOR): `_mono` conventionally names monotonicity implications without requiring a literal `Monotone` conclusion. Explicit versus implicit `x` also changes the hypothesis’s elaboration interface; preserving an alias is reasonable.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-b8303f","file":"Mathlib/SetTheory/ZFC/Class.lean","decl":"ZFClass.coe_subset","line":99,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `ZFSet.coe_subset_coe` (SetTheory.ZFC.Basic), `ZFClass.coe_subset` (SetTheory.ZFC.Class) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: `ZFClass` is `abbrev ZFClass := Set ZFSet`, so `ZFClass.coe_subset` is literally ZFSet.coe_subset_coe. The ZFClass.coe_* family is intended class-side API and the deprecation target of Class.coe_subset (2026-09-25), but each member is re-proved. ZFClass.coe_subset could be an alias of the ZFSet lemma.","fix":"Declare `ZFClass.coe_subset` as an `alias` of `ZFSet.coe_subset_coe`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-76f227","file":"Mathlib/SetTheory/ZFC/Class.lean","decl":"ZFClass.coe_insert","line":105,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `ZFClass.coe_insert` (SetTheory.ZFC.Class), `ZFSet.coe_insert` (SetTheory.ZFC.Basic) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: Because `ZFClass` is an abbrev for `Set ZFSet`, `ZFClass.coe_insert` (not simp) restates `ZFSet.coe_insert` (@[simp, norm_cast]), and both are proved by `ext; simp`. The ZFClass.coe_* family is the intended deprecation target of Class.coe_*, so it should alias the ZFSet lemmas instead of re-proving them.","fix":"Declare `ZFClass.coe_insert` as an `alias` of `ZFSet.coe_insert`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-fb0ca9","file":"Mathlib/SetTheory/ZFC/Class.lean","decl":"ZFClass.coe_union","line":107,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `ZFSet.coe_union` (SetTheory.ZFC.Basic), `ZFClass.coe_union` (SetTheory.ZFC.Class) state exactly the same thing (Lean-checked). Reviewer: `ZFClass` is now `abbrev ZFClass := Set ZFSet`, so the new ZFClass.coe_union (added in the 2026-09-25 Class→ZFClass refactor, no attributes) states the @[simp, norm_cast] ZFSet.coe_union. ZFC/Class imports ZFC/Basic. Deprecate ZFClass.coe_union, retargeting the deprecated Class.coe_union to ZFSet.coe_union.","fix":"Deprecate `ZFClass.coe_union` in favour of `ZFSet.coe_union`.","ev":"dupscan/Check.lean: `example := (@ZFClass.coe_union : type_of% @ZFSet.coe_union)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 35, rating MAJOR): The abbreviation leaves no separate class-level operation or automation behavior to preserve. Retargeting the deprecated `Class` theorem to the existing ZFSet theorem avoids another compatibility layer.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-f24a50","file":"Mathlib/SetTheory/ZFC/Class.lean","decl":"ZFClass.coe_inter","line":109,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `ZFSet.coe_inter` (SetTheory.ZFC.Basic), `ZFClass.coe_inter` (SetTheory.ZFC.Class) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: ZFClass is now `abbrev ZFClass := Set ZFSet`, so ZFClass.coe_inter is literally ZFSet.coe_inter. The ZFClass.coe_* family (union/insert/sdiff/subset are matching groups) is intended, being the deprecation target of Class.coe_inter (2026-09-25), but is re-proved. Fix: alias to ZFSet.coe_*.","fix":"Declare `ZFClass.coe_inter` as an `alias` of `ZFSet.coe_inter`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-75df93","file":"Mathlib/SetTheory/ZFC/Class.lean","decl":"ZFClass.coe_sdiff","line":111,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `ZFSet.coe_sdiff` (SetTheory.ZFC.Basic), `ZFClass.coe_sdiff` (SetTheory.ZFC.Class) state exactly the same thing (Lean-checked). Reviewer: This is the sdiff case of the ZFSet/ZFClass coe group. With `abbrev ZFClass := Set ZFSet`, the attribute-less ZFClass.coe_sdiff from the 2026-09-25 refactor restates @[simp, norm_cast] ZFSet.coe_sdiff. Deprecate ZFClass.coe_sdiff.","fix":"Deprecate `ZFClass.coe_sdiff` in favour of `ZFSet.coe_sdiff`.","ev":"dupscan/Check.lean: `example := (@ZFClass.coe_sdiff : type_of% @ZFSet.coe_sdiff)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 36, rating MAJOR): `ZFClass` introduces no distinct set-difference operation here, and the lower theorem already carries both relevant attributes.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-756ba9","file":"Mathlib/Tactic/CategoryTheory/Bicategory/Normalize.lean","decl":"Mathlib.Tactic.Bicategory.eval_monoidalComp","line":60,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Mathlib.Tactic.Bicategory.eval_monoidalComp` (Tactic.CategoryTheory.Bicategory.Normalize), `Mathlib.Tactic.Bicategory.eval_bicategoricalComp` (Tactic.CategoryTheory.Bicategory.Normalize) state exactly the same thing (Lean-checked). Reviewer: Both live in the same namespace Mathlib.Tactic.Bicategory with identical statement and proof. The bicategory normalizer only uses eval_bicategoricalComp (l.536); eval_monoidalComp here is dead code copied from Monoidal/Normalize (which has its own). Delete it; tactic-internal, so no deprecation needed.","fix":"Deprecate `Mathlib.Tactic.Bicategory.eval_monoidalComp` in favour of `Mathlib.Tactic.Bicategory.eval_bicategoricalComp`.","ev":"dupscan/Check.lean: `example := (@Mathlib.Tactic.Bicategory.eval_bicategoricalComp : type_of% @Mathlib.Tactic.Bicategory.eval_monoidalComp)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 37, rating MAJOR): The normalizer quotes `eval_bicategoricalComp`; the monoidal-named copy has no attribute-driven role or separate interface. Removing the unused helper is sensible.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-29e116","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.WhiskerLeft","line":99,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-constructor-docstring","claim":"The docstring of the constructor `WhiskerLeft.of` says \"Construct the expression for a right-whiskered 2-morphism\", but its argument is a `HorizontalComp` (a horizontal composite `η₁ ◫ … ◫ ηₙ` of right-whiskered 2-morphisms), not a `WhiskerRight`. For example, the normal form of `U ◁ (f ⊗ₘ g)` is `.whisker _ U (.of (HorizontalComp.cons _ f (.of g)))`, where `.of` wraps a two-factor horizontal composite, not a right-whiskered morphism.","fix":"Say \"Construct the expression for a horizontal composite `η₁ ◫ … ◫ ηₙ` of right-whiskered 2-morphisms.\"","ev":"Source L99-100: `/-- Construct the expression for a right-whiskered 2-morphism. -/ | of (η : HorizontalComp) : WhiskerLeft`. hunts/coherence-normalize/batch0/probe1.lean (`shape%` prints the constructor tree of each normal-form block): `#check shape% U ◁ (f ⊗ₘ g)` prints `[(_ ◁ of [atom ◫ atom])]`; output in hunts/coherence-normalize/batch0/probe1.out.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-a16cba","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.MonadWhiskerLeft","line":151,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-wrong-notation","claim":"The docstring of the field `MonadWhiskerLeft.whiskerLeftM` reads \"The expression for the left whiskering `f ▷ η`.\" `▷` is right whiskering (`η ▷ f`); left whiskering is `f ◁ η`. The formula in the docstring is wrong.","fix":"Change the field docstring to \"The expression for the left whiskering `f ◁ η`.\"","ev":"git grep -n \"f ▷ η`\" origin/master -- Mathlib/Tactic/CategoryTheory  =>  Coherence/Normalize.lean:151:  /-- The expression for the left whiskering `f ▷ η`. -/  (cf. Datatypes.lean MonadMor₂.whiskerLeftM: \"The expression for the left whiskering `f ◁ η`.\")","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-b2f447","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.MonadNormalExpr","line":155,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"class-determined-by-another-class","claim":"The class tower MonadWhiskerRight → MonadHorizontalComp → MonadWhiskerLeft → MonadNormalExpr is fully determined by `MonadMor₂`: both instances in Mathlib (Monoidal/Normalize.lean L777-787, Bicategory/Normalize.lean L538-548) are the same generic code, differing only in `hConsM`, where the bicategory version throws (and `MonadMor₂.horizontalCompM` for bicategories throws too). A generic `[Monad m] [MonadMor₂ m] : MonadNormalExpr m` is `rfl`-equal to the monoidal instance and agrees field by field with the bicategory one on nilM/consM/whiskerLeftM/whiskerRightM. The three parent classes are never used as an instance argument anywhere in Mathlib (only `MonadNormalExpr` is, at Normalize.lean L207/L355/L514 and Coherence/Basic.lean L42/L98). The linear `extends` chain also makes `MonadWhiskerLeft` require `hConsM`, which bicategories cannot supply.","fix":"Replace the four classes by plain `def`s (or one generic instance) over `[MonadMor₂ m]`, and delete the duplicated instance bodies in Monoidal/Normalize.lean and Bicategory/Normalize.lean.","ev":"hunts/coherence-normalize/batch1/Probe1.lean section C: `abbrev genericNormalExpr {m} [Monad m] [MonadMor₂ m] : MonadNormalExpr m where whiskerRightM η h := do return .whisker (← MonadMor₂.whiskerRightM η.e (.of h)) η h; hConsM η θ := do return .cons (← MonadMor₂.horizontalCompM η.e θ.e) η θ; whiskerLeftM f η := do return .whisker (← MonadMor₂.whiskerLeftM (.of f) η.e) f η; nilM α := do return .nil (← MonadMor₂.homM α) α; consM α η ηs := do return .cons (← MonadMor₂.comp₂M (← MonadMor₂.homM α) (← MonadMor₂.comp₂M η.e ηs.e)) α η ηs` then `example : (genericNormalExpr : MonadNormalExpr Monoidal.MonoidalM) = (inferInstance : MonadNormalExpr Monoidal.MonoidalM) := rfl` and the field-wise `rfl`s for Bicategory.BicategoryM (nilM, consM, whiskerLeftM, whiskerRightM) all compile; `git grep -nw MonadWhiskerLeft origin/master -- Mathlib MathlibTest` shows no binder use.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-d3395c","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.WhiskerRight.srcM","line":166,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"recomputes-cached-field","claim":"The eight recursive functions WhiskerRight/HorizontalComp/WhiskerLeft/NormalExpr.srcM/tgtM recompute, with one `comp₁M` call per constructor level, what the existing `Mor₂.srcM`/`Mor₂.tgtM` (Coherence/Datatypes.lean) return in O(1) on the `e : Mor₂` field that every constructor already caches. On every node of the normal forms of 24 test morphisms (14 monoidal, 10 bicategory) plus idM/associatorM outputs, `x.srcM`/`x.tgtM` were defeq to the true domain/codomain (so they are correct) and syntactically equal to `x.e.srcM`/`x.e.tgtM` (0 differences).","fix":"Define each as `x.e.srcM` / `x.e.tgtM` (or call `Mor₂.srcM` on `.e` directly at the use sites).","ev":"hunts/coherence-normalize/batch1/Probe1.lean section A: for each node `x` of `(← eval nm (← MkMor₂.ofExpr e)).expr`, checks `isDefEq` of `(← x.srcM).e`/`(← x.tgtM).e` with the domain/codomain of `inferType x.e.e`, and counts `(← x.srcM).e == (← x.e.srcM).e`; output Probe1.out: 28 runs, all `... checks passed; 0 syntactic differences from .e.srcM/tgtM`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-e760ac","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.MkEvalComp","line":269,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"proof-builder-docstring-omits-contract","claim":"The class and method docstrings (\"Evaluate the expression `α ≫ β`\", \"Evaluate `(α ≫ η ≫ ηs) ≫ θ`\") describe the job of `evalComp`, not of these methods: each method returns the proof term certifying one evaluation step, and nothing in this file says what equation the returned `Expr` proves or what the `e_*` argument must prove (`mkEvalCompCons`'s `e_η` must prove `ηs ≫ θ = ι` and the result proves `(α ≫ η ≫ ηs) ≫ θ = α ≫ η ≫ ι`); the contract is only recoverable from `Mathlib.Tactic.Monoidal.evalComp_cons` (Monoidal/Normalize.lean:44) and its bicategory twin (Bicategory/Normalize.lean:45). The class docstring also names only the structural case `α ≫ β`. The undocumented positional contract is not hypothetical: in the sibling class `MkEvalHorizontalComp`, `mkEvalHorizontalCompAux'OfWhisker` is called with two arguments swapped, which breaks `monoidal` (see the out-of-batch CRITICAL finding).","fix":"Document each method as \"Given `e_ι : ηs ≫ θ = ι`, return a proof of `(α ≫ η ≫ ηs) ≫ θ = α ≫ η ≫ ι`\" (and similarly), and the class as building the evaluation proofs for `η ≫ θ`.","ev":"src.lean:268-275 vs Monoidal/Normalize.lean:36-47 (`evalComp_nil_nil`, `evalComp_nil_cons`, `evalComp_cons (e_ι : ηs ≫ θ = ι) : (α.hom ≫ η ≫ ηs) ≫ θ = α.hom ≫ η ≫ ι`) and the instances at Monoidal/Normalize.lean:237, Bicategory/Normalize.lean:163.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-c9c450","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.MkEvalWhiskerLeft","line":278,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"proof-builder-docstring-omits-contract","claim":"Docstrings say \"Evaluate `(f ≫ g) ◁ η`\" etc., but the methods return proof terms and the file never states their contract; e.g. `mkEvalWhiskerLeftComp`'s four `Expr`s must prove `g ◁ η = η₁`, `f ◁ η₁ = η₂`, `η₂ ≫ (α_ f g i).inv = η₃`, `(α_ f g h).hom ≫ η₃ = η₄` and the result proves `(f ≫ g) ◁ η = η₄`, which is written only in `Mathlib.Tactic.Monoidal.evalWhiskerLeft_comp` (Monoidal/Normalize.lean:77) and `Mathlib.Tactic.Bicategory.evalWhiskerLeft_comp` (Bicategory/Normalize.lean:77). The undocumented positional contract is not hypothetical: in the sibling class `MkEvalHorizontalComp`, `mkEvalHorizontalCompAux'OfWhisker` is called with two arguments swapped, which breaks `monoidal` (see the out-of-batch CRITICAL finding).","fix":"State, per method, the equations the `e_*` arguments prove and the equation the returned proof term proves.","ev":"src.lean:277-288 vs Monoidal/Normalize.lean:68-89 and instances at Monoidal/Normalize.lean:289, Bicategory/Normalize.lean:221. Argument orders of all four methods agree between class, caller `evalWhiskerLeft` and both instances (checked by hand; tactic paths exercised in hunts/coherence-normalize/batch2/probe_behaviour.lean, all compile).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-1b80e0","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.MkEvalWhiskerRight","line":291,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"proof-builder-docstring-omits-contract","claim":"Same missing contract as `MkEvalWhiskerLeft`: \"Evaluate …\" docstrings on methods that return proof terms with up to seven unexplained `e_*` hypotheses (`mkEvalWhiskerRightConsWhisker`), contract only in Monoidal/Normalize.lean:110-160 and Bicategory/Normalize.lean:107-160. Also: the `mkEvalWhiskerRightConsOfOf` docstring \"Evaluate ` (α ≫ η ≫ ηs) ▷ j`\" uses `j`, which is the instances' name, while the binder here is `f` (and has a stray leading space in the code span); `mkEvalWhiskerRightComp` writes `η ▷ (g ⊗ h)` for 1-morphism composition whereas the sibling `mkEvalWhiskerLeftComp` and `Mor₁.comp` write `f ≫ g`. The undocumented positional contract is not hypothetical: in the sibling class `MkEvalHorizontalComp`, `mkEvalHorizontalCompAux'OfWhisker` is called with two arguments swapped, which breaks `monoidal` (see the out-of-batch CRITICAL finding).","fix":"Document each method's hypotheses and conclusion, write `(α ≫ η ≫ ηs) ▷ f` and `η ▷ (g ≫ h)`.","ev":"src.lean:290-310; Monoidal/Normalize.lean:395 `mkEvalWhiskerRightConsOfOf j α η …`; Coherence/Datatypes.lean:78 (`comp e f g` is \"the expression for `f ≫ g`\"). Argument orders of all seven methods agree between class, callers and both instances (checked by hand; paths exercised in hunts/coherence-normalize/batch2/probe_behaviour.lean, e.g. `(f ⊗ₘ g) ▷ V`, `(V ◁ f) ▷ (W ⊗ 𝟙_ C)`, `(f ◁ κ) ▷ h` in a bicategory — all compile).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-c54ab4","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.MkEvalHorizontalComp","line":313,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"inconsistent-positional-binder-order","claim":"The field `mkEvalHorizontalCompAux'OfWhisker` (lines 323–324) takes eight positional arguments of the same two types (`η₁ ηθ ηθ₁ ηθ₂ : NormalExpr`, `e_ηθ e_η₁ e_ηθ₁ e_ηθ₂ : Expr`), told apart only by their binder names, and those names are in opposite orders (`η₁` before `ηθ`, but `e_ηθ` before `e_η₁`). The caller (line 481) followed one order and the Monoidal implementation (Monoidal/Normalize.lean:549, binders `η₁ ηθ … e_η₁ e_ηθ`) the other, which caused the CRITICAL ill-typed certificate recorded for `evalHorizontalCompAux'`. Every other field's binder names agree with its caller.","fix":"Use one order for both groups (`e_η₁ e_ηθ`), as PR #44543 does, and document which equation each `e_*` proves.","ev":"measured: Normalize.lean:323-324 `(η₁ ηθ ηθ₁ ηθ₂ : NormalExpr) (e_ηθ e_η₁ e_ηθ₁ e_ηθ₂ : Expr)`; call at :481 `… ηθ η₁ ηθ₁ ηθ₂ e_η₁ e_ηθ e_ηθ₁ e_ηθ₂`; Monoidal/Normalize.lean:549 `mkEvalHorizontalCompAux'OfWhisker f η θ η₁ ηθ ηθ₁ ηθ₂ e_η₁ e_ηθ e_ηθ₁ e_ηθ₂`. Consequence shown in hunts/coherence-normalize/batch3/P1.lean line 32.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-753d44","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.MkEvalHorizontalComp","line":313,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-misdescribes-output","claim":"The class docstring ('Evaluate the expression `η ◫ θ`') and the field docstrings ('Evaluate `(α ≫ η ≫ ηs) ◫ β`', …) describe the fields as evaluators. In fact each field takes the normal forms and sub-proofs that `evalHorizontalComp*` has already computed and returns only the proof term (`m Expr`) for one rewriting step: the Monoidal instance returns `q(evalHorizontalComp_cons_cons $e_ηθ …)`, and the Bicategory instance throws 'not implemented'. No docstring says which equation each `e_*` argument must prove. That positional contract is exactly the one broken at line 481.","fix":"Say that each field builds the proof `lhs = result` from the given sub-proofs, and state each `e_*` argument's equation.","ev":"measured: Normalize.lean:312-335 docstrings vs Monoidal/Normalize.lean:484-675 (each field returns `q(<lemma> $e_…)`).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-6886e7","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.MkEval","line":338,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-misdescribes-output","claim":"The docstring 'Evaluate the expression of a 2-morphism into a normalized form' and the field docstrings ('Evaluate the expression `η ≫ θ` into a normalized form', …) describe evaluation. The class only provides proof-term builders: e.g. `mkEvalComp η θ η' θ' ηθ e_η e_θ e_ηθ : m Expr` receives the normal form `ηθ` and returns the proof of `η ≫ θ = ηθ` (`q(eval_comp $e_η $e_θ $e_ηθ)` in Monoidal/Normalize.lean:695). `eval` does the normalization.","fix":"Describe `MkEval` as the interface that assembles the equality proofs for `eval`, and state the equation each field returns.","ev":"measured: Normalize.lean:337-352 vs Monoidal/Normalize.lean:677-775.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-156f77","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.evalCompNil","line":360,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass-mkeval","claim":"Takes `[MkEval (CoherenceM ρ)]` (section variable, line 355), but uses only `mkEvalCompNilNil`/`mkEvalCompNilCons`, so it needs `[MkEvalComp (CoherenceM ρ)]`; none of `MkEval`'s six own fields are used. Only `eval` needs the full `MkEval`, so splitting `MkEval` into parent classes buys nothing here. A copy of the file with line 355 weakened to `[MkEvalComp …]`, with `[MkEvalWhiskerLeft …]` added at line 373 and `[MkEvalWhiskerRight …] [MkEvalHorizontalComp …]` added before the mutual block, compiles unchanged, and `eval` still works through the parent instances.","fix":"Declare the parent classes actually used (`MkEvalComp`, `MkEvalWhiskerLeft`, `MkEvalWhiskerRight`, `MkEvalHorizontalComp`) instead of `MkEval` in the section variables.","ev":"hunts/coherence-normalize/batch3/P3b_weak.lean (diff vs src.lean: lines 355, 373, +400); compiles with no errors; `#check @evalCompNil` shows the weakened binders.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-417f79","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.evalComp","line":365,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass-mkeval","claim":"Takes `[MkEval (CoherenceM ρ)]` (section variable, line 355), but uses only `MkEvalComp` fields (directly and through `evalCompNil`); none of `MkEval`'s six own fields are used. Only `eval` needs the full `MkEval`, so splitting `MkEval` into parent classes buys nothing here. A copy of the file with line 355 weakened to `[MkEvalComp …]`, with `[MkEvalWhiskerLeft …]` added at line 373 and `[MkEvalWhiskerRight …] [MkEvalHorizontalComp …]` added before the mutual block, compiles unchanged, and `eval` still works through the parent instances.","fix":"Declare the parent classes actually used (`MkEvalComp`, `MkEvalWhiskerLeft`, `MkEvalWhiskerRight`, `MkEvalHorizontalComp`) instead of `MkEval` in the section variables.","ev":"hunts/coherence-normalize/batch3/P3b_weak.lean (diff vs src.lean: lines 355, 373, +400); compiles with no errors; `#check @evalComp` shows the weakened binders.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-6d381a","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.evalWhiskerLeft","line":376,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass-mkeval","claim":"Takes `[MkEval (CoherenceM ρ)]` (section variable, line 355), but needs only `[MkEvalComp]` and `[MkEvalWhiskerLeft]`; none of `MkEval`'s six own fields are used. Only `eval` needs the full `MkEval`, so splitting `MkEval` into parent classes buys nothing here. A copy of the file with line 355 weakened to `[MkEvalComp …]`, with `[MkEvalWhiskerLeft …]` added at line 373 and `[MkEvalWhiskerRight …] [MkEvalHorizontalComp …]` added before the mutual block, compiles unchanged, and `eval` still works through the parent instances.","fix":"Declare the parent classes actually used (`MkEvalComp`, `MkEvalWhiskerLeft`, `MkEvalWhiskerRight`, `MkEvalHorizontalComp`) instead of `MkEval` in the section variables.","ev":"hunts/coherence-normalize/batch3/P3b_weak.lean (diff vs src.lean: lines 355, 373, +400); compiles with no errors; `#check @evalWhiskerLeft` shows the weakened binders.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-4b88fa","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.evalWhiskerRightAux","line":404,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass-mkeval","claim":"Takes `[MkEval (CoherenceM ρ)]` (section variable, line 355), but (like the rest of its mutual block) needs only the four parent classes `MkEvalComp`, `MkEvalWhiskerLeft`, `MkEvalWhiskerRight`, `MkEvalHorizontalComp`; none of `MkEval`'s six own fields are used. Only `eval` needs the full `MkEval`, so splitting `MkEval` into parent classes buys nothing here. A copy of the file with line 355 weakened to `[MkEvalComp …]`, with `[MkEvalWhiskerLeft …]` added at line 373 and `[MkEvalWhiskerRight …] [MkEvalHorizontalComp …]` added before the mutual block, compiles unchanged, and `eval` still works through the parent instances.","fix":"Declare the parent classes actually used (`MkEvalComp`, `MkEvalWhiskerLeft`, `MkEvalWhiskerRight`, `MkEvalHorizontalComp`) instead of `MkEval` in the section variables.","ev":"hunts/coherence-normalize/batch3/P3b_weak.lean (diff vs src.lean: lines 355, 373, +400); compiles with no errors; `#check @evalWhiskerRightAux` shows the weakened binders.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-824027","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.evalWhiskerRight","line":416,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass-mkeval","claim":"Takes `[MkEval (CoherenceM ρ)]` (section variable, line 355), but (like the rest of its mutual block) needs only the four parent classes `MkEvalComp`, `MkEvalWhiskerLeft`, `MkEvalWhiskerRight`, `MkEvalHorizontalComp`; none of `MkEval`'s six own fields are used. Only `eval` needs the full `MkEval`, so splitting `MkEval` into parent classes buys nothing here. A copy of the file with line 355 weakened to `[MkEvalComp …]`, with `[MkEvalWhiskerLeft …]` added at line 373 and `[MkEvalWhiskerRight …] [MkEvalHorizontalComp …]` added before the mutual block, compiles unchanged, and `eval` still works through the parent instances.","fix":"Declare the parent classes actually used (`MkEvalComp`, `MkEvalWhiskerLeft`, `MkEvalWhiskerRight`, `MkEvalHorizontalComp`) instead of `MkEval` in the section variables.","ev":"hunts/coherence-normalize/batch3/P3b_weak.lean (diff vs src.lean: lines 355, 373, +400); compiles with no errors; `#check @evalWhiskerRight` shows the weakened binders.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-3affa0","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.evalHorizontalCompAux","line":454,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass-mkeval","claim":"Takes `[MkEval (CoherenceM ρ)]` (section variable, line 355), but (like the rest of its mutual block) needs only the four parent classes; none of `MkEval`'s six own fields are used. Only `eval` needs the full `MkEval`, so splitting `MkEval` into parent classes buys nothing here. A copy of the file with line 355 weakened to `[MkEvalComp …]`, with `[MkEvalWhiskerLeft …]` added at line 373 and `[MkEvalWhiskerRight …] [MkEvalHorizontalComp …]` added before the mutual block, compiles unchanged, and `eval` still works through the parent instances.","fix":"Declare the parent classes actually used (`MkEvalComp`, `MkEvalWhiskerLeft`, `MkEvalWhiskerRight`, `MkEvalHorizontalComp`) instead of `MkEval` in the section variables.","ev":"hunts/coherence-normalize/batch3/P3b_weak.lean (diff vs src.lean: lines 355, 373, +400); compiles with no errors; `#check @evalHorizontalCompAux` shows the weakened binders.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-207209","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.evalHorizontalCompAux'","line":468,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass-mkeval","claim":"Takes `[MkEval (CoherenceM ρ)]` (section variable, line 355), but (like the rest of its mutual block) needs only the four parent classes; none of `MkEval`'s six own fields are used. Only `eval` needs the full `MkEval`, so splitting `MkEval` into parent classes buys nothing here. A copy of the file with line 355 weakened to `[MkEvalComp …]`, with `[MkEvalWhiskerLeft …]` added at line 373 and `[MkEvalWhiskerRight …] [MkEvalHorizontalComp …]` added before the mutual block, compiles unchanged, and `eval` still works through the parent instances.","fix":"Declare the parent classes actually used (`MkEvalComp`, `MkEvalWhiskerLeft`, `MkEvalWhiskerRight`, `MkEvalHorizontalComp`) instead of `MkEval` in the section variables.","ev":"hunts/coherence-normalize/batch3/P3b_weak.lean (diff vs src.lean: lines 355, 373, +400); compiles with no errors; `#check @evalHorizontalCompAux'` shows the weakened binders.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-ea3e57","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.evalHorizontalCompAux'","line":468,"sev":"MINOR","status":"superseded","cat":"correctness","pattern":"swapped-positional-arguments-ill-typed-certificate","claim":"In the `.of η, .whisker _ f θ` branch (line 481) the call `mkEvalHorizontalCompAux'OfWhisker f η θ ηθ η₁ ηθ₁ ηθ₂ e_η₁ e_ηθ …` passes `ηθ η₁` into the two NormalExpr slots that the class field (line 324) and its only implementation (Monoidal/Normalize.lean:549) read as `η₁ ηθ`, while the proofs are passed in the order the implementation expects. The Monoidal instance therefore builds `evalHorizontalCompAux'_of_whisker` with `η₁ :=` the normal form of `(η ▷ f) ⊗ θ` and `ηθ :=` the normal form of `η ▷ f`, which is ill-typed. `monoidal` then fails with '(kernel) application type mismatch' on every goal whose normalization reaches `η ⊗ₘ (X ◁ θ)`, even the reflexive `f ⊗ₘ (U ◁ g) = f ⊗ₘ (U ◁ g)`, and also on `(U ◁ f) ⊗ₘ (V ◁ g)`, `f ⊗ₘ (U ◁ V ◁ g)` and `𝟙_ C ◁ (f ⊗ₘ (U ◁ g))`. The kernel rejects the term, so nothing unsound is proved, but this branch of the evaluator returns a wrong certificate (and `eval`, `evalHorizontalComp` and the string-diagram widget inherit it). All 26 other reflexive branch probes pass. With the two arguments swapped, every failing goal closes, including the non-reflexive `f ⊗ₘ (U ◁ g) = (α_ _ _ _).inv ≫ ((f ▷ U) ⊗ₘ g) ≫ (α_ _ _ _).hom` (true by `simp [tensorHom_def]`). An open upstream PR, leanprover-community/mathlib4#44543 (opened 2026-10-06, unmerged at 4beb549110), makes exactly this fix. Graded MAJOR, not CRITICAL: the kernel rejects the ill-typed certificate, so nothing false is proved; the tactic fails on true goals in its domain (reproduced independently: `example : f ⊗ₘ (Z ◁ g) = f ⊗ₘ (Z ◁ g) := by monoidal` → (kernel) application type mismatch, while `(X ◁ f) ⊗ₘ g` works). Found independently by batches 0–3 and by Astra's blind pass (its top finding), but ALREADY FIXED UPSTREAM by open PR leanprover-community/mathlib4#44543 (gaetanserre, opened 2026-10-06, identical one-line swap plus tests) — not our discovery; no draft PR opened.","fix":"Pass `η₁ ηθ` instead of `ηθ η₁` at line 481 and rename the class binders to `e_η₁ e_ηθ`, as upstream PR #44543 does; add the reflexive regression tests.","ev":"import Mathlib.Tactic.CategoryTheory.Monoidal.Basic\nopen CategoryTheory MonoidalCategory\nvariable {C : Type u} [Category.{v} C] [MonoidalCategory C] {X Y Z W U : C}\nexample (f : X ⟶ Y) (g : Z ⟶ W) : f ⊗ₘ (U ◁ g) = f ⊗ₘ (U ◁ g) := by monoidal\n-- error: (kernel) application type mismatch  @Monoidal.evalHorizontalCompAux'_of_whisker C _ _ U Z X W Y f g (…tensorHom (whiskerRight f U) g…)\n--   argument has type (X ⊗ U) ⊗ Z ⟶ (Y ⊗ U) ⊗ W but function has type ∀ {η₁ : X ⊗ U ⟶ Y ⊗ U} …\n-- Full probes: hunts/coherence-normalize/batch3/P1.lean (T1c, line 32; T2g, line 63) and hunts/coherence-normalize/batch3/P2.lean section R (R11/R17/R21/R22, lines 133/142/147/148: kernel errors; the 26 other reflexive branch goals pass). Fix check: P2.lean section F1 (`monoidal_fixHC`, the shipped instance with the two NormalExpr arguments swapped, i.e. the call-site fix) closes all of them with no errors. | main/repro.lean: `by monoidal` on `f ⊗ₘ (Z ◁ g) = f ⊗ₘ (Z ◁ g)` → (kernel) application type mismatch.","evr":"fails-as-expected","astraV":"agrees","astraS":"Astra's blind A1 pass independently ranked this its top (P1 correctness) finding: the `.of η, .whisker _ f θ` branch passes `ηθ η₁` where the interface and monoidal builder expect `η₁ ηθ`, producing a kernel-rejected proof; fix by swapping (plus renaming the class's `e_` binders).","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: tactic argument swap, already addressed by another contributor's PR #44543; not counted as MAJOR.","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-3034f9","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.evalHorizontalComp","line":484,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass-mkeval","claim":"Takes `[MkEval (CoherenceM ρ)]` (section variable, line 355), but (like the rest of its mutual block) needs only the four parent classes; none of `MkEval`'s six own fields are used. Only `eval` needs the full `MkEval`, so splitting `MkEval` into parent classes buys nothing here. A copy of the file with line 355 weakened to `[MkEvalComp …]`, with `[MkEvalWhiskerLeft …]` added at line 373 and `[MkEvalWhiskerRight …] [MkEvalHorizontalComp …]` added before the mutual block, compiles unchanged, and `eval` still works through the parent instances.","fix":"Declare the parent classes actually used (`MkEvalComp`, `MkEvalWhiskerLeft`, `MkEvalWhiskerRight`, `MkEvalHorizontalComp`) instead of `MkEval` in the section variables.","ev":"hunts/coherence-normalize/batch3/P3b_weak.lean (diff vs src.lean: lines 355, 373, +400); compiles with no errors; `#check @evalHorizontalComp` shows the weakened binders.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-7b89dd","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.eval","line":524,"sev":"MINOR","status":"confirmed","cat":"correctness","pattern":"evaluator-rejects-covered-inputs","claim":"In the `.isoHom`/`.isoInv` branches, `eval` accepts only a structural *atom* or an atomic iso; any other iso goes to `| _ => throwError \"not implemented. try dsimp first.\"` (lines 534, 542). So `monoidal` fails on purely structural goals that its docstring covers and `monoidal_coherence` proves: `(α_ X Y Z ≪≫ (α_ X Y Z).symm).hom = 𝟙 _`, `(α_ X Y Z).symm.hom = (α_ X Y Z).inv`, `(whiskerLeftIso W (α_ X Y Z)).hom = W ◁ (α_ X Y Z).hom`. `bicategory` fails in the same way. `eval` also rejects its own output: normal forms are built from `(… ≪≫ …).hom` and `(whiskerLeftIso …).hom` structural composites, so `monoidal_nf` followed by `monoidal` fails even on `f ≫ g = f ≫ g`. The docstring ('Evaluate the expression of a 2-morphism into a normalized form') does not mention the restriction. The `isStructural` predicate defined at line 111, unused anywhere in Mathlib, is exactly what this case needs. Non-structural composites such as `(α ≪≫ β).hom` also fail. That case is outside this fix, and the error message points to the `dsimp` workaround. Graded MINOR, not MAJOR: the branch throws an explicit \"not implemented. try dsimp first.\" — a signposted limitation, not a wrong result. Reproduced: `monoidal` on `(α_ X Y Z).symm.hom = (α_ X Y Z).inv` and `monoidal_nf; monoidal` on `f ≫ g = f ≫ g` both fail with that message (main/repro2.lean); `monoidal_coherence` proves the first. No upstream report found.","fix":"Replace the `.structuralAtom α` cases by `| α => if α.isStructural then return ⟨← nilM α, ← mkEqRefl e.e⟩` (and `nilM (← symmM α)` for `isoInv`). This was checked: it closes the three structural goals, the `monoidal_nf; monoidal` re-entry and the bicategory analogue, and leaves the existing `monoidal` tests passing.","ev":"import Mathlib.Tactic.CategoryTheory.Monoidal.Basic\nopen CategoryTheory MonoidalCategory\nvariable {C : Type u} [Category.{v} C] [MonoidalCategory C] {X Y Z W : C}\nexample : (α_ X Y Z ≪≫ (α_ X Y Z).symm).hom = 𝟙 _ := by monoidal          -- error: not implemented. try dsimp first.\nexample : (α_ X Y Z).symm.hom = (α_ X Y Z).inv := by monoidal               -- same error\nexample : (whiskerLeftIso W (α_ X Y Z)).hom = W ◁ (α_ X Y Z).hom := by monoidal -- same error\nexample : (α_ X Y Z ≪≫ (α_ X Y Z).symm).hom = 𝟙 _ := by monoidal_coherence -- ok\nexample (f : X ⟶ Y) (g : Y ⟶ Z) : f ≫ g = f ≫ g := by monoidal_nf; monoidal -- same error\n-- Probes: hunts/coherence-normalize/batch3/P1.lean T3/T4 (lines 72-99) and hunts/coherence-normalize/batch3/P2.lean line 180 and line 198 (bicategory). Fix check: P2.lean section F2 (`evalFixed` = `eval` with the isStructural branch, driven by copies of `normalForm`/`main`): lines 172-177, 184, 186 and 201 compile.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-b90e8f","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.eval","line":524,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-misdescribes-signature","claim":"The module docstring's 'Main definitions' entry says '`Tactic.BicategoryLike.eval`: Given a Lean expression `e` that represents a morphism in a monoidal category, this function returns a pair of `⟨e', pf⟩`'. The real declaration is `Mathlib.Tactic.BicategoryLike.eval : Name → Mor₂ → CoherenceM ρ Eval.Result`: it takes a `Mor₂` (not an `Expr`) and a trace-class `nm`, and serves bicategories too. Its own docstring does not explain `nm` or say that it throws on `Iso.hom`/`Iso.inv` of non-atomic isos.","fix":"Fix the module-doc entry (full name, `Mor₂` input, `Eval.Result` output, monoidal and bicategory) and document `nm` and the unsupported inputs in `eval`'s docstring.","ev":"measured: hunts/coherence-normalize/batch3/P1.lean `#check @Mathlib.Tactic.BicategoryLike.eval` prints `{ρ : Type} → [MonadMor₁ (CoherenceM ρ)] → … → Lean.Name → Mor₂ → CoherenceM ρ Eval.Result`; module doc lines 57-60.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-819bf6","file":"Mathlib/Tactic/ClickSuggestions/FindPremises.lean","decl":"Mathlib.Tactic.ClickSuggestions.isMVarSwap","line":50,"sev":"MINOR","status":"confirmed","cat":"correctness","pattern":"equality-check-ignores-universes","claim":"`isMVarSwap` (\"`true` if `s` and `t` are equal up to swapping the `MVarId`s\") ignores universe levels in its `.sort` and `.const` branches whenever the expression has level parameters, so it identifies expressions that differ in rigid universes: `isMVarSwap (.sort (.param u)) (.sort (.succ (.param u)))` and `isMVarSwap (.const ULift [u+1, 0]) (.const ULift [u, 0])` both return `true`. Since a `true` result makes `Entries.addConst`/`addFVar` drop the reverse (`←`) rewrite entry, such lemmas lose their reverse rewrite suggestion. The pruning also ignores premises: for `h : ∀ a b, a ≤ b → f a b = f b a` the reverse entry is dropped although `← h a b hab` is the useful direction.","fix":"Compare universe levels (up to level-metavariable renaming) in the `.sort`/`.const` branches, and only prune the reverse entry when the premises are also symmetric.","ev":"probe1.lean (module, `import all`): `#eval isMVarSwap (.sort (.param `u)) (.sort (.succ (.param `u)))` = `true`; the `ULift` levels case = `true`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-b403eb","file":"Mathlib/Tactic/ClickSuggestions/FindPremises.lean","decl":"Mathlib.Tactic.ClickSuggestions.computeLCtxDiscrTrees","line":275,"sev":"MINOR","status":"confirmed","cat":"correctness","pattern":"index-lookup-config-mismatch","claim":"Local-hypothesis entries are built under the caller's `Meta.Config` (`computeLCtxDiscrTrees` does not wrap `Entries.addFVar` in `withConfig librarySearchIndexConfig`), while imported and current-module entries are built under `librarySearchIndexConfig` (via `foldImportedDecls`/`foldCurrFileDecls`) and `getMatches`/`getImportMatches` always look up under `librarySearchIndexConfig` (`proj := .no`). Keys for local hypotheses can therefore be computed with projections reduced and then fail to match at lookup.","fix":"Run `computeLCtxDiscrTrees`' insertion under `withConfig (fun _ ↦ librarySearchIndexConfig)`.","ev":"Source L241–297: L250/L267 pass `librarySearchIndexConfig` to the folds, L288/L296 use it for lookup, L275–281 use none.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-60c956","file":"Mathlib/Tactic/Inclusion/Extension/IntervalDyadicReal/BinarySplit.lean","decl":"Inclusion.IntervalDyadicReal.midpoint","line":25,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"`midpoint` has no specification lemma, such as `(midpoint a b).toRat = (a.toRat + b.toRat) / 2`, and nothing in Mathlib or core states one. `mem_binarySplitMap` uses no property of it, so the file proves coverage but never that the cover actually bisects (any split point, even one outside `[l, u]`, gives the same theorem).","fix":"Add `toRat_midpoint` (and `l ≤ u → l ≤ midpoint l u ∧ midpoint l u ≤ u`) next to the definition.","ev":"git grep -n 'midpoint' origin/master -- Mathlib/Tactic/Inclusion Mathlib/Data/Dyadic.lean: only the definition (L25) and its two uses (L38, L49); core Init/Data/Dyadic has no lemma about `shiftRight` values (only `shiftRight_trailingZeros_mod_two`).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b28ca9","file":"Mathlib/Tactic/NormNum/Abs.lean","decl":"Mathlib.Meta.NormNum.evalAbs","line":56,"sev":"MINOR","status":"confirmed","cat":"correctness","pattern":"unchecked-assume-instances-commute","claim":"`evalAbs` matches `@abs _ $instLattice $instAddGroup $a`, synthesizes its own `Ring`/`IsOrderedRing`, and uses `assumeInstancesCommute` without checking that these agree with the captured `AddGroup`. With a non-canonical `AddGroup ℚ` (transferred along `x ↦ x - 1`, so zero is `1` and `|0| = 2`), `norm_num` reduces the *true* goal `|0| = 2` to `⊢ False`, and on `|0| = 0` it produces a certificate the kernel rejects ('application type mismatch'). Nothing unsound follows, since the kernel catches it, but the tactic misleads. The unchecked `assumeInstancesCommute` pattern is common in norm_num extensions. Graded MINOR: tactic robustness on non-canonical instances, not a wrong library statement.","fix":"Use `assertInstancesCommute` (or check the captured instances against the synthesized ones) and fail gracefully on mismatch.","ev":"-- hunts/normnum-abs/P2.lean: `abbrev shiftedAddGroup : AddGroup ℚ := shift.addGroup` (shift x = x - 1); `example : @abs ℚ inferInstance shiftedAddGroup 0 = 2 := by norm_num` → `unsolved goals ⊢ False` plus a (kernel) application type mismatch; `... = 0 := by norm_num` → (kernel) application type mismatch on `isNat_eq_true (isNat_abs_nonneg ...)`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-cf3a82","file":"Mathlib/Tactic/NormNum/BigOperators.lean","decl":"Mathlib.Meta.Multiset.insert_eq_cons","line":175,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Mathlib.Meta.Multiset.insert_eq_cons` (Tactic.NormNum.BigOperators), `Multiset.insert_eq_cons` (Data.Multiset.ZeroCons) state exactly the same thing (Lean-checked). Reviewer: `Mathlib.Meta.Multiset.insert_eq_cons` is an rfl copy of the root @[simp] lemma, which is already imported via BigOperators.Group.Finset.Basic. It has no uses at all: only `Finset.insert_eq_cons` is used in the file, at l.253. Delete the tactic-namespace copy.","fix":"Deprecate `Mathlib.Meta.Multiset.insert_eq_cons` in favour of `Multiset.insert_eq_cons`.","ev":"dupscan/Check.lean: `example := (@Multiset.insert_eq_cons : type_of% @Mathlib.Meta.Multiset.insert_eq_cons)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 38, rating MAJOR): The tactic uses its Finset helper, while the Multiset copy has no uses or special attributes. The already imported root theorem suffices.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-f4ae07","file":"Mathlib/Tactic/Widget/SelectPanelUtils.lean","decl":"String.renameMetaVar","line":41,"sev":"MINOR","status":"confirmed","cat":"correctness","pattern":"string-level-rewrite-of-syntax","claim":"`String.renameMetaVar` works on raw characters, so on the pretty-printed goals it is applied to (by the `calc`, `congrm?` and `conv?` widgets) it corrupts text that merely contains `?m.`: `x ++ \"?m.12\"` becomes `x ++ \"?_\"` and `«?m.12»` becomes `«?_»`, changing the generated tactic; it also mangles `?m.foo` into `?_foo` and `?m.12.3` into `?_.3`, and leaves named metavariables such as `?goal` untouched, contrary to its docstring (\"Replace all meta-variable names\").","fix":"Print with `pp.mvars.anonymous := false` (or `pp.mvars := false`), as `Lean.Meta.Tactic.TryThis.delabToRefinableSyntax` does, instead of post-processing the string.","ev":"probe2.lean `#eval`s: `\"x ++ \\\"?_\\\"\"`, `\"«?_»\"`, `\"?goal\"`, `\"?_foo\"`, `\"?_.3\"`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-07c626","file":"Mathlib/Tactic/Widget/SelectPanelUtils.lean","decl":"mkSelectionPanelRPC","line":107,"sev":"MINOR","status":"suspected","cat":"correctness","pattern":"sanitized-names-in-generated-code","claim":"The callback runs in `md.lctx.sanitizeNames`, so inaccessible/shadowed hypotheses are presented under display names like `h✝`; callbacks that print hypothesis names into the inserted code (e.g. `conv at h✝ => …` from the `conv?` widget when an older shadowed `h` is selected) generate code that does not resolve.","fix":"Expose names (`Lean.MVarId.exposeNames`/`withExposedNames`) in the inserted code, or reject selections in inaccessible hypotheses.","ev":"Source L107; not reproduced in an interactive widget session.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-3b60ed","file":"Mathlib/Tactic/Widget/SelectPanelUtils.lean","decl":"mkSelectionPanelRPC","line":109,"sev":"MINOR","status":"confirmed","cat":"correctness","pattern":"positions-vs-uninstantiated-expr","claim":"`mkSelectionPanelRPC` hands the callback `md.type.consumeMData`, the raw goal type, while the selected `SubExpr.Pos`s come from the infoview, which renders `instantiateMVars` of the goal (`Lean.Widget.goalToInteractive`). If the goal type contains assigned metavariables the positions refer to a different tree than the expression the callback (e.g. `insertMetaVar`) navigates.","fix":"Pass `← instantiateMVars md.type` (then `consumeMData`).","ev":"Source L106–110: `mkCmdStr (selectedLocations params) md.type.consumeMData`, no `instantiateMVars`; core `goalToInteractive` instantiates before computing positions.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-51af0e","file":"Mathlib/Topology/Algebra/Algebra/Equiv.lean","decl":"ContinuousAlgEquiv.coeCLE_apply","line":134,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `ContinuousAlgEquiv.coeCLE_apply` (Topology.Algebra.Algebra.Equiv), `ContinuousAlgEquiv.toContinuousLinearEquiv_apply` (Topology.Algebra.Algebra.Equiv) state exactly the same thing (Lean-checked). Reviewer: Adjacent @[simp] rfl lemmas; the `Coe` instance (line 132) is `⟨toContinuousLinearEquiv⟩`, so `(e : A ≃L[R] B) a` is `e.toContinuousLinearEquiv a`. Keep `toContinuousLinearEquiv_apply` (fits `toContinuousLinearEquiv_symm`/`trans_toContinuousLinearEquiv` naming), deprecate `coeCLE_apply` (unused).","fix":"Deprecate `ContinuousAlgEquiv.coeCLE_apply` in favour of `ContinuousAlgEquiv.toContinuousLinearEquiv_apply`.","ev":"dupscan/Check.lean: `example := (@ContinuousAlgEquiv.toContinuousLinearEquiv_apply : type_of% @ContinuousAlgEquiv.coeCLE_apply)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 41, rating MAJOR): The coercion instance expands to the named conversion, and both lemmas have identical simp roles. The longer conversion-based name fits the surrounding API.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-07e9f6","file":"Mathlib/Topology/Algebra/Algebra/Equiv.lean","decl":"ContinuousAlgEquiv.coeCLE_refl","line":209,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `ContinuousAlgEquiv.coeCLE_refl` (Topology.Algebra.Algebra.Equiv), `ContinuousAlgEquiv.refl_toContinuousLinearEquiv` (Topology.Algebra.Algebra.Equiv) state exactly the same thing (Lean-checked). Reviewer: Six lines apart, both @[simp] rfl: `(refl R A).toContinuousLinearEquiv = .refl R A`. Neither is used. Keep the name that matches the LHS and deprecate `coeCLE_refl`.","fix":"Deprecate `ContinuousAlgEquiv.coeCLE_refl` in favour of `ContinuousAlgEquiv.refl_toContinuousLinearEquiv`.","ev":"dupscan/Check.lean: `example := (@ContinuousAlgEquiv.refl_toContinuousLinearEquiv : type_of% @ContinuousAlgEquiv.coeCLE_refl)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 43, rating MAJOR): Both already state the equality using `.toContinuousLinearEquiv`, so even the surface statements provide no separate coercion interface.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-0e6066","file":"Mathlib/Topology/Algebra/ContinuousAffineEquiv.lean","decl":"ContinuousAffineEquiv.image_symm_eq_preimage","line":245,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `ContinuousAffineEquiv.image_symm` (Topology.Algebra.ContinuousAffineEquiv), `ContinuousAffineEquiv.image_symm_eq_preimage` (Topology.Algebra.ContinuousAffineEquiv) state exactly the same thing (Lean-checked). Reviewer: Same file: `e.symm '' s = e ⁻¹' s` appears as @[simp] image_symm (pairs with preimage_symm and mirrors AffineEquiv.image_symm) and as protected image_symm_eq_preimage. ContinuousAffineEquiv is the only equiv type with both. Deprecate image_symm_eq_preimage.","fix":"Deprecate `ContinuousAffineEquiv.image_symm_eq_preimage` in favour of `ContinuousAffineEquiv.image_symm`.","ev":"dupscan/Check.lean: `example := (@ContinuousAffineEquiv.image_symm_eq_preimage : type_of% @ContinuousAffineEquiv.image_symm)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup3 item 40, rating MINOR): The longer name mirrors [Equiv.image_symm_eq_preimage](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Logic/Equiv/Set.lean#L67) and pairs with `image_eq_preimage_symm`; the shorter name mirrors AffineEquiv. A supported alias preserves both conventional interfaces.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-2fe717","file":"Mathlib/Topology/Algebra/ContinuousAffineEquiv.lean","decl":"ContinuousAffineEquiv.symm_refl","line":268,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `ContinuousAffineEquiv.symm_refl` (Topology.Algebra.ContinuousAffineEquiv), `ContinuousAffineEquiv.refl_symm` (Topology.Algebra.ContinuousAffineEquiv) state exactly the same thing (Lean-checked). Reviewer: Adjacent @[simp] rfl lemmas `(refl k P₁).symm = refl k P₁`, neither used by name. `refl_symm` is the dominant name (Equiv, Homeomorph, LinearEquiv, ContinuousLinearEquiv, ContinuousAlgEquiv...). Keep it, deprecate `symm_refl`.","fix":"Deprecate `ContinuousAffineEquiv.symm_refl` in favour of `ContinuousAffineEquiv.refl_symm`.","ev":"dupscan/Check.lean: `example := (@ContinuousAffineEquiv.refl_symm : type_of% @ContinuousAffineEquiv.symm_refl)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 42, rating MAJOR): Both have identical attributes and interfaces; `refl_symm` follows the prevailing equivalence convention.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-7d43d7","file":"Mathlib/Topology/Algebra/Module/ClosedSubmodule.lean","decl":"ClosedSubmodule.closure_toSubmodule_eq","line":213,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `ClosedSubmodule.closure_toSubmodule_eq` (Topology.Algebra.Module.ClosedSubmodule), `Submodule.closure_eq` (Topology.Algebra.Module.ClosedSubmodule) state exactly the same thing (Lean-checked). Reviewer: Same file: @[simp] Submodule.closure_eq {s : ClosedSubmodule} : s.closure = s and ClosedSubmodule.closure_toSubmodule_eq : s.toSubmodule.closure = s elaborate identically. The second has 1 use (l.293).","fix":"Deprecate `ClosedSubmodule.closure_toSubmodule_eq` in favour of `Submodule.closure_eq`.","ev":"dupscan/Check.lean: `example := (@Submodule.closure_eq : type_of% @ClosedSubmodule.closure_toSubmodule_eq)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 39, rating MAJOR): Writing the coercion explicitly as `.toSubmodule` adds no distinct rewrite rule, and the surviving theorem already provides simp behavior.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-07b162","file":"Mathlib/Topology/Algebra/Nonarchimedean/AdicTopology.lean","decl":"hasBasis_nhds_zero_adic","line":98,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"reprovable-from-existing-api","claim":"The 12-line hand-unfolded proof of `hasBasis_nhds_zero_adic` is `by simpa using I.adic_basis.toRing_subgroups_basis.hasBasis_nhds_zero` (the generic basis lemma plus `I ^ n • ⊤ = I ^ n`).","fix":"Replace the proof by the one-line `simpa`.","ev":"hunts/adic-topology/probe2.lean, first example: compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-8ed114","file":"Mathlib/Topology/Algebra/Nonarchimedean/AdicTopology.lean","decl":"openAddSubgroup","line":145,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-describes-other-object","claim":"`Ideal.openAddSubgroup`'s docstring says it gives the basis elements 'for the `I`-adic topology on an `R`-module `M`, seen as open additive subgroups of `M`', but the declaration is `@OpenAddSubgroup R _ I.adicTopology` — the subgroup `I ^ n` of the ring `R`, and `M` is not an argument. Also `adicModuleTopology`'s docstring says 'associated to an ideal `M`' (it is `I`), and `hasBasis_nhds_zero_adic`'s says 'the neighborhoods of zero has basis'.","fix":"Say 'the open additive subgroup `I ^ n` of `R` for the `I`-adic topology'; fix the `M`/`I` typo.","ev":"Measured: source L142-145 (statement is about `R`), L136.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-7b4d93","file":"Mathlib/Topology/Algebra/Nonarchimedean/AdicTopology.lean","decl":"isAdic_iff","line":163,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`isAdic_iff` and `is_ideal_adic_pow` assume `[IsTopologicalRing R]`, but only `[IsTopologicalAddGroup R]` is used (the ← direction goes through `IsTopologicalAddGroup.ext`; the adic topology is then a ring topology anyway); `is_bot_adic_iff` needs no compatibility class at all: `IsAdic ⊥ → DiscreteTopology` follows from `IsAdic.hasBasis_nhds` at `n = 1`, and a discrete ring is a topological ring by instance.","fix":"Weaken to `[IsTopologicalAddGroup R]` in `isAdic_iff`/`is_ideal_adic_pow` and drop `[IsTopologicalRing A]` from `is_bot_adic_iff`.","ev":"hunts/adic-topology/probe1.lean: `isAdic_iff'` (original proof, `IsTopologicalAddGroup`), `is_bot_adic_iff'` (no compatibility class) and `is_ideal_adic_pow'` (`IsTopologicalAddGroup`) all compile, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-663d58","file":"Mathlib/Topology/Algebra/Order/Floor.lean","decl":"tendsto_floor_atTop","line":65,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"general-material-in-specialised-file","claim":"`tendsto_floor_atTop`, `tendsto_floor_atBot`, `tendsto_ceil_atTop`, `tendsto_ceil_atBot` are purely order-theoretic (no topology in statement or proof) but live in Topology/Algebra/Order/Floor.lean, under a standing `-- TODO: move to Mathlib/Order/Filter/AtTopBot/Floor.lean` (L65). That target file already exists and is imported here, and the lemmas compile from it alone; so importing them pulls in the topology hierarchy for no reason.","fix":"Move the four lemmas to Order/Filter/AtTopBot/Floor.lean and drop the TODO.","ev":"hunts/topo-floor/probe1.lean: `tendsto_floor_atTop'` and `tendsto_ceil_atBot'` with the original proofs compile importing only Algebra/Order/Floor/Ring and Order/Filter/AtTopBot/Floor, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-4a0af6","file":"Mathlib/Topology/Algebra/Order/Floor.lean","decl":"tendsto_floor_atTop","line":67,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`[IsStrictOrderedRing α]` is not needed for `tendsto_floor_atTop` (and, per Astra, for the other three `atTop`/`atBot` lemmas and the one-sided floor/ceil limits): `Int.floor_mono.tendsto_atTop_atTop fun n ↦ ⟨n, Int.le_floor.mpr le_rfl⟩` works over any `[Ring α] [LinearOrder α] [FloorRing α]`. Astra also proposes `ClosedIciTopology`/`ClosedIicTopology` instead of `OrderClosedTopology` for the one-sided limits, `SeparatelyContinuousAdd` instead of `IsTopologicalAddGroup` for the `fract` lemmas (covering the Sorgenfrey line), and `OrderClosedTopology` instead of `OrderTopology` for `comp_fract` (items 2-5; only the first is compiled here).","fix":"Drop `IsStrictOrderedRing` where unused and weaken the topology classes per lemma.","ev":"hunts/topo-floor/probe1.lean (B): `tendsto_floor_atTop` without `IsStrictOrderedRing` compiles, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-ab988e","file":"Mathlib/Topology/Algebra/Order/Floor.lean","decl":"continuousOn_floor","line":85,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-codomain-variant","claim":"`continuousOn_floor`/`continuousOn_ceil` are about the cast functions `fun x ↦ (⌊x⌋ : α)`, not `Int.floor : α → ℤ`, although the names and the module docstring ('`Int.floor` is continuous on `Ico n (n + 1)`') suggest the latter; the integer-valued versions are missing (one-line proofs) (Astra A1 item 1).","fix":"Add `continuousOn_intFloor`/`continuousOn_intCeil` for `ℤ`-valued maps and document the cast versions.","ev":"hunts/topo-floor/probe1.lean (C): `ContinuousOn (Int.floor : R → ℤ) (Ico (n : R) (n + 1))` by `(continuousOn_congr <| Int.floor_eq_on_Ico n).mpr continuousOn_const` compiles, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261013-c7a977","file":"Mathlib/Topology/Algebra/SeparationQuotient/Basic.lean","decl":"SeparationQuotient.instModule","line":391,"sev":"MINOR","status":"suspected","cat":"generality","pattern":"too-strong-typeclass","claim":"The additive structure and `instModule` on `SeparationQuotient M` assume joint `[ContinuousAdd M]`, but compatibility of inseparability with addition only needs each translation to be continuous (x ⤳ x' ⇒ x+y ⤳ x'+y, then y ⤳ y' ⇒ x'+y ⤳ x'+y', and specialization is transitive); Mathlib has `SeparatelyContinuousAdd` (Topology/Algebra/Monoid/Defs.lean:58). Example from Astra: ℚ with the cofinite topology has separately but not jointly continuous addition. Raised by Astra's blind pass on SeparationQuotient/FiniteDimensional.lean; not yet checked in Lean.","fix":"Check whether the `Add`/`AddCommMonoid`/`Module` instances on `SeparationQuotient` (and `mkCLM`) can be stated under `[SeparatelyContinuousAdd M]`; if so, weaken them and the downstream `instModuleFinite`.","ev":"Not yet probed. Source: hunts/sepquot-findim/A1.answer.md point 1; `class SeparatelyContinuousAdd` exists at Mathlib/Topology/Algebra/Monoid/Defs.lean:58.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":""},{"id":"RT-20261013-f839e8","file":"Mathlib/Topology/Algebra/SeparationQuotient/FiniteDimensional.lean","decl":"SeparationQuotient.instModuleFinite","line":24,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"defeq-abuse-quotient-implementation","claim":"The proof passes `Quotient.mk_surjective` as the surjectivity of `mkCLM R M`, which only typechecks by unfolding `SeparationQuotient` to its `Quotient` implementation; the type's own API lemma `SeparationQuotient.surjective_mk` (Topology/Inseparable.lean) states exactly what is needed and is what the sibling files (`SeparationQuotient/Basic.lean`, `Section.lean`) use.","fix":"`Module.Finite.of_surjective (mkCLM R M).toLinearMap surjective_mk`.","ev":"hunts/sepquot-findim/irr_orig.lean: with `attribute [local irreducible] SeparationQuotient`, the original proof fails ('Application type mismatch … Quotient.mk_surjective'); hunts/sepquot-findim/irr_new.lean: the same with `surjective_mk` compiles, exit 0; hunts/sepquot-findim/copy.lean: the file with the replacement compiles with the Mathlib linter set, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261007-9ac3a0","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"lightToProfinite","line":78,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-instance-on-functor-image","claim":"`SecondCountableTopology (lightToProfinite.obj X)` is not found by instance search (only `TotallyDisconnectedSpace` is, via Profinite's instance), so Profinite-level results needing second countability or metrizability do not apply to `lightToProfinite.obj S` without `inferInstanceAs`, although the file itself works with `lightToProfinite.obj S` (e.g. `instCountableDiscreteQuotient`, `toLightDiagram`).","fix":"Add `instance {X : LightProfinite} : SecondCountableTopology (lightToProfinite.obj X) := X.prop.2`.","ev":"hunts/lightprofinite/batch0/probe_missing.lean, line 15: `example (X : LightProfinite) : SecondCountableTopology (lightToProfinite.obj X) := inferInstance` fails (synthInstanceFailed), while line 17 (TotallyDisconnectedSpace) compiles; with the instance added (hunts/lightprofinite/batch0/probe2.lean) it compiles.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-e43b8b","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"lightProfiniteToCompHaus","line":86,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-instance-on-functor-image","claim":"API out of sync with Profinite (which the file's own comment asks to keep in sync): Profinite/Basic.lean:86 provides `instance {X : Profinite} : TotallyDisconnectedSpace (profiniteToCompHaus.obj X)`, but LightProfinite has no analogue, so neither `TotallyDisconnectedSpace (lightProfiniteToCompHaus.obj X)` nor `SecondCountableTopology (lightProfiniteToCompHaus.obj X)` is found by instance search.","fix":"Add `instance {X : LightProfinite} : TotallyDisconnectedSpace (lightProfiniteToCompHaus.obj X) := X.prop.1` and the `SecondCountableTopology` analogue `:= X.prop.2`, mirroring Profinite/Basic.lean:86.","ev":"hunts/lightprofinite/batch0/probe_missing.lean (the Profinite line compiles; the two lightProfiniteToCompHaus lines fail with synthInstanceFailed); hunts/lightprofinite/batch0/probe2.lean adds the instances and the same examples then compile.\nimport Mathlib.Topology.Category.LightProfinite.Basic\n\nopen CategoryTheory\n\n/-! Batch 0: instances available on `Profinite` images that are missing on `LightProfinite` images.\nExpected: the Profinite line compiles, the three LightProfinite lines fail to synthesize. -/\n\n-- Profinite has this (Profinite/Basic.lean:86)\nexample (X : Profinite) : TotallyDisconnectedSpace (profiniteToCompHaus.obj X) := inferInstance\n-- LightProfinite has no analogue\nexample (X : LightProfinite) : TotallyDisconnectedSpace (lightProfiniteToCompHaus.obj X) :=\n  inferInstance\nexample (X : LightProfinite) : SecondCountableTopology (lightProfiniteToCompHaus.obj X) :=\n  inferInstance\nexample (X : LightProfinite) : SecondCountableTopology (lightToProfinite.obj X) := inferInstance\n-- while the totally-disconnected one on the `Profinite` image is found (via Profinite's instance)\nexample (X : LightProfinite) : TotallyDisconnectedSpace (lightToProfinite.obj X) := inferInstance\n","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-01cfb5","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"FintypeCat.toLightProfinite","line":102,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-compatibility-with-parent-functor","claim":"No declaration relates `FintypeCat.toLightProfinite` to `FintypeCat.toProfinite`, although `toLightProfinite ⋙ lightToProfinite = toProfinite` holds by `rfl` and downstream code relies on it silently by defeq (LightProfinite/Extend.lean:70 `rfl` example and :81 passing `lightToProfinite.mapCone c` where `Profinite.Extend.functor_initial` expects a `Cone (F ⋙ toProfinite)`). `git grep` finds no line mentioning both functors.","fix":"Add `FintypeCat.toLightProfiniteCompLightToProfinite : toLightProfinite ⋙ lightToProfinite ≅ toProfinite := Iso.refl _` (or the `rfl` equation) and use it in LightProfinite/Extend.lean.","ev":"hunts/lightprofinite/batch1/P1.lean (b): `example : FintypeCat.toLightProfinite.{u} ⋙ lightToProfinite = FintypeCat.toProfinite.{u} := rfl` compiles; `git -C ~/mathlib-redteam grep -n toLightProfinite origin/master -- Mathlib | grep -i 'lightToProfinite\\|toProfinite\\b'` returns nothing.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-071c71","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightProfinite.instTotallyDisconnectedSpaceCarrierToTopTruePtCompHausLimitConeCompLightProfiniteToCompHaus","line":128,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"single-use-instance-reproving-parent","claim":"A global instance keyed on the specific term `(CompHaus.limitCone (F ⋙ lightProfiniteToCompHaus)).pt.toTop`, used only once (in `limitCone`, nothing else in Mathlib mentions `CompHaus.limitCone`), re-proving what `Profinite.limitCone` already proves: it is definitionally `(Profinite.limitCone (F ⋙ lightToProfinite)).pt.prop`. The `Profinite` counterpart inlines this proof instead of exporting an instance.","fix":"Delete the instance and fill the first `prop` component of `limitCone` with `(Profinite.limitCone.{v, u} (F ⋙ lightToProfinite)).pt.prop`.","ev":"hunts/lightprofinite/batch1/P1.lean (c): `example {J : Type v} [SmallCategory J] (F : J ⥤ LightProfinite.{max u v}) : TotallyDisconnectedSpace (CompHaus.limitCone.{v, u} (F ⋙ lightProfiniteToCompHaus)).pt.toTop := (Profinite.limitCone.{v, u} (F ⋙ lightToProfinite)).pt.prop` compiles; hunts/lightprofinite/batch1/C2.lean (src.lean with the instance deleted and `· exact (Profinite.limitCone.{v, u} (F ⋙ lightToProfinite)).pt.prop`) compiles with no errors.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-407e06","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightProfinite.limitCone","line":136,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"countable-category-where-countable-objects-suffice","claim":"`[CountableCategory J]` is stronger than needed: second countability of the cone point only needs countably many objects (the product `∀ j, F.obj j`), never countable hom-types. With `[Countable J]` in both `limitCone` and `limitConeIsLimit`, the whole file (incl. `createsCountableLimits`, `HasCountableLimits`) still compiles.","fix":"Replace `[CountableCategory J]` by `[Countable J]` in `limitCone` and `limitConeIsLimit` and say \"a category with countably many objects\" in the docstring.","ev":"hunts/lightprofinite/batch1/C1.lean (src.lean with L136 and L156 `[CountableCategory J]` → `[Countable J]`) compiles with no errors.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-873193","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightProfinite.limitConeIsLimit","line":156,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"rederived-instead-of-transported","claim":"The 10-line definition re-runs the limit argument against `CompHaus.limitConeIsLimit` (ending in a non-terminal `simp [← h]` followed by `rfl`), although `lightToProfinite.mapCone (limitCone F)` is definitionally `Profinite.limitCone (F ⋙ lightToProfinite)`, so it is the transport of `Profinite.limitConeIsLimit` along the fully faithful `lightToProfinite`: one line noncomputably, or a computable 3-line `IsLimit.ofFaithful`.","fix":"Define it as `.ofFaithful lightToProfinite (Profinite.limitConeIsLimit.{v, u} _) (fun S ↦ ConcreteCategory.ofHom ((Profinite.limitConeIsLimit.{v, u} _).lift (lightToProfinite.mapCone S)).hom.hom) fun _ ↦ rfl`.","ev":"hunts/lightprofinite/batch1/C3b.lean (src.lean with that body) compiles with no errors; hunts/lightprofinite/batch1/C3.lean `isLimitOfReflects lightToProfinite (Profinite.limitConeIsLimit.{v, u} _)` elaborates but needs `noncomputable` (only error: lean.dependsOnNoncomputable); P1.lean (g),(g') compile as `noncomputable example`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-778d71","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"createsCountableLimits","line":170,"sev":"MINOR","status":"suspected","cat":"generality","pattern":"universe-coupling","claim":"Astra A1 item 2 (not compiled): `createsCountableLimits` is stated for `lightToProfinite.{max v u}` with `[SmallCategory J] [CountableCategory J]`, tying the universe of the spaces to that of the index category; countable categories can be shrunk (`CountableCategory.homAsTypeEquiv`, `createsLimitsOfShapeOfEquiv`), so e.g. `CreatesLimitsOfShape (ULift.{1} ℕ) lightToProfinite.{0}` should hold but is outside the instance's universe pattern.","fix":"Generalise via `CountableCategory.homAsTypeEquiv` and `createsLimitsOfShapeOfEquiv`.","ev":"Suspected: Astra A1 item 2 (probe not run).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-e1ef8b","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightProfinite.instPreservesLimitsOfShapeOppositeNatForgetContinuousMapCarrierToTopAndTotallyDisconnectedSpaceSecondCountableTopology","line":180,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"instance-for-special-shape-only","claim":"Only provides `PreservesLimitsOfShape ℕᵒᵖ (forget LightProfinite)`, although the identical two-line proof gives `PreservesLimitsOfShape J (forget LightProfinite)` for every countable `J : Type` (the shapes `createsCountableLimits`/`HasCountableLimits` are set up for); today `inferInstance` fails for countable `J`. With the general instance, `ℕᵒᵖ` is still found. The gap shows downstream: Condensed/Light/Functors.lean:70-71 rebuilds `PreservesLimitsOfShape J LightProfinite.toTopCat` inline.","fix":"State the instance for `{J : Type} [SmallCategory J] [CountableCategory J]` (same proof), and add the analogous `LightProfinite.toTopCat` instance.","ev":"hunts/lightprofinite/batch2/probe3.lean: after `attribute [-instance]` on this instance, `instance generalised {J : Type} [SmallCategory J] [CountableCategory J] : PreservesLimitsOfShape J (forget LightProfinite.{u}) := have : PreservesLimitsOfSize.{0, 0} (forget Profinite.{u}) := preservesLimitsOfSize_shrink _; inferInstanceAs (PreservesLimitsOfShape J (lightToProfinite ⋙ forget Profinite))` compiles and `example : PreservesLimitsOfShape ℕᵒᵖ (forget LightProfinite.{u}) := inferInstance` compiles; probe1.lean P5 shows the countable-J `inferInstance` fails today and the toTopCat version compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-c3bf1b","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightProfinite.isClosedMap","line":187,"sev":"MINOR","status":"pr-open","cat":"reuse","pattern":"restates-comphauslike-api","claim":"Restates `CompHausLike.isClosedMap` (CompHausLike/Basic.lean:226, `theorem isClosedMap {X Y : CompHausLike.{u} P} (f : X ⟶ Y) : IsClosedMap f`), which applies verbatim because `LightProfinite` is an abbrev of `CompHausLike`; the proof is literally `CompHausLike.isClosedMap _` and the two constants are rfl-equal. No use anywhere in Mathlib, and Profinite/CompHaus/Stonean no longer carry such a copy, so the file's 'keep in sync with Profinite' rationale does not apply.","fix":"Deprecate `LightProfinite.isClosedMap` as an alias of `CompHausLike.isClosedMap`.","ev":"hunts/lightprofinite/batch2/probe1.lean (P1): `example : IsClosedMap f := CompHausLike.isClosedMap f` and `example : @LightProfinite.isClosedMap.{u} = @CompHausLike.isClosedMap.{u} _ := rfl`; hunts/lightprofinite/batch2/src_fix.lean compiles with the declaration deleted","evr":"compiles","astraV":"","astraS":"","pr":44601,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-ec792c","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightProfinite.isIso_of_bijective","line":191,"sev":"MINOR","status":"pr-open","cat":"reuse","pattern":"restates-comphauslike-api","claim":"Restates `CompHausLike.isIso_of_bijective` (CompHausLike/Basic.lean:230, `theorem isIso_of_bijective {X Y : CompHausLike.{u} P} (f : X ⟶ Y) (bij : Function.Bijective f) : IsIso f`), which applies directly to `LightProfinite` morphisms; the proof even detours through `lightProfiniteToCompHaus` and `isIso_of_fully_faithful`. Its only consumers are `isoOfBijective` and `forget_reflectsIsomorphisms` in this file, which are themselves duplicates; the Profinite/CompHaus copies were removed.","fix":"Deprecate `LightProfinite.isIso_of_bijective` as an alias of `CompHausLike.isIso_of_bijective`.","ev":"hunts/lightprofinite/batch2/probe1.lean (P2): `example (bij : Function.Bijective f) : IsIso f := CompHausLike.isIso_of_bijective f bij`; hunts/lightprofinite/batch2/src_fix.lean compiles with it deleted","evr":"compiles","astraV":"","astraS":"","pr":44601,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-a31558","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightProfinite.forget_reflectsIsomorphisms","line":200,"sev":"MINOR","status":"pr-open","cat":"reuse","pattern":"restates-comphauslike-api","claim":"Duplicates the general instance `CompHausLike.forget_reflectsIsomorphisms : (forget (CompHausLike.{u} P)).ReflectsIsomorphisms` (CompHausLike/Basic.lean:244), which applies because `LightProfinite` is an abbrev. Currently the light copy shadows it (`#synth` returns `LightProfinite.forget_reflectsIsomorphisms`); with it erased, instance search finds `CompHausLike.forget_reflectsIsomorphisms`. Profinite/CompHaus/Stonean have no such copy.","fix":"Delete the instance (or keep it only as a deprecated alias of `CompHausLike.forget_reflectsIsomorphisms`).","ev":"hunts/lightprofinite/batch2/probe1.lean (P4): `attribute [-instance] LightProfinite.forget_reflectsIsomorphisms` then `example : (forget LightProfinite.{u}).ReflectsIsomorphisms := inferInstance`; `#synth` with pp.fullNames prints `CompHausLike.forget_reflectsIsomorphisms` (erased) vs `LightProfinite.forget_reflectsIsomorphisms` (default)","evr":"compiles","astraV":"","astraS":"","pr":44601,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-10fe69","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightProfinite.epi_iff_surjective","line":207,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"copied-proof-across-comphauslike-categories","claim":"The 33-line proof (L209-241) is a near-verbatim copy of `Profinite.epi_iff_surjective` (Profinite/Basic.lean:234) and the same clopen-separation argument as `Stonean.epi_iff_surjective` (Stonean/Basic.lean:126). It only uses that the codomain is totally disconnected and that `ULift (Fin 2)` lies in the category, so one `CompHausLike` lemma covers LightProfinite, Profinite and Stonean, each in one line.","fix":"Add `CompHausLike.epi_iff_surjective_of_totallyDisconnectedSpace [HasProp P (ULift (Fin 2))] [TotallyDisconnectedSpace Y]` and derive the three `epi_iff_surjective` from it.","ev":"hunts/lightprofinite/batch2/probe1.lean (P6): the general theorem `CompHausLike.epi_iff_surjective_of_totallyDisconnectedSpace {P : TopCat.{u} → Prop} [HasProp P (ULift.{u} (Fin 2))] {X Y : CompHausLike.{u} P} [TotallyDisconnectedSpace Y] (f : X ⟶ Y) : Epi f ↔ Function.Surjective f` compiles (clean under mathlibStandardSet), and `example {X Y : LightProfinite.{u}} (f : X ⟶ Y) : Epi f ↔ Function.Surjective f := CompHausLike.epi_iff_surjective_of_totallyDisconnectedSpace f` plus the Profinite and Stonean versions compile","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-65874f","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightDiagram","line":249,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"undocumented-morphism-convention","claim":"The module docstring and `LightDiagram`'s docstring never say that morphisms of `LightDiagram` are all continuous maps between the limit spaces (the category is induced from `Profinite` via `toProfinite`), not maps of the chosen towers; e.g. the identity of the two-point space is a morphism from the tower `pt, 2, 2, …` to the constant tower `2`, though no natural transformation of towers induces it. Readers of 'the equivalence `LightProfinite ≌ LightDiagram`' can easily misread what it asserts (Astra A1 item 11).","fix":"State in the docstrings that `LightDiagram` is a full subcategory-like category of `Profinite` (morphisms are continuous maps of the limits).","ev":"Measured: `instance : Category LightDiagram := inferInstanceAs <| Category (InducedCategory _ toProfinite)` (source L262-264); docstrings L249-258 and module docstring L17-24.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-feb578","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightDiagram.toProfinite","line":260,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"api-stated-on-unfolded-form-not-on-def","claim":"`LightDiagram.toProfinite` is a plain `def`, but the file states its API about the underlying space on `S.cone.pt` instead: the `SecondCountableTopology` instance at L306 and `lightDiagramToLightProfinite.obj` at L327. So that API does not carry over to `toProfinite`. `SecondCountableTopology S.toProfinite` and `SecondCountableTopology (lightDiagramToProfinite.obj S)` both fail to synthesize; the second is the carrier of `forget LightDiagram`. `SecondCountableTopology S.cone.pt` succeeds. With `toProfinite` as an `abbrev` (CopyB) the whole file compiles and the `S.toProfinite` form is found; the `lightDiagramToProfinite.obj S` form is still not found.","fix":"Make `toProfinite` an `abbrev` (or restate the L306 instance on `S.toProfinite`) and use `S.toProfinite` consistently instead of `S.cone.pt`.","ev":"example (S : LightDiagram) : SecondCountableTopology S.cone.pt := inferInstance  -- ok; example (S : LightDiagram) : SecondCountableTopology S.toProfinite := inferInstance  -- error: failed to synthesize; example (S : LightDiagram) : SecondCountableTopology (lightDiagramToProfinite.obj S) := inferInstance  -- error. Files: hunts/lightprofinite/batch3/Probe1.lean (P1e), hunts/lightprofinite/batch3/CopyB_abbrevToProfinite.lean.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-947926","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightDiagram.instCategory","line":263,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"simps-bang-instead-of-induced-hom-api","claim":"`@[simps!]` on the `Category LightDiagram` instance generates only the fully applied `LightDiagram.id_hom_hom_hom_apply` and `LightDiagram.comp_hom_hom_hom_apply`, whose right-hand side uses the raw field `TopCat.Hom.hom'`. Nothing in the file uses them: the file compiles with `@[simps!]` deleted (CopyA). The standard induced-category API that `ObjectProperty.FullSubcategory` (`hom_ext`, `FullSubcategory.id_hom`, `FullSubcategory.comp_hom`) and `CommMon` provide is missing. As a result `simp` makes no progress on `(f ≫ g).hom = f.hom ≫ g.hom` or on `InducedCategory.Hom.hom (𝟙 X) = 𝟙 X.toProfinite`, although both hold by `rfl`. It also fails on `lightDiagramToProfinite.map (f ≫ g) = f.hom ≫ g.hom`, leaving `(f ≫ g).hom = f.hom ≫ g.hom`. With the generated lemma, `simp` leaves `g.hom.hom.hom' (f.hom.hom.hom' a) = (TopCat.Hom.hom g.hom.hom) ((TopCat.Hom.hom f.hom.hom) a)`. The same goal in a FullSubcategory (control) is closed by `simp`. Adding `id_hom`, `comp_hom` and `hom_ext` (CopyE) makes `simp` and `ext` close all of these goals.","fix":"Replace `@[simps!]` by explicit `@[simp] id_hom`, `@[simp, reassoc] comp_hom` and `@[ext] hom_ext` lemmas at the `InducedCategory.Hom` level, as `ObjectProperty.FullSubcategory` does.","ev":"example {X Y Z : LightDiagram} (f : X ⟶ Y) (g : Y ⟶ Z) : (f ≫ g).hom = f.hom ≫ g.hom := by simp  -- error: `simp` made no progress (the `rfl` version compiles); example {C : Type*} [Category C] (P : ObjectProperty C) {X Y Z : P.FullSubcategory} (f : X ⟶ Y) (g : Y ⟶ Z) : P.ι.map (f ≫ g) = f.hom ≫ g.hom := by simp  -- control: compiles. Files: hunts/lightprofinite/batch3/Probe3.lean (P3b/P3d fail, P3c control ok), hunts/lightprofinite/batch3/Probe2.lean (P2a/P2b/P2c), hunts/lightprofinite/batch3/CopyA_noSimps.lean (file compiles without @[simps!]), hunts/lightprofinite/batch3/CopyE_inducedApi.lean (simp closes the goals once the lemmas are added).","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-371445","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"lightDiagramToProfinite","line":273,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-fullyfaithful-structure","claim":"There is no `Functor.FullyFaithful` structure for `lightDiagramToProfinite`, although its docstring calls it fully faithful. Its siblings each have one: `lightToProfiniteFullyFaithful` (L82), `FintypeCat.toLightProfiniteFullyFaithful` (L107) and `CompHausLike.fullyFaithfulCompHausLikeToTop`. The `Full`/`Faithful` instances (L275/L277) come instead from `show (inducedFunctor _).Full from inferInstance`. The structure is a one-liner from `fullyFaithfulInducedFunctor`. (A side quirk: the `@[simps!]`-generated `lightDiagramToProfinite_map` has binders `{X Y : InducedCategory Profinite LightDiagram.toProfinite}`, not `LightDiagram`.)","fix":"Add `def lightDiagramToProfiniteFullyFaithful : lightDiagramToProfinite.FullyFaithful := fullyFaithfulInducedFunctor _` and derive the Full/Faithful instances from it.","ev":"example : lightDiagramToProfinite.FullyFaithful := fullyFaithfulInducedFunctor _  -- compiles (hunts/lightprofinite/batch3/Probe1.lean P1g); git grep 'lightDiagramToProfiniteFullyFaithful\\|FullyFaithful' in the file: only lightToProfiniteFullyFaithful and FintypeCat.toLightProfiniteFullyFaithful.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-60172f","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightProfinite.instCountableClopensCarrierToTopAndTotallyDisconnectedSpaceSecondCountableTopology","line":281,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"general-instance-stated-for-light-profinite","claim":"`Countable (Clopens S)` is proved only for `S : LightProfinite`, by rewriting with `Clopens.countable_iff_secondCountable`, which needs `[CompactSpace X] [T2Space X] [TotallyDisconnectedSpace X]`. The direction used holds for every compact second-countable space, with no T2 or total-disconnectedness hypotheses. Mathlib has no such general instance: `Topology/ClopenBox.lean` has only the iff and `countable_prod`. A general `instance [CompactSpace X] [SecondCountableTopology X] : Countable (Clopens X)` (its proof is the ← half of the iff) compiles, and with it this instance can be deleted: CopyC2 compiles the whole file without it.","fix":"Add the general instance to `Mathlib/Topology/ClopenBox.lean` (and use it in the iff) and delete this one.","ev":"example {X : Type*} [TopologicalSpace X] [CompactSpace X] [SecondCountableTopology X] : Countable (Clopens X) := by\n  have : ∀ (s : Clopens X), ∃ (t : Finset (countableBasis X)), s.1 = (SetLike.coe t).sUnion :=\n    fun s ↦ eq_sUnion_finset_of_isTopologicalBasis_of_isCompact_open _\n      (isBasis_countableBasis X) s.1 s.2.1.isCompact s.2.2\n  let f : Clopens X → Finset (countableBasis X) := fun s ↦ (this s).choose\n  have hf : f.Injective := by\n    intro s t (h : Exists.choose _ = Exists.choose _)\n    ext1; change s.carrier = t.carrier\n    rw [(this s).choose_spec, (this t).choose_spec, h]\n  exact hf.countable\n-- compiles (hunts/lightprofinite/batch3/Probe2.lean P2f); whole file with L281 replaced: hunts/lightprofinite/batch3/CopyC2_generalInstancesWithBridge.lean (exit 0)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-55e0c6","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightProfinite.instCountableDiscreteQuotient","line":285,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"general-instance-stated-for-light-profinite","claim":"This holds for any compact space with countably many clopens: the proof is literally `(DiscreteQuotient.finsetClopens_inj X).countable`, which needs only `[CompactSpace X]`. But it is stated only for light profinite sets, and Mathlib has no `Countable (DiscreteQuotient X)` instance at all. With the general instances (CopyC2), this declaration reduces to a bridge `inferInstanceAs (Countable (DiscreteQuotient S))` and the file compiles. Without such a bridge the `lightToProfinite.obj S` form is not found (CopyC).","fix":"Add `instance [CompactSpace X] [Countable (Clopens X)] : Countable (DiscreteQuotient X)` next to `finsetClopens_inj` in `Mathlib/Topology/DiscreteQuotient.lean` and keep only the bridge for `lightToProfinite.obj S`.","ev":"example {X : Type*} [TopologicalSpace X] [CompactSpace X] [Countable (Clopens X)] :\n    Countable (DiscreteQuotient X) :=\n  (DiscreteQuotient.finsetClopens_inj X).countable\n-- compiles (hunts/lightprofinite/batch3/Probe2.lean); hunts/lightprofinite/batch3/CopyC2_generalInstancesWithBridge.lean exit 0; hunts/lightprofinite/batch3/CopyC_generalInstances.lean shows the bridge is needed.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-a74b7f","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightProfinite.instCountableDiscreteQuotient","line":285,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"instance-on-wrong-carrier","claim":"The instance is stated for `DiscreteQuotient (lightToProfinite.obj S)`, not `DiscreteQuotient S`. The two carriers are not reducibly equal, because `CompHausLike.toCompHausLike` is a `def`, so for `S : LightProfinite` the instance `Countable (DiscreteQuotient S)` fails to synthesize. Conversely, the neighbouring instance `Countable (Clopens S)` (L281) is not found for `Clopens (lightToProfinite.obj S)`. The two instances meet only through a defeq unfolding inside this proof term.","fix":"Provide the instance for `DiscreteQuotient S` (ideally from a general instance) and derive the `lightToProfinite.obj S` form from it with `inferInstanceAs`.","ev":"example (S : LightProfinite) : Countable (DiscreteQuotient (lightToProfinite.obj S)) := inferInstance  -- ok; example (S : LightProfinite) : Countable (DiscreteQuotient S) := inferInstance  -- error: failed to synthesize; example (S : LightProfinite) : Countable (Clopens (lightToProfinite.obj S)) := inferInstance  -- error. File: hunts/lightprofinite/batch3/Probe1.lean (P1c, P1d).","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-99c431","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightProfinite.toLightDiagram","line":290,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-wrong-output-type","claim":"The docstring says 'A profinite space which is light gives rise to a light profinite space', but the input is already a `LightProfinite` and the output is a `LightDiagram` (a presentation as a sequential limit of finite sets), not a light profinite space.","fix":"Reword to: 'A light profinite space gives rise to a `LightDiagram`, i.e. a presentation of it as a sequential limit of finite sets (its discrete quotients along a cofinal sequence).'","ev":"-- hunts/lightprofinite/batch4/probe1.lean (P2)\nexample (S : LightProfinite.{u}) : LightProfinite.{u} := S.toLightDiagram\n-- error: Type mismatch: S.toLightDiagram has type LightDiagram but is expected to have type LightProfinite","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-5cc367","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"instSecondCountableTopologyCarrierToTopTotallyDisconnectedSpacePtOppositeNatProfiniteCone","line":306,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"reprove-instead-of-transport","claim":"The 17-line proof (open scoped Classical, counting clopens through `LocallyConstant.equivClopens`, six `refine @...` explicit-instance steps) re-derives second countability of a sequential limit, which this file already proves for `LightProfinite.limitCone` (L144). Transporting along the cone-point iso to that limit cone gives a 5-line proof with no classical reasoning.","fix":"Replace the proof by transport along `S.isLimit.conePointUniqueUpToIso (isLimitOfPreserves lightToProfinite (LightProfinite.limitConeIsLimit F))` with `Homeomorph.secondCountableTopology`, and drop `open scoped Classical in`.","ev":"-- hunts/lightprofinite/batch4/copyFix.lean (whole file, compiles with no warnings); also probe2/probe3.lean\ninstance (S : LightDiagram.{u}) : SecondCountableTopology S.cone.pt :=\n  let F := S.diagram ⋙ FintypeCat.toLightProfinite\n  have : SecondCountableTopology (lightToProfinite.mapCone (LightProfinite.limitCone F)).pt :=\n    inferInstanceAs (SecondCountableTopology (LightProfinite.limitCone F).pt)\n  (homeoOfIso (S.isLimit.conePointUniqueUpToIso (isLimitOfPreserves lightToProfinite\n    (LightProfinite.limitConeIsLimit F)))).secondCountableTopology","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-bd5ec2","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightProfinite.equivDiagram","line":333,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"preimage-iso-of-refl","claim":"The counit is built from `lightDiagramToProfinite.preimageIso (Iso.refl _)`, i.e. `Functor.preimage` (`Classical.choose`), so its components are not definitionally identities. That forces a 7-line naturality proof, a `simpa using!` triangle proof, and two `set_option backward.*` compatibility options. Removing either option breaks the current proof. With `InducedCategory.isoMk (Iso.refl X.toProfinite)` the auto-params discharge naturality and the triangle, and neither option is needed.","fix":"Define `counitIso := NatIso.ofComponents (fun X ↦ InducedCategory.isoMk (Iso.refl X.toProfinite))`, delete the explicit naturality and `functor_unitIso_comp` proofs, and remove both `set_option backward.*` lines.","ev":"-- hunts/lightprofinite/batch4/copyFix.lean / copyK.lean (whole file compiles, no warnings, without either set_option):\nnoncomputable def LightProfinite.equivDiagram : LightProfinite.{u} ≌ LightDiagram.{u} where\n  functor := lightProfiniteToLightDiagram\n  inverse := lightDiagramToLightProfinite\n  unitIso := Iso.refl _\n  counitIso := NatIso.ofComponents (fun X ↦ InducedCategory.isoMk (Iso.refl X.toProfinite))\n-- copyB.lean/copyC.lean: dropping either backward option alone from the original gives 'unsolved goals' in the naturality proof.\n-- probe5.lean: example (S : LightDiagram.{u}) : (LightProfinite.equivDiagram.counitIso.hom.app S).hom = 𝟙 S.toProfinite := rfl  -- fails (Type mismatch)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-c9bf9f","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightDiagram'","line":364,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"hand-rolled-small-model","claim":"`LightDiagram'` is a hand-built small model whose only use (no consumers outside this file) is proving `EssentiallySmall.{u} LightDiagram.{u}`. It needs `LightDiagram'.toProfinite`, a category instance, `toLightFunctor`, its Faithful, Full, EssSurj and IsEquivalence instances, and `LightDiagram.equivSmall`. Mathlib's generic `essentiallySmall_iff` plus `small_of_surjective` from `ℕᵒᵖ ⥤ FintypeCat.Skeleton.{u}` proves the same instance in 8 lines.","fix":"Prove `EssentiallySmall.{u} LightDiagram.{u}` by `(essentiallySmall_iff _).2 ⟨small_of_surjective …, inferInstance⟩`, reusing the existing essential-surjectivity iso, and delete `LightDiagram'` and its attendant declarations (or keep them only if an explicit small model is wanted as API).","ev":"-- hunts/lightprofinite/batch4/probe4.lean (compiles)\nexample : EssentiallySmall.{u} LightDiagram.{u} := by\n  refine (essentiallySmall_iff _).2 ⟨small_of_surjective (α := ℕᵒᵖ ⥤ Skeleton.{u})\n    (f := fun d ↦ toSkeleton (⟨d ⋙ Skeleton.equivalence.functor, _, limit.isLimit _⟩ :\n      LightDiagram)) fun Y ↦ ?_, inferInstance⟩\n  obtain ⟨Y, rfl⟩ : ∃ Y' : LightDiagram, toSkeleton Y' = Y := ⟨_, toSkeleton_fromSkeleton_obj Y⟩\n  refine ⟨Y.diagram ⋙ Skeleton.equivalence.inverse, toSkeleton_eq_toSkeleton_iff.2\n    ⟨lightDiagramToProfinite.preimageIso ((Limits.lim.mapIso (Functor.isoWhiskerRight\n      (Functor.isoWhiskerLeft Y.diagram Skeleton.equivalence.counitIso) toProfinite)) ≪≫\n      (limit.isLimit _).conePointUniqueUpToIso Y.isLimit)⟩⟩\nexample : EssentiallySmall.{u} LightProfinite.{u} :=\n  (essentiallySmall_congr LightProfinite.equivDiagram).2 inferInstance\n-- git grep: LightDiagram' / LightDiagram.equivSmall occur only in LightProfinite/Basic.lean","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-bcc053","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"instEssentiallySmallLightDiagram","line":401,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"universe-specialised-smallness","claim":"`EssentiallySmall.{u} LightDiagram.{u}` holds for every smallness universe w, not just u: `Skeleton LightDiagram.{u}` is the image of `ℕᵒᵖ ⥤ FintypeCat.Skeleton.{u}` (which Mathlib's `Small.{w} (C ⥤ D)` instance makes w-small once `FintypeCat.Skeleton` has `Small.{w}`/`LocallySmall.{w}`), and the category is `LocallySmall.{w}` by `locallySmall_congr LightProfinite.equivDiagram`.","fix":"State it as `EssentiallySmall.{w} LightDiagram.{u}` via `(essentiallySmall_iff _).2 ⟨inferInstance, inferInstance⟩` with the `Small.{w} (Skeleton LightDiagram)` and `LocallySmall.{w} LightDiagram` instances.","ev":"hunts/lightprofinite/batch5/refactor_src.lean, instances `Small.{w} (Skeleton LightDiagram.{u})`, `LocallySmall.{w} LightDiagram.{u}`, `EssentiallySmall.{w} LightDiagram.{u}` (compiles)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-eeedb4","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"instEssentiallySmallLightProfinite","line":404,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"universe-specialised-smallness","claim":"`EssentiallySmall.{u} LightProfinite.{u}` fixes the smallness universe to u, but light profinite sets are essentially small in every universe w (in particular w = 0, the absolute smallness that motivates 'light'). The ingredients are also missing: `Small.{w} X` for a light profinite X (X embeds in `Clopens X → Prop`, `Clopens X` countable) and `LocallySmall.{w} LightProfinite.{u}`. With them, `EssentiallySmall.{w} LightProfinite.{u}` follows from `essentiallySmall_congr`/`locallySmall_congr` and Mathlib's `Small.{w} (C ⥤ D)` instance.","fix":"Add `Small.{w}` for light profinite spaces and `LocallySmall.{w} LightProfinite.{u}`, and state the instance as `EssentiallySmall.{w} LightProfinite.{u}` (downstream `equivSmallModel.{u} LightProfinite.{u}` still resolves).","ev":"hunts/lightprofinite/batch5/probe1.lean section B (compiles: `example : EssentiallySmall.{w} LightProfinite.{u}` and `example : EssentiallySmall.{0} LightProfinite.{u}`); hunts/lightprofinite/batch5/refactor_src.lean (full-file copy with `instance : EssentiallySmall.{w} LightProfinite.{u} := (essentiallySmall_congr LightProfinite.equivDiagram).2 inferInstance`, plus `example : EssentiallySmall.{u} LightProfinite.{u} := inferInstance` and `equivSmallModel.{u} LightProfinite.{u}` still elaborating; compiles)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-1e1ed8","file":"Mathlib/Topology/Category/Profinite/Basic.lean","decl":"FintypeCat.botTopology","line":137,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"duplicate-instance-boilerplate","claim":"`FintypeCat.botTopology` and `FintypeCat.discreteTopology` (Profinite/Basic.lean:137,143, used via `attribute [local instance]` in Profinite/LightProfinite) duplicate the scoped instances of `FintypeCatDiscrete` (Topology/Category/FinTopCat.lean:84-85, opened in Galois/ContAction and Galois/Equivalence): both give `⊥` and are equal by `rfl`; FinTopCat.lean's imports are already in Profinite/Basic's closure.","fix":"Name the FintypeCatDiscrete instances and register them with `attribute [local instance]` in Profinite/LightProfinite; deprecate the Profinite declarations.","ev":"dupscan/body/probe.lean: `FintypeCat.botTopology X = FintypeCatDiscrete.instTopologicalSpaceObjFinite X := rfl` compiles.","evr":"compiles","astraV":"agrees","astraS":"Astra item 2: agrees it is redundant, but small instance boilerplate (MINOR); reuse the scoped declarations individually so the scoped HasForget₂ instance is not also activated.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-90f7a0","file":"Mathlib/Topology/Category/Stonean/Basic.lean","decl":"Stonean.toCompHaus","line":81,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-preserves-epi-instance","claim":"`Stonean.toCompHaus` and `Stonean.toProfinite` preserve epimorphisms (epi ↔ surjective in all three categories, by `Stonean.epi_iff_surjective`, `CompHaus.epi_iff_surjective`, `Profinite.epi_iff_surjective`), but neither has a `PreservesEpimorphisms` instance anywhere in Mathlib, so `#synth` fails for both and the generic `Functor.projective_of_map_projective` cannot be used.","fix":"Register `instance : Stonean.toCompHaus.PreservesEpimorphisms` and the `toProfinite` one via the three `epi_iff_surjective` lemmas.","ev":"probe2.lean L6–7: `#synth Stonean.toCompHaus.PreservesEpimorphisms` and `#synth Stonean.toProfinite.PreservesEpimorphisms` → failed to synthesize.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-08edbf","file":"Mathlib/Topology/Category/Stonean/Basic.lean","decl":"Stonean.mkFinite","line":114,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-instance","claim":"There is no instance saying a discrete space is extremally disconnected: `example [TopologicalSpace X] [DiscreteTopology X] : ExtremallyDisconnected X := inferInstance` fails. `Stonean.mkFinite` proves it inline (`constructor; intro U _; apply isOpen_discrete`) instead of using such an instance, and `Stonean.of` cannot be used for finite discrete spaces.","fix":"Add `instance [DiscreteTopology X] : ExtremallyDisconnected X` in `Topology/ExtremallyDisconnected.lean`; then `mkFinite X := Stonean.of X`.","ev":"Copy.lean final `example`: failed to synthesize `ExtremallyDisconnected X` from `[DiscreteTopology X]`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-d13230","file":"Mathlib/Topology/Category/Stonean/Basic.lean","decl":"Stonean.instProjectiveCompHausCompHaus","line":157,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"copy-pasted-proof","claim":"The three projectivity instances (`instProjectiveCompHausCompHaus` L157, the `Profinite` one L170, the `Stonean` one L183) repeat the same 10-line tactic proof (`intro`, surjectivity from `epi_iff_surjective`, `CompactT2.ExtremallyDisconnected.projective`, `use ofHom _ ⟨f', h.left⟩`, `ext`, `congrm`), differing only in the `epi_iff_surjective` lemma used.","fix":"Factor a lemma `projective_of_lift (hlift : ∀ … surjective …)` used by all three, or derive two of them from the `CompHaus` one with `Functor.FullyFaithful` + epi reflection.","ev":"measured: L157–167, L170–180, L183–193 of src.lean are identical up to `CompHaus`/`Profinite`/`Stonean`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-1bc671","file":"Mathlib/Topology/Category/Stonean/Basic.lean","decl":"CompHaus.presentation","line":205,"sev":"MINOR","status":"confirmed","cat":"hygiene","pattern":"auto-generated-instance-name-referenced","claim":"`CompHaus.presentation` fills its `prop` field with `instExtremallyDisconnectedCarrierToTopTrueOfProjective X.projectivePresentation.p`, the auto-generated name of the anonymous instance at L55. Such names change whenever the instance's statement or the name generator changes, and `prop := inferInstance` works in its place.","fix":"Write `prop := inferInstance` (or name the L55 instance and refer to that name).","ev":"Copy.lean (src.lean with L205 replaced by `prop := inferInstance`): no error at that line.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-147c1f","file":"Mathlib/Topology/Category/Stonean/Basic.lean","decl":"Profinite.lift","line":286,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-claims-unproved-identity","claim":"The docstring of `Profinite.lift` says \"It is `CompHaus.lift e f` as a morphism in `Profinite`\", but the definition is an independent `Projective.factorThru e f` in `Profinite` (L292). Both are arbitrary choices of a lift, made in different hom types, and no lemma relates them, so the stated identification is unsupported.","fix":"Drop the identification from the docstring, or define `Profinite.lift` by transporting `CompHaus.lift` through `profiniteToCompHaus`.","ev":"Source L286–292: `def lift … := Projective.factorThru e f`, with no reference to `CompHaus.lift`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-bf1b41","file":"Mathlib/Topology/Category/UniformSpace.lean","decl":"CpltSepUniformSpace.hom_ofHom","line":95,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `UniformSpaceCat.hom_ofHom` (Topology.Category.UniformSpace), `CpltSepUniformSpace.hom_ofHom` (Topology.Category.UniformSpace) have exactly the same statement (Lean-checked), so `CpltSepUniformSpace.hom_ofHom` does not state what its name promises and the intended lemma is missing. Reviewer: This is a copy-paste error: `CpltSepUniformSpace.hom_ofHom` is stated about `UniformSpaceCat.ofHom`, because CpltSepUniformSpace has no ofHom of its own, so it is literally UniformSpaceCat.hom_ofHom. Delete the CpltSep copy.","fix":"Restate `CpltSepUniformSpace.hom_ofHom` as its name says (keep `UniformSpaceCat.hom_ofHom`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@CpltSepUniformSpace.hom_ofHom : type_of% @UniformSpaceCat.hom_ofHom)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 29, rating MAJOR): The declaration explicitly concerns `UniformSpaceCat`, despite its namespace and neighboring completed-space lemmas. However, `ConcreteCategory.hom_ofHom` already handles `CpltSepUniformSpace`, so deleting the copy is sufficient. A retained specialization should quantify over `X Y : CpltSepUniformSpace` and state `ConcreteCategory.hom (ConcreteCategory.ofHom (C := CpltSepUniformSpace) f) = f`. [Specialized source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Topology/Category/UniformSpace.lean#L181-L212), [general law](https://github.com/leanprover-community/mathlib","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-ba6a22","file":"Mathlib/Topology/Closure.lean","decl":"closure_inter_subset","line":254,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `closure_inter_subset_inter_closure` (Topology.Closure), `closure_inter_subset` (Topology.Closure) state exactly the same thing (Lean-checked). Reviewer: Eight lines apart in the same file, proved separately: one via monotone_closure.map_inf_le, the other via subset_inter/closure_mono. They differ only in whether s and t are explicit. Keep the older mathlib3 name, which has 6 uses; `closure_inter_subset` has none.","fix":"Deprecate `closure_inter_subset` in favour of `closure_inter_subset_inter_closure`.","ev":"dupscan/Check.lean: `example := (@closure_inter_subset : type_of% @closure_inter_subset_inter_closure)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 44, rating MINOR): The implicit-argument version offers slight convenience, but no separate automation role. Consolidating under the established name is reasonable, though the benefit is small.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-ac7fa2","file":"Mathlib/Topology/Compactification/OnePoint/Basic.lean","decl":"OnePoint.some_eq_iff","line":78,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `OnePoint.coe_eq_coe` (Topology.Compactification.OnePoint.Basic), `OnePoint.some_eq_iff` (Topology.Compactification.OnePoint.Basic) state exactly the same thing (Lean-checked). Reviewer: The coercion is `OnePoint.some`, so `some_eq_iff (x₁ x₂) : some x₁ = some x₂ ↔ x₁ = x₂` (@[simp]) restates `coe_eq_coe` (@[norm_cast], coe_injective.eq_iff). Keep coe_eq_coe, which is used in ProjectiveLine and Basic, and give it @[simp, norm_cast]. Deprecate some_eq_iff, which has no uses.","fix":"Deprecate `OnePoint.some_eq_iff` in favour of `OnePoint.coe_eq_coe`.","ev":"dupscan/Check.lean: `example := (@OnePoint.some_eq_iff : type_of% @OnePoint.coe_eq_coe)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 45, rating MAJOR): Both attributes can live on `coe_eq_coe`, matching OnePoint’s preferred coercion interface. The constructor’s `match_pattern` annotation does not require a theorem named `some_eq_iff`.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-8d1699","file":"Mathlib/Topology/Compactness/Lindelof.lean","decl":"LindelofSpace.elim_nhds_subcover","line":170,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `LindelofSpace.elim_nhds_subcover` (Topology.Compactness.Lindelof), `countable_cover_nhds` (Topology.Compactness.Lindelof) state exactly the same thing (Lean-checked). Reviewer: Both are in Lindelof.lean and differ only in whether U is explicit. They mirror CompactSpace.elim_nhds_subcover / finite_cover_nhds, which differ there only because one says `= ⊤` and the other `= univ`. Keep countable_cover_nhds (5 uses, sits next to countable_cover_nhds_interior) and deprecate LindelofSpace.elim_nhds_subcover (1 use).","fix":"Deprecate `LindelofSpace.elim_nhds_subcover` in favour of `countable_cover_nhds`.","ev":"dupscan/Check.lean: `example := (@countable_cover_nhds : type_of% @LindelofSpace.elim_nhds_subcover)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (dup3 item 46, rating MINOR): The class-namespaced eliminator and root convenience theorem mirror the [CompactSpace API](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Topology/Compactness/Compact.lean#L804), with explicit versus inferred `U`. Preserve those interfaces while sharing the proof.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-5bbfc8","file":"Mathlib/Topology/Compactness/SigmaCompact.lean","decl":"isSigmaCompact_univ","line":151,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `SigmaCompactSpace.isSigmaCompact_univ` (Topology.Compactness.SigmaCompact), `isSigmaCompact_univ` (Topology.Compactness.SigmaCompact) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: Root isSigmaCompact_univ is the intended root-namespace export of the class field SigmaCompactSpace.isSigmaCompact_univ (like isCompact_univ), but it is re-proved via isSigmaCompact_univ_iff.mpr instead of `h.1`/alias/export.","fix":"Declare `isSigmaCompact_univ` as an `alias` of `SigmaCompactSpace.isSigmaCompact_univ`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-7259dd","file":"Mathlib/Topology/ContinuousMap/LocallyConstant.lean","decl":"LocallyConstant.toContinuousMapMonoidHom","line":27,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`toContinuousMapMonoidHom` (and its `to_additive` twin `toContinuousMapAddMonoidHom`) assume `[Monoid Y]`, but a `→*` needs only `[MulOneClass Y]` (with `[ContinuousMul Y]` for `C(X, Y)`'s multiplication). The whole file compiles with `[MulOneClass Y]`.","fix":"Use `[MulOneClass Y]` (additive: `[AddZeroClass Y]`).","ev":"hunts/cm-locconst/mulone.lean: src with `def toContinuousMapMonoidHom [MulOneClass Y] [ContinuousMul Y]` compiles (exit 0, no warnings), including the downstream `__ := toContinuousMap*Hom` uses.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-397c57","file":"Mathlib/Topology/DiscreteSubset.lean","decl":"IsDiscrete.nhdsWithin","line":1,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `nhdsWithin_of_mem_discrete` (Topology.Separation.Basic), `IsDiscrete.nhdsWithin` (Topology.DiscreteSubset) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: `IsDiscrete.nhdsWithin` (DiscreteSubset, which imports Separation/Basic) is the intended dot-notation form of `nhdsWithin_of_mem_discrete`, but it is derived independently from `isDiscrete_iff_nhdsWithin.mp`. Make it `protected alias IsDiscrete.nhdsWithin := nhdsWithin_of_mem_discrete`, or deprecate the root name in favour of the dot form.","fix":"Declare `IsDiscrete.nhdsWithin` as an `alias` of `nhdsWithin_of_mem_discrete`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-21828c","file":"Mathlib/Topology/Hom/ContinuousEvalConst.lean","decl":"ContinuousOn.coeFun","line":59,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"copy-paste-misstated-lemma","claim":"Misstated by copy-paste: `ContinuousOn.coeFun` (Topology.Hom.ContinuousEvalConst), `ContinuousOn.eval_const` (Topology.Hom.ContinuousEvalConst) have exactly the same statement (Lean-checked), so `ContinuousOn.coeFun` does not state what its name promises and the intended lemma is missing. Reviewer: Copy-paste bug: `ContinuousOn.coeFun` takes `(x : α)` and concludes `ContinuousOn (f · x) s`, a verbatim copy of `ContinuousOn.eval_const`, instead of `ContinuousOn (fun z ↦ ⇑(f z)) s` like its `Continuous/At/WithinAt.coeFun` siblings. Keep `eval_const`; restate `coeFun` as `fun z hz ↦ (hf z hz).coeFun`. Astra rates it CRITICAL (a lemma weaker than or unrelated to its name).","fix":"Restate `ContinuousOn.coeFun` as its name says (keep `ContinuousOn.eval_const`), or deprecate it if the intended lemma is not wanted.","ev":"dupscan/Check.lean: `example := (@ContinuousOn.eval_const : type_of% @ContinuousOn.coeFun)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (mis item 23, rating CRITICAL): Continuity of every evaluation yields continuity into the product, but those are distinct API conclusions. The other `.coeFun` lemmas make the intended form explicit. Correct: `(hf : ContinuousOn f s) : ContinuousOn (fun z ↦ ⇑(f z)) s`, with proof `fun z hz ↦ (hf z hz).coeFun`. Remove the extra evaluation argument. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Topology/Hom/ContinuousEvalConst.lean#L59-L98)","pr":null,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: a lemma whose name does not match its statement (here a copy-pasted neighbour) is a MINOR error; CRITICAL is reserved for wrong values/definitions like ModularForm.L.","at":"2026-10-07","commit":""},{"id":"RT-20261007-ca5b1d","file":"Mathlib/Topology/Homeomorph/Lemmas.lean","decl":"Homeomorph.ofDiscrete","line":563,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"convenience-interface-defined-twice","claim":"`Homeomorph.ofDiscrete` (Homeomorph/Lemmas.lean:563) rebuilds `Equiv.toHomeomorphOfDiscrete` (Homeomorph/Defs.lean:488) instead of forwarding to it (equal by `rfl`); Astra: the two entry points are defensible API, but the body should be shared.","fix":"Define `Homeomorph.ofDiscrete e := e.toHomeomorphOfDiscrete`.","ev":"dupscan/defs/probe2.lean: `e.toHomeomorphOfDiscrete = Homeomorph.ofDiscrete e := rfl` compiles (import Mathlib), exit 0. Found by dupscan/DefEqScan.lean (same type, defeq bodies).","evr":"compiles","astraV":"disagrees","astraS":"**ITEM 1: VERDICT: disagrees** There is a defensible API distinction: `e.toHomeomorphOfDiscrete` provides source-object dot notation, while `Homeomorph.ofDiscrete e` also supports `.ofDiscrete e` when the expected type is a homeomorphism. This justifies two entry points, though not independently constructing their bodies. Both are ordinary definitions without distinguishing `simps` attributes. Keep **`Equiv.toHomeomorphOfDiscrete` as the implementation**, and make `Homeomorph.ofDiscrete` a forwarding definition. I found no documented statement that this alias arrangement was intentional; this is an API-design defense of retaining the names. [","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-8dec47","file":"Mathlib/Topology/Instances/NNReal/Lemmas.lean","decl":"tendsto_real_toNNReal_atTop","line":105,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `tendsto_real_toNNReal_atTop` (Topology.Instances.NNReal.Lemmas), `Real.tendsto_toNNReal_atTop` (Topology.Instances.NNReal.Lemmas) state exactly the same thing (Lean-checked). Reviewer: Same file, 15 lines apart, both `Tendsto Real.toNNReal atTop atTop`, proved differently. Keep `Real.tendsto_toNNReal_atTop` (fits the `Real.map_/comap_/tendsto_toNNReal_atTop_iff` names around it), deprecate root `tendsto_real_toNNReal_atTop` (one use, line 110).","fix":"Deprecate `tendsto_real_toNNReal_atTop` in favour of `Real.tendsto_toNNReal_atTop`.","ev":"dupscan/Check.lean: `example := (@Real.tendsto_toNNReal_atTop : type_of% @tendsto_real_toNNReal_atTop)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 47, rating MAJOR): Keep the namespaced spelling, but move it earlier and use the `map_toNNReal_atTop.le` proof. Simply redirecting the earlier use to the later theorem would introduce a forward dependency.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-6d1290","file":"Mathlib/Topology/LocallyFinsupp/Pushforward.lean","decl":"(module docstring)","line":12,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-docstring","claim":"The module docstring says the pushforward is 'between prespectral spaces' in one place and 'between spectral spaces' in another; the actual assumptions are an arbitrary source X and a prespectral target Y (`#check @Function.locallyFinsupp.map` has no instance on X). The 'Notes' say the cycle weight will be the residue-field degree, but `AlgebraicCycle.mapCoeff` actually uses `if wx x = wy (f.base x) then f.residueDegree x else 0` (the dimension cutoff of Stacks 02R4).","fix":"Say 'arbitrary source, prespectral target'; mention the dimension cutoff in the weight.","ev":"#check @Function.locallyFinsupp.map\n-- {X Y R} [TopologicalSpace X] [TopologicalSpace Y] … [Semiring R] [PrespectralSpace Y] (f : X → Y) (w : X → R), IsSpectralMap f → …","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a4c90c","file":"Mathlib/Topology/LocallyFinsupp/Pushforward.lean","decl":"Function.locallyFinsupp.map","line":49,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"The pushforward has none of its basic laws: `simp` cannot show `map f w hf 0 = 0` or `map f w hf (c + d) = map f w hf c + map f w hf d` (it is an additive map but not packaged as `AddMonoidHom`), and there is no composition law `map g v hg (map f w hf c) = map (g ∘ f) (fun x ↦ w x * v (f x)) (hg.comp hf) c`, no evaluation on `single`, and no exported fibre-finiteness lemma `(f ⁻¹' {y} ∩ c.support).Finite`, which is what makes the `finsum` meaningful. For cycles (the stated purpose) additivity and functoriality are essential.","fix":"Add `map_zero`, `map_add` (or `mapAddMonoidHom`), `map_comp`, `map_single` and `finite_fiber_inter_support`.","ev":"example (c d : locallyFinsupp X R) :\n    locallyFinsupp.map f w hf (c + d) = locallyFinsupp.map f w hf c + locallyFinsupp.map f w hf d := by\n  simp   -- error: `simp` made no progress\nexample : locallyFinsupp.map f w hf 0 = 0 := by simp   -- error: `simp` made no progress","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6c5989","file":"Mathlib/Topology/LocallyFinsupp/Pushforward.lean","decl":"Function.locallyFinsupp.map","line":49,"sev":"MINOR","status":"suspected","cat":"generality","pattern":"too-strong-typeclass","claim":"(Astra A1, not settled) `map`, `map_apply` and `support_map_subset_of_forall_mem` use only additivity and `x * 0 = 0`, so `[NonUnitalNonAssocSemiring R]` should suffice (and a module-valued version with ℕ weights would suit degree-weighted cycles); `map_id` needs weight 1 only on `c.support` (or `∀ x, c x * w x = c x`). A naive weakening of the section variable breaks two `grind` calls, so the proofs need adjusting.","fix":"Weaken the coefficient class and adjust the two `grind` steps; weaken `map_id`'s hypothesis.","ev":"-- hunts/lfs-pushforward/ProbeCopy.lean with [NonUnitalNonAssocSemiring R]: two `grind` failures (proof needs rework)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-1b6e9b","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.externalCoveringNumber","line":68,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"parallel-definition-missing-common-generalisation","claim":"`externalCoveringNumber ε A` is the minimal cardinality of a `SetRel.IsCover`-cover for the entourage {edist ≤ ε}; Mathlib already defines exactly this infimum (for an arbitrary entourage) as `Dynamics.coverMincard T F U n` at time `n = 1` (`dynEntourage_one`), so `externalCoveringNumber ε A = Dynamics.coverMincard T A {(x, y) | edist x y ≤ ε} 1` for every map `T`. The two files build the same object independently and duplicate its basic API (`coverMincard_empty`/`externalCoveringNumber_empty`, `coverMincard_eq_zero_iff`/`externalCoveringNumber_eq_zero`, `one_le_coverMincard_iff`/`externalCoveringNumber_pos_iff`), although `Mathlib/Basic/Rel/Cover.lean` explicitly layers both metric and dynamical covers over `SetRel.IsCover`. Graded MINOR, not MAJOR: the existing object is only reachable through a dummy map `T` and time `1`, so it is not a direct replacement; the defect is the missing shared `SetRel`-level covering number.","fix":"Introduce `SetRel.coveringNumber U s := ⨅ N, ⨅ (_ : IsCover U s N), N.encard` next to `SetRel.IsCover`, and define both `Metric.externalCoveringNumber` and `Dynamics.coverMincard` (as `SetRel.coveringNumber (dynEntourage T U n) F`) through it, moving the shared empty/zero/positivity API there.","ev":"-- hunts/covering-numbers/batch0/Probe1.lean section (a)\n/-! ### (a) `externalCoveringNumber` = time-1 `Dynamics.coverMincard` of the distance entourage -/\n\nexample {X : Type*} [PseudoEMetricSpace X] (T : X → X) (ε : ℝ≥0) (A : Set X) :\n    externalCoveringNumber ε A = Dynamics.coverMincard T A {(x, y) | edist x y ≤ ε} 1 := by\n  apply le_antisymm\n  · refine le_iInf₂ fun s hs ↦ ?_\n    have : IsCover ε A (s : Set X) := by\n      unfold Dynamics.IsDynCoverOf at hs\n      rw [Dynamics.dynEntourage_one] at hs\n      exact hs\n    exact this.externalCoveringNumber_le_encard.trans (by simp)\n  · refine le_iInf₂ fun C hC ↦ ?_\n    rcases C.finite_or_infinite with hfin | hinf\n    · lift C to Finset X using hfin\n      have hC' : Dynamics.IsDynCoverOf T A {(x, y) | edist x y ≤ ε} 1 (C : Set X) := by\n        unfold Dynamics.IsDynCoverOf\n        rw [Dynamics.dynEntourage_one]\n        exact hC\n      exact hC'.coverMincard_le_card.trans (by simp)\n    · simp [hinf.encard_eq]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-d6fc29","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.coveringNumber","line":74,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-finiteness-characterisation","claim":"There is no finiteness API for the covering numbers: nothing characterises `coveringNumber ε A < ⊤` / `externalCoveringNumber ε A < ⊤` (existence of a finite cover), and nothing links them to `TotallyBounded`, although `Cover.lean` has `exists_finite_isCover_of_totallyBounded`. The only `coveringNumber_lt_top` in Mathlib is `HasCoveringExponent.coveringNumber_lt_top` (CoveringExponent.lean:48). Both directions of `TotallyBounded A ↔ ∀ ε ≠ 0, coveringNumber ε A < ⊤` (and the external variant) are a few lines.","fix":"Add `TotallyBounded.coveringNumber_lt_top (hε : ε ≠ 0)` and `totallyBounded_iff_externalCoveringNumber_lt_top`/`totallyBounded_iff_coveringNumber_lt_top` (plus `coveringNumber_lt_top_iff : coveringNumber ε A < ⊤ ↔ ∃ C ⊆ A, C.Finite ∧ IsCover ε A C`).","ev":"-- hunts/covering-numbers/batch0/Probe1.lean section (d); absence measured by git grep 'coveringNumber_lt_top\\|coveringNumber_ne_top\\|TotallyBounded' over Mathlib (only CoveringExponent.lean:48,60)\n/-! ### (d) missing finiteness API: link with `TotallyBounded` -/\n\nexample {X : Type*} [PseudoEMetricSpace X] {ε : ℝ≥0} {A : Set X} (hε : ε ≠ 0)\n    (hA : TotallyBounded A) : coveringNumber ε A < ⊤ := by\n  obtain ⟨N, hNA, hN, hcov⟩ := exists_finite_isCover_of_totallyBounded hε hA\n  exact (hcov.coveringNumber_le_encard hNA).trans_lt hN.encard_lt_top\n\nexample {X : Type*} [PseudoEMetricSpace X] {A : Set X}\n    (h : ∀ ε : ℝ≥0, ε ≠ 0 → externalCoveringNumber ε A < ⊤) : TotallyBounded A := by\n  rw [EMetric.totallyBounded_iff]\n  intro ε hε\n  obtain ⟨δ, h0, hδε⟩ := ENNReal.lt_iff_exists_nnreal_btwn.1 hε\n  have hδ0 : δ ≠ 0 := by rintro rfl; simp at h0\n  obtain ⟨C, hC, hfin⟩ : ∃ C, IsCover δ A C ∧ C.encard < ⊤ := by\n    simpa [externalCoveringNumber, iInf_lt_iff] using h δ hδ0\n  refine ⟨C, encard_lt_top_iff.1 hfin, fun x hx ↦ ?_⟩\n  obtain ⟨y, hy, hxy⟩ := hC hx\n  change edist x y ≤ (δ : ℝ≥0∞) at hxy\n  exact mem_biUnion hy (show edist x y < ε from hxy.trans_lt hδε)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-ba3a91","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.packingNumber","line":80,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-monotonicity-api","claim":"`packingNumber` lacks its basic order API: antitone in `ε` and monotone in `A`. The file provides the analogues for the covering numbers (`externalCoveringNumber_anti`, `coveringNumber_anti`, `externalCoveringNumber_mono_set`), but `git grep 'packingNumber_anti\\|packingNumber_mono\\|Antitone.*packingNumber\\|Monotone.*packingNumber' origin/master -- Mathlib` returns nothing; both facts are one-liners from `IsSeparated.anti`/`IsSeparated.encard_le_packingNumber`.","fix":"Add `packingNumber_anti (h : ε ≤ δ) : packingNumber δ A ≤ packingNumber ε A` and `packingNumber_mono_set (h : A ⊆ B) : packingNumber ε A ≤ packingNumber ε B` beside the covering-number versions.","ev":"-- hunts/covering-numbers/batch0/Probe1.lean section (c); absence measured by git grep (no hits)\n/-! ### (c) missing API on `packingNumber`: antitone in `ε`, monotone in `A` (one-liners) -/\n\nexample {X : Type*} [PseudoEMetricSpace X] {ε δ : ℝ≥0} {A : Set X} (h : ε ≤ δ) :\n    packingNumber δ A ≤ packingNumber ε A :=\n  iSup₂_le fun _ hC ↦ iSup_le fun hs ↦\n    (hs.anti (by exact_mod_cast h)).encard_le_packingNumber hC\n\nexample {X : Type*} [PseudoEMetricSpace X] {ε : ℝ≥0} {A B : Set X} (h : A ⊆ B) :\n    packingNumber ε A ≤ packingNumber ε B :=\n  iSup₂_le fun _ hC ↦ iSup_le fun hs ↦ hs.encard_le_packingNumber (hC.trans h)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-89ce91","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.packingNumber","line":85,"sev":"MINOR","status":"suspected","cat":"docs","pattern":"docstring-says-max-for-sup","claim":"The module docstring and the `packingNumber` docstring call it the 'maximal cardinality' of an ε-separated subset, but it is a supremum (`⨆ … encard`) that need not be attained: in the metric space ∐ₙ Fin (n+1) (distance 2 within a block, 1 across blocks), `packingNumber 1 univ = ⊤` while every separated set lies in one finite block (Astra A1 item 2; not formalised). `exists_set_encard_eq_packingNumber` correctly assumes `≠ ⊤`.","fix":"Say 'supremum of the cardinalities (attained when finite)'.","ev":"Suspected: Astra A1 item 2 counterexample (not formalised).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-a2053d","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.externalCoveringNumber_anti","line":149,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-gcongr-attribute","claim":"`externalCoveringNumber_anti (h : ε ≤ δ)` is not tagged `@[gcongr]` (and has no bundled `Antitone` form), so `gcongr` cannot reduce `externalCoveringNumber δ A ≤ externalCoveringNumber ε A` to `ε ≤ δ`. The set-monotonicity sibling `externalCoveringNumber_mono_set` is untagged as well.","fix":"Tag `externalCoveringNumber_anti` (and `externalCoveringNumber_mono_set`) with `@[gcongr]`.","ev":"-- batch1/Probe1.lean (compiles: gcongr fails on the bare goal)\nexample (h : ε ≤ δ) : externalCoveringNumber δ A ≤ externalCoveringNumber ε A := by\n  fail_if_success gcongr\n  exact externalCoveringNumber_anti h\n-- batch1/Probe2.lean (compiles): with the tag, gcongr closes it\nattribute [gcongr] coveringNumber_anti externalCoveringNumber_anti externalCoveringNumber_mono_set\nexample (h : ε ≤ δ) : externalCoveringNumber δ A ≤ externalCoveringNumber ε A := by gcongr\n-- batch1/CoveringNumbersGcongr.lean: copy of src.lean with `@[gcongr]` on the lemma compiles cleanly","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-88ab2b","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.coveringNumber_anti","line":155,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-gcongr-attribute","claim":"`coveringNumber_anti (h : ε ≤ δ) : coveringNumber δ A ≤ coveringNumber ε A` is not tagged `@[gcongr]` (and there is no bundled `Antitone (coveringNumber · A)`), so `gcongr` cannot reduce a goal `coveringNumber δ A ≤ coveringNumber ε A` to `ε ≤ δ`. Compare `Set.encard_le_encard`, which is `@[gcongr]` and has the bundled `Set.encard_mono`.","fix":"Tag `coveringNumber_anti` with `@[gcongr]` (optionally add a bundled `Antitone fun ε ↦ coveringNumber ε A`).","ev":"-- batch1/Probe1.lean (compiles: gcongr fails on the bare goal)\nexample (h : ε ≤ δ) : coveringNumber δ A ≤ coveringNumber ε A := by\n  fail_if_success gcongr\n  exact coveringNumber_anti h\n-- batch1/Probe2.lean (compiles): the tag is accepted and gcongr then closes the goal\nattribute [gcongr] coveringNumber_anti externalCoveringNumber_anti externalCoveringNumber_mono_set\nexample (h : ε ≤ δ) : coveringNumber δ A ≤ coveringNumber ε A := by gcongr\n-- batch1/CoveringNumbersGcongr.lean: copy of src.lean with `@[gcongr]` on the lemmas compiles cleanly","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-a0ed17","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.externalCoveringNumber_mono_set","line":160,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-gcongr-tag","claim":"The set-monotonicity lemma `externalCoveringNumber_mono_set` (A ⊆ B → externalCoveringNumber ε A ≤ externalCoveringNumber ε B) is not tagged `@[gcongr]`, unlike its Mathlib analogues `Set.encard_le_encard` (Data/Set/Card.lean:188) and `Metric.ediam_mono` (Topology/EMetricSpace/Diam.lean:88). As a result `gcongr` cannot reduce `externalCoveringNumber ε A + 1 ≤ externalCoveringNumber ε B + 1` to `A ⊆ B`: it leaves the goal `externalCoveringNumber ε A ≤ externalCoveringNumber ε B` open.","fix":"Tag `externalCoveringNumber_mono_set` with `@[gcongr]` (and likewise the radius-antitone `externalCoveringNumber_anti`/`coveringNumber_anti`).","ev":"hunts/covering-numbers/batch2/probe1.lean section P5: `example (h : A ⊆ B) : externalCoveringNumber ε A + 1 ≤ externalCoveringNumber ε B + 1 := by gcongr; guard_target = externalCoveringNumber ε A ≤ externalCoveringNumber ε B; exact externalCoveringNumber_mono_set h` compiles (gcongr leaves the goal open), and with `attribute [local gcongr] externalCoveringNumber_mono_set in` the same goal closes by `gcongr` alone.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-63a189","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.externalCoveringNumber_le_one_of_ediam_le","line":203,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"hypothesis-stronger-than-needed","claim":"`externalCoveringNumber_le_one_of_ediam_le` and `externalCoveringNumber_eq_one_of_ediam_le` (L195) assume `ediam A ≤ ε`, but an external cover only needs `A ⊆ closedEBall x ε` for some `x : X` (not necessarily in `A`). Both are just the internal lemmas composed with `externalCoveringNumber_le_coveringNumber`, so they never use the freedom that distinguishes external covers. For `A = {-1, 1} ⊆ ℝ` and `ε = 1`: `ediam A = 2 > 1`, so neither lemma applies, yet `externalCoveringNumber 1 A = 1` (centre `0 ∉ A`), while `coveringNumber 1 A = 2`.","fix":"Add `externalCoveringNumber_le_one_of_subset_closedEBall (hA : A ⊆ closedEBall x ε)` (one line from `IsCover.externalCoveringNumber_le_encard`), plus an `= 1` version for nonempty `A`, and derive the `ediam` forms from them.","ev":"hunts/covering-numbers/batch2/probe1.lean section P3: `lemma externalCoveringNumber_le_one_of_subset_closedEBall (hA : A ⊆ closedEBall x ε) : externalCoveringNumber ε A ≤ 1 := ((isCover_iff_subset_iUnion_closedEBall (N := {x})).2 (by simpa using hA)).externalCoveringNumber_le_encard |>.trans (by simp)`; `example : ¬ ediam ({-1, 1} : Set ℝ) ≤ (1 : ℝ≥0)`; `example : externalCoveringNumber 1 ({-1, 1} : Set ℝ) = 1`; `example : coveringNumber 1 ({-1, 1} : Set ℝ) = 2`. All compile.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-dc7295","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.coveringNumber_le_one_of_ediam_le","line":210,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"hypothesis-stronger-than-needed","claim":"`coveringNumber_le_one_of_ediam_le` and `coveringNumber_eq_one_of_ediam_le` (L185) assume `ediam A ≤ ε`, a diameter bound, where the proof only needs a radius bound: some `a ∈ A` with `A ⊆ closedEBall a ε`. For `A = Icc (-1) 1 ⊆ ℝ` and `ε = 1`: `ediam A = 2 > 1`, so neither lemma applies, yet `coveringNumber 1 A = 1` (centre `0 ∈ A`).","fix":"Add `coveringNumber_le_one_of_subset_closedEBall (hx : x ∈ A) (hA : A ⊆ closedEBall x ε)`, plus the matching `= 1` version, and derive the `ediam` forms from them in one line via `edist_le_ediam_of_mem`.","ev":"hunts/covering-numbers/batch2/probe1.lean section P3: `lemma coveringNumber_le_one_of_subset_closedEBall (hx : x ∈ A) (hA : A ⊆ closedEBall x ε) : coveringNumber ε A ≤ 1 := (((isCover_iff_subset_iUnion_closedEBall (N := {x})).2 (by simpa using hA)).coveringNumber_le_encard (by simpa using hx)).trans (by simp)`; the file's `coveringNumber_le_one_of_ediam_le` is re-derived from it; `example : ¬ ediam (Icc (-1 : ℝ) 1) ≤ (1 : ℝ≥0)`; `example : coveringNumber 1 (Icc (-1 : ℝ) 1) = 1`. All compile.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-28242b","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.packingNumber_singleton","line":225,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-sibling-api","claim":"The packing number has no analogue of coveringNumber_eq_one_of_ediam_le / externalCoveringNumber_eq_one_of_ediam_le / *_le_one_of_ediam_le (L185-214), although the same bound holds: if ediam A ≤ ε then no two distinct points of A are ε-separated, so packingNumber ε A ≤ 1, with equality when A is nonempty. As a result, packingNumber_singleton gets a three-line proof of its own, while its siblings coveringNumber_singleton and externalCoveringNumber_singleton (L217, L221) are one-line corollaries of the ediam lemmas.","fix":"Add packingNumber_le_one_of_ediam_le and packingNumber_eq_one_of_ediam_le (6 lines), and prove packingNumber_singleton as packingNumber_eq_one_of_ediam_le (by simp) (by simp).","ev":"hunts/covering-numbers/batch3/Probe1.lean section P4:\nlemma packingNumber_le_one_of_ediam_le (hA : ediam A ≤ ε) : packingNumber ε A ≤ 1 := by\n  simp only [packingNumber, iSup_le_iff]\n  intro C hCA hC\n  rw [Set.encard_le_one_iff]\n  intro a b ha hb\n  by_contra hab\n  exact (hC ha hb hab).not_ge ((edist_le_ediam_of_mem (hCA ha) (hCA hb)).trans hA)\n\nlemma packingNumber_eq_one_of_ediam_le (hne : A.Nonempty) (hA : ediam A ≤ ε) :\n    packingNumber ε A = 1 :=\n  (packingNumber_le_one_of_ediam_le hA).antisymm (by simpa [Order.one_le_iff_pos])\n\nexample (ε : ℝ≥0) (x : X) : packingNumber ε {x} = 1 :=\n  packingNumber_eq_one_of_ediam_le (by simp) (by simp)\n-- grep: `git grep -n 'packingNumber_.*ediam' origin/master -- Mathlib` finds nothing","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-76bb18","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.exists_set_encard_eq_coveringNumber","line":231,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"unconditional-attainment-gated-by-finiteness","claim":"The hypothesis coveringNumber ε A ≠ ⊤ is only used for the C.Finite conjunct, and that conjunct already follows from the equation C.encard = coveringNumber ε A. Attaining the infimum needs no hypothesis at all, since ℕ∞ is well-ordered and A covers itself: ∃ C ⊆ A, IsCover ε A C ∧ C.encard = coveringNumber ε A holds for every A and ε. Mathlib has no such unconditional statement, only this gated one.","fix":"Add the unconditional exists_isCover_encard_eq_coveringNumber (ε A) (7 lines via ENat.exists_eq_iInf) and derive this lemma from it in two lines.","ev":"hunts/covering-numbers/batch3/Probe1.lean sections P1/P1':\nlemma exists_isCover_encard_eq_coveringNumber (ε : ℝ≥0) (A : Set X) :\n    ∃ C ⊆ A, IsCover ε A C ∧ C.encard = coveringNumber ε A := by\n  have : Nonempty {s : Set X // s ⊆ A ∧ IsCover ε A s} := ⟨⟨A, subset_rfl, .rfl⟩⟩\n  obtain ⟨C, hC⟩ :=\n    ENat.exists_eq_iInf (fun C : {s : Set X // s ⊆ A ∧ IsCover ε A s} ↦ (C : Set X).encard)\n  refine ⟨C, C.2.1, C.2.2, ?_⟩\n  rw [hC, coveringNumber]\n  simp_rw [iInf_subtype, iInf_and]\n\nexample (h : coveringNumber ε A ≠ ⊤) :\n    ∃ C, C ⊆ A ∧ C.Finite ∧ IsCover ε A C ∧ C.encard = coveringNumber ε A :=\n  let ⟨C, hCA, hC, hCe⟩ := exists_isCover_encard_eq_coveringNumber ε A\n  ⟨C, hCA, Set.encard_ne_top_iff.mp (hCe ▸ h), hC, hCe⟩","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-107de6","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.exists_set_encard_eq_coveringNumber","line":231,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-hypothesis-discharger","claim":"Every lemma about minimalCover that has a hypothesis assumes coveringNumber ε A ≠ ⊤. Yet Mathlib has no lemma that derives this from a finite internal cover, from TotallyBounded A or from IsCompact A. The only lemma that concludes coveringNumber ε A ≠ ⊤ is HasCoveringExponent.coveringNumber_ne_top (CoveringExponent.lean:60). The characterisation coveringNumber ε A ≠ ⊤ ↔ ∃ C ⊆ A, C.Finite ∧ IsCover ε A C (this lemma plus its converse) is also missing.","fix":"Add coveringNumber_ne_top_iff (5 lines, from this lemma and IsCover.coveringNumber_le_encard) and TotallyBounded.coveringNumber_ne_top (from exists_finite_isCover_of_totallyBounded).","ev":"hunts/covering-numbers/batch3/Probe2.lean section P8:\nlemma coveringNumber_ne_top_iff :\n    coveringNumber ε A ≠ ⊤ ↔ ∃ C ⊆ A, C.Finite ∧ IsCover ε A C := by\n  refine ⟨fun h ↦ ?_, fun ⟨C, hCA, hC, hcov⟩ ↦ ?_⟩\n  · obtain ⟨C, hCA, hC, hcov, -⟩ := exists_set_encard_eq_coveringNumber h\n    exact ⟨C, hCA, hC, hcov⟩\n  · exact ((hcov.coveringNumber_le_encard hCA).trans_lt hC.encard_lt_top).ne\n\nlemma _root_.TotallyBounded.coveringNumber_ne_top (hA : TotallyBounded A) (hε : ε ≠ 0) :\n    coveringNumber ε A ≠ ⊤ :=\n  coveringNumber_ne_top_iff.2 (exists_finite_isCover_of_totallyBounded hε hA)\n-- grep `coveringNumber_(ne_top|lt_top)|totallyBounded.*coveringNumber` over origin/master Mathlib: only HasCoveringExponent.coveringNumber_{lt,ne}_top","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-8794b0","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.minimalCover","line":249,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"avoidable-junk-value","claim":"The junk value ∅ is documented but can be avoided. An internal ε-cover of minimum cardinality exists for every A and ε (see the generality finding on exists_set_encard_eq_coveringNumber). Today, whenever A is nonempty and coveringNumber ε A = ⊤, minimalCover is not a cover of A at all. For example, minimalCover 0 (univ : Set ℕ) = ∅, which does not satisfy IsCover. Because of this, isCover_minimalCover and encard_minimalCover must assume coveringNumber ε A ≠ ⊤. If minimalCover were chosen from the unconditional existence instead, it would always be a cover of cardinality coveringNumber ε A, and only finite_minimalCover would need the hypothesis. This is a trade-off: finite_minimalCover would lose its unconditional form.","fix":"Define minimalCover ε A := (exists_isCover_encard_eq_coveringNumber ε A).choose, which makes isCover_minimalCover and encard_minimalCover hypothesis-free and moves the hypothesis to finite_minimalCover.","ev":"hunts/covering-numbers/batch3/Probe1.lean sections P2/P3:\nexample (hA : A.Nonempty) (h : coveringNumber ε A = ⊤) : ¬ IsCover ε A (minimalCover ε A) := by\n  simp [minimalCover, h, hA.ne_empty]\nexample : coveringNumber 0 (univ : Set ℕ) = ⊤ := by simp\nexample : minimalCover 0 (univ : Set ℕ) = ∅ := by simp [minimalCover]\nexample : ¬ IsCover 0 (univ : Set ℕ) (minimalCover 0 (univ : Set ℕ)) := by simp [minimalCover]\n\nnoncomputable def minimalCover' (ε : ℝ≥0) (A : Set X) : Set X :=\n  (exists_isCover_encard_eq_coveringNumber ε A).choose\nlemma isCover_minimalCover' : IsCover ε A (minimalCover' ε A) :=\n  (exists_isCover_encard_eq_coveringNumber ε A).choose_spec.2.1\nlemma encard_minimalCover' : (minimalCover' ε A).encard = coveringNumber ε A :=\n  (exists_isCover_encard_eq_coveringNumber ε A).choose_spec.2.2\nlemma finite_minimalCover' (h : coveringNumber ε A ≠ ⊤) : (minimalCover' ε A).Finite :=\n  Set.encard_ne_top_iff.mp ((encard_minimalCover' (ε := ε) (A := A)) ▸ h)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-b90a41","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.maximalSeparatedSet","line":288,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-bridge-to-existing-api","claim":"No lemma says that maximalSeparatedSet ε A is Maximal (fun N ↦ N ⊆ A ∧ IsSeparated ε N) when packingNumber ε A ≠ ⊤. That is the predicate consumed by Cover.lean's IsCover.of_maximal_isSeparated (Vershynin 4.2.6, Cover.lean:100). With that 5-line lemma, isCover_maximalSeparatedSet (L306, a 14-line proof that redoes 4.2.6 by hand) becomes the one-liner IsCover.of_maximal_isSeparated (maximal_maximalSeparatedSet h).","fix":"Add maximal_maximalSeparatedSet (h : packingNumber ε A ≠ ⊤) : Maximal (fun N ↦ N ⊆ A ∧ IsSeparated ε N) (maximalSeparatedSet ε A) and derive isCover_maximalSeparatedSet from IsCover.of_maximal_isSeparated.","ev":"hunts/covering-numbers/batch3/Probe1.lean section P5:\nlemma maximal_maximalSeparatedSet (h : packingNumber ε A ≠ ⊤) :\n    Maximal (fun N ↦ N ⊆ A ∧ IsSeparated ε N) (maximalSeparatedSet ε A) := by\n  refine ⟨⟨maximalSeparatedSet_subset, isSeparated_maximalSeparatedSet⟩, fun N hN hle ↦ ?_⟩\n  have hfin : (maximalSeparatedSet ε A).Finite :=\n    Set.encard_ne_top_iff.mp (by rwa [encard_maximalSeparatedSet h])\n  exact (hfin.eq_of_subset_of_encard_le hle (encard_le_of_isSeparated hN.1 hN.2 h)).symm.le\n\nexample (h : packingNumber ε A ≠ ⊤) : IsCover ε A (maximalSeparatedSet ε A) :=\n  IsCover.of_maximal_isSeparated (maximal_maximalSeparatedSet h)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-bd03d6","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.encard_le_of_isSeparated","line":299,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"name-omits-key-constant","claim":"The name `Metric.encard_le_of_isSeparated` reads as a general fact about separated sets, but the conclusion is `C.encard ≤ (maximalSeparatedSet ε A).encard` (under `C ⊆ A` and `packingNumber ε A ≠ ⊤`); the key constant `maximalSeparatedSet` is missing from the name (cf. the sibling `IsSeparated.encard_le_packingNumber`).","fix":"Rename to `IsSeparated.encard_le_encard_maximalSeparatedSet` with a deprecated alias, or drop it in favour of `IsSeparated.encard_le_packingNumber` + `encard_maximalSeparatedSet` (its only consumer is `isCover_maximalSeparatedSet`).","ev":"src.lean L299-301: `lemma encard_le_of_isSeparated (h_subset : C ⊆ A) (h_sep : IsSeparated ε C) (h : packingNumber ε A ≠ ⊤) : C.encard ≤ (maximalSeparatedSet ε A).encard`; `git grep encard_le_of_isSeparated origin/master -- Mathlib` finds no use outside the file.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-0d00fb","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.isCover_maximalSeparatedSet","line":306,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"reproves-mathlib-lemma","claim":"The 12-line proof re-proves by hand Vershynin 4.2.6 (a maximal separated subset is a cover), which Mathlib already has as `Metric.IsCover.of_maximal_isSeparated (hN : Maximal (fun N ↦ N ⊆ s ∧ IsSeparated ε N) N) : IsCover ε s N` (Topology/MetricSpace/Cover.lean:100); maximality of `maximalSeparatedSet` follows from `Set.Finite.eq_of_subset_of_encard_le`.","fix":"Prove it as `.of_maximal_isSeparated ⟨⟨maximalSeparatedSet_subset, isSeparated_maximalSeparatedSet⟩, fun _ hN hsub ↦ (Set.Finite.eq_of_subset_of_encard_le (Set.encard_ne_top_iff.mp (encard_maximalSeparatedSet h ▸ h)) hsub (encard_le_of_isSeparated hN.1 hN.2 h)).ge⟩`.","ev":"hunts/covering-numbers/batch4/Probe1.lean §P1 (standalone example) and hunts/covering-numbers/batch4/SrcCopy.lean L305-310 (drop-in replacement in a copy of the file; whole copy compiles): `.of_maximal_isSeparated ⟨⟨maximalSeparatedSet_subset, isSeparated_maximalSeparatedSet⟩, fun _N hN hsub ↦ (Set.Finite.eq_of_subset_of_encard_le (Set.encard_ne_top_iff.mp (encard_maximalSeparatedSet h ▸ h)) hsub ((hN.2.encard_le_packingNumber hN.1).trans (encard_maximalSeparatedSet h).ge)).ge⟩`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-018f22","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Isometry.coveringNumber_image'","line":382,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-injectivity-hypothesis","claim":"The hypothesis `hf_inj : Set.InjOn f A` is redundant: `coveringNumber ε (f '' A) = coveringNumber ε A` holds for every isometry between pseudo-emetric spaces (pick preimages `g` of a cover of `f '' A`; `f` is automatically injective on `range g`). E.g. it holds for the non-injective `SeparationQuotient.mk`.","fix":"Drop `hf_inj` (prove the `≥` direction with `range g` and `InjOn f (range g)`), make this the unprimed lemma, and deprecate the primed one.","ev":"hunts/covering-numbers/batch4/Probe1.lean §P6: theorem coveringNumber_image_noInj {f : X → Y} (hf : Isometry f) : coveringNumber ε (f '' A) = coveringNumber ε A (PseudoEMetricSpace X Y, no injectivity), plus the `SeparationQuotient.mk` instance at L88; drop-in version in hunts/covering-numbers/batch4/SrcCopy.lean L354-388 (whole copy compiles)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-73096d","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Isometry.coveringNumber_image","line":410,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"false-claim-in-docstring","claim":"The docstring asserts that in a `PseudoEMetricSpace` \"an additional injectivity assumption is needed\"; this is false — the equality holds for every isometry, including non-injective ones such as `SeparationQuotient.mk`.","fix":"Remove the claim (after generalising, a single lemma with no injectivity hypothesis suffices).","ev":"hunts/covering-numbers/batch4/Probe1.lean §P6 and L88-92: `coveringNumber ε (SeparationQuotient.mk '' A) = coveringNumber ε A` proved for a non-injective isometry","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-9decb0","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Isometry.coveringNumber_image","line":414,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`[EMetricSpace X]` is stronger than needed: the same conclusion holds with `[PseudoEMetricSpace X]` and no injectivity, so the EMetric/pseudo split into two lemmas is unnecessary.","fix":"State `Isometry.coveringNumber_image` for `PseudoEMetricSpace X` with no injectivity hypothesis.","ev":"hunts/covering-numbers/batch4/Probe1.lean L82-85: example {f : X → Y} (hf : Isometry f) {A : Set X} : coveringNumber ε (f '' A) = coveringNumber ε A := coveringNumber_image_noInj hf  -- X : PseudoEMetricSpace","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-580a3f","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Isometry.coveringNumber_image","line":414,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-companion-api","claim":"Only `coveringNumber` gets an isometry-image lemma; the companion `packingNumber ε (f '' A) = packingNumber ε A` (for every isometry of pseudo-emetric spaces) and `externalCoveringNumber ε (f '' A) ≤ externalCoveringNumber ε A` are missing.","fix":"Add `Isometry.packingNumber_image` and `Isometry.externalCoveringNumber_image_le` next to `Isometry.coveringNumber_image`.","ev":"hunts/covering-numbers/batch4/Probe2.lean (theorem packingNumber_image {f : X → Y} (hf : Isometry f) : packingNumber ε (f '' A) = packingNumber ε A, and the external `≤` example; both compile)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-7c65c2","file":"Mathlib/Topology/MetricSpace/Pseudo/Defs.lean","decl":"Metric.eball_top_eq_univ","line":986,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Metric.eball_top_eq_univ` (Topology.MetricSpace.Pseudo.Defs), `Metric.eball_top` (Topology.MetricSpace.Pseudo.Defs) state exactly the same thing (Lean-checked). Reviewer: Same file: `eball x ∞ = univ` is proved twice. Keep @[simp] `eball_top` and deprecate `eball_top_eq_univ`, which has 1 use in Normed/Algebra/Exponential.","fix":"Deprecate `Metric.eball_top_eq_univ` in favour of `Metric.eball_top`.","ev":"dupscan/Check.lean: `example := (@Metric.eball_top : type_of% @Metric.eball_top_eq_univ)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 49, rating MAJOR): `∞` and `⊤` denote the same radius here, and `eball_top` already supplies simp behavior. Preserve the explanatory docstring when consolidating.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-bd888f","file":"Mathlib/Topology/OpenPartialHomeomorph/Defs.lean","decl":"OpenPartialHomeomorph.toFun_eq_coe","line":122,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `OpenPartialHomeomorph.coe_toPartialEquiv` (Topology.OpenPartialHomeomorph.Defs), `OpenPartialHomeomorph.toFun_eq_coe` (Topology.OpenPartialHomeomorph.Defs) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: Both names come from intended families (toFun_eq_coe/invFun_eq_coe and coe_toPartialEquiv/_symm). They coincide only because PartialEquiv's CoeFun unfolds to `.toFun`, giving two identical @[simp, mfld_simps] rfl lemmas. Fix: make one an alias of the other.","fix":"Declare `OpenPartialHomeomorph.toFun_eq_coe` as an `alias` of `OpenPartialHomeomorph.coe_toPartialEquiv`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-af41c9","file":"Mathlib/Topology/Order/Basic.lean","decl":"exists_Ioc_subset_of_mem_nhds","line":34,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"module-docstring-names-wrong-lemma","claim":"The module docstring's 'Main statements' bullet (L34–36) names `exists_Ioc_subset_of_mem_nhds`, `exists_Ico_subset_of_mem_nhds`. The property it describes ('a neighbourhood of `x` contains `[x, z)` for some `z ∈ (x, y]`, a neighbourhood of `y` contains `(z, y]` for some `z ∈ [x, y)`') is that of the PRIMED lemmas `exists_Ico_subset_of_mem_nhds'` / `exists_Ioc_subset_of_mem_nhds'`. The unprimed lemmas take `∃ l, l < a` and give no such bound (type mismatch). The bullet also lists Ioc before Ico but describes the Ico statement first.","fix":"Point the bullet at `exists_Ico_subset_of_mem_nhds'` and `exists_Ioc_subset_of_mem_nhds'`, in that order, or describe the unprimed statements instead.","ev":"hunts/topology-order-basic/batch3/p3_fails.lean F1: `example [OrderTopology α] {x y : α} (hxy : x < y) {s : Set α} (hs : s ∈ 𝓝 y) : ∃ z ∈ Ico x y, Ioc z y ⊆ s := exists_Ioc_subset_of_mem_nhds hs ⟨x, hxy⟩` → Type mismatch (has type `∃ l < y, Ioc l y ⊆ s`); F2 is the same for `exists_Ico_subset_of_mem_nhds`. hunts/topology-order-basic/batch3/p1_basic.lean P3: the same two statements compile from `exists_Ioc_subset_of_mem_nhds' hs hxy` / `exists_Ico_subset_of_mem_nhds' hs hxy`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-f2f6cd","file":"Mathlib/Topology/Order/Basic.lean","decl":"Preorder.topology","line":67,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-scope-mismatch","claim":"The docstring says the order topology is defined 'on a partial order `α`', but the definition takes only `[Preorder α]` (and the class and module docstrings say preorder). It also writes the set-builder `{ x ∣ a < x }` with U+2223 DIVIDES instead of `|`.","fix":"Say 'on a preorder `α`' and write the set-builder with an ASCII `|`.","ev":"measured: src.lean L62 '(Order) topology on a partial order `α`' vs L67 'def Preorder.topology (α : Type*) [Preorder α]'; python unicodedata on L62-63 reports '∣' = 0x2223 DIVIDES","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-e032f9","file":"Mathlib/Topology/Order/Basic.lean","decl":"isOpen_lt'","line":111,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"defeq-set-builder-twin","claim":"`isOpen_lt' a : IsOpen {b | a < b}` is definitionally `isOpen_Ioi' a : IsOpen (Ioi a)` (`{b | a < b} = Ioi a` is `rfl`, and each lemma proves the other's statement as a bare term). So the file keeps a defeq set-builder twin, and its dual `isOpen_gt'`/`isOpen_Iio'` is another. OrderClosed.lean has only the interval forms (`isClosed_Iic`, with no `{b | b ≤ a}` twin). Simp does not connect the two forms. The prime also misleadingly suggests a variant of `isOpen_lt`, which is a different statement about two continuous functions. There are 5 external uses.","fix":"Prove `isOpen_Ioi'`/`isOpen_Iio'` directly and make `isOpen_lt'`/`isOpen_gt'` deprecated aliases.","ev":"hunts/topology-order-basic/batch0/Probe1.lean §P6: `example [OrderTopology α] (a : α) : IsOpen {b : α | a < b} := isOpen_Ioi' a` and `example ... : IsOpen (Ioi a) := isOpen_lt' a` both compile; §P12: `{b : α | a < b} = Ioi a := rfl` compiles, `by simp` fails with 'simp made no progress'","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-c464f0","file":"Mathlib/Topology/Order/Basic.lean","decl":"tendstoIcoClassNhds","line":150,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"instance-hypothesis-stronger-than-proof-uses","claim":"`[OrderTopology α]` is stronger than the proof uses: `tendstoIxxClass_of_subset fun _ _ => Ico_subset_Icc_self` needs only `[TendstoIxxClass Icc (𝓝 a) (𝓝 a)]`. As stated, types with an `Icc` instance but no `OrderTopology` (Pi types, via `tendstoIccClassNhdsPi`) get no `Ico` instance: `TendstoIxxClass Ico (𝓝 f) (𝓝 f)` for `f : ι → α` fails to synthesize on master.","fix":"State it as `instance tendstoIcoClassNhds (a : α) [TendstoIxxClass Icc (𝓝 a) (𝓝 a)] : TendstoIxxClass Ico (𝓝 a) (𝓝 a)`.","ev":"hunts/topology-order-basic/batch1/BasicGen2.lean (copy of src.lean with the three instances restated as `(a : α) [TendstoIxxClass Icc (𝓝 a) (𝓝 a)] : TendstoIxxClass Ixx (𝓝 a) (𝓝 a)`; whole file compiles with zero errors/warnings, and its appended tests `TendstoIxxClass Ico (𝓝 f) (𝓝 f)` / `Ioo` for `f : ι → α`, and `Ioo (𝓝[Ici f] f) (𝓝[Ioi f] f)`, resolve while the OrderTopology cases still resolve). On master the Pi queries fail: hunts/topology-order-basic/batch1/ProbeA.lean section A2 (`failed to synthesize TendstoIxxClass Ico (𝓝 f) (𝓝 f)`).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-294f6c","file":"Mathlib/Topology/Order/Basic.lean","decl":"tendstoIocClassNhds","line":153,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"instance-hypothesis-stronger-than-proof-uses","claim":"`[OrderTopology α]` is stronger than the proof uses: `tendstoIxxClass_of_subset fun _ _ => Ioc_subset_Icc_self` needs only `[TendstoIxxClass Icc (𝓝 a) (𝓝 a)]`. As stated, types with an `Icc` instance but no `OrderTopology` (Pi types, via `tendstoIccClassNhdsPi`) get no `Ioc` instance: `TendstoIxxClass Ioc (𝓝 f) (𝓝 f)` for `f : ι → α` fails to synthesize on master.","fix":"State it as `instance tendstoIocClassNhds (a : α) [TendstoIxxClass Icc (𝓝 a) (𝓝 a)] : TendstoIxxClass Ioc (𝓝 a) (𝓝 a)`.","ev":"hunts/topology-order-basic/batch1/BasicGen2.lean (copy of src.lean with the three instances restated as `(a : α) [TendstoIxxClass Icc (𝓝 a) (𝓝 a)] : TendstoIxxClass Ixx (𝓝 a) (𝓝 a)`; whole file compiles with zero errors/warnings, and its appended tests `TendstoIxxClass Ico (𝓝 f) (𝓝 f)` / `Ioo` for `f : ι → α`, and `Ioo (𝓝[Ici f] f) (𝓝[Ioi f] f)`, resolve while the OrderTopology cases still resolve). On master the Pi queries fail: hunts/topology-order-basic/batch1/ProbeA.lean section A2 (`failed to synthesize TendstoIxxClass Ioc (𝓝 f) (𝓝 f)`).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-581a47","file":"Mathlib/Topology/Order/Basic.lean","decl":"tendstoIooClassNhds","line":156,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"instance-hypothesis-stronger-than-proof-uses","claim":"`[OrderTopology α]` is stronger than the proof uses: `tendstoIxxClass_of_subset fun _ _ => Ioo_subset_Icc_self` needs only `[TendstoIxxClass Icc (𝓝 a) (𝓝 a)]`. As stated, types with an `Icc` instance but no `OrderTopology` (Pi types, via `tendstoIccClassNhdsPi`) get no `Ioo` instance: `TendstoIxxClass Ioo (𝓝 f) (𝓝 f)` for `f : ι → α` fails to synthesize on master.","fix":"State it as `instance tendstoIooClassNhds (a : α) [TendstoIxxClass Icc (𝓝 a) (𝓝 a)] : TendstoIxxClass Ioo (𝓝 a) (𝓝 a)`.","ev":"hunts/topology-order-basic/batch1/BasicGen2.lean (copy of src.lean with the three instances restated as `(a : α) [TendstoIxxClass Icc (𝓝 a) (𝓝 a)] : TendstoIxxClass Ixx (𝓝 a) (𝓝 a)`; whole file compiles with zero errors/warnings, and its appended tests `TendstoIxxClass Ico (𝓝 f) (𝓝 f)` / `Ioo` for `f : ι → α`, and `Ioo (𝓝[Ici f] f) (𝓝[Ioi f] f)`, resolve while the OrderTopology cases still resolve). On master the Pi queries fail: hunts/topology-order-basic/batch1/ProbeA.lean section A2 (`failed to synthesize TendstoIxxClass Ioo (𝓝 f) (𝓝 f)`).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-aa4b81","file":"Mathlib/Topology/Order/Basic.lean","decl":"isTopologicalBasis_biInter_Ioi_Iio_of_generateFrom","line":183,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-wrong-interval-terminology","claim":"Docstring says the topology is 'generated by half-open intervals with endpoints in a set `c`', but the generating sets are the open rays `Ioi a`, `Iio a` (half-infinite open intervals, as the preceding docstring of `exists_countable_generateFrom_Ioi_Iio` correctly says). 'Half-open interval' conventionally means `Ico`/`Ioc` (the generators of the Sorgenfrey topology), so the docstring names the wrong objects.","fix":"Replace 'half-open intervals' by 'open half-infinite intervals `Ioi a` and `Iio a`'.","ev":"src.lean lines 180-181: '/-- If a topology is generated by half-open intervals with endpoints in a set `c`, then the sets formed by intersecting finitely many of these intervals form a topological basis. -/' versus hypothesis `h : ts = generateFrom { s | ∃ a ∈ c, s = Ioi a ∨ s = Iio a }` (line 184).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-624f5d","file":"Mathlib/Topology/Order/Basic.lean","decl":"tendsto_of_tendsto_of_tendsto_of_le_of_le'","line":220,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"squeeze-needs-only-tendstoixxclass","claim":"The squeeze theorem assumes `[OrderTopology α]` but its proof `(hg.Icc hh).of_smallSets <| hgf.and hfh` uses only `TendstoIxxClass Icc (𝓝 a) (𝓝 a)`. Hence it does not apply to functions valued in `ι → α` (product topology, pointwise order), where it is true and where Mathlib already provides the needed `Icc` instance (`tendstoIccClassNhdsPi`).","fix":"Add a version assuming `[TendstoIxxClass Icc (𝓝 a) (𝓝 a)]` without `@[to_dual self]` (to_dual cannot validate it) and derive the `OrderTopology` versions from it.","ev":"hunts/topology-order-basic/batch1/ProbeA.lean: A1 `tendsto_of_tendsto_of_tendsto_of_le_of_le hg hh hgf hfh` for `f g h : β → ι → α` fails with `failed to synthesize OrderTopology (ι → α)`; A1' `theorem squeeze_gen' ... [Preorder α] [TopologicalSpace α] {a : α} [TendstoIxxClass Icc (𝓝 a) (𝓝 a)] (hg : Tendsto g b (𝓝 a)) (hh : Tendsto h b (𝓝 a)) (hgf : ∀ᶠ x in b, g x ≤ f x) (hfh : ∀ᶠ x in b, f x ≤ h x) : Tendsto f b (𝓝 a) := (hg.Icc hh).of_smallSets <| hgf.and hfh` (the verbatim master proof) compiles and then proves the Pi-valued squeeze. Fix caveat measured in hunts/topology-order-basic/batch1/BasicGen.out: putting `[TendstoIxxClass Icc (𝓝 a) (𝓝 a)]` on the existing declarations breaks `@[to_dual self]` validation (to_dual dualises the binder to `TendstoIxxClass (fun a b ↦ Icc b a) (𝓝 a) (𝓝 a)`).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-188033","file":"Mathlib/Topology/Order/Basic.lean","decl":"tendsto_of_tendsto_of_tendsto_of_le_of_le","line":231,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"squeeze-needs-only-tendstoixxclass","claim":"Same as for the primed version: `[OrderTopology α]` is only used through the primed lemma, whose proof needs just `TendstoIxxClass Icc (𝓝 a) (𝓝 a)`; the everywhere-inequality squeeze is unavailable for `ι → α`-valued functions although true there.","fix":"Derive it from a `[TendstoIxxClass Icc (𝓝 a) (𝓝 a)]` version of the primed lemma (keeping the `OrderTopology` form for `@[to_dual self]`).","ev":"hunts/topology-order-basic/batch1/ProbeA.lean: A1 `tendsto_of_tendsto_of_tendsto_of_le_of_le hg hh hgf hfh` for `f g h : β → ι → α` fails with `failed to synthesize OrderTopology (ι → α)`; A1' `theorem squeeze_gen' ... [Preorder α] [TopologicalSpace α] {a : α} [TendstoIxxClass Icc (𝓝 a) (𝓝 a)] (hg : Tendsto g b (𝓝 a)) (hh : Tendsto h b (𝓝 a)) (hgf : ∀ᶠ x in b, g x ≤ f x) (hfh : ∀ᶠ x in b, f x ≤ h x) : Tendsto f b (𝓝 a) := (hg.Icc hh).of_smallSets <| hgf.and hfh` (the verbatim master proof) compiles and then proves the Pi-valued squeeze. Fix caveat measured in hunts/topology-order-basic/batch1/BasicGen.out: putting `[TendstoIxxClass Icc (𝓝 a) (𝓝 a)]` on the existing declarations breaks `@[to_dual self]` validation (to_dual dualises the binder to `TendstoIxxClass (fun a b ↦ Icc b a) (𝓝 a) (𝓝 a)`).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-230153","file":"Mathlib/Topology/Order/Basic.lean","decl":"tendsto_of_tendsto_of_tendsto_of_le_of_le","line":231,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"module-doc-cites-wrong-variant","claim":"The module docstring (lines 37-39) lists `tendsto_of_tendsto_of_tendsto_of_le_of_le` as the squeeze theorem 'if `g` and `h` both converge to `a`, and eventually `g x ≤ f x ≤ h x`, then `f` converges to `a`', but the unprimed lemma requires `g ≤ f` and `f ≤ h` everywhere; the eventual version is `tendsto_of_tendsto_of_tendsto_of_le_of_le'`.","fix":"Cite `tendsto_of_tendsto_of_tendsto_of_le_of_le'` there (or drop 'eventually').","ev":"hunts/topology-order-basic/batch1/ProbeA.lean section A4: `tendsto_of_tendsto_of_tendsto_of_le_of_le hg hh hgf hfh` with `hgf : ∀ᶠ x in b, g x ≤ f x` fails with 'Application type mismatch ... expected to have type g ≤ f'.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-83bca3","file":"Mathlib/Topology/Order/Basic.lean","decl":"tendsto_order_unbounded","line":244,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"unused-wrapper-of-existing-iff","claim":"Reprovable directly from `tendsto_order` in a two-branch term, and it has no consumer anywhere in Mathlib (`git grep -w tendsto_order_unbounded origin/master -- Mathlib` hits only its own declaration).","fix":"Deprecate it in favour of `tendsto_order` (or keep it but note it is a convenience form).","ev":"hunts/topology-order-basic/batch1/ProbeA.lean section A6: `example ... (hu : ∃ u, a < u) (hl : ∃ l, l < a) (h : ∀ l u, l < a → a < u → ∀ᶠ b in x, l < f b ∧ f b < u) : Tendsto f x (𝓝 a) := tendsto_order.2 ⟨fun l hl' => hu.elim fun u hu => (h l u hl' hu).mono fun _ => And.left, fun u hu => hl.elim fun l hl' => (h l u hl' hu).mono fun _ => And.right⟩` compiles; consumer count measured by git grep = 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-b894e3","file":"Mathlib/Topology/Order/Basic.lean","decl":"tendstoIccClassNhdsPi","line":257,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"instance-hypothesis-stronger-than-proof-uses","claim":"`[∀ i, OrderTopology (α i)]` is only used to get `Tendsto.Icc` on each coordinate, i.e. `TendstoIxxClass Icc (𝓝 (f i)) (𝓝 (f i))`. Because the factors must be order topologies, nested Pi types get nothing: `TendstoIxxClass Icc (𝓝 f) (𝓝 f)` for `f : ι → κ → α` fails to synthesize on master although true.","fix":"Replace `[∀ i, OrderTopology (α i)]` by `[∀ i, TendstoIxxClass Icc (𝓝 (f i)) (𝓝 (f i))]` (proof unchanged).","ev":"hunts/topology-order-basic/batch1/BasicGen2.lean: same proof with binder `(f : ∀ i, α i) [∀ i, TendstoIxxClass Icc (𝓝 (f i)) (𝓝 (f i))]` compiles in the full file with zero warnings, and the appended nested test `example (f : ι → κ → α) : TendstoIxxClass Icc (𝓝 f) (𝓝 f) := inferInstance` resolves; on master it fails (hunts/topology-order-basic/batch1/ProbeA.lean section A3).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-3dcafb","file":"Mathlib/Topology/Order/Basic.lean","decl":"tendstoIccClassNhdsPi","line":257,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-prod-companion-instance","claim":"There is a Pi instance but no product instance: `TendstoIxxClass Icc (𝓝 p) (𝓝 p)` for `p : α × β` (componentwise order, two order topologies) fails to synthesize, so e.g. the squeeze theorem cannot be used for `α × β`-valued functions. The instance is true and short.","fix":"Add `instance tendstoIccClassNhdsProd (p : α × β) [TendstoIxxClass Icc (𝓝 p.1) (𝓝 p.1)] [TendstoIxxClass Icc (𝓝 p.2) (𝓝 p.2)] : TendstoIxxClass Icc (𝓝 p) (𝓝 p)` next to the Pi one.","ev":"hunts/topology-order-basic/batch1/ProbeC.lean: C1 `inferInstance` for `TendstoIxxClass Icc (𝓝 p) (𝓝 p)`, `p : α × β`, fails on master; C2 a 10-line proof (`tendsto_smallSets_iff`, `mem_nhds_prod_iff`, `Tendsto.Icc` on each projection, `Icc_prod_eq`) compiles, after which `inferInstance` succeeds; the same instance also compiles inside the file in hunts/topology-order-basic/batch1/BasicGen2.lean.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-020272","file":"Mathlib/Topology/Order/Basic.lean","decl":"StrictMono.isEmbedding_of_ordConnected","line":328,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-order-dual-variant","claim":"No `StrictAnti` (order-dual codomain) counterpart exists (`StrictAnti.isEmbedding_of_ordConnected`, likewise `StrictAnti.induced_topology_eq_preorder`); it is a one-liner from this lemma at `βᵒᵈ`.","fix":"Add `StrictAnti.isEmbedding_of_ordConnected := hf.dual_right.isEmbedding_of_ordConnected (β := βᵒᵈ) hc.dual`.","ev":"hunts/topology-order-basic/batch2/probe1.lean section (C): `theorem probe_StrictAnti_isEmbedding_of_ordConnected ... (hf : StrictAnti f) (hc : OrdConnected (range f)) : IsEmbedding f := hf.dual_right.isEmbedding_of_ordConnected (β := βᵒᵈ) hc.dual` compiles; hunts/topology-order-basic/batch2/probe2_absent.lean shows `Unknown constant StrictAnti.isEmbedding_of_ordConnected`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-5b5806","file":"Mathlib/Topology/Order/Basic.lean","decl":"nhdsGE_eq_iInf_inf_principal","line":348,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-strict-side-variant","claim":"Only the closed-side version exists: there is no `nhdsGT_eq_iInf_inf_principal` / `nhdsLT_eq_iInf_inf_principal` (`𝓝[>] a = (⨅ u > a, 𝓟 (Iio u)) ⊓ 𝓟 (Ioi a)`), although it holds in the same `Preorder` generality by the same proof (only `Ici_subset_Ioi.2 hl` becomes `fun _ hx => hl.trans hx`).","fix":"Add `nhdsGT_eq_iInf_inf_principal` (with `to_dual` `nhdsLT_eq_iInf_inf_principal`) next to it, proved as in probe1.lean.","ev":"hunts/topology-order-basic/batch2/probe1.lean section (B) `probe_nhdsGT_eq_iInf_inf_principal` compiles; hunts/topology-order-basic/batch2/probe2_absent.lean shows `Unknown identifier nhdsGT_eq_iInf_inf_principal` / `nhdsLT_eq_iInf_inf_principal`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-addadd","file":"Mathlib/Topology/Order/Basic.lean","decl":"nhdsGE_eq_iInf_principal","line":355,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-strict-side-variant","claim":"Only the closed-side version exists: there is no `nhdsGT_eq_iInf_principal` / `nhdsLT_eq_iInf_principal` (`(∃ u, a < u) → 𝓝[>] a = ⨅ u > a, 𝓟 (Ioo a u)`), the `Preorder` counterpart of `nhdsGT_basis_of_exists_gt` (which needs `LinearOrder`); it follows in one `simp only` line exactly as this lemma does.","fix":"Add `nhdsGT_eq_iInf_principal` (with `to_dual` `nhdsLT_eq_iInf_principal`) via `simp only [nhdsGT_eq_iInf_inf_principal, biInf_inf ha, inf_principal, Iio_inter_Ioi]`.","ev":"hunts/topology-order-basic/batch2/probe1.lean section (B) `probe_nhdsGT_eq_iInf_principal` compiles; hunts/topology-order-basic/batch2/probe2_absent.lean shows `Unknown identifier nhdsGT_eq_iInf_principal` / `nhdsLT_eq_iInf_principal`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-df5e4e","file":"Mathlib/Topology/Order/Basic.lean","decl":"nhdsGE_basis","line":367,"sev":"MINOR","status":"pr-open","cat":"reuse","pattern":"exact-duplicate-in-sibling-file","claim":"`nhdsGE_basis` (Basic.lean:367) and `nhdsGE_basis_Ico` (Mathlib/Topology/Order/LeftRightNhds.lean:259, `theorem nhdsGE_basis_Ico [NoMaxOrder α] (a : α) : (𝓝[≥] a).HasBasis (fun u => a < u) (Ico a)`, same section variables `[TopologicalSpace α] [LinearOrder α] [OrderTopology α]`) are the same statement with identical binders and instances; the `to_dual` pair `nhdsLE_basis`/`nhdsLE_basis_Ioc` duplicates likewise. `nhdsGE_basis_Ico` has one use (Counterexamples/SorgenfreyLine.lean:122), `nhdsLE_basis_Ioc` none. (Graded MINOR, not MAJOR: a duplicated lemma (the fix is a deprecation alias), per the lane's duplicate-grading rule after the user's calibration.)","fix":"Deprecate `nhdsGE_basis_Ico` (with its `to_dual` `nhdsLE_basis_Ioc`) in LeftRightNhds.lean as an alias of `nhdsGE_basis`/`nhdsLE_basis` and update the one use in Counterexamples/SorgenfreyLine.lean.","ev":"hunts/topology-order-basic/batch2/probe1.lean section (A): `example : @nhdsGE_basis_Ico = @nhdsGE_basis := rfl` and `example : @nhdsLE_basis_Ioc = @nhdsLE_basis := rfl` (import Mathlib.Topology.Order.LeftRightNhds)","evr":"compiles","astraV":"agrees","astraS":"Agrees (A2 claim 1): hypotheses, arguments and conclusions coincide (`Ico a` vs `fun u => Ico a u`); LeftRightNhds already imports Basic, so dependency order does not justify the copy; neither has a distinct simp role. Consolidate both pairs incl. the `to_dual` twins. Rated MAJOR.","pr":44581,"res":"Re-graded MAJOR→MINOR on 2026-10-07 by the user: two names for the same lemma is a MINOR duplicate; MAJOR duplication means a second definition/construction (as in the Tau Ceti red team's wins), not a duplicated lemma.","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-538bce","file":"Mathlib/Topology/Order/Basic.lean","decl":"nhds_top_basis_Ici","line":382,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"global-hypothesis-only-used-locally","claim":"`nhds_top_basis_Ici` (and its `to_dual` `nhds_bot_basis_Iic`) assumes global `[DenselyOrdered α]`, but its proof only uses `exists_between` below `⊤`: the hypothesis `∀ a < ⊤, ∃ b, a < b ∧ b < ⊤` suffices with the proof unchanged. `ℕ∞` satisfies it but is not densely ordered, so `nhds_top_basis_Ici` cannot be used at `(⊤ : ℕ∞)` although the basis statement holds there.","fix":"Replace `[DenselyOrdered α]` by the local interpolation hypothesis (keeping the dense version as a corollary).","ev":"probe_astra.lean: `nhds_top_basis_Ici'` with `(h : ∀ a < ⊤, ∃ b, a < b ∧ b < ⊤)` and the original proof compiles and applies to `ℕ∞`; `nhds_top_basis_Ici` at `ℕ∞` fails: failed to synthesize `DenselyOrdered ℕ∞`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-023063","file":"Mathlib/Topology/Order/Basic.lean","decl":"order_separated","line":408,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"typeclass-stronger-than-needed","claim":"`order_separated` assumes `[OrderTopology α]`, but the statement holds with the same two-line proof (`isOpen_Iio`/`isOpen_Ioi` in place of `isOpen_gt'`/`isOpen_lt'`) under `[OrderClosedTopology α]`, and even under just `[ClosedIicTopology α] [ClosedIciTopology α]`, with only `Mathlib.Topology.Order.OrderClosed` imported. Applying it in an order-closed space fails (`failed to synthesize OrderTopology α`). Its only consumer is the `OrderTopology.to_orderClosedTopology` instance, so it can't simply be generalised in place.","fix":"State it under `[ClosedIicTopology α] [ClosedIciTopology α]` in `Mathlib/Topology/Order/OrderClosed.lean`, and inline the `Iio x`/`Ioi y` separation from `LT.lt.exists_disjoint_Iio_Ioi` in `OrderTopology.to_orderClosedTopology`, which cannot use the generalised form.","ev":"hunts/topology-order-basic/batch3/p2_orderclosed.lean (`order_separated'` and the ClosedIic+ClosedIci `example`, compile, exit 0); hunts/topology-order-basic/batch3/p3_fails.lean F5: `example [OrderClosedTopology α] {a₁ a₂ : α} (h : a₁ < a₂) : ∃ u v : Set α, IsOpen u ∧ IsOpen v ∧ a₁ ∈ u ∧ a₂ ∈ v ∧ ∀ b₁ ∈ u, ∀ b₂ ∈ v, b₁ < b₂ := order_separated h` → failed to synthesize OrderTopology α","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-3c1b38","file":"Mathlib/Topology/Order/Basic.lean","decl":"IsOpen.exists_Ioo_subset","line":455,"sev":"MINOR","status":"confirmed","cat":"correctness","pattern":"empty-interval-trivial-conclusion","claim":"The conclusion `∃ a b, a < b ∧ Ioo a b ⊆ s` holds for EVERY set `s` (open or not, empty or not) once `α` has a covering pair `a ⋖ b`, because then `Ioo a b = ∅`. This covers every nontrivial non-densely-ordered type, e.g. `ℤ`, `ℕ`, `Fin n`. So the hypotheses `IsOpen s` and `s.Nonempty` only matter for densely ordered `α`, and the lemma has no docstring warning that the interval may be empty. Its only consumer, `dense_of_exists_between`, is unaffected: its hypothesis already supplies a point of `Ioo a b`.","fix":"Add a docstring saying that `Ioo a b` may be empty unless `α` is densely ordered, so the lemma has content only in that case.","ev":"hunts/topology-order-basic/batch3/p1_basic.lean P1: `example {a b : α} (hab : a ⋖ b) (s : Set α) : ∃ a b, a < b ∧ Ioo a b ⊆ s := ⟨a, b, hab.lt, hab.Ioo_eq ▸ empty_subset s⟩` and `example : ∃ a b : ℤ, a < b ∧ Ioo a b ⊆ (∅ : Set ℤ) := ⟨0, 1, zero_lt_one, fun x hx => by obtain ⟨h1, h2⟩ := hx; omega⟩`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-63a5ea","file":"Mathlib/Topology/Order/Basic.lean","decl":"IsUpperSet.isClosed","line":477,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"typeclass-stronger-than-needed","claim":"It inherits the section's `[OrderTopology α]` but only uses `IsUpperSet.eq_empty_or_Ici` and `isClosed_Ici`, so it holds under `[ClosedIciTopology α]`; its `to_dual` `IsLowerSet.isClosed` holds under `[ClosedIicTopology α]`. Both are provable with only `Mathlib.Topology.Order.OrderClosed` imported. In an order-closed, non-order-topology space it cannot be applied (failed to synthesize OrderTopology α). It is also general material in the wrong file. No consumers outside this file.","fix":"Move it, together with its `to_dual`, to the `ClosedIciTopology` section of `Mathlib/Topology/Order/OrderClosed.lean`, assuming `[ClosedIciTopology α]` (dual `[ClosedIicTopology α]`).","ev":"hunts/topology-order-basic/batch3/p2_orderclosed.lean: `theorem IsUpperSet.isClosed' [ClosedIciTopology α] [WellFoundedLT α] {s : Set α} (h : IsUpperSet s) : IsClosed s := by obtain rfl | ⟨a, rfl⟩ := h.eq_empty_or_Ici; exacts [isClosed_empty, isClosed_Ici]` plus the ClosedIic dual (compile, exit 0); hunts/topology-order-basic/batch3/p3_fails.lean F3: `h.isClosed` under `[OrderClosedTopology α]` → failed to synthesize OrderTopology α","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-24a0ad","file":"Mathlib/Topology/Order/Basic.lean","decl":"IsLowerSet.isOpen","line":482,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"typeclass-stronger-than-needed","claim":"It inherits `[OrderTopology α]` but only needs `[ClosedIciTopology α]`, since it is the complement of `IsUpperSet.isClosed`. Its `to_dual` `IsUpperSet.isOpen` needs only `[ClosedIicTopology α]`. Both are provable with only `Mathlib.Topology.Order.OrderClosed` imported. It cannot be applied in an order-closed, non-order-topology space. No consumers outside this file.","fix":"Move it with `IsUpperSet.isClosed` to `Mathlib/Topology/Order/OrderClosed.lean`, assuming `[ClosedIciTopology α]` (dual `[ClosedIicTopology α]`).","ev":"hunts/topology-order-basic/batch3/p2_orderclosed.lean: `theorem IsLowerSet.isOpen' [ClosedIciTopology α] [WellFoundedLT α] {s : Set α} (h : IsLowerSet s) : IsOpen s := by simpa using h.compl.isClosed'` and the ClosedIic dual via `h.eq_univ_or_Ioi` (compile, exit 0); hunts/topology-order-basic/batch3/p3_fails.lean F4: `h.isOpen` under `[OrderClosedTopology α]` → failed to synthesize OrderTopology α","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-37b078","file":"Mathlib/Topology/Order/Basic.lean","decl":"Dense.topology_eq_generateFrom","line":524,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"denselyordered-where-countable-covers-suffice","claim":"`[DenselyOrdered α]` is stronger than needed. The conclusion `‹TopologicalSpace α› = generateFrom (Ioi '' s ∪ Iio '' s)` holds for any dense `s` that contains both endpoints of every covering pair `x ⋖ y` (under `DenselyOrdered` there are no covering pairs, so this recovers the Mathlib lemma). Some hypothesis is needed: in `[0,1] ∪ [2,3] ⊆ ℝ` with the order topology, `s = ℚ ∩ ((0,1) ∪ (2,3))` is dense but `Ioi 1 = [2,3]` is not in the topology generated by its rays. The weakened lemma has the same proof shape with a `by_cases a ∈ s` split instead of `Dense.Ioi_eq_biUnion`.","fix":"Add `Dense.topology_eq_generateFrom_of_covBy (hl : ∀ ⦃x y⦄, x ⋖ y → x ∈ s) (hr : ∀ ⦃x y⦄, x ⋖ y → y ∈ s)` and derive the `DenselyOrdered` version from it via `not_covBy_of_denselyOrdered`.","ev":"hunts/topology-order-basic/batch4/probe4.lean Q1: `theorem Dense.topology_eq_generateFrom_of_covBy {s : Set α} (hs : Dense s) (hl : ∀ ⦃x y : α⦄, x ⋖ y → x ∈ s) (hr : ∀ ⦃x y : α⦄, x ⋖ y → y ∈ s) : ‹TopologicalSpace α› = .generateFrom (Ioi '' s ∪ Iio '' s)` (no `DenselyOrdered`) compiles; Q1b recovers the Mathlib statement under `[DenselyOrdered α]`. probe4.out is empty (no errors or warnings).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-e220ec","file":"Mathlib/Topology/Order/Basic.lean","decl":"SecondCountableTopology.of_separableSpace_orderTopology","line":558,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"denselyordered-where-countable-covers-suffice","claim":"`[DenselyOrdered α]` can be weakened to `{x : α | ∃ y, x ⋖ y}.Countable`, and then the result is an iff: a separable linear order with the order topology is second-countable if and only if only countably many points have a cover. The converse is `countable_setOfPred_covBy_right`, in the same file. The docstring says DenselyOrdered 'cannot be dropped' (double arrow space). That is true, but the double arrow space fails only because it has uncountably many covers. The current hypothesis excludes second-countable orders with jumps, such as `[0,1] ∪ [2,3] ⊆ ℝ` with its order topology.","fix":"Add `SecondCountableTopology.of_separableSpace_of_countable_covBy (hc : {x | ∃ y, x ⋖ y}.Countable)` (5 lines from the generalised `Dense.topology_eq_generateFrom_of_covBy`), keep the DenselyOrdered version as a corollary, and state the iff in the docstring.","ev":"hunts/topology-order-basic/batch4/probe4.lean Q2: `theorem sc_of_sep_covBy [SeparableSpace α] (hc : {x : α | ∃ y, x ⋖ y}.Countable) : SecondCountableTopology α` compiles. So do `example [SeparableSpace α] : SecondCountableTopology α ↔ {x : α | ∃ y, x ⋖ y}.Countable := ⟨fun _ => countable_setOfPred_covBy_right, sc_of_sep_covBy⟩` and the DenselyOrdered special case. (probe3.lean P7 has an independent 35-line proof, which also compiles.)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-b442b4","file":"Mathlib/Topology/Order/Basic.lean","decl":"countable_setOfPred_covBy_right","line":566,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"docstring-describes-sibling-statement","claim":"The docstring 'The set of points which are isolated on the right is countable…' (and its to_dual 'isolated on the left') describes a different set. 'Isolated on the right' is `{x | 𝓝[>] x = ⊥}`, which is exactly the set in `countable_setOfPred_isolated_right` (LeftRightNhds.lean:128), and that lemma carries the word-for-word identical docstring. This lemma's set `{x | ∃ y, x ⋖ y}` leaves out a top element: `⊤` is isolated on the right but has no cover. Two different statements share one description, and this one is not described accurately.","fix":"Reword to 'The set of points that have a cover (`x ⋖ y` for some `y`) is countable in a second-countable space' (dual: 'that cover some point').","ev":"hunts/topology-order-basic/batch4/probe3.lean P5: `example [TopologicalSpace α] [LinearOrder α] [OrderTop α] : (⊤ : α) ∈ {x : α | 𝓝[>] x = ⊥} ∧ (⊤ : α) ∉ {x : α | ∃ y, x ⋖ y} := ⟨by simp, fun ⟨_, hy⟩ => hy.lt.not_ge le_top⟩` compiles. probe3.out (#eval findDocString?) shows the identical docstrings on countable_setOfPred_covBy_right and countable_setOfPred_isolated_right.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-95dfc9","file":"Mathlib/Topology/Order/Basic.lean","decl":"countable_setOfPred_covBy_right","line":569,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"order-topology-where-order-closed-suffices","claim":"`[OrderTopology α]` is not needed. The statement holds for any linear order with `[ClosedIciTopology α] [SecondCountableTopology α]`, and the `to_dual` partner `countable_setOfPred_covBy_left` needs only `[ClosedIicTopology α]`. Proof: if `x ⋖ y` then `Iic x = Iio y` is open, so some basis set `b x` satisfies `x ∈ b x ⊆ Iic x`. Then `x = max (b x)`, so `x ↦ b x` is injective into the countable basis. The extra hypothesis excludes, for example, second-countable order-closed subspaces of ℝ that are not OrdConnected, such as `S = Iic 0 ∪ Ioi 1`. There `OrderTopology S` is not an instance, and is false, because `Iic 0` is open in `S` but not order-open. Its direct consumers are L619 and L632 in this file, LeftRightNhds.lean:133 and CountableSeparating.lean:36, and the needless hypothesis propagates to the 6 lemmas below it.","fix":"Restate under `[ClosedIciTopology α]` (dual `[ClosedIicTopology α]`) with the short injectivity proof, and move it to `Mathlib/Topology/Order/OrderClosed.lean`, which already has the needed imports.","ev":"hunts/topology-order-basic/batch4/probe3.lean P1/P1b: `theorem covBy_right_weak [TopologicalSpace α] [LinearOrder α] [ClosedIciTopology α] [SecondCountableTopology α] : Set.Countable { x : α | ∃ y, x ⋖ y }` and the dual `covBy_left_weak` under `[ClosedIicTopology α]` compile. P1c recovers the Mathlib statement. P9: `example : {x : S | ∃ y, x ⋖ y}.Countable := covBy_right_weak` compiles for `S := Iic 0 ∪ Ioi 1 : Set ℝ`. probe3_neg.lean: `example : OrderTopology S := inferInstance` and `:= countable_setOfPred_covBy_right` fail with 'failed to synthesize OrderTopology ↑S'.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-39abb3","file":"Mathlib/Topology/Order/Basic.lean","decl":"countable_setOfPred_covBy_right","line":569,"sev":"MINOR","status":"confirmed","cat":"proof","pattern":"long-proof-short-replacement","claim":"The proof runs 37 lines (L571–607). It covers α by `countableBasis` sets, builds a second `choose!` family `z`, and proves pairwise disjointness of `Ioc (z x) x` by two symmetric `by_contra!` blocks. A 9-line proof under weaker hypotheses picks `b x ∈ countableBasis α` with `x ∈ b x ⊆ Iic x` and notes that `x ↦ b x` is injective because `x` is the maximum of `b x`.","fix":"Replace the proof with the `MapsTo.countable_of_injOn` argument from probe3 P1 (9 lines).","ev":"hunts/topology-order-basic/batch4/probe3.lean P1 (lines 13–23), compiles. Measured: src.lean L571–607 = 37 proof lines.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-10b958","file":"Mathlib/Topology/Order/Basic.lean","decl":"countable_of_isolated_left'","line":617,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"unused-restatement-of-sibling","claim":"`countable_of_isolated_left'` is `countable_setOfPred_covBy_left` with `y ⋖ x` unfolded through `covBy_iff_Ioo_eq` (its whole proof is that `simpa`). It is used nowhere: `git grep countable_of_isolated_left origin/master -- .` hits only its own declaration. There is no right-hand counterpart. Its docstring is word-for-word that of `countable_setOfPred_isolated_left` (LeftRightNhds), a different lemma about `𝓝[<] x = ⊥`.","fix":"Deprecate `countable_of_isolated_left'` in favour of `countable_setOfPred_covBy_left` (callers: `simpa only [← covBy_iff_Ioo_eq] using countable_setOfPred_covBy_left`).","ev":"hunts/topology-order-basic/batch4/probe3.lean P5: `example : { x : α | ∃ y, y < x ∧ Ioo y x = ∅ } = { x | ∃ y, y ⋖ x } := by simp only [← covBy_iff_Ioo_eq]` compiles. Measured: `git -C mathlib4 grep -n countable_of_isolated origin/master -- .` returns only Mathlib/Topology/Order/Basic.lean:617.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-ff127f","file":"Mathlib/Topology/Order/Basic.lean","decl":"countable_of_isolated_left'","line":617,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"order-topology-where-order-closed-suffices","claim":"Like `countable_setOfPred_covBy_left`, which it restates, it needs only `[ClosedIicTopology α]`, not `[OrderTopology α]`. (This is moot if the lemma is deprecated.)","fix":"Covered by deprecating it, or else restate it under `[ClosedIicTopology α]`.","ev":"hunts/topology-order-basic/batch4/probe3.lean P8: `example [TopologicalSpace α] [LinearOrder α] [ClosedIicTopology α] [SecondCountableTopology α] : Set.Countable { x : α | ∃ y, y < x ∧ Ioo y x = ∅ } := by simpa only [← covBy_iff_Ioo_eq] using covBy_left_weak` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-fb6b1c","file":"Mathlib/Topology/Order/Basic.lean","decl":"Set.PairwiseDisjoint.countable_of_Ioo","line":626,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"order-topology-where-order-closed-suffices","claim":"`[OrderTopology α]` is not needed: `[OrderClosedTopology α]` suffices. The proof uses only `isOpen_Ioo` (order-closed) and `countable_setOfPred_covBy_right`, which needs only `ClosedIciTopology` (see that finding). The original proof goes through verbatim. There are 4 consumers (Basic.lean:671, LeftRightNhds.lean:170, Monotone.lean:70, BorelSpace/Order.lean:831). The docstring says only 'in a second-countable space', so it covers order-closed second-countable spaces that the hypotheses exclude, such as the subspace `Iic 0 ∪ Ioi 1` of ℝ.","fix":"Restate under `[OrderClosedTopology α]` and move it with `countable_setOfPred_covBy_right` to `Topology/Order/OrderClosed.lean`.","ev":"hunts/topology-order-basic/batch4/probe3.lean P2: `theorem countable_of_Ioo_weak [TopologicalSpace α] [LinearOrder α] [OrderClosedTopology α] [SecondCountableTopology α] {y : α → α} {s : Set α} (h : PairwiseDisjoint s fun x => Ioo x (y x)) (h' : ∀ x ∈ s, x < y x) : s.Countable` compiles, using the original proof term with `covBy_right_weak`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-0772bf","file":"Mathlib/Topology/Order/Basic.lean","decl":"countable_image_lt_image_Ioi_within","line":641,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"order-topology-where-order-closed-suffices","claim":"`[OrderTopology α]` on the codomain is not needed: `[OrderClosedTopology α]` suffices. The original 31-line proof compiles verbatim once `Set.PairwiseDisjoint.countable_of_Ioo` is weakened as above. For example, the lemma then applies to `f : ℝ → S` with `S = Iic 0 ∪ Ioi 1 ⊆ ℝ` (subspace topology, not the order topology). The `to_dual` partner and the three sibling lemmas inherit this.","fix":"Restate under `[OrderClosedTopology α]`.","ev":"hunts/topology-order-basic/batch4/probe3.lean P3a: `theorem image_lt_within_weak [TopologicalSpace α] [LinearOrder α] [OrderClosedTopology α] [LinearOrder β] [SecondCountableTopology α] (t : Set β) (f : β → α) : Set.Countable {x ∈ t | ∃ z, f x < z ∧ ∀ y ∈ t, x < y → z ≤ f y}` compiles with the Mathlib proof verbatim (only the countable_of_Ioo call swapped). P9: `example (f : ℝ → S) : Set.Countable {x | ∃ z, f x < z ∧ ∀ y, x < y → z ≤ f y} := image_lt_weak f` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-29cf3c","file":"Mathlib/Topology/Order/Basic.lean","decl":"countable_image_lt_image_Ioi","line":681,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"order-topology-where-order-closed-suffices","claim":"`[OrderTopology α]` can be weakened to `[OrderClosedTopology α]`. The proof is a `simpa` from the `_within` version, which holds under that class.","fix":"Restate under `[OrderClosedTopology α]`.","ev":"hunts/topology-order-basic/batch4/probe3.lean P3c: `theorem image_lt_weak [TopologicalSpace α] [LinearOrder α] [OrderClosedTopology α] [LinearOrder β] (f : β → α) [SecondCountableTopology α] : Set.Countable {x | ∃ z, f x < z ∧ ∀ y, x < y → z ≤ f y} := by simpa using image_lt_within_weak univ f` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-8aee4a","file":"Mathlib/Topology/Order/Basic.lean","decl":"countable_image_gt_image_Ioi_within","line":692,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"order-topology-where-order-closed-suffices","claim":"`[OrderTopology α]` can be weakened to `[OrderClosedTopology α]`. The proof is the `lt` version at `αᵒᵈ`, and `OrderClosedTopology` transfers to `αᵒᵈ`.","fix":"Restate under `[OrderClosedTopology α]`.","ev":"hunts/topology-order-basic/batch4/probe3.lean P3b: `theorem image_gt_within_weak [TopologicalSpace α] [LinearOrder α] [OrderClosedTopology α] [LinearOrder β] [SecondCountableTopology α] (t : Set β) (f : β → α) : Set.Countable {x ∈ t | ∃ z, z < f x ∧ ∀ y ∈ t, x < y → f y ≤ z} := image_lt_within_weak (α := αᵒᵈ) t f` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-9b6c69","file":"Mathlib/Topology/Order/Basic.lean","decl":"countable_image_gt_image_Ioi","line":702,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"order-topology-where-order-closed-suffices","claim":"`[OrderTopology α]` can be weakened to `[OrderClosedTopology α]`. The same proof works at `αᵒᵈ`.","fix":"Restate under `[OrderClosedTopology α]`.","ev":"hunts/topology-order-basic/batch4/probe3.lean P3c: `theorem image_gt_weak [TopologicalSpace α] [LinearOrder α] [OrderClosedTopology α] [LinearOrder β] (f : β → α) [SecondCountableTopology α] : Set.Countable {x | ∃ z, z < f x ∧ ∀ y, x < y → f y ≤ z} := image_lt_weak (α := αᵒᵈ) f` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-5f18a2","file":"Mathlib/Topology/Order/Basic.lean","decl":"instIsCountablyGenerated_atTop","line":707,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"order-topology-where-order-closed-suffices","claim":"`[OrderTopology α]` is not needed: `[ClosedIicTopology α]` suffices (dual `atBot`: `[ClosedIciTopology α]`). The proof uses the topology only through `isOpen_Ioi` (meeting a countable dense set), and it goes through verbatim. Instance search still finds the weaker instance for every `OrderTopology` type, via `OrderTopology → OrderClosedTopology → ClosedIicTopology`.","fix":"Restate the instance under `[ClosedIicTopology α]` (to_dual handles atBot) and move it to OrderClosed.lean.","ev":"hunts/topology-order-basic/batch4/probe3.lean P4: `theorem atTop_cg_weak [TopologicalSpace α] [LinearOrder α] [ClosedIicTopology α] [SeparableSpace α] : IsCountablyGenerated (atTop : Filter α)` compiles with the original proof verbatim. P9: `example : IsCountablyGenerated (atTop : Filter S) := atTop_cg_weak` for `S = Iic 0 ∪ Ioi 1 : Set ℝ` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-67685c","file":"Mathlib/Topology/Order/Basic.lean","decl":"pi_Iic_mem_nhds'","line":728,"sev":"MINOR","status":"confirmed","cat":"docs","pattern":"stale-implementation-note","claim":"The section note (L728-730) says each primed `pi_Ixx_mem_nhds'` exists because 'sometimes Lean fails to unify different instances while trying to apply the dependent version to, e.g., `ι → ℝ`'. The probe shows the dependent versions apply to `ι → ℝ` directly, even with non-canonical instance paths, so the note is stale.","fix":"Remove the note together with the primed lemmas (or reword it if a concrete failing case is found).","ev":"hunts/topology-order-basic/batch5/probe1.lean §C (compiles, exit 0), e.g.\nvariable {ι : Type*} [Fintype ι] [Nonempty ι] {a b x : ι → ℝ}\nexample (ha : ∀ i, x i < a i) : Iic a ∈ 𝓝 x := pi_Iic_mem_nhds ha\nexample (ha : ∀ i, a i < x i) (hb : ∀ i, x i < b i) : Ioo a b ∈ 𝓝 x := by\n  apply pi_Ioo_mem_nhds <;> assumption\nexample (ha : ∀ i, x i < a i) : ∀ᶠ y in 𝓝 x, y ≤ a := by\n  filter_upwards [pi_Iic_mem_nhds ha] with y hy using hy\nexample (x a : Fin 3 → ℝ) (ha : ∀ i, x i < a i) : Iic a ∈ 𝓝 x := pi_Iic_mem_nhds ha\n-- order via `Lattice.toSemilatticeSup`, topology via the sup pseudo-metric on ι → ℝ:\nexample (ha : ∀ i, x i < a i) :\n    @Iic (ι → ℝ) (@PartialOrder.toPreorder _\n      (@SemilatticeSup.toPartialOrder _ (@Lattice.toSemilatticeSup _ inferInstance))) a ∈\n      @nhds (ι → ℝ) (@UniformSpace.toTopologicalSpace _\n        (@PseudoMetricSpace.toUniformSpace _ inferInstance)) x :=\n  pi_Iic_mem_nhds ha\n(all eight dependent lemmas Iic/Ici/Icc/Iio/Ioi/Ioc/Ioo checked on ι → ℝ). Measured: `git grep -nE \"pi_I(c|o)[a-z]_mem_nhds\" origin/master -- Mathlib MathlibTest Archive Counterexamples` hits only this file.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-00b360","file":"Mathlib/Topology/Order/Basic.lean","decl":"pi_Iic_mem_nhds","line":737,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"order-topology-where-order-closed-suffices","claim":"Assumes `[∀ i, OrderTopology (X i)]`, but the proof only uses `Iic_mem_nhds`, which needs `LinearOrder` + `ClosedIciTopology` (implied by `OrderClosedTopology`; strictly weaker than `OrderTopology`, e.g. any linear order with the discrete topology). The same holds for the `to_dual`-generated dual. Neither has a consumer in Mathlib (git grep of pi_I.._mem_nhds outside this file is empty), so weakening costs nothing.","fix":"Weaken the Pi-section variable (L733-734) to `[∀ i, OrderClosedTopology (X i)]` / `[OrderClosedTopology α]` (only `ClosedIciTopology` is needed for the Iic/Iio lemmas), and optionally move the section to Topology/Order/OrderClosed.lean beside `Icc_mem_nhds`.","ev":"hunts/topology-order-basic/batch5/probe1.lean §B (compiles):\nexample [∀ i, ClosedIciTopology (X i)] (ha : ∀ i, x i < a i) : Iic a ∈ 𝓝 x :=\n  pi_univ_Iic a ▸ set_pi_mem_nhds (Set.toFinite _) fun _ _ => Iic_mem_nhds (ha _)\nand hunts/topology-order-basic/batch5/src_gen.lean = src.lean with the Pi-section variable (L733-734) changed to `[OrderClosedTopology α] ... [∀ i, OrderClosedTopology (X i)]`; the whole file compiles (exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-6a121b","file":"Mathlib/Topology/Order/Basic.lean","decl":"pi_Iic_mem_nhds'","line":741,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"order-topology-where-order-closed-suffices","claim":"Assumes `[OrderTopology α]`, but the proof only uses `Iic_mem_nhds`, which needs `LinearOrder` + `ClosedIciTopology` (implied by `OrderClosedTopology`; strictly weaker than `OrderTopology`, e.g. any linear order with the discrete topology). The same holds for the `to_dual`-generated dual. Neither has a consumer in Mathlib (git grep of pi_I.._mem_nhds outside this file is empty), so weakening costs nothing.","fix":"Weaken the Pi-section variable (L733-734) to `[∀ i, OrderClosedTopology (X i)]` / `[OrderClosedTopology α]` (only `ClosedIciTopology` is needed for the Iic/Iio lemmas), and optionally move the section to Topology/Order/OrderClosed.lean beside `Icc_mem_nhds`.","ev":"hunts/topology-order-basic/batch5/probe1.lean §B (compiles):\nexample {α : Type*} [TopologicalSpace α] [LinearOrder α] [ClosedIciTopology α] {a' x' : ι → α}\n    (ha : ∀ i, x' i < a' i) : Iic a' ∈ 𝓝 x' :=\n  pi_univ_Iic a' ▸ set_pi_mem_nhds (Set.toFinite _) fun _ _ => Iic_mem_nhds (ha _)\nand hunts/topology-order-basic/batch5/src_gen.lean = src.lean with the Pi-section variable (L733-734) changed to `[OrderClosedTopology α] ... [∀ i, OrderClosedTopology (X i)]`; the whole file compiles (exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-aecd75","file":"Mathlib/Topology/Order/Basic.lean","decl":"pi_Iic_mem_nhds'","line":741,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"redundant-nondependent-pi-variant","claim":"`pi_Iic_mem_nhds'` is `pi_Iic_mem_nhds` restated for a constant family (its proof is `pi_Iic_mem_nhds ..`). The section note says it exists because Lean sometimes fails to unify when applying the dependent version to `ι → ℝ`, but `pi_Iic_mem_nhds` and the other dependent lemmas now apply to `ι → ℝ`, `Fin 3 → ℝ` and `ι → α` directly (term, `apply`, `filter_upwards`), even with the order instance taken through `Lattice` and the topology through the sup pseudo-metric. No primed lemma or its dual is used anywhere in Mathlib.","fix":"Deprecate `pi_Iic_mem_nhds'` (and its `to_dual` image) in favour of `pi_Iic_mem_nhds`, and delete the section note's justification.","ev":"hunts/topology-order-basic/batch5/probe1.lean §C (compiles, exit 0), e.g.\nvariable {ι : Type*} [Fintype ι] [Nonempty ι] {a b x : ι → ℝ}\nexample (ha : ∀ i, x i < a i) : Iic a ∈ 𝓝 x := pi_Iic_mem_nhds ha\nexample (ha : ∀ i, a i < x i) (hb : ∀ i, x i < b i) : Ioo a b ∈ 𝓝 x := by\n  apply pi_Ioo_mem_nhds <;> assumption\nexample (ha : ∀ i, x i < a i) : ∀ᶠ y in 𝓝 x, y ≤ a := by\n  filter_upwards [pi_Iic_mem_nhds ha] with y hy using hy\nexample (x a : Fin 3 → ℝ) (ha : ∀ i, x i < a i) : Iic a ∈ 𝓝 x := pi_Iic_mem_nhds ha\n-- order via `Lattice.toSemilatticeSup`, topology via the sup pseudo-metric on ι → ℝ:\nexample (ha : ∀ i, x i < a i) :\n    @Iic (ι → ℝ) (@PartialOrder.toPreorder _\n      (@SemilatticeSup.toPartialOrder _ (@Lattice.toSemilatticeSup _ inferInstance))) a ∈\n      @nhds (ι → ℝ) (@UniformSpace.toTopologicalSpace _\n        (@PseudoMetricSpace.toUniformSpace _ inferInstance)) x :=\n  pi_Iic_mem_nhds ha\n(all eight dependent lemmas Iic/Ici/Icc/Iio/Ioi/Ioc/Ioo checked on ι → ℝ). Measured: `git grep -nE \"pi_I(c|o)[a-z]_mem_nhds\" origin/master -- Mathlib MathlibTest Archive Counterexamples` hits only this file.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-504050","file":"Mathlib/Topology/Order/Basic.lean","decl":"pi_Icc_mem_nhds","line":745,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"order-topology-where-order-closed-suffices","claim":"Assumes `[∀ i, OrderTopology (X i)]`, but the proof only uses `Icc_mem_nhds`, which needs `LinearOrder` + `OrderClosedTopology` (implied by `OrderClosedTopology`; strictly weaker than `OrderTopology`, e.g. any linear order with the discrete topology). The same holds for the `to_dual`-generated dual. Neither has a consumer in Mathlib (git grep of pi_I.._mem_nhds outside this file is empty), so weakening costs nothing.","fix":"Weaken the Pi-section variable (L733-734) to `[∀ i, OrderClosedTopology (X i)]` / `[OrderClosedTopology α]` (only `ClosedIciTopology` is needed for the Iic/Iio lemmas), and optionally move the section to Topology/Order/OrderClosed.lean beside `Icc_mem_nhds`.","ev":"hunts/topology-order-basic/batch5/probe1.lean §B (compiles):\nexample [∀ i, OrderClosedTopology (X i)] (ha : ∀ i, a i < x i) (hb : ∀ i, x i < b i) :\n    Icc a b ∈ 𝓝 x :=\n  pi_univ_Icc a b ▸ set_pi_mem_nhds finite_univ fun _ _ => Icc_mem_nhds (ha _) (hb _)\nand hunts/topology-order-basic/batch5/src_gen.lean = src.lean with the Pi-section variable (L733-734) changed to `[OrderClosedTopology α] ... [∀ i, OrderClosedTopology (X i)]`; the whole file compiles (exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-ba9763","file":"Mathlib/Topology/Order/Basic.lean","decl":"pi_Icc_mem_nhds'","line":749,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"order-topology-where-order-closed-suffices","claim":"Assumes `[OrderTopology α]`, but the proof only uses `Icc_mem_nhds`, which needs `LinearOrder` + `OrderClosedTopology` (implied by `OrderClosedTopology`; strictly weaker than `OrderTopology`, e.g. any linear order with the discrete topology). The same holds for the `to_dual`-generated dual. Neither has a consumer in Mathlib (git grep of pi_I.._mem_nhds outside this file is empty), so weakening costs nothing.","fix":"Weaken the Pi-section variable (L733-734) to `[∀ i, OrderClosedTopology (X i)]` / `[OrderClosedTopology α]` (only `ClosedIciTopology` is needed for the Iic/Iio lemmas), and optionally move the section to Topology/Order/OrderClosed.lean beside `Icc_mem_nhds`.","ev":"hunts/topology-order-basic/batch5/src_gen.lean = src.lean with the Pi-section variable (L733-734) changed to `[OrderClosedTopology α] ... [∀ i, OrderClosedTopology (X i)]`; the whole file compiles (exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-4708d7","file":"Mathlib/Topology/Order/Basic.lean","decl":"pi_Icc_mem_nhds'","line":749,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"redundant-nondependent-pi-variant","claim":"`pi_Icc_mem_nhds'` is `pi_Icc_mem_nhds` restated for a constant family (its proof is `pi_Icc_mem_nhds ..`). The section note says it exists because Lean sometimes fails to unify when applying the dependent version to `ι → ℝ`, but `pi_Icc_mem_nhds` and the other dependent lemmas now apply to `ι → ℝ`, `Fin 3 → ℝ` and `ι → α` directly (term, `apply`, `filter_upwards`), even with the order instance taken through `Lattice` and the topology through the sup pseudo-metric. No primed lemma or its dual is used anywhere in Mathlib.","fix":"Deprecate `pi_Icc_mem_nhds'` (and its `to_dual` image) in favour of `pi_Icc_mem_nhds`, and delete the section note's justification.","ev":"hunts/topology-order-basic/batch5/probe1.lean §C (compiles, exit 0), e.g.\nvariable {ι : Type*} [Fintype ι] [Nonempty ι] {a b x : ι → ℝ}\nexample (ha : ∀ i, x i < a i) : Iic a ∈ 𝓝 x := pi_Iic_mem_nhds ha\nexample (ha : ∀ i, a i < x i) (hb : ∀ i, x i < b i) : Ioo a b ∈ 𝓝 x := by\n  apply pi_Ioo_mem_nhds <;> assumption\nexample (ha : ∀ i, x i < a i) : ∀ᶠ y in 𝓝 x, y ≤ a := by\n  filter_upwards [pi_Iic_mem_nhds ha] with y hy using hy\nexample (x a : Fin 3 → ℝ) (ha : ∀ i, x i < a i) : Iic a ∈ 𝓝 x := pi_Iic_mem_nhds ha\n-- order via `Lattice.toSemilatticeSup`, topology via the sup pseudo-metric on ι → ℝ:\nexample (ha : ∀ i, x i < a i) :\n    @Iic (ι → ℝ) (@PartialOrder.toPreorder _\n      (@SemilatticeSup.toPartialOrder _ (@Lattice.toSemilatticeSup _ inferInstance))) a ∈\n      @nhds (ι → ℝ) (@UniformSpace.toTopologicalSpace _\n        (@PseudoMetricSpace.toUniformSpace _ inferInstance)) x :=\n  pi_Iic_mem_nhds ha\n(all eight dependent lemmas Iic/Ici/Icc/Iio/Ioi/Ioc/Ioo checked on ι → ℝ). Measured: `git grep -nE \"pi_I(c|o)[a-z]_mem_nhds\" origin/master -- Mathlib MathlibTest Archive Counterexamples` hits only this file.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-f942dd","file":"Mathlib/Topology/Order/Basic.lean","decl":"pi_Iio_mem_nhds","line":755,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"order-topology-where-order-closed-suffices","claim":"Assumes `[∀ i, OrderTopology (X i)]`, but the proof only uses `Iio_mem_nhds`, which needs `LinearOrder` + `ClosedIciTopology` (implied by `OrderClosedTopology`; strictly weaker than `OrderTopology`, e.g. any linear order with the discrete topology). The same holds for the `to_dual`-generated dual. Neither has a consumer in Mathlib (git grep of pi_I.._mem_nhds outside this file is empty), so weakening costs nothing.","fix":"Weaken the Pi-section variable (L733-734) to `[∀ i, OrderClosedTopology (X i)]` / `[OrderClosedTopology α]` (only `ClosedIciTopology` is needed for the Iic/Iio lemmas), and optionally move the section to Topology/Order/OrderClosed.lean beside `Icc_mem_nhds`.","ev":"hunts/topology-order-basic/batch5/probe1.lean §B (compiles):\nexample [Nonempty ι] [∀ i, ClosedIciTopology (X i)] (ha : ∀ i, x i < a i) : Iio a ∈ 𝓝 x :=\n  mem_of_superset (set_pi_mem_nhds finite_univ fun i _ ↦ Iio_mem_nhds (ha i))\n    (pi_univ_Iio_subset a)\nand hunts/topology-order-basic/batch5/src_gen.lean = src.lean with the Pi-section variable (L733-734) changed to `[OrderClosedTopology α] ... [∀ i, OrderClosedTopology (X i)]`; the whole file compiles (exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-a8df96","file":"Mathlib/Topology/Order/Basic.lean","decl":"pi_Iio_mem_nhds'","line":759,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"order-topology-where-order-closed-suffices","claim":"Assumes `[OrderTopology α]`, but the proof only uses `Iio_mem_nhds`, which needs `LinearOrder` + `ClosedIciTopology` (implied by `OrderClosedTopology`; strictly weaker than `OrderTopology`, e.g. any linear order with the discrete topology). The same holds for the `to_dual`-generated dual. Neither has a consumer in Mathlib (git grep of pi_I.._mem_nhds outside this file is empty), so weakening costs nothing.","fix":"Weaken the Pi-section variable (L733-734) to `[∀ i, OrderClosedTopology (X i)]` / `[OrderClosedTopology α]` (only `ClosedIciTopology` is needed for the Iic/Iio lemmas), and optionally move the section to Topology/Order/OrderClosed.lean beside `Icc_mem_nhds`.","ev":"hunts/topology-order-basic/batch5/src_gen.lean = src.lean with the Pi-section variable (L733-734) changed to `[OrderClosedTopology α] ... [∀ i, OrderClosedTopology (X i)]`; the whole file compiles (exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-1d826d","file":"Mathlib/Topology/Order/Basic.lean","decl":"pi_Iio_mem_nhds'","line":759,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"redundant-nondependent-pi-variant","claim":"`pi_Iio_mem_nhds'` is `pi_Iio_mem_nhds` restated for a constant family (its proof is `pi_Iio_mem_nhds ..`). The section note says it exists because Lean sometimes fails to unify when applying the dependent version to `ι → ℝ`, but `pi_Iio_mem_nhds` and the other dependent lemmas now apply to `ι → ℝ`, `Fin 3 → ℝ` and `ι → α` directly (term, `apply`, `filter_upwards`), even with the order instance taken through `Lattice` and the topology through the sup pseudo-metric. No primed lemma or its dual is used anywhere in Mathlib.","fix":"Deprecate `pi_Iio_mem_nhds'` (and its `to_dual` image) in favour of `pi_Iio_mem_nhds`, and delete the section note's justification.","ev":"hunts/topology-order-basic/batch5/probe1.lean §C (compiles, exit 0), e.g.\nvariable {ι : Type*} [Fintype ι] [Nonempty ι] {a b x : ι → ℝ}\nexample (ha : ∀ i, x i < a i) : Iic a ∈ 𝓝 x := pi_Iic_mem_nhds ha\nexample (ha : ∀ i, a i < x i) (hb : ∀ i, x i < b i) : Ioo a b ∈ 𝓝 x := by\n  apply pi_Ioo_mem_nhds <;> assumption\nexample (ha : ∀ i, x i < a i) : ∀ᶠ y in 𝓝 x, y ≤ a := by\n  filter_upwards [pi_Iic_mem_nhds ha] with y hy using hy\nexample (x a : Fin 3 → ℝ) (ha : ∀ i, x i < a i) : Iic a ∈ 𝓝 x := pi_Iic_mem_nhds ha\n-- order via `Lattice.toSemilatticeSup`, topology via the sup pseudo-metric on ι → ℝ:\nexample (ha : ∀ i, x i < a i) :\n    @Iic (ι → ℝ) (@PartialOrder.toPreorder _\n      (@SemilatticeSup.toPartialOrder _ (@Lattice.toSemilatticeSup _ inferInstance))) a ∈\n      @nhds (ι → ℝ) (@UniformSpace.toTopologicalSpace _\n        (@PseudoMetricSpace.toUniformSpace _ inferInstance)) x :=\n  pi_Iic_mem_nhds ha\n(all eight dependent lemmas Iic/Ici/Icc/Iio/Ioi/Ioc/Ioo checked on ι → ℝ). Measured: `git grep -nE \"pi_I(c|o)[a-z]_mem_nhds\" origin/master -- Mathlib MathlibTest Archive Counterexamples` hits only this file.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-1041e5","file":"Mathlib/Topology/Order/Basic.lean","decl":"pi_Ioc_mem_nhds","line":763,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"order-topology-where-order-closed-suffices","claim":"Assumes `[∀ i, OrderTopology (X i)]`, but the proof only uses `Ioc_mem_nhds`, which needs `LinearOrder` + `OrderClosedTopology` (implied by `OrderClosedTopology`; strictly weaker than `OrderTopology`, e.g. any linear order with the discrete topology). The same holds for the `to_dual`-generated dual. Neither has a consumer in Mathlib (git grep of pi_I.._mem_nhds outside this file is empty), so weakening costs nothing.","fix":"Weaken the Pi-section variable (L733-734) to `[∀ i, OrderClosedTopology (X i)]` / `[OrderClosedTopology α]` (only `ClosedIciTopology` is needed for the Iic/Iio lemmas), and optionally move the section to Topology/Order/OrderClosed.lean beside `Icc_mem_nhds`.","ev":"hunts/topology-order-basic/batch5/probe1.lean §B (compiles):\nexample [Nonempty ι] [∀ i, OrderClosedTopology (X i)] (ha : ∀ i, a i < x i)\n    (hb : ∀ i, x i < b i) : Ioc a b ∈ 𝓝 x := by\n  refine mem_of_superset (set_pi_mem_nhds Set.finite_univ fun i _ => ?_) (pi_univ_Ioc_subset a b)\n  exact Ioc_mem_nhds (ha i) (hb i)\nand hunts/topology-order-basic/batch5/src_gen.lean = src.lean with the Pi-section variable (L733-734) changed to `[OrderClosedTopology α] ... [∀ i, OrderClosedTopology (X i)]`; the whole file compiles (exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-13051e","file":"Mathlib/Topology/Order/Basic.lean","decl":"pi_Ioc_mem_nhds","line":763,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"to-dual-missing-reorder","claim":"Plain `@[to_dual]` (no `(reorder := ha hb)`) generates `pi_Ico_mem_nhds : (∀ i, x i < a i) → (∀ i, b i < x i) → Ico b a ∈ 𝓝 x`, which takes the UPPER-bound hypothesis first. The scalar `Ico_mem_nhds` (from `Ioc_mem_nhds` with `to_dual (reorder := ha hb)`) and `pi_Icc_mem_nhds`/`pi_Ioo_mem_nhds` take the lower bound first, so `pi_Ico_mem_nhds h₁ h₂` does not match `Ico_mem_nhds h₁ h₂`. `pi_Ico_mem_nhds'` has the same problem.","fix":"Tag `pi_Ioc_mem_nhds` (and `pi_Ioc_mem_nhds'`) with `@[to_dual (reorder := ha hb)]`, like `Ioc_mem_nhds`.","ev":"hunts/topology-order-basic/batch5/probe1.lean §A `#check` output:\n@pi_Ico_mem_nhds : ... [Nonempty ι], (∀ (i : ι), x i < a i) → (∀ (i : ι), b i < x i) → Ico b a ∈ 𝓝 x\n@Ico_mem_nhds : ... {a b x : α}, b < x → x < a → Ico b a ∈ 𝓝 x\nWith `@[to_dual (reorder := ha hb)]` (in hunts/topology-order-basic/batch5/src_gen.lean, compiles) the output becomes `(∀ (i : ι), b i < x i) → (∀ (i : ι), x i < a i) → Ico b a ∈ 𝓝 x`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-afcf03","file":"Mathlib/Topology/Order/Basic.lean","decl":"pi_Ioc_mem_nhds'","line":768,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"order-topology-where-order-closed-suffices","claim":"Assumes `[OrderTopology α]`, but the proof only uses `Ioc_mem_nhds`, which needs `LinearOrder` + `OrderClosedTopology` (implied by `OrderClosedTopology`; strictly weaker than `OrderTopology`, e.g. any linear order with the discrete topology). The same holds for the `to_dual`-generated dual. Neither has a consumer in Mathlib (git grep of pi_I.._mem_nhds outside this file is empty), so weakening costs nothing.","fix":"Weaken the Pi-section variable (L733-734) to `[∀ i, OrderClosedTopology (X i)]` / `[OrderClosedTopology α]` (only `ClosedIciTopology` is needed for the Iic/Iio lemmas), and optionally move the section to Topology/Order/OrderClosed.lean beside `Icc_mem_nhds`.","ev":"hunts/topology-order-basic/batch5/src_gen.lean = src.lean with the Pi-section variable (L733-734) changed to `[OrderClosedTopology α] ... [∀ i, OrderClosedTopology (X i)]`; the whole file compiles (exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-1cde6c","file":"Mathlib/Topology/Order/Basic.lean","decl":"pi_Ioc_mem_nhds'","line":768,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"redundant-nondependent-pi-variant","claim":"`pi_Ioc_mem_nhds'` is `pi_Ioc_mem_nhds` restated for a constant family (its proof is `pi_Ioc_mem_nhds ..`). The section note says it exists because Lean sometimes fails to unify when applying the dependent version to `ι → ℝ`, but `pi_Ioc_mem_nhds` and the other dependent lemmas now apply to `ι → ℝ`, `Fin 3 → ℝ` and `ι → α` directly (term, `apply`, `filter_upwards`), even with the order instance taken through `Lattice` and the topology through the sup pseudo-metric. No primed lemma or its dual is used anywhere in Mathlib. (Its generated dual `pi_Ico_mem_nhds'` also takes the upper-bound hypothesis first because `(reorder := ha hb)` is missing; see the finding on `pi_Ioc_mem_nhds`.)","fix":"Deprecate `pi_Ioc_mem_nhds'` (and its `to_dual` image) in favour of `pi_Ioc_mem_nhds`, and delete the section note's justification.","ev":"hunts/topology-order-basic/batch5/probe1.lean §C (compiles, exit 0), e.g.\nvariable {ι : Type*} [Fintype ι] [Nonempty ι] {a b x : ι → ℝ}\nexample (ha : ∀ i, x i < a i) : Iic a ∈ 𝓝 x := pi_Iic_mem_nhds ha\nexample (ha : ∀ i, a i < x i) (hb : ∀ i, x i < b i) : Ioo a b ∈ 𝓝 x := by\n  apply pi_Ioo_mem_nhds <;> assumption\nexample (ha : ∀ i, x i < a i) : ∀ᶠ y in 𝓝 x, y ≤ a := by\n  filter_upwards [pi_Iic_mem_nhds ha] with y hy using hy\nexample (x a : Fin 3 → ℝ) (ha : ∀ i, x i < a i) : Iic a ∈ 𝓝 x := pi_Iic_mem_nhds ha\n-- order via `Lattice.toSemilatticeSup`, topology via the sup pseudo-metric on ι → ℝ:\nexample (ha : ∀ i, x i < a i) :\n    @Iic (ι → ℝ) (@PartialOrder.toPreorder _\n      (@SemilatticeSup.toPartialOrder _ (@Lattice.toSemilatticeSup _ inferInstance))) a ∈\n      @nhds (ι → ℝ) (@UniformSpace.toTopologicalSpace _\n        (@PseudoMetricSpace.toUniformSpace _ inferInstance)) x :=\n  pi_Iic_mem_nhds ha\n(all eight dependent lemmas Iic/Ici/Icc/Iio/Ioi/Ioc/Ioo checked on ι → ℝ). Measured: `git grep -nE \"pi_I(c|o)[a-z]_mem_nhds\" origin/master -- Mathlib MathlibTest Archive Counterexamples` hits only this file.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-ddb490","file":"Mathlib/Topology/Order/Basic.lean","decl":"pi_Ioo_mem_nhds","line":772,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"order-topology-where-order-closed-suffices","claim":"Assumes `[∀ i, OrderTopology (X i)]`, but the proof only uses `Ioo_mem_nhds`, which needs `LinearOrder` + `OrderClosedTopology` (implied by `OrderClosedTopology`; strictly weaker than `OrderTopology`, e.g. any linear order with the discrete topology). The same holds for the `to_dual`-generated dual. Neither has a consumer in Mathlib (git grep of pi_I.._mem_nhds outside this file is empty), so weakening costs nothing.","fix":"Weaken the Pi-section variable (L733-734) to `[∀ i, OrderClosedTopology (X i)]` / `[OrderClosedTopology α]` (only `ClosedIciTopology` is needed for the Iic/Iio lemmas), and optionally move the section to Topology/Order/OrderClosed.lean beside `Icc_mem_nhds`.","ev":"hunts/topology-order-basic/batch5/probe1.lean §B (compiles):\nexample [Nonempty ι] [∀ i, OrderClosedTopology (X i)] (ha : ∀ i, a i < x i)\n    (hb : ∀ i, x i < b i) : Ioo a b ∈ 𝓝 x := by\n  refine mem_of_superset (set_pi_mem_nhds Set.finite_univ fun i _ => ?_) (pi_univ_Ioo_subset a b)\n  exact Ioo_mem_nhds (ha i) (hb i)\nand hunts/topology-order-basic/batch5/src_gen.lean = src.lean with the Pi-section variable (L733-734) changed to `[OrderClosedTopology α] ... [∀ i, OrderClosedTopology (X i)]`; the whole file compiles (exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-ce5665","file":"Mathlib/Topology/Order/Basic.lean","decl":"pi_Ioo_mem_nhds'","line":777,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"order-topology-where-order-closed-suffices","claim":"Assumes `[OrderTopology α]`, but the proof only uses `Ioo_mem_nhds`, which needs `LinearOrder` + `OrderClosedTopology` (implied by `OrderClosedTopology`; strictly weaker than `OrderTopology`, e.g. any linear order with the discrete topology). The same holds for the `to_dual`-generated dual. Neither has a consumer in Mathlib (git grep of pi_I.._mem_nhds outside this file is empty), so weakening costs nothing.","fix":"Weaken the Pi-section variable (L733-734) to `[∀ i, OrderClosedTopology (X i)]` / `[OrderClosedTopology α]` (only `ClosedIciTopology` is needed for the Iic/Iio lemmas), and optionally move the section to Topology/Order/OrderClosed.lean beside `Icc_mem_nhds`.","ev":"hunts/topology-order-basic/batch5/src_gen.lean = src.lean with the Pi-section variable (L733-734) changed to `[OrderClosedTopology α] ... [∀ i, OrderClosedTopology (X i)]`; the whole file compiles (exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-be19f9","file":"Mathlib/Topology/Order/Basic.lean","decl":"pi_Ioo_mem_nhds'","line":777,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"redundant-nondependent-pi-variant","claim":"`pi_Ioo_mem_nhds'` is `pi_Ioo_mem_nhds` restated for a constant family (its proof is `pi_Ioo_mem_nhds ..`). The section note says it exists because Lean sometimes fails to unify when applying the dependent version to `ι → ℝ`, but `pi_Ioo_mem_nhds` and the other dependent lemmas now apply to `ι → ℝ`, `Fin 3 → ℝ` and `ι → α` directly (term, `apply`, `filter_upwards`), even with the order instance taken through `Lattice` and the topology through the sup pseudo-metric. No primed lemma or its dual is used anywhere in Mathlib.","fix":"Deprecate `pi_Ioo_mem_nhds'` (and its `to_dual` image) in favour of `pi_Ioo_mem_nhds`, and delete the section note's justification.","ev":"hunts/topology-order-basic/batch5/probe1.lean §C (compiles, exit 0), e.g.\nvariable {ι : Type*} [Fintype ι] [Nonempty ι] {a b x : ι → ℝ}\nexample (ha : ∀ i, x i < a i) : Iic a ∈ 𝓝 x := pi_Iic_mem_nhds ha\nexample (ha : ∀ i, a i < x i) (hb : ∀ i, x i < b i) : Ioo a b ∈ 𝓝 x := by\n  apply pi_Ioo_mem_nhds <;> assumption\nexample (ha : ∀ i, x i < a i) : ∀ᶠ y in 𝓝 x, y ≤ a := by\n  filter_upwards [pi_Iic_mem_nhds ha] with y hy using hy\nexample (x a : Fin 3 → ℝ) (ha : ∀ i, x i < a i) : Iic a ∈ 𝓝 x := pi_Iic_mem_nhds ha\n-- order via `Lattice.toSemilatticeSup`, topology via the sup pseudo-metric on ι → ℝ:\nexample (ha : ∀ i, x i < a i) :\n    @Iic (ι → ℝ) (@PartialOrder.toPreorder _\n      (@SemilatticeSup.toPartialOrder _ (@Lattice.toSemilatticeSup _ inferInstance))) a ∈\n      @nhds (ι → ℝ) (@UniformSpace.toTopologicalSpace _\n        (@PseudoMetricSpace.toUniformSpace _ inferInstance)) x :=\n  pi_Iic_mem_nhds ha\n(all eight dependent lemmas Iic/Ici/Icc/Iio/Ioi/Ioc/Ioo checked on ι → ℝ). Measured: `git grep -nE \"pi_I(c|o)[a-z]_mem_nhds\" origin/master -- Mathlib MathlibTest Archive Counterexamples` hits only this file.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-39f4ef","file":"Mathlib/Topology/Order/Basic.lean","decl":"LeftOrdContinuous.continuousWithinAt_Iic","line":791,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"conditionally-complete-hypothesis-unneeded","claim":"Assumes `ConditionallyCompleteLinearOrder` + `OrderTopology` on both X and Y. The conclusion holds for any `LinearOrder X` with `ClosedIicTopology X` and any `LinearOrder Y` with `OrderTopology Y`: if `x` is the LUB of the nonempty `Iio x`, LOC plus `IsLUB.exists_between` give `w < x` with `z < f w`; otherwise `𝓝[≤] x` is eventually `{x}`. This covers e.g. ℚ. Its converse `Monotone.leftOrdContinuous` (Topology/Order/Monotone.lean:193) is already stated for plain linear orders, so the weakening also yields `LeftOrdContinuous f ↔ Monotone f ∧ ∀ x, ContinuousWithinAt f (Iic x) x`.","fix":"Restate the section under `[LinearOrder X] [TopologicalSpace X] [LinearOrder Y] [TopologicalSpace Y] [OrderTopology Y]` (adding `[ClosedIicTopology X]` / `[ClosedIciTopology X]` / `[OrderClosedTopology X]` per lemma) with the probe proof, drop 'conditionally complete' from the docstrings, and consider moving the trio next to its converse `Monotone.leftOrdContinuous` in Topology/Order/Monotone.lean together with the iff.","ev":"hunts/topology-order-basic/batch5/probe1.lean §D (L100-134) proves the three lemmas under `[LinearOrder X] [TopologicalSpace X] [LinearOrder Y] [TopologicalSpace Y] [OrderTopology Y]` plus `[ClosedIicTopology X]` / `[ClosedIciTopology X]` / `[OrderClosedTopology X]`:\ntheorem LeftOrdContinuous.continuousWithinAt_Iic' [ClosedIicTopology X]\n    (hf : LeftOrdContinuous f) (x : X) : ContinuousWithinAt f (Iic x) x := by\n  rw [ContinuousWithinAt, tendsto_order]\n  refine ⟨fun z hz => ?_, fun z hz => ?_⟩\n  · by_cases h : (Iio x).Nonempty ∧ IsLUB (Iio x) x\n    · obtain ⟨_, ⟨w, hw, rfl⟩, hzw, -⟩ := (hf h.1 h.2).exists_between hz\n      filter_upwards [Ioc_mem_nhdsLE hw] with t ht using hzw.trans_le (hf.mono ht.1.le)\n    · have : ∀ᶠ t in 𝓝[≤] x, t = x := by\n        rw [not_and_or, not_nonempty_iff_eq_empty] at h\n        rcases h with h | h\n        · filter_upwards [self_mem_nhdsWithin] with t ht\n          exact ht.antisymm (not_lt.1 fun htx => eq_empty_iff_forall_notMem.1 h t htx)\n        · obtain ⟨u, hu, hux⟩ : ∃ u ∈ upperBounds (Iio x), u < x := by\n            by_contra! H\n            exact h ⟨fun _ h => h.le, fun u hu => H u hu⟩\n          filter_upwards [Ioc_mem_nhdsLE hux] with t ht\n          exact ht.2.antisymm (not_lt.1 fun htx => (hu htx).not_gt ht.1)\n      filter_upwards [this] with t ht\n      rwa [ht]\n  · filter_upwards [self_mem_nhdsWithin] with t ht using (hf.mono ht).trans_lt hz\nplus ℚ → ℚ applications: `example (f : ℚ → ℚ) (hl : LeftOrdContinuous f) (hr : RightOrdContinuous f) : Continuous f := by\n  fail_if_success exact Continuous.of_ordContinuous hl hr\n  exact Continuous.of_ordContinuous' hl hr` (compiles), and the iff `LeftOrdContinuous f ↔ Monotone f ∧ ∀ x, ContinuousWithinAt f (Iic x) x := ⟨fun hf => ⟨hf.mono, hf.continuousWithinAt_Iic'⟩, fun h => h.1.leftOrdContinuous h.2⟩` (compiles). hunts/topology-order-basic/batch5/src_gen.lean puts the weakened trio in place of L784-824 (with `@[to_dual existing]` kept) and compiles (exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-3094e6","file":"Mathlib/Topology/Order/Basic.lean","decl":"RightOrdContinuous.continuousWithinAt_Ici","line":814,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"conditionally-complete-hypothesis-unneeded","claim":"Order dual of `LeftOrdContinuous.continuousWithinAt_Iic`, with the same unneeded conditional completeness and `OrderTopology X`: `LinearOrder X` + `ClosedIciTopology X` and `LinearOrder Y` + `OrderTopology Y` suffice (proof `hf.dual.continuousWithinAt_Iic'`).","fix":"Restate the section under `[LinearOrder X] [TopologicalSpace X] [LinearOrder Y] [TopologicalSpace Y] [OrderTopology Y]` (adding `[ClosedIicTopology X]` / `[ClosedIciTopology X]` / `[OrderClosedTopology X]` per lemma) with the probe proof, drop 'conditionally complete' from the docstrings, and consider moving the trio next to its converse `Monotone.leftOrdContinuous` in Topology/Order/Monotone.lean together with the iff.","ev":"hunts/topology-order-basic/batch5/probe1.lean §D (L100-134) proves the three lemmas under `[LinearOrder X] [TopologicalSpace X] [LinearOrder Y] [TopologicalSpace Y] [OrderTopology Y]` plus `[ClosedIicTopology X]` / `[ClosedIciTopology X]` / `[OrderClosedTopology X]`:\ntheorem LeftOrdContinuous.continuousWithinAt_Iic' [ClosedIicTopology X]\n    (hf : LeftOrdContinuous f) (x : X) : ContinuousWithinAt f (Iic x) x := by\n  rw [ContinuousWithinAt, tendsto_order]\n  refine ⟨fun z hz => ?_, fun z hz => ?_⟩\n  · by_cases h : (Iio x).Nonempty ∧ IsLUB (Iio x) x\n    · obtain ⟨_, ⟨w, hw, rfl⟩, hzw, -⟩ := (hf h.1 h.2).exists_between hz\n      filter_upwards [Ioc_mem_nhdsLE hw] with t ht using hzw.trans_le (hf.mono ht.1.le)\n    · have : ∀ᶠ t in 𝓝[≤] x, t = x := by\n        rw [not_and_or, not_nonempty_iff_eq_empty] at h\n        rcases h with h | h\n        · filter_upwards [self_mem_nhdsWithin] with t ht\n          exact ht.antisymm (not_lt.1 fun htx => eq_empty_iff_forall_notMem.1 h t htx)\n        · obtain ⟨u, hu, hux⟩ : ∃ u ∈ upperBounds (Iio x), u < x := by\n            by_contra! H\n            exact h ⟨fun _ h => h.le, fun u hu => H u hu⟩\n          filter_upwards [Ioc_mem_nhdsLE hux] with t ht\n          exact ht.2.antisymm (not_lt.1 fun htx => (hu htx).not_gt ht.1)\n      filter_upwards [this] with t ht\n      rwa [ht]\n  · filter_upwards [self_mem_nhdsWithin] with t ht using (hf.mono ht).trans_lt hz\nplus ℚ → ℚ applications: `example (f : ℚ → ℚ) (hl : LeftOrdContinuous f) (hr : RightOrdContinuous f) : Continuous f := by\n  fail_if_success exact Continuous.of_ordContinuous hl hr\n  exact Continuous.of_ordContinuous' hl hr` (compiles), and the iff `LeftOrdContinuous f ↔ Monotone f ∧ ∀ x, ContinuousWithinAt f (Iic x) x := ⟨fun hf => ⟨hf.mono, hf.continuousWithinAt_Iic'⟩, fun h => h.1.leftOrdContinuous h.2⟩` (compiles). hunts/topology-order-basic/batch5/src_gen.lean puts the weakened trio in place of L784-824 (with `@[to_dual existing]` kept) and compiles (exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-abec06","file":"Mathlib/Topology/Order/Basic.lean","decl":"Continuous.of_ordContinuous","line":819,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"conditionally-complete-hypothesis-unneeded","claim":"Assumes conditionally complete linear orders with order topologies on both sides, but `LinearOrder X` + `OrderClosedTopology X` and `LinearOrder Y` + `OrderTopology Y` suffice. The current lemma does not apply to `f : ℚ → ℚ` (`fail_if_success` succeeds), while the weakened one proves it.","fix":"Restate the section under `[LinearOrder X] [TopologicalSpace X] [LinearOrder Y] [TopologicalSpace Y] [OrderTopology Y]` (adding `[ClosedIicTopology X]` / `[ClosedIciTopology X]` / `[OrderClosedTopology X]` per lemma) with the probe proof, drop 'conditionally complete' from the docstrings, and consider moving the trio next to its converse `Monotone.leftOrdContinuous` in Topology/Order/Monotone.lean together with the iff.","ev":"hunts/topology-order-basic/batch5/probe1.lean §D (L100-134) proves the three lemmas under `[LinearOrder X] [TopologicalSpace X] [LinearOrder Y] [TopologicalSpace Y] [OrderTopology Y]` plus `[ClosedIicTopology X]` / `[ClosedIciTopology X]` / `[OrderClosedTopology X]`:\ntheorem LeftOrdContinuous.continuousWithinAt_Iic' [ClosedIicTopology X]\n    (hf : LeftOrdContinuous f) (x : X) : ContinuousWithinAt f (Iic x) x := by\n  rw [ContinuousWithinAt, tendsto_order]\n  refine ⟨fun z hz => ?_, fun z hz => ?_⟩\n  · by_cases h : (Iio x).Nonempty ∧ IsLUB (Iio x) x\n    · obtain ⟨_, ⟨w, hw, rfl⟩, hzw, -⟩ := (hf h.1 h.2).exists_between hz\n      filter_upwards [Ioc_mem_nhdsLE hw] with t ht using hzw.trans_le (hf.mono ht.1.le)\n    · have : ∀ᶠ t in 𝓝[≤] x, t = x := by\n        rw [not_and_or, not_nonempty_iff_eq_empty] at h\n        rcases h with h | h\n        · filter_upwards [self_mem_nhdsWithin] with t ht\n          exact ht.antisymm (not_lt.1 fun htx => eq_empty_iff_forall_notMem.1 h t htx)\n        · obtain ⟨u, hu, hux⟩ : ∃ u ∈ upperBounds (Iio x), u < x := by\n            by_contra! H\n            exact h ⟨fun _ h => h.le, fun u hu => H u hu⟩\n          filter_upwards [Ioc_mem_nhdsLE hux] with t ht\n          exact ht.2.antisymm (not_lt.1 fun htx => (hu htx).not_gt ht.1)\n      filter_upwards [this] with t ht\n      rwa [ht]\n  · filter_upwards [self_mem_nhdsWithin] with t ht using (hf.mono ht).trans_lt hz\nplus ℚ → ℚ applications: `example (f : ℚ → ℚ) (hl : LeftOrdContinuous f) (hr : RightOrdContinuous f) : Continuous f := by\n  fail_if_success exact Continuous.of_ordContinuous hl hr\n  exact Continuous.of_ordContinuous' hl hr` (compiles), and the iff `LeftOrdContinuous f ↔ Monotone f ∧ ∀ x, ContinuousWithinAt f (Iic x) x := ⟨fun hf => ⟨hf.mono, hf.continuousWithinAt_Iic'⟩, fun h => h.1.leftOrdContinuous h.2⟩` (compiles). hunts/topology-order-basic/batch5/src_gen.lean puts the weakened trio in place of L784-824 (with `@[to_dual existing]` kept) and compiles (exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-4fa72d","file":"Mathlib/Topology/PartialHomeomorph/Defs.lean","decl":"PartialHomeomorph.toFun_eq_coe","line":111,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"alias-proved-twice","claim":"Intended alias proved twice: `PartialHomeomorph.toFun_eq_coe` (Topology.PartialHomeomorph.Defs), `PartialHomeomorph.coe_toPartialEquiv` (Topology.PartialHomeomorph.Defs) state exactly the same thing (Lean-checked); the second name is wanted (e.g. for dot notation) but is re-proved instead of declared with `alias`. Reviewer: Same situation as OpenPartialHomeomorph: toFun_eq_coe and coe_toPartialEquiv belong to intended naming families but are syntactically identical @[simp] rfl lemmas because PartialEquiv's coercion unfolds to toFun. Fix: alias one to the other.","fix":"Declare `PartialHomeomorph.toFun_eq_coe` as an `alias` of `PartialHomeomorph.coe_toPartialEquiv`.","ev":"dupscan/Check.lean: the pair elaborates as each other's statement (all 273 checks pass, exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-dd2e6a","file":"Mathlib/Topology/SeparatedMap.lean","decl":"IsSeparatedMap.comp_left","line":111,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"There is no composition lemma for either notion. `IsSeparatedMap.comp`, saying that `g ∘ f` is separated when `g` and `f` are separated and `f` is continuous, and the analogous `IsLocallyInjective.comp` both take 5 lines. `comp_left` and `comp_right` (each for both notions) are the special cases where one factor is injective, since injective maps are separated and locally injective.","fix":"Add `IsSeparatedMap.comp` and `IsLocallyInjective.comp` (continuous inner map) and derive the `comp_left`/`comp_right` lemmas from them.","ev":"-- hunts/separated-map/P.lean: `theorem IsLocallyInjective.comp' (hg : IsLocallyInjective g) (hf : IsLocallyInjective f) (cont : Continuous f) : IsLocallyInjective (g ∘ f)` and `IsSeparatedMap.comp'` (same shape) compile; `git grep 'IsSeparatedMap.comp\\b\\|IsLocallyInjective.comp\\b'` finds nothing.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6b18c1","file":"Mathlib/Topology/SeparatedMap.lean","decl":"IsLocallyInjective","line":122,"sev":"MINOR","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"`IsLocallyInjective` lacks the API that parallels what `IsSeparatedMap` has: there is no `IsLocallyInjective.pullback`, the analogue of `IsSeparatedMap.pullback` (stability under base change), and no discrete-domain lemma `[DiscreteTopology X] → IsLocallyInjective f`, the analogue of `T2Space.isSeparatedMap`. Each has a 1–4 line proof.","fix":"Add `IsLocallyInjective.pullback` (the `IsSeparatedMap.pullback` proof with the open-diagonal iff) and `DiscreteTopology.isLocallyInjective`.","ev":"-- hunts/separated-map/P2.lean: both statements compile (pullback by the copied proof with `isLocallyInjective_iff_isOpen_diagonal`; discrete by `⟨{x}, isOpen_discrete _, by simp, Set.injOn_singleton _ _⟩`); `#check @IsLocallyInjective.pullback` and `#check @DiscreteTopology.isLocallyInjective` are unknown constants.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-f82c3e","file":"Mathlib/Topology/SeparatedMap.lean","decl":"Function.Injective.IsLocallyInjective","line":124,"sev":"MINOR","status":"confirmed","cat":"naming","pattern":"name-breaks-convention","claim":"Two theorems carry UpperCamelCase names, which Mathlib reserves for Props and types: `Function.Injective.IsLocallyInjective` (L124) and `IsLocallyInjective_iff_isOpenEmbedding` (L147). Dot notation `inj.isLocallyInjective` does not resolve, and the second name is inconsistent with its siblings `isLocallyInjective_iff_nhds`, `isLocallyInjective_iff_isOpen_diagonal` and `isLocallyInjective_iff_isOpenMap`.","fix":"Rename to `Function.Injective.isLocallyInjective` and `isLocallyInjective_iff_isOpenEmbedding`, with deprecated aliases.","ev":"-- hunts/separated-map/P.lean: `example {f : X → Y} (inj : f.Injective) : IsLocallyInjective f := inj.isLocallyInjective` fails (invalid field); `isLocallyInjective_iff_isOpenEmbedding` is an unknown identifier.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-27e12a","file":"Mathlib/Topology/SeparatedMap.lean","decl":"IsSeparatedMap.const_of_comp","line":214,"sev":"MINOR","status":"confirmed","cat":"generality","pattern":"redundant-hypothesis","claim":"`IsSeparatedMap.const_of_comp` (and `constOn_of_comp`) assume `sep : IsSeparatedMap p`, but constancy of a continuous `g` with `p ∘ g` constant on a preconnected space follows from local injectivity of `p` alone: `g` is then locally constant. Separatedness is needed only for `eq_of_comp_eq`, where the two lifts differ. The hypothesis is passed by consumers in `Topology/Covering/Basic.lean` and `Topology/Homotopy/Lifting.lean`.","fix":"Prove `IsLocallyInjective.const_of_comp`/`constOn_of_comp` without `sep` (via `PreconnectedSpace.induction₂'`) and derive the current ones, or drop `sep` from them.","ev":"-- hunts/separated-map/P2.lean: `example ... [PreconnectedSpace A] {p : E → X} {g : A → E} (hp : IsLocallyInjective p) (hg : Continuous g) (h : ∀ a b, p (g a) = p (g b)) (a b : A) : g a = g b` proved in 7 lines by `PreconnectedSpace.induction₂'`; compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-5a4fb7","file":"Mathlib/Topology/VectorBundle/Basic.lean","decl":"Bundle.Pretrivialization.linearMapAt_eq_zero","line":149,"sev":"MINOR","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Bundle.Pretrivialization.linearMapAt_def_of_notMem` (Topology.VectorBundle.Basic), `Bundle.Pretrivialization.linearMapAt_eq_zero` (Topology.VectorBundle.Basic) state exactly the same thing (Lean-checked). Reviewer: These are adjacent, with identical statements and identical proofs (`dite_eq_right hb`). Keep `_def_of_notMem`, which pairs with `_def_of_mem` and with the Trivialization version at line 245. Deprecate linearMapAt_eq_zero (unused).","fix":"Deprecate `Bundle.Pretrivialization.linearMapAt_eq_zero` in favour of `Bundle.Pretrivialization.linearMapAt_def_of_notMem`.","ev":"dupscan/Check.lean: `example := (@Bundle.Pretrivialization.linearMapAt_eq_zero : type_of% @Bundle.Pretrivialization.linearMapAt_def_of_notMem)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup3 item 52, rating MAJOR): These are identical branch computations with identical interfaces and no distinguishing attributes. The proposed survivor preserves both the membership pair and consistency with Trivialization.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-5dff62","file":"Mathlib/Util/ElabWithoutMVars.lean","decl":"elabTermWithoutNewMVars","line":20,"sev":"MINOR","status":"confirmed","cat":"correctness","pattern":"docstring-overstates","claim":"The docstring's guarantee ('ensuring it has no metavariables') does not hold, even for new metavariables. `elabTermWithHoles` filters out `let rec` auxiliary metavariables and only collects expression metavariables, so for `let rec f (n : Nat) : Nat := n; f 0` the returned term has `hasExprMVar = true`, and for `Sort _` it has `hasLevelMVar = true`. The callers (`linarith`, `nlinarith`, `order`) can therefore receive terms with metavariables in these cases. Graded MINOR: unusual arguments, and the docstring and implementation disagree.","fix":"Either check `e.hasMVar` after instantiation (e.g. reuse `Lean.Elab.Tactic.ensureHasNoMVars`/`Expr.ensureHasNoMVars`) or document that only holes reported by `elabTermWithHoles` are rejected.","ev":"-- hunts/elab-without-mvars/P.lean: with `audit_term t := withMainContext do let e ← elabTermWithoutNewMVars `audit_term t; logInfo m!\"expr={e.hasExprMVar}, level={e.hasLevelMVar}\"`, `audit_term (let rec f (n : Nat) : Nat := n; f 0)` logs `expr=true, level=false` and `audit_term (Sort _)` logs `expr=false, level=true`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-01d483","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.ofClass","line":67,"sev":"NIT","status":"confirmed","cat":"api","pattern":"coe-attribute-without-coercion-instance","claim":"`ofClass` is tagged `@[coe]` but no coercion instance uses it. The delaborator therefore prints `AlgEquiv.ofClass f` as `↑f` (`#check (AlgEquiv.ofClass f).symm` shows `(↑f).symm : A₂ ≃ₐ[R] A₁`), yet `↑f` at type `A₁ ≃ₐ[R] A₂` does not elaborate. A goal state copied from the infoview does not compile.","fix":"Either restore `instance : CoeTC F (A ≃ₐ[R] B) := ⟨AlgEquiv.ofClass⟩` or drop `@[coe]` so the printed term round-trips.","ev":"batch0/probe1.lean P1: `#check (AlgEquiv.ofClass f).symm` prints `(↑f).symm : A₂ ≃ₐ[R] A₁`; `example : A₁ ≃ₐ[R] A₂ := ↑f` fails with 'Type mismatch' (probe1.out).","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-1283e9","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.instFunLike","line":107,"sev":"NIT","status":"suspected","cat":"api","pattern":"unexplained-shortcut-instance","claim":"The shortcut `FunLike (A₁ ≃ₐ[R] A₂) A₁ A₂` instance is justified only by 'Helper instance since the coercion is not always found', and that could not be reproduced. It is `with_reducible_and_instances rfl`-equal to `EquivLike.toFunLike` (so there is no diamond). Without it, a copy of Equiv.lean compiles (2.8 s against 2.9 s for the original), and so do three heavy downstream files with `attribute [-instance] AlgEquiv.instFunLike`: Algebra/Algebra/Tower.lean, RingTheory/TensorProduct/Maps.lean (7.3 s against 7.6 s) and Algebra/MvPolynomial/Equiv.lean. `#synth` then falls back to `EquivLike.toFunLike`. Whether any other downstream file needs it is unchecked (that needs a full build). Similar shortcut instances exist for `StarAlgEquiv`, `BialgEquiv` and `CoalgEquiv`.","fix":"Give the docstring a concrete reproducer, or try deleting the instance in a full Mathlib CI run.","ev":"batch0/probe1.lean P4 (`(AlgEquiv.instFunLike : FunLike ..) = EquivLike.toFunLike := by with_reducible_and_instances rfl` compiles); batch0/src_nohelper.lean and src_nohelper_check.lean (instance deleted; whole file compiles; `#synth` -> EquivLike.toFunLike); batch0/ds_Tower.lean, ds_Maps.lean, ds_Equiv.lean (downstream copies with `attribute [-instance] AlgEquiv.instFunLike`, all exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-689304","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.congr_arg","line":120,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"per-type-wrapper-of-dfunlike-lemma","claim":"`AlgEquiv.congr_arg {f} {x x'} : x = x' → f x = f x'` is `DFunLike.congr_arg f` verbatim, which is also its proof. Dot notation on the hypothesis cannot reach it. It has 1 external use (FieldTheory/Finite/Extension.lean:150). It belongs to the uniform per-type wrapper API (`RingEquiv.congr_arg` Ring/Equiv.lean:151), hence only a NIT.","fix":"Optional: deprecate in favour of `DFunLike.congr_arg` together with the other per-type copies.","ev":"batch0/probe1.lean P3: `example {f : A₁ ≃ₐ[R] A₂} {x x' : A₁} : x = x' → f x = f x' := DFunLike.congr_arg f` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7d0078","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.congr_fun","line":123,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"per-type-wrapper-of-dfunlike-lemma","claim":"`AlgEquiv.congr_fun {f g} (h : f = g) (x) : f x = g x` is `DFunLike.congr_fun h x` verbatim. It is proved by `congr($h x)`, whereas `RingEquiv.congr_fun` is proved by `DFunLike.congr_fun h x`. It has 2 external uses (Algebra/Tower.lean:259, Star/StarAlgHom.lean:849). It belongs to the uniform per-type wrapper API, hence only a NIT.","fix":"Optional: deprecate in favour of `DFunLike.congr_fun` together with the other per-type copies (or at least prove it by `DFunLike.congr_fun h x`).","ev":"batch0/probe1.lean P3: `example {f g : A₁ ≃ₐ[R] A₂} (h : f = g) (x : A₁) : f x = g x := DFunLike.congr_fun h x` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-5738f9","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.coe_fun_injective","line":147,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"inconsistent-coe-injective-name","claim":"`coe_fun_injective` is the only lemma of that name in Mathlib. The sibling types use `coe_fn_injective` (`AlgHom.coe_fn_injective` Hom.lean:182, `Equiv.coe_fn_injective` Logic/Equiv/Defs.lean:115) or `coe_injective` (`LinearEquiv.coe_injective` Module/Equiv/Defs.lean:184).","fix":"If kept, rename to `coe_injective` (or `coe_fn_injective`, to match `AlgHom`) with a deprecated alias.","ev":"git grep -n 'theorem coe_fun_injective\\|theorem coe_fn_injective\\|theorem coe_injective' origin/master -- Mathlib/Algebra/Algebra/Hom.lean Mathlib/Logic/Equiv/Defs.lean Mathlib/Algebra/Module/Equiv/Defs.lean","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7d1ded","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.coe_toAlgHom","line":201,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"stray-whitespace","claim":"Line 201 has a double space after the colon: `theorem coe_toAlgHom :  DFunLike.coe e.toAlgHom = e := rfl`.","fix":"Delete the extra space.","ev":"sed -n 201p src.lean -> `theorem coe_toAlgHom :  DFunLike.coe e.toAlgHom = e := rfl`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c8bca7","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.coe_toAlgHom_injective","line":203,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-inconsistent-with-siblings","claim":"The statement is `Function.Injective AlgEquiv.toAlgHom` (pp.coercions false), injectivity of `toAlgHom` itself. The `coe_` prefix suggests injectivity of `fun e => ⇑e.toAlgHom` (the `coe_toAlgHom` shape). It also breaks the file's own scheme: on the same date (2026-05-05) `coe_ringEquiv_injective` became `toRingEquiv_injective`, but `coe_algHom_injective` became `coe_toAlgHom_injective`; the siblings are `toLinearEquiv_injective` and `toLinearMap_injective`. `AlgEquiv.toAlgHom_injective` is unused (git grep). It has 30 references.","fix":"Rename to `AlgEquiv.toAlgHom_injective` with a deprecated alias `coe_toAlgHom_injective`.","ev":"hunts/algequiv/batch1/probe1.lean (P1): `#check @AlgEquiv.coe_toAlgHom_injective` prints `Function.Injective AlgEquiv.toAlgHom`; `git grep -nw 'coe_toAlgHom_injective\\|coe_algHom_injective' origin/master -- Mathlib | wc -l` = 30; `git grep toAlgHom_injective` finds only `MulSemiringAction.toAlgHom_injective`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a51379","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.toRingHom_toAlgHom","line":213,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-wording","claim":"The docstring 'The two paths coercion can take to a `RingHom` are equivalent' calls an equality 'equivalent' and has no final period.","fix":"Change it to 'The two coercion paths from `A₁ ≃ₐ[R] A₂` to `A₁ →+* A₂` agree.'","ev":"sed -n 213p src.lean","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-e88518","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.toRingHom_toAlgHom","line":214,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"confusing-reversed-name","claim":"`toRingHom_toAlgHom` and the simp lemma `toAlgHom_toRingHom` (L210) have reversed names but the same left side, `RingHomClass.toRingHom e.toAlgHom`. They differ only on the right (`… e.toRingEquiv` here, `… e` there). The name describes neither side in the file's dot-order convention (`toAlgHom_toRingHom` = `e.toAlgHom.toRingHom`), and the pair is easy to mix up.","fix":"Rename it to describe the equation, for example `toAlgHom_toRingHom_eq_toRingEquiv_toRingHom`, or deprecate it as in the reuse finding.","ev":"hunts/algequiv/batch1/probe1.lean (P1, pp.coercions false): toAlgHom_toRingHom : `RingHomClass.toRingHom e.toAlgHom = RingHomClass.toRingHom e`; toRingHom_toAlgHom : `RingHomClass.toRingHom e.toAlgHom = RingHomClass.toRingHom e.toRingEquiv`; P2 `c1.type == c2.type` = false","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d35127","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.refl","line":242,"sev":"NIT","status":"confirmed","cat":"api","pattern":"implicit-args-inconsistent-with-siblings","claim":"`AlgEquiv.refl` takes every argument implicitly (`{R} {A₁} … : A₁ ≃ₐ[R] A₁`). The sibling identity morphisms take theirs explicitly: `RingEquiv.refl (R)`, `LinearEquiv.refl (R M)`, `StarAlgEquiv.refl` (`variable (R A) in`), `AlgHom.id R A`. Callers therefore write type ascriptions: 9 of the 54 `AlgEquiv.refl` occurrences in Mathlib are `(AlgEquiv.refl : _ ≃ₐ[_] _)`.","fix":"Long-established and widely used, so record it only; if it is ever touched, make `R` and `A₁` explicit to match `AlgHom.id R A`.","ev":"hunts/algequiv/batch1/probe1.lean (P11): `#check @AlgEquiv.refl` = `{R : Type u_4} → {A₁ : Type u_5} → … → A₁ ≃ₐ[R] A₁`; `#check @RingEquiv.refl` = `(R : Type u_4) → … → R ≃+* R`; `#check @LinearEquiv.refl` = `(R) → (M) → …`; git grep: 54 `AlgEquiv.refl`, 9 `(AlgEquiv.refl : `, 0 named-argument uses.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-5f429c","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.symm","line":261,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"tactic-proof-golfable-to-term","claim":"The `commutes'` field is proved by a three-step `rw [← symm_apply_apply …]; congr; simp` (an unstructured `congr` followed by a closing `simp`). The one-term proof `e.toRingEquiv.symm_apply_eq.2 (e.commutes r).symm` works: the whole file compiles with it and gives no warnings.","fix":"Use `commutes' := fun r => e.toRingEquiv.symm_apply_eq.2 (e.commutes r).symm`.","ev":"hunts/algequiv/batch1/symm_golf.lean (copy of src.lean with that one replacement; exit 0, no output)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6be2f7","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.symm_toEquiv_eq_symm","line":290,"sev":"NIT","status":"confirmed","cat":"api","pattern":"implicit-arg-on-equation-lemma","claim":"`symm_toEquiv_eq_symm` takes `e` implicitly, so `symm_toEquiv_eq_symm e` does not elaborate (\"Function expected\"), whereas the MulEquiv/RingEquiv/LinearEquiv analogues take it explicitly. It is also oriented against its siblings. `MulEquiv.toEquiv_symm`, `RingEquiv.coe_toEquiv_symm` and `LinearEquiv.toEquiv_symm` (all @[simp]) push the Equiv coercion inside `symm`, but this lemma pulls it out, so the Equiv-level simp normal form of `symm` differs between AlgEquiv and its parents. The docstring itself is accurate: simp proves `invFun_eq_symm` only with this lemma.","fix":"Make `e` explicit, as in `MulEquiv.coe_toEquiv_symm (f : M ≃* N)`; the direction can stay, but note the deliberate difference from `RingEquiv.coe_toEquiv_symm` in the docstring.","ev":"batch2/probe2.lean S4 `example (e : A₁ ≃ₐ[R] A₂) : (e : A₁ ≃ A₂).symm = e.symm := symm_toEquiv_eq_symm e` -> error `Function expected at symm_toEquiv_eq_symm`; batch2/probe1.lean #check: `(EquivLike.toEquiv e).symm = EquivLike.toEquiv e.symm` versus `RingEquiv.coe_toEquiv_symm : EquivLike.toEquiv e.symm = (EquivLike.toEquiv e).symm`; D1a `e.invFun = e.symm := by simp` compiles, D1b with `[-AlgEquiv.symm_toEquiv_eq_symm]` fails.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-beff15","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.toRingEquiv_symm","line":315,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"swapped-to-symm-lemma-names","claim":"The names of the symm-coercion lemmas are swapped relative to Mathlib's `toX_symm : e.symm.toX = e.toX.symm` convention. That convention is followed by `StarRingEquiv.toRingEquiv_symm`, `MulEquiv.toEquiv_symm`, `LinearEquiv.toEquiv_symm` and this file's own `AlgEquiv.toLinearEquiv_symm` (L520). Here `AlgEquiv.toRingEquiv_symm` (L315) states the reverse, `e.toRingEquiv.symm = ↑e.symm`. The convention's statement is called `symm_toRingEquiv` (L319), and likewise `symm_toAddEquiv` (L323) and `symm_toMulEquiv` (L327). RingEquiv names the latter two `coe_toAddEquiv_symm`/`coe_toMulEquiv_symm`.","fix":"After deprecating `toRingEquiv_symm`, rename `symm_toRingEquiv`/`symm_toAddEquiv`/`symm_toMulEquiv` to `toRingEquiv_symm`/`toAddEquiv_symm`/`toMulEquiv_symm`, keeping deprecated aliases.","ev":"measured by grep on origin/master: Mathlib/Algebra/Star/StarRingHom.lean:365 `theorem toRingEquiv_symm (e : A ≃⋆+* B) : e.symm.toRingEquiv = e.toRingEquiv.symm`; Mathlib/Algebra/Module/Equiv/Defs.lean:281 `theorem toEquiv_symm : e.symm.toEquiv = e.toEquiv.symm`; Mathlib/Algebra/Group/Equiv/Defs.lean:299 `theorem toEquiv_symm (f : M ≃* N) : (f.symm : N ≃ M) = (f : M ≃ N).symm`; Equiv.lean:520 `toLinearEquiv_symm : e.symm.toLinearEquiv = e.toLinearEquiv.symm` versus Equiv.lean:315 `toRingEquiv_symm : (e : A₁ ≃+* A₂).symm = e.symm` and :319 `symm_toRingEquiv : (e.symm : A₂ ≃+* A₁) = (e : A₁ ≃+* A₂).symm`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d3b05d","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.trans","line":389,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"unexplained-show-defeq","claim":"The `commutes'` field of `trans` is proved with an unexplained term-mode `show e₂.toFun (e₁.toFun _) = _ by rw [e₁.commutes', e₂.commutes']`. That proof depends on how the structure instance's `toFun` unfolds by defeq. Plain `commutes' r := by simp` works, and so does the term `(e₂.toAlgHom.comp e₁.toAlgHom).commutes`.","fix":"Replace the field's proof with `commutes' r := by simp`, or add a comment explaining the `show`.","ev":"hunts/algequiv/batch3/probe2_src.lean is src.lean with line 389 replaced by `commutes' r := by simp }`; the whole file compiles. hunts/algequiv/batch3/probe1.lean section (6) also compiles both `commutes' := (e₂.toAlgHom.comp e₁.toAlgHom).commutes` and `commutes' r := by simp`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-000e75","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.toLinearMap_ofAlgHom","line":544,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-could-be-rfl","claim":"The proof `LinearMap.ext fun _ => rfl` can be a bare `rfl`, like its neighbours `toAlgHom_ofAlgHom` and `toLinearMap_ofBijective`.","fix":"Replace `LinearMap.ext fun _ => rfl` with `rfl`.","ev":"hunts/algequiv/batch4/probe1.lean (P4): `example (φ : A₁ →ₐ[R] A₂) (ψ : A₂ →ₐ[R] A₁) (h₁ h₂) : (ofAlgHom φ ψ h₁ h₂).toLinearMap = φ.toLinearMap := rfl` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b02b03","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.toLinearEquiv_toLinearMap","line":548,"sev":"NIT","status":"confirmed","cat":"api","pattern":"reducible-rfl-fold-lemma","claim":"`toLinearEquiv_toLinearMap : e.toLinearEquiv.toLinearMap = e.toLinearMap` is `X = X` up to reducible unfolding. `toLinearMap` is an `abbrev` whose body is exactly the LHS, so the lemma is `(AlgEquiv.toLinearMap.eq_1 e).symm` and holds by `with_reducible rfl`, and `simp` proves it. It is purely a fold lemma for `rw`, used once in Mathlib (RingTheory/DedekindDomain/Different.lean:522, inside `simp only`). This is the reducible-transparency version of `toAlgHom_eq_coe` and `toRingEquiv_eq_coe`, which the file deprecated as 'Now a syntactic equality'. It is harmless and not a correctness issue: the name says exactly what it states.","fix":"Either add a comment marking it as the fold direction of the `abbrev`, or deprecate it like `toAlgHom_eq_coe`, with the one use switched to unfolding `AlgEquiv.toLinearMap`.","ev":"hunts/algequiv/batch4/probe1.lean (P1): `example (e : A₁ ≃ₐ[R] A₂) : e.toLinearEquiv.toLinearMap = e.toLinearMap := by with_reducible rfl` compiles; (P3c) `:= by simp` compiles. hunts/algequiv/batch4/probe3.lean (R2): `:= (AlgEquiv.toLinearMap.eq_1 e).symm` compiles; `#print AlgEquiv.toLinearMap` shows `@[reducible] def ... := fun e ↦ ↑↑e`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-436298","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.toLinearMap_apply","line":552,"sev":"NIT","status":"confirmed","cat":"api","pattern":"redundant-simp-attribute","claim":"The `@[simp]` attribute is redundant with generic lemmas. Because `toLinearMap` is an `abbrev`, `simp` proves `e.toLinearMap x = e x` without this lemma, using `LinearEquiv.coe_coe` (simp, Mathlib/Algebra/Module/Equiv/Defs.lean:205) and the `simps`-generated `AlgEquiv.toLinearEquiv_apply`. The lemma itself is still a reasonable `rw` lemma.","fix":"Optional: drop `@[simp]` (keeping the lemma), since simp already reaches `e x` through `LinearEquiv.coe_coe` and `toLinearEquiv_apply`.","ev":"hunts/algequiv/batch4/probe1.lean (P2g/P2g'): `example : e.toLinearMap x = e x := by simp [-toLinearMap_apply]` compiles; `simp?` suggests `simp only [LinearEquiv.coe_coe, toLinearEquiv_apply]`. hunts/algequiv/batch4/probe3.lean (R3): that `simp only` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-82b688","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.trans_toLinearMap","line":559,"sev":"NIT","status":"confirmed","cat":"api","pattern":"simp-rhs-not-simp-normal","claim":"The `@[simp]` right-hand side `g.toLinearMap.comp f.toLinearMap` is not in simp-normal form. Through the abbrev, the generic simp lemma `LinearEquiv.comp_coe : ↑f' ∘ₛₗ ↑f = ↑(f.trans f')` folds it straight back, so `simp` turns `(f.trans g).toLinearMap` into `↑(↑f ≪≫ₗ ↑g)` (`simp?` reports `simp only [trans_toLinearMap, LinearEquiv.comp_coe]`), never into the stated RHS. On equality goals `simp` also proves the lemma without it, via `LinearEquiv.comp_coe`, `LinearEquiv.toLinearMap_inj` and `toLinearEquiv_trans`.","fix":"Choose one normal form: either state the simp RHS as `(f.toLinearEquiv.trans g.toLinearEquiv).toLinearMap` and keep the `∘ₗ` form as a non-simp `rw` lemma, or document that `simp` will not produce the composition.","ev":"hunts/algequiv/batch4/probe3.lean (R1): `example (P : (A₁ →ₗ[R] A₃) → Prop) (h : P (f.toLinearEquiv.trans g.toLinearEquiv).toLinearMap) : P (f.trans g).toLinearMap := by simp; exact h` compiles, and trace_state shows `⊢ P ↑((↑f).trans ↑g)`. hunts/algequiv/batch4/probe2.lean (Q1): `simp? [-trans_toLinearMap]` closes the lemma with `simp only [LinearEquiv.comp_coe, LinearEquiv.toLinearMap_inj, toLinearEquiv_trans]`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c8f0cc","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.ofBijective","line":576,"sev":"NIT","status":"confirmed","cat":"generality","pattern":"concrete-hom-instead-of-hom-class","claim":"`ofBijective` takes a concrete `f : A₁ →ₐ[R] A₂`, whereas its direct analogues `RingEquiv.ofBijective` (`[NonUnitalRingHomClass F R S] (f : F)`) and `MulEquiv.ofBijective` (`[MulHomClass F M N] (f : F)`) take any hom class. The version with `{F} [FunLike F A₁ A₂] [AlgHomClass F R A₁ A₂] (f : F)`, defined as `{ RingEquiv.ofBijective f hf with commutes' := AlgHomClass.commutes f }`, compiles together with all its lemmas (`coe_ofBijective`, `ofBijective_apply`, `toLinearMap_ofBijective`, `toAlgHom_ofBijective` with RHS `AlgHom.ofClass f`, and both `symm`/`apply` lemmas) in a copy of the file, which is simpNF-clean. On `AlgHom`s it is definitionally the current one (`rfl`). Downstream elaboration was not checked.","fix":"Generalise `ofBijective` and its lemmas to `(f : F)` with `[FunLike F A₁ A₂] [AlgHomClass F R A₁ A₂]`, as in `RingEquiv.ofBijective`.","ev":"hunts/algequiv/batch4/copy2.lean (src.lean with the generalised `ofBijective` section, plus `#lint only simpNF synTaut unusedArguments`) compiles with 'All linting checks passed'. hunts/algequiv/batch4/probe1.lean (P5): `example (φ : A₁ →ₐ[R] A₂) (hφ : Function.Bijective φ) : ofBijective' φ hφ = ofBijective φ hφ := rfl` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6b2d8b","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.ofLinearEquiv_symm.aux","line":620,"sev":"NIT","status":"confirmed","cat":"api","pattern":"obsolete-aux-def-for-simp-lemma","claim":"The auxiliary def is unnecessary, and it causes the simp dead end in `ofLinearEquiv_symm` (next finding). If the right-hand side's proof arguments are stated with types `l.symm 1 = 1` and `∀ x y, l.symm (x * y) = l.symm x * l.symm y` (proofs via `l.symm_apply_eq`), they never mention the left-hand side, so there is nothing to loop on. With that restatement as the simp lemma, `simp` terminates on `(ofLinearEquiv l h1 hm).symm.symm.symm (l y) = y` and closes it. The docstring's stated purpose (\"avoid looping in dsimp\") no longer needs this def.","fix":"Delete `ofLinearEquiv_symm.aux` (deprecated) after restating `ofLinearEquiv_symm` with proof arguments typed in terms of `l.symm`.","ev":"hunts/algequiv/batch5/probe3.lean (P13): theorem ofLinearEquiv_symm₂ ... := rfl with RHS `ofLinearEquiv l.symm (l.symm_apply_eq.mpr h1.symm) (fun x y => l.symm_apply_eq.mpr (by rw [hm, l.apply_symm_apply, l.apply_symm_apply]))`; attribute [-simp] ofLinearEquiv_symm; attribute [local simp] ofLinearEquiv_symm₂; example ... : (ofLinearEquiv l h1 hm).symm.symm.symm (l y) = y := by simp","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-74757c","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.ofLinearEquiv_toLinearEquiv","line":631,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"swapped-binder-names","claim":"The binder names are swapped relative to their types. The lemma reads `(map_mul : ↑e 1 = 1) (map_one : ∀ x y, ↑e (x * y) = ↑e x * ↑e y)`, so the natural named-argument call `(map_one := h1) (map_mul := hm)` fails to elaborate; only the swapped form works.","fix":"Write the binders as `(map_one) (map_mul)`, matching the order of `ofLinearEquiv`'s arguments.","ev":"hunts/algequiv/batch5/probe1.lean (P3): #check @AlgEquiv.ofLinearEquiv_toLinearEquiv  -- (map_mul : ↑e 1 = 1) (map_one : ∀ (x y : A₁), ↑e (x * y) = ↑e x * ↑e y)\nexample ... := by fail_if_success exact AlgEquiv.ofLinearEquiv_toLinearEquiv e (map_one := h1) (map_mul := hm); exact AlgEquiv.ofLinearEquiv_toLinearEquiv e (map_mul := h1) (map_one := hm)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-35477b","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.coe_pow","line":676,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"hand-rolled-induction-instead-of-hom-coe-pow","claim":"The proof is a hand-rolled `n.rec` with two `ext; simp` steps. The generic `hom_coe_pow` (Mathlib/Algebra/Group/Basic.lean:1065) proves it in one term, as it already does for `LinearEquiv.coe_pow` and `StarAlgEquiv.coe_pow`.","fix":"Replace the proof with `hom_coe_pow _ rfl (fun _ _ ↦ rfl) _ _`.","ev":"hunts/algequiv/batch5/probe1.lean (P8): example (e : A ≃ₐ[R] A) (n : ℕ) : ⇑(e ^ n) = e^[n] := hom_coe_pow _ rfl (fun _ _ ↦ rfl) _ _","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-86c064","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.instMulDistribMulActionUnits","line":730,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"hand-rolled-instance-has-combinator","claim":"The 5-line instance body re-implements Mathlib's combinator `Units.mulDistribMulActionRight : MulDistribMulAction M Nˣ` (Mathlib/Algebra/Group/Action/Units.lean:150, an abbrev built from `MulDistribMulAction M N`, here supplied by `applyMulSemiringAction`). The two are defeq at default transparency (`rfl` succeeds; `with_reducible_and_instances rfl` does not). Replacing the body with the combinator compiles in a copy of the file, and `smul_units_def` still holds by `rfl`. There is no diamond: `Units.mulAction'` would need `IsScalarTower (R ≃ₐ[R] R) R R`, which fails to synthesize. Downstream files were not rebuilt.","fix":"Define the instance as `Units.mulDistribMulActionRight`, and do the same for the `AlgHom` twin in Mathlib/Algebra/Algebra/Hom.lean:511.","ev":"probe1.lean L30-31: example : (inferInstance : MulDistribMulAction (A ≃ₐ[R] A) Aˣ) = Units.mulDistribMulActionRight (M := A ≃ₐ[R] A) (N := A) := rfl  -- compiles; Equiv_fix.lean: `instance : MulDistribMulAction (A₁ ≃ₐ[R] A₁) A₁ˣ := Units.mulDistribMulActionRight`, with `smul_units_def := rfl` unchanged, compiles; probe4.lean: IsScalarTower (R ≃ₐ[R] R) R R fails to synthesize (hunts/algequiv/batch6/","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-70d705","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.algHomUnitsEquiv","line":775,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"uncommented-show","claim":"`left_inv` and `right_inv` are proved by `show (↑(f⁻¹ * f) : S →ₐ[R] S) x = x by rw [inv_mul_cancel]; rfl` (and the symmetric form): an uncommented `show` that relies on defeq, followed by `rw`, then `rfl`. The terms `DFunLike.congr_fun f.inv_mul` and `DFunLike.congr_fun f.mul_inv` are enough.","fix":"Replace the two fields with `left_inv := DFunLike.congr_fun f.inv_mul` and `right_inv := DFunLike.congr_fun f.mul_inv`.","ev":"probe1.lean L73-78: example (R S : Type*) [CommSemiring R] [Semiring S] [Algebra R S] (f : (S →ₐ[R] S)ˣ) : S ≃ₐ[R] S := { (f : S →ₐ[R] S) with invFun := ↑(f⁻¹), left_inv := DFunLike.congr_fun f.inv_mul, right_inv := DFunLike.congr_fun f.mul_inv }  -- compiles; the same change compiles in Equiv_fix.lean (hunts/algequiv/batch6/","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4a42c9","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.algHomUnitsEquiv","line":775,"sev":"NIT","status":"suspected","cat":"reuse","pattern":"reprovable-from-existing-api","claim":"The forward map of `algHomUnitsEquiv` rebuilds an `AlgEquiv` from two inverse `AlgHom`s by hand, which is `AlgEquiv.ofAlgHom (u : A →ₐ[R] A) ↑u⁻¹ u.val_inv u.inv_val` (expected `rfl`). Not compiled here.","fix":"Define the forward map with `AlgEquiv.ofAlgHom`.","ev":"Astra A1 sketch.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d4be9a","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"AlgEquiv.instIsLocalHomAlgHomToAlgHom","line":790,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"stale-todo-comment","claim":"A leftover TODO asks: 'Morally this is just `isLocalHom_equiv`: can we obviate the need for this instance?'. The answer is no, given the current instances. With the instance removed, both `IsLocalHom e.toAlgHom` and `IsLocalHom (e : A →ₐ[R] A₂)` fail to synthesize, because `isLocalHom_equiv` (Mathlib/Algebra/Group/Units/Equiv.lean:214) needs `EquivLike F`, and `A →ₐ[R] A₂` is not `EquivLike`. The 2-line proof, which goes through `toRingEquiv`, can be the one-liner `⟨IsLocalHom.map_nonunit (f := e)⟩`.","fix":"Replace the TODO with a comment saying `isLocalHom_equiv` does not apply because `A₁ →ₐ[R] A₂` is not `EquivLike`, and use `⟨IsLocalHom.map_nonunit (f := e)⟩` as the proof.","ev":"probe1.lean L53-56: attribute [-instance] AlgEquiv.instIsLocalHomAlgHomToAlgHom in example (e : A ≃ₐ[R] A₂) : IsLocalHom e.toAlgHom := inferInstance  -- error: failed to synthesize (also for `(e : A →ₐ[R] A₂)`); L52: `⟨IsLocalHom.map_nonunit (f := e)⟩` compiles; Equiv_fix.lean uses it and compiles (hunts/algequiv/batch6/","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-46db1c","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"MulSemiringAction.toAlgEquiv","line":868,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"stale-cross-reference","claim":"The docstring calls `toAlgEquiv` (unbundled, `G → A ≃ₐ[R] A`) 'a stronger version of `MulSemiringAction.toRingEquiv`'. But `MulSemiringAction.toRingEquiv` is now the bundled `G →* (A ≃+* A)`, `rfl`-equal to `MulSemiringAction.toRingAut`: its simps lemmas were renamed with 2026-06-19 deprecations. So its true analogue is `toAlgAut`, and the same name now means bundled at the ring level but unbundled at the algebra level.","fix":"Cite `MulSemiringAction.toRingEquiv G A g` (applied) in the docstring, or note the bundling difference. Separately, consider deduplicating `toRingEquiv` and `toRingAut`.","ev":"hunts/algequiv/batch7/probe1.lean (a): `#check @MulSemiringAction.toRingEquiv` prints `(G : Type u_1) → [Group G] → (R : Type u_2) → [Semiring R] → [MulSemiringAction G R] → G →* R ≃+* R`. hunts/algequiv/batch7/probe1b.lean (b): `example ... : MulSemiringAction.toRingEquiv G S = MulSemiringAction.toRingAut G S := rfl` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-e7b844","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"LinearEquiv.algEquivOfRing","line":964,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"long-rw-chain","claim":"`right_inv` is a 7-line `calc` whose second step is a single 15-lemma `rw` chain, and whose first step inserts the artificial factor `e (e.symm 1 • 1)`. This is brittle. A 6-line proof (a `key` identity plus a 2-step `calc`) works and also covers non-commutative `A`.","fix":"Replace it with the `key`/`calc` proof in batch7/EquivCopy.lean (this comes for free with the generality fix).","ev":"src.lean lines 964-970 (measured: 4 + 15 rewrites). The replacement is in hunts/algequiv/batch7/EquivCopy.lean `LinearEquiv.algEquivOfRing.right_inv`: `have key (y : A) : algebraMap R A (e.symm y) * e 1 = y := by rw [← Algebra.smul_def, ← map_smul, smul_eq_mul, mul_one, e.apply_symm_apply]; calc _ = algebraMap R A (e.symm 1) * e 1 * algebraMap R A (e.symm (e 1 * x)) := by rw [key, one_mul] _ = x := by rw [mul_assoc, ← Algebra.commutes, key, ← mul_assoc, key, one_mul]`. It compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4b5a7b","file":"Mathlib/Algebra/Algebra/Equiv.lean","decl":"LinearEquiv.conjAlgEquiv","line":979,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"stale-todo-cross-reference","claim":"`conjAlgEquiv` is the `AlgEquiv` upgrade of `LinearEquiv.conj`: `(e.conjAlgEquiv R).toLinearEquiv = e.conj` by `rfl`. Even so, `LinearEquiv.conj` (Mathlib/Algebra/Module/Equiv/Basic.lean:721) still says `-- TODO: upgrade to AlgEquiv (but this file currently cannot import AlgEquiv)`, and `conjAlgEquiv`'s docstring does not cross-reference `conj` or `conjRingEquiv`.","fix":"Replace the TODO at Module/Equiv/Basic.lean:721 with `See LinearEquiv.conjAlgEquiv for the AlgEquiv version`, and add `See also LinearEquiv.conj and LinearEquiv.conjRingEquiv` to `conjAlgEquiv`'s docstring.","ev":"hunts/algequiv/batch7/probe1.lean section (l): `example ... (e : M₁ ≃ₗ[R] M₂) (f : Module.End R M₁) : e.conjAlgEquiv R f = e.conj f := rfl` and `(e.conjAlgEquiv R).toLinearEquiv = e.conj := rfl` both compile. `grep -n 'TODO: upgrade to AlgEquiv' Mathlib/Algebra/Module/Equiv/Basic.lean` gives line 721.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-905ee4","file":"Mathlib/Algebra/Algebra/Pi.lean","decl":"(file)","line":11,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring","claim":"The module docstring's 'Main definitions' lists only `Pi.algebra`, `Pi.evalAlgHom`, `Pi.constAlgHom`, omitting `AlgHom.pi`, `AlgHom.compLeft`, the `AlgEquiv.pi*`/`funUnique`/`sumArrowEquivProdArrow` equivalences and `Pi.algebraMap`; several public lemmas (`algebraMap_def`, `algebraMap_apply`, `coe_evalAlgHom`, the `AlgEquiv` `_apply` lemmas) have no docstrings.","fix":"Complete the list and add one-line docstrings.","ev":"Measured: source.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-ab9b24","file":"Mathlib/Algebra/Algebra/Pi.lean","decl":"AlgEquiv.piCongrRight","line":170,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"copied-docstring","claim":"`AlgEquiv.piCongrRight`'s docstring says the family of algebra equivalences 'generates a multiplicative equivalence between `Π i, A₁ i` and `Π i, A₂ i`', but the result is an `AlgEquiv` (the text is copied from `MulEquiv.piCongrRight`).","fix":"Say 'an algebra equivalence'.","ev":"Measured: source docstring vs type `(Π i, A₁ i) ≃ₐ[R] Π i, A₂ i`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261013-ac10f9","file":"Mathlib/Algebra/Category/ModuleCat/Biproducts.lean","decl":"(file)","line":10,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"incomplete-module-docstring","claim":"The module docstring only says 'The category of `R`-modules has finite biproducts', omitting the explicit product cones, the comparison isomorphisms and the split-exact equivalences; the comment above the instances says ModuleCat 'automatically has biproducts' (only finite ones); `biprodIsoProd`'s docstring ends with a stray colon.","fix":"List the main definitions in the module docstring, say 'finite biproducts' in the comment, and end the `biprodIsoProd` docstring with a period.","ev":"Measured: src L10-12, L24, L63-65.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f93fe19494d"},{"id":"RT-20261013-45c30e","file":"Mathlib/Algebra/Category/ModuleCat/Biproducts.lean","decl":"binaryProductLimitCone","line":36,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"hand-rolled-standard-construction","claim":"`binaryProductLimitCone` packages the cone by hand (`Discrete.casesOn`/`WalkingPair.casesOn`, a nested `rintro` for naturality, manual `fac`/`uniq`), whereas the parallel `AddCommGrpCat.binaryProductLimitCone` uses `BinaryFan.mk` and `BinaryFan.IsLimit.mk`.","fix":"`cone := BinaryFan.mk (ofHom (LinearMap.fst R M N)) (ofHom (LinearMap.snd R M N))`, `isLimit := BinaryFan.IsLimit.mk _ (fun l r => ofHom (l.hom.prod r.hom)) (fun _ _ => rfl) (fun _ _ => rfl) (by cat_disch)`.","ev":"hunts/modulecat-biprod/copyB.lean: with this body (and `@[simps!]`) the file, including the two `rfl` projection lemmas, compiles with the Mathlib linter set, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f93fe19494d"},{"id":"RT-20261013-2fb2a9","file":"Mathlib/Algebra/Category/ModuleCat/Biproducts.lean","decl":"biprodIsoProd","line":66,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"Only `inv ≫ projection` is described: there is no lemma for `biprod.inl/inr ≫ (biprodIsoProd M N).hom`, `hom ≫ ofHom (LinearMap.fst …)`, or `(biprodIsoProd M N).inv ≫ biprod.desc a b` (the abelian-group file has `AddCommGrpCat.biprodIsoProd_inv_comp_desc`), nor `biproduct.ι ≫ hom` for `biproductIsoPi`.","fix":"Add the `hom`/injection/`desc` companions, mirroring `AddCommGrpCat.biprodIsoProd_inv_comp_desc`.","ev":"Measured: src L70-78, L124-127 are the only lemmas about the two isomorphisms; Mathlib/Algebra/Category/Grp/Biproducts.lean has `biprodIsoProd_inv_comp_desc`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f93fe19494d"},{"id":"RT-20261013-0bfcd8","file":"Mathlib/Algebra/Category/ModuleCat/Biproducts.lean","decl":"biprodIsoProd_inv_comp_fst","line":70,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-reassoc","claim":"The comparison lemmas `biprodIsoProd_inv_comp_fst/snd` and `biproductIsoPi_inv_comp_π` are `@[simp, elementwise]` but not `@[reassoc]`, so `simp` cannot rewrite `(biprodIsoProd M N).inv ≫ biprod.fst ≫ k`.","fix":"Tag them `@[reassoc (attr := simp), elementwise]`.","ev":"hunts/modulecat-biprod/probe_assoc.lean: `simp` fails on `(biprodIsoProd M N).inv ≫ biprod.fst ≫ k = ofHom (LinearMap.fst S M N) ≫ k`; hunts/modulecat-biprod/copyF.lean: with `@[reassoc (attr := simp)]` the same `simp` closes it, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f93fe19494d"},{"id":"RT-20261013-938bd9","file":"Mathlib/Algebra/Category/ModuleCat/Biproducts.lean","decl":"(file)","line":115,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-variable","claim":"`variable {J : Type} (f : J → ModuleCat.{v} R)` declares an `f` that both following declarations shadow with their own `(f : J → ModuleCat.{v} R)` binder; L139-140 has a double blank line. The split-exact block also makes this basic biproduct file import `Mathlib.Algebra.Homology.ShortComplex.ModuleCat` (short complexes, homology); after s-0 it would belong in `Algebra/Exact`.","fix":"Drop `(f : …)` from the `variable` line, delete the blank line, and move the split-exact equivalences next to `Function.Exact.splitSurjectiveEquiv` (import reduction not tested).","ev":"Measured: src L115, L120, L125, L139-140, L8.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f93fe19494d"},{"id":"RT-20261013-c31b07","file":"Mathlib/Algebra/Category/ModuleCat/Biproducts.lean","decl":"lequivProdOfRightSplitExact","line":174,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"root-namespace-informal-prefix","claim":"`lequivProdOfRightSplitExact`/`lequivProdOfLeftSplitExact` live in the root namespace (`section SplitExact` opens none) with the informal `lequiv` prefix, rather than as `LinearEquiv.…` or `Function.Exact.…` declarations.","fix":"Rename to e.g. `Function.Exact.linearEquivProdOfSection` / `…OfRetraction` (with deprecated aliases).","ev":"Measured: src L131-204 (no `namespace`), names at L174, L190.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f93fe19494d"},{"id":"RT-20261006-27059b","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.overMapUnitIso","line":89,"sev":"NIT","status":"confirmed","cat":"api","pattern":"implicit-arg-not-inferable","claim":"`overMapUnitIso` takes `R` implicitly, but `R` cannot be inferred from its only explicit argument `f`. Its siblings `overMap`, `overFunctorMap` and `overPullback` all make `R` explicit with `variable (R) in`. As a result, `(overMapUnitIso f).hom` does not elaborate ('don't know how to synthesize implicit argument R'), and users must write `overMapUnitIso (R := R) f`. It has 0 uses in Mathlib.","fix":"Add `variable (R) in` before `overMapUnitIso`, as for `overMap`.","ev":"batch0/Probe1.lean P6: `example {X Y : D} (f : X ⟶ Y) := (overMapUnitIso f).hom` -> 'don't know how to synthesize implicit argument `R`'; `(overMapUnitIso (R := R) f).hom` elaborates (the only error there is the codegen 'mark noncomputable'). `#check @overMapUnitIso` shows `{R : Sheaf K RingCat} → {X Y : D} → (f : X ⟶ Y) → ...`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d4663a","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.overPullback","line":95,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-clash-across-analogous-apis","claim":"`SheafOfModules.overPullback R f` is the direct image `f_*` (the pushforward along `Over.pullback f`, from `R.over X`-modules to `R.over Y`-modules). In `CategoryTheory/Sites/Over.lean`, though, `GrothendieckTopology.overPullback A X : Sheaf J A ⥤ Sheaf (J.over X) A` is the restriction functor (the pushforward along `Over.forget X`); its module analogue here is `overFunctor`. Sites also calls the analogue of `overMap` `overMapPullback`. So the same name means restriction in one namespace and direct image in the other.","fix":"Rename to `overPushforward` or `overPullbackPushforward`; at the least, the docstring should say it is the direct image along `f` and contrast it with `GrothendieckTopology.overPullback`.","ev":"git grep: origin/master Mathlib/CategoryTheory/Sites/Over.lean:278 `abbrev overPullback (A : Type u') [Category.{v'} A] (X : C) : Sheaf J A ⥤ Sheaf (J.over X) A := (Over.forget X).sheafPushforwardContinuous _ _ _`; Sites/Over.lean:415 `abbrev overMapPullback {X Y : C} (f : X ⟶ Y) : Sheaf (J.over Y) A ⥤ Sheaf (J.over X) A := (Over.map f).sheafPushforwardContinuous _ _ _`; versus src.lean L95-97.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d77e41","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardId","line":102,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-typo","claim":"The docstring has a typo: 'identifies to the identify functor' should say 'identity functor'. It was copied from `PresheafOfModules.pushforwardId` (Presheaf/Pushforward.lean:124, same typo); a third copy is at CategoryTheory/Center/Basic.lean:30.","fix":"Replace 'identify functor' with 'identity functor' here and at Presheaf/Pushforward.lean:124.","ev":"git grep -n 'identify functor' origin/master -- Mathlib: Presheaf/Pushforward.lean:124, Sheaf/PushforwardContinuous.lean:103, CategoryTheory/Center/Basic.lean:30.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-032380","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardCongr_symm","line":118,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"statement-continuation-indent","claim":"In `pushforwardCongr_symm` (L118), `pushforwardCongr_hom_app_val_app` (L122) and `pushforwardCongr_inv_app_val_app` (L126), the conclusion line of the statement is indented 2 spaces where Mathlib style asks for 4, while the binder line just above uses 4. The same happens in `pushforwardComp_hom_app_val_app`/`_inv_app_val_app` (L145, L149; another batch).","fix":"Indent the statement continuation lines L118, L122, L126 (and L145, L149) by 4 spaces.","ev":"src.lean L116-126 measured: e.g. L117 `    {φ ψ : S ⟶ ...} (e : φ = ψ) :` (4 spaces), L118 `  (pushforwardCongr e).symm = pushforwardCongr e.symm := rfl` (2 spaces); likewise L122, L126.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4fc977","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardCongr_hom_app_val_app","line":120,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"applied-lemma-missing-apply-suffix","claim":"`pushforwardCongr_hom_app_val_app` and `pushforwardCongr_inv_app_val_app` state the applied form `(...).val.app U x = x`, but their names lack the `_apply` suffix. The file is inconsistent about this: `pushforwardNatTrans_app_val_app_apply` (L219) uses the suffix for the same shape, and `@[simps!]` on `pushforwardCongr₂` generates `pushforwardCongr₂_hom_app_val_app_hom_apply`.","fix":"Rename to `pushforwardCongr_hom_app_val_app_apply`/`pushforwardCongr_inv_app_val_app_apply` (with deprecated aliases).","ev":"batch0/Probe3.out: declarations with prefix `SheafOfModules.pushforwardCongr` include `pushforwardCongr₂_hom_app_val_app_hom_apply` next to `pushforwardCongr_hom_app_val_app`; src.lean L122/L126 versus L219.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ebaa46","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardComp","line":137,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-grammar","claim":"Docstring grammar: \"The composition of two pushforward functors … identify to the pushforward for the composition\" has a singular subject with a plural verb. The same sentence is in `PresheafOfModules.pushforwardComp`.","fix":"\"The composition of two pushforward functors on categories of sheaves of modules identifies with the pushforward along the composition.\"","ev":"measured: src.lean L135-136.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-173fc0","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardNatTrans","line":190,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"section-variables-shadow-outer-scope","claim":"The namespace-level `variable`s of L32-37 (`C D D' D'' J K F S R`, `[F.IsContinuous J K]`, `φ`) stay in scope until `end SheafOfModules`, because `pushforwardCompForgetToSheafModuleCat` at L415 uses them. `section NatTrans` (L180-186) and `section Adjunction` (L257-267) declare `C D J K F S` (and `G R φ ψ`) again, which shadows them. Every goal state inside those sections therefore carries about 15 inaccessible hypotheses (`C✝ inst✝⁹ D✝ … D' D'' J✝ K✝ F✝ S✝ R φ✝`), which makes the proofs of `pushforwardNatTrans`, `pushforwardNatIso` and `pushforwardPushforwardAdj` harder to read and debug. No declaration picks up a stray argument (checked with `#check`).","fix":"Put L32-37 and the declarations that use them inside their own `section … end`, and reopen a small section for `pushforwardCompForgetToSheafModuleCat`, so later sections do not shadow live variables.","ev":"hunts/modsheaf-pushfwd/batch1/copy.out (compile of hunts/modsheaf-pushfwd/batch1/copy.lean): the unsolved-goal dumps at copy.lean:217, :303 and :400 list `C✝ … D' D'' J✝ K✝ F✝ S✝ R φ✝` before the section's own `C D J K …`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ee0efb","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardNatTrans","line":198,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"uncommented-change","claim":"The `val.naturality` proof uses an uncommented `change` to move from the `ModuleCat`-level maps to the `Ab`-valued `X.val.presheaf.map`. The `change` is needed: `X.val.map f` has a codomain that depends on `f` (`restrictScalars (R.map f)`), so `simp`/`rw` with `PresheafOfModules.map_comp_apply`, `op_comp` and `α.naturality` cannot rewrite at that level. Three such variants all fail. The checklist asks for a comment on such a `change`.","fix":"Add a comment saying the `change` passes to `X.val.presheaf` because `X.val.map` has an `f`-dependent codomain, which blocks `rw`/`simp` with `map_comp`.","ev":"hunts/modsheaf-pushfwd/batch1/copy.lean `pushforwardNatTransV1` (`ext x; simp [← PresheafOfModules.map_comp_apply, ← op_comp, α.naturality]`), `V2` (`dsimp; rw [← X.val.map_comp_apply, …]`), `V3` (term with `congr_map_apply`): all fail (copy.out errors at copy.lean:217, :234, :249).","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-77382a","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardNatTrans_app_val_app","line":205,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `SheafOfModules.pushforwardNatTrans_app_val_app` (Algebra.Category.ModuleCat.Sheaf.PushforwardContinuous), `SheafOfModules.pushforwardNatTrans_app_val_app_apply` (Algebra.Category.ModuleCat.Sheaf.PushforwardContinuous) state exactly the same thing (Lean-checked). Reviewer: Same file, two @[simp] rfl lemmas with the same elementwise statement `((pushforwardNatTrans φ α).app M).val.app U x = M.val.map (α.app U.unop).op x`, neither used by name. Keep the `_apply` one, since its name matches the applied statement; deprecate `pushforwardNatTrans_app_val_app`, or restate it at morphism level.","fix":"Deprecate `SheafOfModules.pushforwardNatTrans_app_val_app` in favour of `SheafOfModules.pushforwardNatTrans_app_val_app_apply`.","ev":"dupscan/Check.lean: `example := (@SheafOfModules.pushforwardNatTrans_app_val_app_apply : type_of% @SheafOfModules.pushforwardNatTrans_app_val_app)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 7, rating MAJOR): Both are elementwise simp lemmas, so there is no morphism-versus-application distinction to preserve. The `_apply` name accurately describes the existing statement.","pr":null,"res":"Same duplicate as RT-20261006-aaa26d / RT-20261007-df5e4e, already fixed by draft PRs #44580/#44581; kept as a cross-reference only, not a separate win.","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-4b066f","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardNatTrans_comp","line":213,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"binder-shadows-section-variable","claim":"The lemma binds its own `(φ : T ⟶ (H.sheafPushforwardContinuous RingCat J K).obj S)`, which shadows the section variable `φ : T ⟶ (G.sheafPushforwardContinuous RingCat J K).obj S` (L186) that `pushforwardNatTrans_id` and the rest of the section use. A reader of `pushforwardNatTrans φ β` here can easily take `φ` to be the `G`-version. The final signature has only the `H`-version, so nothing is wrong, only confusing.","fix":"Rename the binder (for example `φ' : T ⟶ (H.sheafPushforwardContinuous …).obj S`), or omit it from the section's `φ`.","ev":"hunts/modsheaf-pushfwd/batch1/probe1.lean P2: `#check @SheafOfModules.pushforwardNatTrans_comp` shows a single `(φ : T ⟶ (H.sheafPushforwardContinuous RingCat J K).obj S)` after `α β`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7ee304","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardPushforwardAdj","line":269,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"avoidable-backward-set-option","claim":"`set_option backward.isDefEq.respectTransparency false in` (L269) is a backward-compatibility switch, and here it can be avoided. Without it, the closing `simp` of each triangle proof leaves only `(AddMonoidHom.id _) x = x`, which `rfl` closes. With the option deleted and both final `simp`s replaced by `simp; rfl`, the whole file compiles with no warnings.","fix":"Delete the `set_option … in` and end both `left_triangle_components` and `right_triangle_components` with `simp` followed by `rfl`.","ev":"hunts/modsheaf-pushfwd/batch1/copy.lean `pushforwardPushforwardAdjV1` (original proof, no set_option) fails at copy.lean:400 and :407 with residual `(AddMonoidHom.id ↑(X.val.obj …)) x = x`; hunts/modsheaf-pushfwd/batch1/copy4.lean (set_option removed, `simp; rfl` at the two triangle proofs) compiles with exit 0 and no output.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-75e771","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardPushforwardAdj","line":283,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"uncommented-change","claim":"Both triangle proofs start with an uncommented `change` (L283, L290) that restates the goal through `X.val.presheaf.map`. This is needed for the same reason as in `pushforwardNatTrans`: a plain `ext U x; simp [← PresheafOfModules.map_comp_apply, ← op_comp, pushforwardId, pushforwardComp]` runs for 7.45 s and then times out.","fix":"Add a one-line comment explaining the `change` (it passes to the `Ab`-valued presheaf, where `Functor.map_comp` applies).","ev":"hunts/modsheaf-pushfwd/batch1/copy.lean `pushforwardPushforwardAdjV2`: (deterministic) timeout at whnf, copy.out error at copy.lean:426.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b8e80f","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"(file)","line":325,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-open","claim":"L325 `open CategoryTheory Limits` inside `section Adjunction` repeats the file-level `open CategoryTheory Functor Limits` (L28) and has no effect. In the same section, `pushforwardOver` writes `Limits.prod.snd` despite `Limits` being open.","fix":"Delete L325, and write `prod.snd`.","ev":"Source: L28 `open CategoryTheory Functor Limits` precedes L325 `open CategoryTheory Limits` with no intervening `end` of a scope that opened them.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-fa8cb1","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardOver","line":332,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"misleading-namespace-name","claim":"The name `SheafOfModules.pushforwardOver` reads like a functor on sheaves of modules. It is actually a morphism of sheaves of rings into a pushforward, and the sibling naming convention is `Sheaf.toPushforwardOverPullback`.","fix":"Rename it to `Sheaf.toPushforwardOverStar` (with the move in finding 5) and leave a deprecated alias.","ev":"Measured: probe1 run_cmd dump `SheafOfModules.pushforwardOver : ... (x : C) → R ⟶ ((Over.star x).sheafPushforwardContinuous RingCat J (J.over x)).obj (R.over x)`. The sibling is `Sheaf.toPushforwardOverPullback` (Sites/Over.lean:518).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-fab67c","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardOver","line":332,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-simps","claim":"There is no `@[simps]` or `_hom_app` lemma, unlike the sibling `Sheaf.toPushforwardOverPullback`. Its own consumer has to unfold the definition: `simp [pushforwardOver]` at L344 and L346.","fix":"Add `@[simps]`, or get the API for free by defining it as the adjunction unit (finding 4), whose `Adjunction.sheafPushforwardContinuous` is `@[simps!]`.","ev":"Measured: src.lean L330–335 have no simps attribute, and L344/L346 use `simp [pushforwardOver]`. Sites/Over.lean:516 has `@[simps]` on `Sheaf.toPushforwardOverPullback`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-9fa942","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.overPushforwardOverAdj","line":340,"sev":"NIT","status":"confirmed","cat":"api","pattern":"statement-uses-unfolded-def","claim":"The docstring describes the left adjoint as 'restriction to `Over x`', which is the file's `overFunctor R x` (whose `obj` is `M.over x`). The statement instead spells it as the unfolded `pushforward.{w} (𝟙 (R.over x))`, so the adjunction does not syntactically match the `overFunctor`/`over` API.","fix":"State the type as `overFunctor.{w} R x ⊣ pushforward.{w} (pushforwardOver x)`. It is defeq, so the proof is unchanged.","ev":"hunts/modsheaf-pushfwd/batch2/probe1.lean B2 (`overFunctor.{w} R x = pushforward.{w} (𝟙 (R.over x)) := rfl` compiles). Measured: signature `pushforward (𝟙 (R.over x)) ⊣ pushforward (pushforwardOver x)` from the probe1 run_cmd dump.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-9c25d9","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardPushforwardEquivalence","line":384,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-variable-mismatch","claim":"The docstring 'If `e : C ≌ D`, then the pushforwards along `e.functor` and `e.inverse` forms an equivalence' names a nonexistent `e` (the variable is `eqv`). It has a grammar slip ('forms'). It also omits the ring maps φ, ψ and the compatibility hypotheses H₁, H₂ without which the claim is false.","fix":"Rewrite it as 'If `eqv : C ≌ D` and `φ`, `ψ` are compatible morphisms of sheaves of rings (`H₁`, `H₂`), then the pushforwards `pushforward φ` and `pushforward ψ` form an equivalence.'","ev":"Measured: src.lean L384 docstring against binder `(eqv : C ≌ D)` at L373.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-3ebdd0","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean","decl":"SheafOfModules.pushforwardCompForgetToSheafModuleCat","line":414,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"imprecise-docstring","claim":"The docstring 'Pushforward commutes with `SheafOfModules.forgetToSheafModuleCat`' (no final period) leaves out two things the statement contains. The commutation holds only up to restriction of scalars along `φ.hom.app X`, and it needs initial objects `X` and `F.op.obj X`.","fix":"Say that `pushforward φ ⋙ forgetToSheafModuleCat` is isomorphic to `forgetToSheafModuleCat` followed by restriction of scalars along `φ.hom.app X` and `F.sheafPushforwardContinuous`, for `X` and `F.op.obj X` initial.","ev":"Measured: src.lean L414 docstring against the statement at L415–420.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-8553a1","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.Presentation.IsFinite","line":54,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-typo","claim":"The docstring is ungrammatical: \"A global presentation of a sheaf of module if finite if the type of generators and relations are finite.\"","fix":"\"A global presentation of a sheaf of modules is finite if the types of generators and of relations are finite.\"","ev":"src.lean L52–53.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-2b89ee","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.generatorsOfIsCokernelFree","line":77,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"duplicate-section-variables","claim":"The `variable` at L69 (`{C : Type u₁} [Category.{v₁} C] {J : GrothendieckTopology C} {R : Sheaf J RingCat.{u}}`) declares again the binders already declared at L33–34, which are still in scope. The old ones are shadowed, and they show up as `C✝ J✝ R✝` in every goal of the section (for example in the NoSetOpt.lean error contexts).","fix":"Delete the duplicated `C`, `J`, `R` binders from the `variable` at L69 and keep only the sheafification instances and `{ι σ : Type u}`.","ev":"Lines 33–34 and 69–71 of src.lean. The goal contexts in hunts/modsheaf-quasicoherent/batch0/NoSetOpt.lean's errors begin `C✝ : Type u₁, inst✝³ : Category.{v₁, u₁} C✝, J✝ : GrothendieckTopology C✝, R✝ : Sheaf J✝ RingCat, C : Type u₁, …`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-900c21","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.Presentation.isColimit","line":126,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-misdescribes-def","claim":"The docstring (\"there is two morphism of sheaves … `f : free ι ⟶ free σ` and `g : free σ ⟶ M` satisfying …\") describes an existence statement in terms of `ι`, `σ`, which are not arguments. The declaration is instead the specific colimit witness that `P.generators.π` is a cokernel of `P.relations.π ≫ kernel.ι _`. The statement also spells `P.relations.π` as `(freeHomEquiv _).symm P.relations.s`. The `P.relations.π` form is accepted, see (P1).","fix":"\"The cokernel cofork given by `P.relations.π ≫ kernel.ι _` and `P.generators.π` is a colimit.\" Also state it with `P.relations.π`.","ev":"src.lean L123–128. hunts/modsheaf-quasicoherent/batch0/Probe3.lean (P1): `noncomputable example (P : Presentation M) : IsColimit (CokernelCofork.ofπ (f := P.relations.π ≫ kernel.ι _) P.generators.π (by simp)) := P.isColimit` type-checks.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-f6c15d","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.Presentation.ofIsIso","line":135,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-noncomputable","claim":"`noncomputable def` sits inside the `noncomputable section` opened at L67, so the modifier is redundant.","fix":"Drop `noncomputable` from L135.","ev":"src.lean L67 `noncomputable section`, L135 `noncomputable def Presentation.ofIsIso`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-591e43","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.Presentation.mapRelations","line":162,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"inline-existing-def","claim":"The first two factors `(mapFreeIso F P.relations.I η).hom ≫ F.map ((freeHomEquiv _).symm P.relations.s)` are exactly `P.relations.mapFreeHom F η` (Generators.lean), written out by hand.","fix":"Define `mapRelations := P.relations.mapFreeHom F η ≫ F.map (kernel.ι _) ≫ (mapFreeIso F _ η).inv`.","ev":"hunts/modsheaf-quasicoherent/batch0/Probe.lean (M1): `example : P.mapRelations F η = P.relations.mapFreeHom F η ≫ F.map (kernel.ι _) ≫ (mapFreeIso F _ η).inv := by simp only [Presentation.mapRelations, GeneratingSections.mapFreeHom, Category.assoc]` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-09175e","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.Presentation.mapRelations","line":162,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-misdescribes-def","claim":"The docstring says \"we will obtain relations of `Presentation (F.obj M)`\", but the declaration is a morphism `free P.relations.I ⟶ free P.generators.I`. It is the relation map that `Presentation.map` passes to `presentationOfIsCokernelFree`, not a `GeneratingSections` of a kernel.","fix":"\"The morphism `free P.relations.I ⟶ free P.generators.I` induced by `F`, whose cokernel is `F.obj M`. It gives the relations of `P.map F η`.\"","ev":"src.lean L159–164.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-7e05bc","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.Presentation.mapGenerators","line":169,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"pure-alias-abbrev","claim":"`mapGenerators` is an `abbrev` whose body is literally `P.generators.mapFreeHom F η`, so it is a pure alias. It has 3 uses, all in this file (L173, L184, L185).","fix":"Use `P.generators.mapFreeHom F η` directly and drop the abbrev, or keep it but say in the docstring that it is that alias.","ev":"hunts/modsheaf-quasicoherent/batch0/Probe.lean (M2): `example : P.mapGenerators F η = P.generators.mapFreeHom F η := rfl` compiles. Uses counted with grep.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-7e6b5b","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.Presentation.mapGenerators","line":169,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-misdescribes-def","claim":"The docstring says \"we will obtain generators of `Presentation (F.obj M)`\", but the declaration is the morphism `free P.generators.I ⟶ F.obj M`. The generators themselves are `(P.map F η).generators`, or `P.generators.map F η`.","fix":"\"The morphism `free P.generators.I ⟶ F.obj M` (that is, `P.generators.mapFreeHom F η`) which is the projection of `P.map F η`.\"","ev":"src.lean L166–169.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-f7824d","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.Presentation.map","line":178,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"removable-backward-compat-option","claim":"`set_option backward.defeqAttrib.useBackward true in` on `Presentation.map` is not needed. With it removed, the whole file compiles without messages. The other option, `backward.isDefEq.respectTransparency.types false`, is needed: removing it breaks the `Cocone.ext` step at L188.","fix":"Delete the `set_option backward.defeqAttrib.useBackward true in` line above `Presentation.map` (L178).","ev":"hunts/modsheaf-quasicoherent/batch1/v2.lean = src.lean with L178 deleted: `lake env lean` EXIT=0, no messages (baseline hunts/modsheaf-quasicoherent/batch1/base.lean EXIT=0). hunts/modsheaf-quasicoherent/batch1/v1.lean = src.lean with L177 deleted: 'unsolved goals case one' at L188 (fails). hunts/modsheaf-quasicoherent/batch1/v7_api_nouseBackward.lean (v6_api without the option) is also EXIT=0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-3951d4","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.Presentation.map","line":179,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-iso-direction","claim":"The docstring 'Let `F` be a functor from sheaf of `R`-module to sheaf of `S`-module, if `F` preserves colimits and `F.obj (unit R) ≅ unit S`, ...' states the isomorphism in the opposite direction to the argument `η : unit S ≅ F.obj (unit R)`. It also has grammar slips ('sheaf of `R`-module', a comma splice, 'we will get'). The same text appears in the docstrings of `mapRelations` and `mapGenerators`.","fix":"Rewrite as 'Given a functor `F` from sheaves of `R`-modules to sheaves of `S`-modules which preserves colimits, an isomorphism `η : unit S ≅ F.obj (unit R)` and a presentation `P` of `M`, this is the induced presentation of `F.obj M`.'","ev":"src.lean L153 `(η : unit S ≅ F.obj (unit R))` vs docstring L179-181 '`F.obj (unit R) ≅ unit S`' (read verbatim).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-862421","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.Presentation.map_π_eq","line":192,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-skips-projection","claim":"The name `Presentation.map_π_eq` refers to a `π` of a `Presentation`, but `Presentation` has no `π`. The lemma is about `(P.map F η).generators.π`. Under Mathlib's convention it would be `Presentation.map_generators_π`. The `_eq` suffix is copied from `GeneratingSections.map_π_eq`, where `π` is a projection of the object being mapped.","fix":"Rename to `Presentation.map_generators_π`, keeping a deprecated alias (or fold it into a `map_generators` simp lemma).","ev":"src.lean L192-193: `theorem Presentation.map_π_eq : (P.map F η).generators.π = ...`; `structure Presentation` (L46-50) has only the fields `generators` and `relations`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-edccd6","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.QuasicoherentData.localGeneratorsData","line":228,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-states-theorem-for-construction","claim":"The docstring 'If `M` is quasicoherent, it is locally generated by sections.' reads like a theorem about `M`. The declaration is a construction: it forgets the relations of the given data `q` and keeps the covering and the generators.","fix":"Say 'The local generators data underlying quasi-coherent data `q`: the same covering, with the generators of each local presentation.'","ev":"src.lean L228-235 (read verbatim): docstring vs `def localGeneratorsData (q : M.QuasicoherentData) : M.LocalGeneratorsData where ... generators i := (q.presentation i).generators`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-d56c7e","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.QuasicoherentData.IsFinitePresentation","line":237,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-grammar","claim":"The docstring says 'A (local) presentation of a sheaf of module `M` is a finite presentation if ...': 'sheaf of module' should be 'sheaf of modules', and the class is about quasi-coherent data, which the text calls '(local) presentation'.","fix":"Say 'Quasi-coherent data for a sheaf of modules `M` is of finite presentation if each of its presentations of `M.over (X i)` is finite.'","ev":"src.lean L237-238, read verbatim.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-15395b","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.IsQuasicoherent","line":252,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-stacks-tag","claim":"`IsQuasicoherent` (and `IsFinitePresentation`) have no `@[stacks]` attribute. The file's only reference, Stacks 01BD, is Section 17.10, the ringed-space definition (Def. 17.10.1, points and open neighbourhoods). The notion formalised here, with coverings of a site and global presentations on the slices, is Stacks Definition 18.23.1 (tag 03DL), items (6) and (7). The sibling class `IsLocallyFree` does carry `@[stacks 01C6 \"(1)\"]`.","fix":"Add `@[stacks 03DL \"(6)\"]` to `IsQuasicoherent` and `@[stacks 03DL \"(7)\"]` to `IsFinitePresentation`, and cite 03DL in the module docstring next to 01BD.","ev":"WebFetch https://stacks.math.columbia.edu/tag/01BD -> 'Section 17.10 Quasi-coherent modules', Def. 17.10.1 for a ringed space (X, O_X); https://stacks.math.columbia.edu/tag/03DL -> Definition 18.23.1 (ringed sites), (6) quasi-coherent, (7) finite presentation. src.lean L252-255 and L268-272 have no attribute.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-929cba","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.IsQuasicoherent","line":255,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"dead-autoparam","claim":"The field's autoParam `nonempty_quasicoherentData : Nonempty (QuasicoherentData.{u₁} M) := by infer_instance` is dead. Mathlib has no `Nonempty (QuasicoherentData _)` instance, and every construction of `IsQuasicoherent` passes the field explicitly (L258 `⟨⟨q.shrink⟩⟩`, L281, L390, L404, LocallyFree.lean:137 via `isQuasicoherent`).","fix":"Drop the `:= by infer_instance` default.","ev":"`git grep -n -E 'Nonempty \\(.*QuasicoherentData' origin/master -- Mathlib` finds only the field itself (Quasicoherent.lean:255).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-d31171","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.QuasicoherentData.pushforward","line":305,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"implied-instance-binder","claim":"Section nesting gives `QuasicoherentData.pushforward`, `isQuasicoherent_pushforward` and `isQuasicoherent_pushforward_of_isLeftAdjoint` both `[∀ X : C, HasWeakSheafify (J.over X) AddCommGrpCat]` (from the variable at L200) and `[∀ X : C, HasSheafify (J.over X) AddCommGrpCat]` (from section `map`, L295). The second implies the first, so the first binder is redundant.","fix":"Restructure the `variable`s (or `omit` the weak one in section `map`) so these declarations take only `[∀ X, HasSheafify (J.over X) _]`.","ev":"Signature dump (hunts/modsheaf-quasicoherent/batch2/ProbeB.lean, run_cmd B0, output in ProbeB.out): `SheafOfModules.isQuasicoherent_pushforward :: ∀ … [inst_1 : ∀ (X : C), HasWeakSheafify (J.over X) AddCommGrpCat] … [∀ (X : C), HasSheafify (J.over X) AddCommGrpCat] …` (same for the other two). hunts/modsheaf-quasicoherent/batch2/QcCopy.lean `probeA3d` restates `isQuasicoherent_pushforward` in a section without the `HasWeakSheafify` binder and proves it by `isQuasicoherent_pushforward G φ η h`. It compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-0f17e8","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.isQuasicoherent_pushforward_of_isLeftAdjoint","line":352,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"redundant-have-instance","claim":"`have : G'.IsContinuous (K.over X) (J.over Y) := Functor.isContinuous_comp _ _ _ (J.over _) _` is redundant, because the instance at Mathlib/CategoryTheory/Sites/Over.lean:370-375 already provides `(Over.post F ⋙ Over.map f).IsContinuous`. The cocontinuity `have` is needed.","fix":"Delete the `G'.IsContinuous` `have`.","ev":"hunts/modsheaf-quasicoherent/batch2/QcCopy.lean: `probeA3c` (the original proof minus the `IsContinuous` `have`) compiles. `probeA3b` (minus both `have`s) fails with `failed to synthesize G'.IsCocontinuous (K.over X) (J.over Y)`, and `probeA3a` (minus the `respectTransparency` option) fails with `failed to synthesize IsIso a`. So the option and the cocontinuity `have` are both needed.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-b3f1c5","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.Presentation.quasicoherentData","line":381,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"duplicated-proof-of-sibling","claim":"The three-line `coversTop` proof (`rw [Sieve.ext_iff]; intro _ f; simp [Sieve.top_apply]`) is the one-liner `GrothendieckTopology.covering_of_eq_top J <| by simp` that the sibling `GeneratingSections.localGeneratorsData` (Generators.lean:198) uses for the same cover `X := id`. Also, `(by rfl)` is used to build an `Iso` where `Iso.refl _` is meant.","fix":"Use `coversTop _ := GrothendieckTopology.covering_of_eq_top J <| by simp` and `(Iso.refl _)`.","ev":"hunts/modsheaf-quasicoherent/batch2/QcCopy.lean `Presentation.quasicoherentData'` with `coversTop _ := GrothendieckTopology.covering_of_eq_top J <| by simp` and `presentation x := P.map (pushforward (𝟙 (R.over x))) (Iso.refl _)` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-3fd3f1","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.QuasicoherentData.bind","line":428,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-undefined-notation","claim":"The docstring 'Given an cover `X` and a quasicoherent data for `M` restricted onto each `Mᵢ`, we may glue them into a quasicoherent data of `M` itself.' has grammar slips ('an cover', 'a quasicoherent data'), and `Mᵢ` is never defined (it should be `M.over (X i)`).","fix":"Reword as 'Given a family `X i` covering the terminal object and quasi-coherent data `D i` for each restriction `M.over (X i)`, glue them into quasi-coherent data for `M`.'","ev":"Source lines 428-429 of src.lean (quoted in the claim).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-490d36","file":"Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean","decl":"SheafOfModules.QuasicoherentData.bind","line":430,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"shadowed-section-variable","claim":"`QuasicoherentData.bind` (L430) and `IsQuasicoherent.of_coversTop` (L445) re-bind `{R : Sheaf J RingCat.{u}}`, which shadows the file-level `variable {R : Sheaf J RingCat.{u}}` (L35) for no reason. In the elaborated signatures `R` consequently appears after the instance binders.","fix":"Drop the local `{R : Sheaf J RingCat.{u}}` binders and use the section variable.","ev":"Source L35 `variable … {R : Sheaf J RingCat.{u}}`; L430 `noncomputable def QuasicoherentData.bind {R : Sheaf J RingCat.{u}}`; L445 `lemma IsQuasicoherent.of_coversTop {R : Sheaf J RingCat.{u}}`. Signature dump in ProbeB.out shows `… [inst_4 : …] → {R : Sheaf J RingCat} → (M : SheafOfModules R) …`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-18c68b","file":"Mathlib/Algebra/Category/MonCat/Colimits.lean","decl":"(file)","line":1,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring","claim":"No docstrings on `quot_one`, `quot_mul`, `cocone_naturality`, `cocone_naturality_components`, the `Inhabited` instance and `hasColimits_monCat`.","fix":"Add one-line docstrings.","ev":"Measured: source.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-71e774","file":"Mathlib/Algebra/Category/MonCat/Colimits.lean","decl":"(file)","line":11,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"stale-module-doc","claim":"Most of the module docstring is Lean 3 history (the `#print monoid` output 'a long time ago', a python-script thought experiment, the Lean 4 `#print Monoid` output) rather than a description of the file; the `Relation` constructors carry trailing `--` comments that describe the *next* constructor ('-- Make it an equivalence relation:' on the `inductive` line, '-- There's always a `map` relation' after `trans`, etc.).","fix":"Replace the history with a short description of the construction; move each comment above the constructor it describes.","ev":"Measured: source L11-46, L89-108.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-4d201c","file":"Mathlib/Algebra/Exact/Basic.lean","decl":"Function.Exact.of_comp_eq_zero_of_ker_in_range","line":58,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Function.Exact.of_comp_of_mem_range` (Algebra.Exact.Basic), `Function.Exact.of_comp_eq_zero_of_ker_in_range` (Algebra.Exact.Basic) state exactly the same thing (Lean-checked). Reviewer: to_additive images of MulExact.of_comp_of_mem_range (l.58) and MulExact.of_comp_eq_one_of_ker_in_range (l.73): `g ∘ f = 1` and `g.comp f = 1` are the same term, and the hypotheses match. of_comp_of_mem_range is used (and mirrored by exact_of_comp_of_mem_range); deprecate the other.","fix":"Deprecate `Function.Exact.of_comp_eq_zero_of_ker_in_range` in favour of `Function.Exact.of_comp_of_mem_range`.","ev":"dupscan/Check.lean: `example := (@Function.Exact.of_comp_eq_zero_of_ker_in_range : type_of% @Function.Exact.of_comp_of_mem_range)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 9, rating MAJOR): Both provide the same exactness constructor with the same calling convention; composition notation supplies no separate API role.","pr":null,"res":"to_additive image of the multiplicative duplicate (Commute.inv / Subgroup.map_inf_eq / Function.MulExact), counted once there.","at":"2026-10-07","commit":""},{"id":"RT-20261007-7f58f2","file":"Mathlib/Algebra/Group/Commute/Defs.lean","decl":"AddCommute.neg","line":165,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `AddCommute.neg` (Algebra.Group.Commute.Defs), `AddCommute.add_neg` (Algebra.Group.Commute.Defs) state exactly the same thing (Lean-checked). Reviewer: Additive images of `Commute.inv` and `Commute.mul_inv`: adjacent, both `Commute a b → (a * b)⁻¹ = a⁻¹ * b⁻¹`, with the same `by rw [hab.eq, mul_inv_rev]` proof. Keep `Commute.mul_inv`/`AddCommute.add_neg` (mirrors the unconditional `mul_inv`), deprecate `Commute.inv`/`AddCommute.neg` (an ambiguous name).","fix":"Deprecate `AddCommute.neg` in favour of `AddCommute.add_neg`.","ev":"dupscan/Check.lean: `example := (@AddCommute.add_neg : type_of% @AddCommute.neg)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 23, rating MAJOR): Both are methods on the same `AddCommute` witness, so removing `neg` does not eliminate witness-based notation. `add_neg` describes the negation-of-a-sum conclusion more clearly.","pr":null,"res":"to_additive image of the multiplicative duplicate (Commute.inv / Subgroup.map_inf_eq / Function.MulExact), counted once there.","at":"2026-10-07","commit":""},{"id":"RT-20261007-9c7d04","file":"Mathlib/Algebra/Group/Subgroup/Map.lean","decl":"AddSubgroup.map_inf_eq","line":247,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `AddSubgroup.map_inf_eq` (Algebra.Group.Subgroup.Map), `AddSubgroup.map_inf` (Algebra.Group.Subgroup.Map) state exactly the same thing (Lean-checked). Reviewer: to_additive images of Subgroup.map_inf (l.214) and Subgroup.map_inf_eq (l.247): both state `map f (H ⊓ K) = map f H ⊓ map f K` for injective f, 30 lines apart. Keep map_inf (next to map_iInf, matches Submodule.map_inf); map_inf_eq is unused.","fix":"Deprecate `AddSubgroup.map_inf_eq` in favour of `AddSubgroup.map_inf`.","ev":"dupscan/Check.lean: `example := (@AddSubgroup.map_inf : type_of% @AddSubgroup.map_inf_eq)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 13, rating MAJOR): The two declarations have matching explicit arguments and translation attributes, so `map_inf_eq` adds neither dot notation nor another automation role.","pr":null,"res":"to_additive image of the multiplicative duplicate (Commute.inv / Subgroup.map_inf_eq / Function.MulExact), counted once there.","at":"2026-10-07","commit":""},{"id":"RT-20261006-6f6180","file":"Mathlib/Algebra/Group/TypeTags/Hom.lean","decl":"(file)","line":12,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"module-doc-title-only","claim":"The module docstring is a title only (\"# Transport algebra morphisms between additive and multiplicative types.\", ending in a period), with no description and no list of the main declarations (`toMultiplicative`, `toAdditive`, their Left/Right variants, the ext lemmas, the bundled equivalences).","fix":"Add a short description and a `## Main declarations` list.","ev":"Source L12–14.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-822d90","file":"Mathlib/Algebra/Group/TypeTags/Hom.lean","decl":"AddMonoidHom.toMultiplicative","line":25,"sev":"NIT","status":"confirmed","cat":"generality","pattern":"hom-transport-stronger-than-hom-class","claim":"`A →+ B` is defined for `[AddZero A] [AddZero B]`, but the six transports (and their `coe_`/`_id`/ext lemmas) require `AddZeroClass`/`MulOneClass`. The bodies use no identity law; the obstacle is upstream: `TypeTags/Basic.lean` has `MulOneClass (Multiplicative α)` from `AddZeroClass α` but no `MulOne (Multiplicative α)` from `AddZero α`, so `Multiplicative A →* Multiplicative B` does not even elaborate for `[AddZero A]`. Only exotic non-unital `AddZero` structures are excluded.","fix":"Add `MulOne (Multiplicative α)`/`AddZero (Additive α)` instances in `TypeTags/Basic.lean`, then weaken the transports to `AddZero`/`MulOne`.","ev":"probe2.lean L17 `#check fun [AddZero A] [AddZero B] => (A →+ B)` elaborates; L18 `(Multiplicative A →* Multiplicative B)` fails: failed to synthesize `MulOne (Multiplicative A)`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-52deee","file":"Mathlib/Algebra/Homology/HomotopyCategory/Acyclic.lean","decl":"(file)","line":29,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-open","claim":"`open ... Pretriangulated` at L29 is unused: nothing in the file needs an unqualified `CategoryTheory.Pretriangulated` name.","fix":"Use `open CategoryTheory Limits`.","ev":"hunts/homotopy-acyclic/NoOpen.lean (src with `open CategoryTheory Limits`) compiles with no output (exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-05c166","file":"Mathlib/Algebra/Homology/HomotopyCategory/Acyclic.lean","decl":"HomotopyCategory.subcategoryAcyclic","line":37,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"Acyclic complexes form a thick subcategory, but `(subcategoryAcyclic C).IsStableUnderRetracts` is not available (neither here nor generically for `Functor.homologicalKernel`).","fix":"Add `IsStableUnderRetracts` for `Functor.homologicalKernel` (retract of zero is zero) and get it here by `infer_instance`.","ev":"-- hunts/homotopy-acyclic/P2.lean: `example [Abelian C] : (HomotopyCategory.subcategoryAcyclic C).IsStableUnderRetracts := by infer_instance` fails (synthInstanceFailed) with `Mathlib.CategoryTheory.ObjectProperty.Retract` imported.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-0c49fa","file":"Mathlib/Algebra/Homology/HomotopyCategory/Acyclic.lean","decl":"HomotopyCategory.quotient_obj_mem_subcategoryAcyclic_iff_acyclic","line":61,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`quotient_obj_mem_subcategoryAcyclic_iff_acyclic` is not `@[simp]`, so `simpa using hK` cannot turn `K.Acyclic` into membership of its image; its three consumer files (DerivedCategory/Plus, KInjective, KProjective) rewrite with it by hand in both directions.","fix":"Tag it `@[simp]` (LHS is a membership of an image under `quotient`, RHS the complex-level predicate).","ev":"-- hunts/homotopy-acyclic/P.lean\nexample (K : CochainComplex C ℤ) (hK : K.Acyclic) : HomotopyCategory.subcategoryAcyclic C ((HomotopyCategory.quotient _ _).obj K) := by simpa using hK  -- fails: type mismatch after simplification","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d2d979","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"(file)","line":9,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-import","claim":"The public imports `Mathlib.Algebra.Category.Grp.Preadditive`, `Mathlib.Algebra.Category.ModuleCat.Basic` and `Mathlib.Algebra.Module.Pi` are redundant: they come transitively through `ModuleCat.Limits`, and the file compiles without them.","fix":"Drop the three imports (after checking downstream with the import minimizer).","ev":"hunts/homcomplex/noimp.lean (src without those three imports) compiles with the lakefile options, 0 errors.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-61cba2","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"(file)","line":20,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-typos","claim":"The module docstring has several slips: 'arbitrary families for morphisms' (of), 'a term of type of `Cochain F G n`', 'the signs conventions', and 'choices, which provides' (provide). The `linearHomComplex` docstring says 'a `R`-linear'.","fix":"Fix the wording.","ev":"src L20, L24, L29.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-dbe23c","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.zero_v","line":106,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-shadowing-binder","claim":"`zero_v`, `add_v`, `sub_v`, `neg_v`, `smul_v` and `units_smul_v` (L106–127) each re-bind `{n : ℤ}`, shadowing the section variable `n`, which is already implicit after `variable {F G n}` (L76). The binder is a leftover: deleting it gives the same signatures, and the file still compiles.","fix":"Drop the `{n : ℤ}` binder from these six lemmas.","ev":"hunts/homcomplex/batch0/SemiringR.lean (L106–126 with `{n : ℤ}` removed; the whole file compiles cleanly)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a8793b","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.ofHoms_zero","line":140,"sev":"NIT","status":"confirmed","cat":"api","pattern":"simp-lemma-misses-spelling","claim":"`ofHoms_zero` is stated for the lambda `ofHoms (fun p => 0)`, while its name reads `ofHoms 0 = 0`. Simp does not identify the two spellings: `simp` makes no progress on `ofHoms (0 : ∀ p, F.X p ⟶ G.X p) = 0`. Conversely, a lemma stated with `0` does not fire on the lambda.","fix":"Add a companion `@[simp] lemma ofHoms_zero' : ofHoms (0 : ∀ p, F.X p ⟶ G.X p) = 0` (or state the main lemma with `0` and keep the lambda form as the primed variant).","ev":"hunts/homcomplex/batch0/P1.lean section G: `example : Cochain.ofHoms (0 : ∀ p, F.X p ⟶ G.X p) = 0 := by fail_if_success simp; cat_disch`; hunts/homcomplex/batch0/SemiringR.lean P5 shows `simp only [ofHoms_zero_pi]` failing on the lambda form and `simp only [Cochain.ofHoms_zero]` failing on the `0` form","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a2e389","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"(file)","line":272,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"doc-grammar","claim":"The batches.json entry \"`comp_assoc`\" is the `/-! … -/` section comment whose line 272 starts with \"lemma `comp_assoc`\". Its last sentence is ungrammatical: \"there are better choices, which provides the following simplification lemmas\" (should be \"which provide\" / \"leading to\"). The listed lemmas also include `comp_assoc_of_second_degree_eq_neg_third_degree`, which is not a 0-cochain case; the \"In a few cases, like …\" wording covers it, so that part is fine.","fix":"Reword to \"… there are better choices, which lead to the following simplification lemmas.\"","ev":"src.lean L271-274: \"In a few cases, like when one of the three cochains is a `0`-cochain, there are better choices, which provides the following simplification lemmas.\"","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-504063","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.δ","line":407,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-omits-convention","claim":"The docstring of `δ` ('The differential on the complex of morphisms between cochain complexes.') states neither the formula/sign convention ((δ z)_{p,q} = z ≫ d_G + (-1)^m • d_F ≫ z, i.e. Conrad's d f = d∘f - (-1)^n f∘d) nor that `δ n m` is the junk value 0 unless `n + 1 = m`; both are only in the following `/-! -/` note. The definition itself is correct: sign checks at degrees -1→0, 0→1, 1→2 and the Leibniz rule with sign (-1)^{n₂} all compile (batch3/Probe1.lean P3, Probe2.lean Q3).","fix":"Extend the docstring with the defining formula, the sign (-1)^m and the convention that `δ n m = 0` when `n + 1 ≠ m`.","ev":"measured: src.lean line 406 docstring vs lines 407-409 definition and lines 411-415 note; sign checks in hunts/homcomplex/batch3/Probe1.lean (P3) and Probe2.lean (Q3) compile","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-27dd1d","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.δ_shape","line":426,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`δ_shape` (δ n m z = 0 when ¬ n + 1 = m) is not `@[simp]`, unlike its model `HomologicalComplex.shape` (`attribute [simp] shape`, HomologicalComplex.lean:67); plain `simp` cannot close `δ 0 2 z = 0`, and 6 call sites pass it by hand (`simp [δ_shape _ _ h]`). With the attribute the whole file still compiles and `#lint only simpNF simpComm synTaut` passes.","fix":"Tag `δ_shape` with `@[simp]` so `simp` discharges off-diagonal differentials (as `HomologicalComplex.shape` does).","ev":"example (z : Cochain F G 0) : δ 0 2 z = 0 := by\n  fail_if_success simp\n  simp [δ_shape]\nattribute [local simp] δ_shape in\nexample (z : Cochain F G 0) : δ 0 2 z = 0 := by simp\n-- hunts/homcomplex/batch3/Probe2.lean (Q1); whole-file check with @[simp] + lint: hunts/homcomplex/batch3/Copy3.lean","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-5b80ba","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.δ_hom","line":438,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"def-not-lower-camel-case","claim":"`δ_hom` is a `def` (a bundled `→ₗ[R]` map) but is named in snake_case; Mathlib names data lowerCamelCase, as this file does for its siblings `Cocycle.toCochainAddMonoidHom` and `Cocycle.toCochainLinearMap`. The `_hom` suffix also reads like a lemma about an `Iso.hom` (cf. `Functor.OplaxMonoidal.δ_hom`-style lemma names elsewhere in Mathlib).","fix":"Rename to `δHom` (or `δLinearMap`) with a deprecated alias.","ev":"measured: src.lean:438 `def δ_hom : Cochain F G n →ₗ[R] Cochain F G m`; src.lean:715,723 `def toCochainAddMonoidHom`, `def toCochainLinearMap`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-3a106b","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.δ_hom","line":438,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"needless-case-split","claim":"The `map_add'`/`map_smul'` proofs case-split on `n + 1 = m` and go through `δ_v`/`δ_shape`, but additivity and R-linearity hold pointwise from the definition with no index matching; unfolding `δ` gives 3-line proofs without the case split (13 → 7 lines). The rest of the file compiles with the shorter proofs.","fix":"Prove both fields by `ext p q hpq; simp only [δ, Cochain.mk_v, ...]` (plus `abel` for `map_add'`) without `by_cases`.","ev":"  map_add' α β := by\n    ext p q hpq\n    simp only [δ, Cochain.mk_v, Cochain.add_v, add_comp, comp_add, smul_add]\n    abel\n  map_smul' r a := by\n    ext p q hpq\n    simp only [δ, Cochain.mk_v, Cochain.smul_v, Linear.comp_smul, Linear.smul_comp, smul_add,\n      smul_comm m.negOnePow r, RingHom.id_apply]\n-- in hunts/homcomplex/batch3/Copy1.lean (whole file compiles); standalone versions in Probe1.lean (P2)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-60e041","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.δ_δ","line":474,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"long-terminal-simp-only","claim":"The proof ends with a terminal `simp only` listing 16 lemmas; a plain terminal `simp` with only the three `δ_v` instances, `← h₁₂` and `Int.negOnePow_succ` closes the same goal.","fix":"Replace the 16-lemma terminal `simp only` by `simp [δ_v …, δ_v …, δ_v …, ← h₁₂, Int.negOnePow_succ]`.","ev":"  ext p q hpq\n  simp [δ_v n₁ n₂ h₁₂ _ p q hpq _ _ rfl rfl,\n    δ_v n₀ n₁ h₀₁ z p (q - 1) (by lia) (q - 2) _ (by lia) rfl,\n    δ_v n₀ n₁ h₀₁ z (p + 1) q (by lia) _ (p + 2) rfl (by lia), ← h₁₂, Int.negOnePow_succ]\n-- hunts/homcomplex/batch3/Copy3.lean (whole file compiles)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-24b8c7","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.δ_neg_one_cochain","line":552,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"removable-backward-compat-option","claim":"`set_option backward.defeqAttrib.useBackward true in` (a Lean-upgrade compatibility switch) is needed only because the statement's index proof does `dsimp at hij` on `(ComplexShape.up ℤ).Rel j i`; without the option that `dsimp` makes no progress (Copy2.lean), but writing the proof as `simp only [ComplexShape.up_Rel] at hij; lia` lets the option go and the whole file, including the downstream `Cochain.equivHomotopy`, still compiles.","fix":"Replace `by dsimp at hij; rw [← hij, add_neg_cancel_right]` with `by simp only [ComplexShape.up_Rel] at hij; lia` and drop the `set_option`.","ev":"lemma δ_neg_one_cochain (z : Cochain F G (-1)) :\n    δ (-1) 0 z = Cochain.ofHom (Homotopy.nullHomotopicMap'\n      (fun i j hij => z.v i j (by simp only [ComplexShape.up_Rel] at hij; lia))) := by\n-- (proof unchanged) in hunts/homcomplex/batch3/Copy1.lean, compiles; option removed alone: hunts/homcomplex/batch3/Copy2.lean fails with '`dsimp` made no progress'","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2c8188","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex","line":571,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"def-not-lower-camel-case","claim":"`HomComplex F G : CochainComplex AddCommGrpCat ℤ` is a term (an object of a category), so Mathlib's convention calls for lowerCamelCase; its sibling in the same file is `linearHomComplex`, and the analogous constructions are `mappingCone`/`mappingCocone`. (The UpperCamelCase name doubles as the namespace for `Cochain`/`Cocycle`.)","fix":"Optionally rename the complex to `homComplex` (deprecated alias), keeping the `HomComplex` namespace; otherwise leave as a long-established name.","ev":"measured: src.lean:571 `def HomComplex : CochainComplex AddCommGrpCat ℤ`; src.lean:975 `def linearHomComplex : CochainComplex (ModuleCat R) ℤ`; MappingCone.lean:57 `noncomputable def mappingCone : CochainComplex C ℤ`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-8927e6","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex","line":571,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-compatibility-lemma","claim":"`HomComplex F G` is definitionally `forget₂ (ModuleCat R) AddCommGrpCat` applied degreewise to `linearHomComplex R F G` for every `R` (proved by `rfl`), but no lemma or iso records this; `HomComplexCohomology.linearLeftHomologyData'` rebuilds the comparison ad hoc with `parallelPair.ext (Iso.refl _) (Iso.refl _)`.","fix":"Add `(forget₂ (ModuleCat R) AddCommGrpCat).mapHomologicalComplex _ |>.obj (linearHomComplex R F G) = HomComplex F G` (or an iso) next to `linearHomComplex`.","ev":"example {R : Type*} [Ring R] [Linear R C] :\n    ((forget₂ (ModuleCat R) AddCommGrpCat).mapHomologicalComplex _).obj\n      (linearHomComplex R F G) = HomComplex F G := rfl\n-- hunts/homcomplex/batch3/Probe2.lean (Q2); `git grep forget₂` in HomComplex*.lean finds only the two isLimitOfReflects/isColimitOfReflects uses","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-86d2b6","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cocycle.mem_iff","line":590,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"mem-iff-name-mismatch","claim":"`Cocycle.mem_iff` is about membership of a `Cochain` in the subgroup `cocycle F G n`, not about the type `Cocycle`. Because `z : Cochain F G n`, dot notation through the `Cocycle` namespace can never apply. The sibling in HomComplexCohomology.lean:58 follows the `mem_<set>_iff` convention as `HomComplex.mem_coboundaries_iff`.","fix":"Rename to `HomComplex.mem_cocycle_iff`, keeping `Cocycle.mem_iff` as a deprecated alias.","ev":"Cocycle.mem_iff (hnm : n + 1 = m) (z : Cochain F G n) : z ∈ cocycle F G n ↔ δ n m z = 0   -- HomComplex.lean:590\nmem_coboundaries_iff (α : Cocycle K L n) (m : ℤ) (hm : m + 1 = n) : α ∈ coboundaries K L n ↔ ...   -- HomComplexCohomology.lean:58, namespace CochainComplex.HomComplex","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6f9de8","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cocycle.instModule","line":638,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"hand-rolled-instance-transport","claim":"The `Module R (Cocycle F G n)` instance is built by hand with six field proofs (four `aesop` calls), whereas the standard transport along the injective coercion gives a one-line instance that is definitionally equal to it.","fix":"Use `Function.Injective.module R ((cocycle F G n).subtype : Cocycle F G n →+ Cochain F G n) Subtype.val_injective (fun _ _ => rfl)`.","ev":"-- hunts/homcomplex/batch4/HomComplexB.lean (copy of src.lean), inserted after L644:\ndef moduleAlt : Module R (Cocycle F G n) :=\n  Function.Injective.module R ((cocycle F G n).subtype : Cocycle F G n →+ Cochain F G n)\n    Subtype.val_injective (fun _ _ => rfl)\nexample : (moduleAlt : Module R (Cocycle F G n)) = instModule := rfl\n-- both compile (the instance itself elaborates fast: each aesop call takes about 10 ms per the profiler, so this is style only)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-bb5926","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cocycle.δ_eq_zero","line":653,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-binder-shadows-section-variable","claim":"`δ_eq_zero` re-binds `{n : ℤ}` although `variable {n}` (L593/L616) already makes `n` an implicit section variable, so the binder only shadows it. The explicit `(m : ℤ)` re-binding is justified, since it puts `m` after `z`.","fix":"Drop the `{n : ℤ}` binder.","ev":"L593 `variable {n}`; L616 `variable {F G n}`; L653 `lemma δ_eq_zero {n : ℤ} (z : Cocycle F G n) (m : ℤ) : δ n m (z : Cochain F G n) = 0`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a94d28","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cocycle.homOf","line":670,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"inline-rederivation-of-existing-lemma","claim":"The `comm'` proof of `homOf` destructures `z` and re-derives `δ 0 1 z = 0` through `rw [mem_iff 0 1 (zero_add 1)] at hz`, which repeats `Cocycle.δ_eq_zero` proved 15 lines earlier. Using that lemma drops the `rcases`/`dsimp`/`rw` lines.","fix":"`rintro i j rfl; simpa only [δ_zero_cochain_v, Cochain.zero_v, sub_eq_zero] using Cochain.congr_v (δ_eq_zero z 1) i (i + 1) rfl`.","ev":"-- hunts/homcomplex/batch4/HomComplexB2.lean (copy of src.lean), inserted after L678:\ndef homOf' (z : Cocycle F G 0) : F ⟶ G where\n  f i := (z : Cochain _ _ _).v i i (add_zero i)\n  comm' := by\n    rintro i j rfl\n    simpa only [δ_zero_cochain_v, Cochain.zero_v, sub_eq_zero]\n      using Cochain.congr_v (δ_eq_zero z 1) i (i + 1) rfl\n-- compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-fed6f9","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cocycle.isKernel","line":728,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unneeded-backward-option","claim":"`set_option backward.defeqAttrib.useBackward true in` (L728) is not needed. A copy of `isKernel` with only `backward.isDefEq.respectTransparency false` compiles. Dropping `respectTransparency` does break it: `ext : 3; simp [← hl]` leaves goals.","fix":"Delete the `backward.defeqAttrib.useBackward` line above `isKernel`.","ev":"hunts/homcomplex/batch5/srcP.lean: variant `isKernel_P_noUseBackward` (L770-787, only respectTransparency kept) compiles; `isKernel_P_noopt` and `isKernel_P_noRespectTransp` fail at the uniqueness proof (srcP.out)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a1c85d","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.δ_comp_ofHom","line":769,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"double-blank-line","claim":"Two consecutive blank lines (L769-770) follow `δ_comp_ofHom`. It is the only double blank line in the file.","fix":"Delete one of the two blank lines.","ev":"awk 'prev==\"\" && $0==\"\" {print NR} {prev=$0}' src.lean -> 770","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6fdf8a","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.equivHomotopy_apply_of_eq","line":829,"sev":"NIT","status":"confirmed","cat":"api","pattern":"redundant-simp-lemma","claim":"This `@[simp]` lemma is redundant: `simp [-Cochain.equivHomotopy_apply_of_eq]` proves it from the generated `equivHomotopy_apply_coe` and `ofHomotopy_ofEq` (L203). Nothing in Mathlib uses it (git grep finds no other occurrence).","fix":"Drop the lemma, or at least its `@[simp]` attribute.","ev":"hunts/homcomplex/batch5/p1.lean (P5): example {φ₁ φ₂ : F ⟶ G} (h : φ₁ = φ₂) : (Cochain.equivHomotopy _ _ (Homotopy.ofEq h)).1 = 0 := by simp [-Cochain.equivHomotopy_apply_of_eq]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-94ac0e","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.ofHom_injective","line":832,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"injective-not-bundled","claim":"The name says `_injective`, but the lemma is stated unbundled with ordinary implicit binders (`{f₁ f₂ : F ⟶ G} (h : ofHom f₁ = ofHom f₂) : f₁ = f₂`). So `(Cochain.ofHom_injective : Function.Injective Cochain.ofHom)` is a type mismatch and `Cochain.ofHom_injective.eq_iff` is an unknown constant. Mathlib's own `ofHom_injective` lemmas (e.g. `CommGrpCat.ofHom_injective`, Grp/Basic.lean L465) are stated as `Function.Injective`. There is no `ofHom_inj` iff lemma either.","fix":"State it as `Function.Injective (ofHom : (F ⟶ G) → Cochain F G 0)` and add `@[simp] ofHom_inj : ofHom f₁ = ofHom f₂ ↔ f₁ = f₂`.","ev":"hunts/homcomplex/batch5/p1.lean (P7): example : Function.Injective (Cochain.ofHom : (F ⟶ G) → Cochain F G 0) := Cochain.ofHom_injective -- Type mismatch; example (f₁ f₂ : F ⟶ G) : Cochain.ofHom f₁ = Cochain.ofHom f₂ ↔ f₁ = f₂ := Cochain.ofHom_injective.eq_iff -- Unknown constant","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b84e50","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.single","line":838,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"The docstring of `Cochain.single` promises `single f n = 0` when `p + n ≠ q`, but there is no such lemma, only the componentwise `single_v_eq_zero`/`single_v_eq_zero'` (and `single_zero` is about `f = 0`). Similarly, `Cocycle.precomp`/`postcomp` have no identity or composition laws.","fix":"Add `single_eq_zero_of_ne` (conditional simp) and `precomp_id`/`postcomp_id`/composition lemmas.","ev":"src: `single` docstring and the lemmas following it; `git grep 'single_eq_zero_of_ne\\|precomp_id\\|postcomp_id' origin/master -- Mathlib/Algebra/Homology/HomotopyCategory` finds nothing.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-27ab3e","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.single_zero","line":869,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"golfable-case-split","claim":"The 10-line nested case split proving `single_zero` is replaced by the one-liner `ext; simp [single]`.","fix":"Replace the proof by `ext; simp [single]`.","ev":"example (p q n : ℤ) :\n    (Cochain.single (p := p) (q := q) (0 : K.X p ⟶ L.X q) n : Cochain K L n) = 0 := by\n  ext; simp [Cochain.single]\n-- hunts/homcomplex/batch6/probe1.lean","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-3ba885","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.map_comp","line":941,"sev":"NIT","status":"confirmed","cat":"api","pattern":"explicit-arg-inferable","claim":"`variable (K L n)` (L935, meant for `map_zero`) leaks into `map_comp` and `map_ofHom`: `map_comp` takes an explicit `(K : CochainComplex C ℤ)` determined by `z₂`, and `map_ofHom` takes explicit `(K L)` determined by `f`.","fix":"Scope `variable (K L n) in` to `map_zero` only, so `K`/`L` stay implicit in `map_comp` and `map_ofHom`.","ev":"#check @Cochain.map_comp  -- ∀ ... {F G : CochainComplex C ℤ} (K : CochainComplex C ℤ) ... (z₁ : Cochain F G n₁) (z₂ : Cochain G K n₂) ...\n#check @Cochain.map_ofHom  -- ∀ ... (K L : CochainComplex C ℤ) ... (f : K ⟶ L) (Φ : C ⥤ D) ...\n(hunts/homcomplex/batch6/probe1.out)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-bf425c","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cochain.map_comp","line":941,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"shadowed-section-variable","claim":"`map_comp` re-binds `(Φ : C ⥤ D) [Φ.Additive]` (L942), shadowing the section variables of the same name and type declared at L912.","fix":"Delete the binder `(Φ : C ⥤ D) [Φ.Additive]` from `map_comp` and use the section variable.","ev":"src.lean L912 `(Φ : C ⥤ D) [Φ.Additive]` (section variable) and L942 `(Φ : C ⥤ D) [Φ.Additive] :` in map_comp; removing the re-binding compiles (hunts/homcomplex/batch6/src_gen.lean).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6e4cd1","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.linearHomComplex","line":975,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-article","claim":"Docstring says \"in a `R`-linear category\"; Mathlib writes \"an `R`-linear\" (99 occurrences vs 5).","fix":"Write \"in an `R`-linear category\".","ev":"git grep -c 'an `R`-linear' origin/master -- Mathlib  => 99; 'a `R`-linear' => 5","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d8ea9d","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean","decl":"CochainComplex.HomComplex.Cocycle.isKernel'","line":985,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-names-wrong-object","claim":"Docstring says `Cocycle K L n` is the kernel of the differential on `HomComplex K L` (the `AddCommGrpCat`-valued complex), but the statement is about the differential of `linearHomComplex R K L`.","fix":"Say \"is the kernel of the differential on `linearHomComplex R K L`\".","ev":"src.lean L982-983 docstring vs L986 `IsLimit (KernelFork.ofι (f := (linearHomComplex R K L).d n m) ...)`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4b983a","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean","decl":"CochainComplex.HomComplex.CohomologyClass.descAddMonoidHom_cohomologyClass","line":133,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-breaks-convention","claim":"`descAddMonoidHom_cohomologyClass` states `descAddMonoidHom f hf (mk x) = f x`. Its siblings name the constructor (`toHom_mk`, `mk_add`, ...), so `descAddMonoidHom_mk` is the predictable name.","fix":"Rename to `descAddMonoidHom_mk` (deprecated alias).","ev":"src L132-134; siblings L152 `toHom_mk`, L95 `mk_add`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-92b6e7","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean","decl":"CochainComplex.HomComplex.CohomologyClass.mk_smul","line":202,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`mk_zero`/`mk_add`/`mk_sub`/`mk_neg` are `@[simp]` but `mk_smul` (same shape, `rfl`) and the computation rule `toHom_mk` are not.","fix":"Tag `mk_smul` (and probably `toHom_mk`) `@[simp]`, adjusting the `simp [← mk_smul]` calls in the `Module` instance (moot if H2 is applied).","ev":"src L94-104 vs L201-202, L152-153.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ff552b","file":"Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean","decl":"CochainComplex.HomComplex.linearLeftHomologyData","line":301,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"stale-docstring","claim":"The docstring of `linearLeftHomologyData` says '`CohomologyClass K L m` identifies to the cohomology ... in degree `m`', copied from the primed version, but this declaration has no `m`: it is in degree `n`. (Compare the correct unprimed `leftHomologyData` docstring.)","fix":"Replace `m` by `n` in that docstring.","ev":"src L301-306 (`linearLeftHomologyData [Linear R C] : ((linearHomComplex R K L).sc n).LeftHomologyData`) vs L258-259.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-d3e966","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"HomologicalComplexUpToQuasiIso.Q","line":40,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-instance","claim":"`HomologicalComplexUpToQuasiIso.Q` (and `Qh`) get no `EssSurj` instance: `infer_instance` fails for `Q.EssSurj`, although `Localization.essSurj _ (HomologicalComplex.quasiIso C c)` provides it in one term; `DerivedCategory/Basic.lean` registers it only for its `up ℤ` specialisation.","fix":"Register `instance : (HomologicalComplexUpToQuasiIso.Q (C := C) (c := c)).EssSurj := Localization.essSurj _ _` (and the `Qh` analogue).","ev":"main/probe_esssurj.lean: `infer_instance` for `Q.EssSurj` fails; `Localization.essSurj _ (HomologicalComplex.quasiIso C c)` compiles.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-18fa3a","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"HomologicalComplexUpToQuasiIso","line":48,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"stale-module-docstring","claim":"The module docstring describing this category is stale and in the future tense. It says 'When `C` is abelian, this will be the derived category', but `DerivedCategory/Basic.lean:87` now defines `DerivedCategory := HomologicalComplexUpToQuasiIso C (ComplexShape.up ℤ)`. It says 'we shall show' the homotopy-category comparison, which is proved in this file (instances at L234, L287, L312). It does not name the main declarations (`Q`, `Qh`, `homologyFunctor`, `mapHomologicalComplexUpToQuasiIso`).","fix":"Rewrite the module docstring in the present tense, pointing to `DerivedCategory` and listing the main definitions and the `Qh.IsLocalization` instance.","ev":"src.lean L17-25 vs `def DerivedCategory : Type (max u v) := HomologicalComplexUpToQuasiIso C (ComplexShape.up ℤ)` at origin/master:Mathlib/Algebra/Homology/DerivedCategory/Basic.lean:87","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-4b9610","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"HomologicalComplexUpToQuasiIso.isIso_Q_map_iff_mem_quasiIso","line":71,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unneeded-backward-compat-option","claim":"The `set_option backward.defeqAttrib.useBackward true in` on this lemma (L70) is unnecessary: the file compiles cleanly without it. The same option on L38 and L113 is still needed, since removing those breaks `dsimp`/`simp only`.","fix":"Delete the `set_option backward.defeqAttrib.useBackward true in` line before `isIso_Q_map_iff_mem_quasiIso`.","ev":"hunts/homology-localization/batch0/NoBackward70.lean (src.lean minus line 70) compiles with no messages; hunts/homology-localization/batch0/NoBackward.lean (minus lines 38, 70, 113) errors only at src L42 (`dsimp` made no progress) and src L115 (unsolved goals)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-7c1de6","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"ComplexShape.QFactorsThroughHomotopy","line":157,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"class-restates-general-predicate","claim":"The class's only field `areEqualizedByLocalization : ∀ {K L} {f g : K ⟶ L}, Homotopy f g → AreEqualizedByLocalization (HomologicalComplex.quasiIso C c) f g` is the general predicate `HomRel.FactorsThroughLocalization` (Mathlib/CategoryTheory/Localization/Quotient.lean:35: `def FactorsThroughLocalization (W : MorphismProperty C) : Prop := ∀ ⦃X Y : C⦄ ⦃f g : X ⟶ Y⦄, homRel f g → AreEqualizedByLocalization W f g`) applied to the homotopy relation `homotopic C c` (HomotopyCategory.lean:33, `fun _ _ f g => Nonempty (Homotopy f g)`). Probe P1 proves `c.QFactorsThroughHomotopy C ↔ (homotopic C c).FactorsThroughLocalization (HomologicalComplex.quasiIso C c)` with a one-line term in each direction. The class does not use the general predicate and the file has no bridge lemma, so the general results about it (`HomRel.FactorsThroughLocalization.strictUniversalPropertyFixedTarget'`, `.isLocalizedEquivalence`, used for model categories in AlgebraicTopology/ModelCategory/{Cofibrant,Fibrant}ObjectHomotopy.lean and {Left,Right}Homotopy.lean) are never applied to homological complexes; see the instance@L234 finding for what this costs. Importing Localization/Quotient.lean adds exactly 1 module to this file's import closure (measured by walking the import graph). A class is still needed for instance search, so this is a restatement, not a drop-in replacement.","fix":"Keep the class but state its field as `(homotopic C c).FactorsThroughLocalization (HomologicalComplex.quasiIso C c)`, or add a bridge lemma `ComplexShape.QFactorsThroughHomotopy.factorsThroughLocalization`.","ev":"hunts/homology-localization/batch1/probe2.lean theorem p1: `theorem p1 : c.QFactorsThroughHomotopy C ↔ (homotopic C c).FactorsThroughLocalization (HomologicalComplex.quasiIso C c) := ⟨fun _ _ _ _ _ ⟨h⟩ => ComplexShape.QFactorsThroughHomotopy.areEqualizedByLocalization h, fun h => ⟨fun h' => h ⟨h'⟩⟩⟩` (imports Mathlib.Algebra.Homology.Localization and Mathlib.CategoryTheory.Localization.Quotient); probe2.out: 'Probe.p1' depends on axioms: [propext, Classical.choice, Quot.sound].","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"Re-graded MINOR→NIT on 2026-10-07: Astra A2 claim 4 disagrees that it is a duplicate — `QFactorsThroughHomotopy` is an instance-search interface with consumers and registered instances, and its field takes an actual homotopy where `homotopic` packages `Nonempty`; at most a bridge lemma/cross-reference is missing.","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-b445ba","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"HomologicalComplexUpToQuasiIso.quotientCompQhIso","line":184,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"data-defined-by-tactic","claim":"This data (an `Iso`) is defined in tactic mode as `by apply Quotient.lift.isLift`. The term `Quotient.lift.isLift _ _ _` elaborates in its place.","fix":"Write `def quotientCompQhIso : HomotopyCategory.quotient C c ⋙ Qh ≅ Q := Quotient.lift.isLift _ _ _`.","ev":"hunts/homology-localization/batch1/copy1.lean (copy of src.lean with line 184-185 replaced by `def quotientCompQhIso : HomotopyCategory.quotient C c ⋙ Qh ≅ Q :=\\n  Quotient.lift.isLift _ _ _`): no error at that declaration; `#print axioms HomologicalComplexUpToQuasiIso.quotientCompQhIso` gives [propext, Classical.choice, Quot.sound] (copy1.out). The only errors in copy1.out (lines 213, 222) come from a separate, failed experiment removing the `set_option backward.isDefEq.respectTransparency false` on the `homologyFunctorFactorsh_*_app` lemmas. Those options are needed.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-ff9675","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"HomologicalComplexUpToQuasiIso.Qh_inverts_quasiIso","line":187,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"element-chase-instead-of-api","claim":"The 6-line proof works element by element: it destructures objects, lifts φ through `map_surjective` and rewrites with `quotient_map_mem_quasiIso_iff`. The same fact follows in two lines from API that already exists, using `quasiIso_eq_quasiIso_map_quotient` (line 141), `MorphismProperty.IsInvertedBy.map_iff` and `MorphismProperty.IsInvertedBy.iff_of_iso`.","fix":"Replace the proof with `rw [HomotopyCategory.quasiIso_eq_quasiIso_map_quotient, MorphismProperty.IsInvertedBy.map_iff, ← MorphismProperty.IsInvertedBy.iff_of_iso _ (quotientCompQhIso C c).symm]; exact Localization.inverts Q _`.","ev":"hunts/homology-localization/batch1/probe2.lean theorem p4: `theorem p4 : (HomotopyCategory.quasiIso C c).IsInvertedBy Qh := by rw [HomotopyCategory.quasiIso_eq_quasiIso_map_quotient, MorphismProperty.IsInvertedBy.map_iff, ← MorphismProperty.IsInvertedBy.iff_of_iso _ (quotientCompQhIso C c).symm]; exact Localization.inverts Q _`; 'Probe.p4' depends on axioms: [propext, Classical.choice, Quot.sound].","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-758ae5","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"ComplexShape.strictUniversalPropertyFixedTargetQuotient","line":261,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"unused-have","claim":"The line `have : DecidableRel c.Rel := by classical infer_instance` inside `lift` is a leftover. `Homotopy.map_eq_of_inverts_homotopyEquivalences` is declared under `omit [DecidableRel c.Rel] in` (HomotopyCofiber.lean:766) and takes no decidability instance. A copy of the file with the line deleted compiles, and `ComplexShape.quotient_isLocalization` still elaborates.","fix":"Delete line 261 (`have : DecidableRel c.Rel := by classical infer_instance`).","ev":"hunts/homology-localization/batch1/copy1.lean (src.lean with line 261 deleted): no error in the Cylinder section; `#print axioms ComplexShape.quotient_isLocalization` gives [propext, Classical.choice, Quot.sound] (copy1.out).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-57c8d8","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"ComplexShape.QFactorsThroughHomotopy_of_exists_prev","line":272,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"uppercase-theorem-name","claim":"This is a theorem whose conclusion is the Prop-valued class `QFactorsThroughHomotopy`, but its name starts with an upper-case letter. Mathlib's convention writes a Prop-valued structure or class in lowerCamelCase inside a theorem name (compare `quotient_isLocalization` on L266, which also names a class), so this should be `qFactorsThroughHomotopy_of_exists_prev`. It has no consumers outside this file.","fix":"Rename to `ComplexShape.qFactorsThroughHomotopy_of_exists_prev`, with a deprecated alias.","ev":"Measured: src.lean L272 `lemma ComplexShape.QFactorsThroughHomotopy_of_exists_prev [CategoryWithHomology C] : c.QFactorsThroughHomotopy C`; `git grep QFactorsThroughHomotopy_of_exists_prev origin/master -- Mathlib` gives only Localization.lean:272, 294 and 319.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-43c71d","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"ComplexShape.QFactorsThroughHomotopy_of_exists_prev","line":272,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"redundant-by-exact","claim":"The field proof is `{K L f g} h := by exact <term>`. The `by exact` is redundant, and the binders `K L f g` are named but never used. The bare term `areEqualizedByLocalization h := h.map_eq_of_inverts_homotopyEquivalences hc _ (...)` compiles.","fix":"Write `areEqualizedByLocalization h := h.map_eq_of_inverts_homotopyEquivalences hc _ (...)` in term mode.","ev":"hunts/homology-localization/batch2/probe1.lean P9 (term-mode instance body) compiles; hunts/homology-localization/batch2/LocCopy.lean uses it in place (exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-7348fc","file":"Mathlib/Algebra/Homology/Localization.lean","decl":"CategoryTheory.Functor.mapHomologicalComplexUpToQuasiIsoFactorsh_hom_app","line":410,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"inconsistent-component-lemma-name","claim":"The lemma evaluates `hom.app` at `(HomotopyCategory.quotient _ _).obj K`, the same shape as this file's `homologyFunctorFactorsh_hom_app_quotient_obj` (L208), but it is named `_hom_app` without the `_quotient_obj` suffix. The downstream wrapper `mapDerivedCategoryFactorsh_hom_app` (ExactFunctor.lean) copies the inconsistency.","fix":"Rename to `mapHomologicalComplexUpToQuasiIsoFactorsh_hom_app_quotient_obj`, with a deprecated alias.","ev":"Measured: src.lean L208 `lemma homologyFunctorFactorsh_hom_app_quotient_obj (K) (i) : (homologyFunctorFactorsh C c i).hom.app ((HomotopyCategory.quotient _ _).obj K) = ...` against L410 `lemma mapHomologicalComplexUpToQuasiIsoFactorsh_hom_app (K) : (F.mapHomologicalComplexUpToQuasiIsoFactorsh c).hom.app ((HomotopyCategory.quotient _ _).obj K) = ...`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-112740","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.instSemiring","line":74,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-structure-source","claim":"The source `__ := AddMonoidWithOne.unary` (L75) is a leftover. Every field it could supply comes from another source: `natCast`, `natCast_zero` and `natCast_succ` are given explicitly (L82-84), `one` comes from `instMonoid`, and `add`/`zero`/`nsmul` come from `addCommMonoid`. All it does is route `toAddMonoid` and `toOne` through the `AddMonoidWithOne.unary` abbrev (`#print` shows `toAddMonoid := __spread.0.toAddMonoid` with `__spread.0 := AddMonoidWithOne.unary`). With the line deleted, the file compiles cleanly, and the rebuilt structure equals `Module.End.instSemiring` by `with_reducible_and_instances rfl`.","fix":"Delete `__ := AddMonoidWithOne.unary` from `instSemiring`.","ev":"hunts/linearmap-end/batch1/End_nounary.lean (src.lean minus L75) compiles with the brief's flags, no errors or warnings. hunts/linearmap-end/batch1/probe2.lean Q2: `abbrev semiringNoUnary : Semiring (Module.End R M) where __ := Module.End.instMonoid; __ := LinearMap.addCommMonoid; mul_zero := comp_zero; ... natCast := fun n ↦ n • (1 : M →ₗ[R] M); natCast_zero := zero_smul ℕ _; natCast_succ := fun n ↦ AddMonoid.nsmul_succ n _` and `example : (semiringNoUnary : Semiring (Module.End R M)) = Module.End.instSemiring := by with_reducible_and_instances rfl` both compile. Q1 `#print Module.End.instSemiring` shows the `AddMonoidWithOne.unary` spread.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-0cd10e","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.isUnit_apply_inv_apply_of_isUnit","line":120,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-does-not-describe-conclusion","claim":"The names `isUnit_apply_inv_apply_of_isUnit` and `isUnit_inv_apply_apply_of_isUnit` name the `IsUnit` hypothesis twice. The leading `isUnit_` reads as a conclusion of the form `IsUnit _`, but the conclusions are the equations `f (h.unit.inv x) = x` and `h.unit.inv (f x) = x`. The convention, with the conclusion first and `_of_` for hypotheses, gives `apply_inv_apply_of_isUnit` / `inv_apply_apply_of_isUnit`, matching `Equiv.apply_symm_apply` and `CircleDeg1Lift.units_apply_inv_apply`.","fix":"Rename to `Module.End.apply_inv_apply_of_isUnit` / `Module.End.inv_apply_apply_of_isUnit` with deprecated aliases (7 call sites).","ev":"`#check @Module.End.isUnit_apply_inv_apply_of_isUnit` (hunts/linearmap-end/batch1/probe1.lean P1) prints `... (h : IsUnit f) (x : M), f (h.unit.inv x) = x`; the twin prints `h.unit.inv (f x) = x`. hunts/linearmap-end/batch1/End_general.lean declares the renamed lemmas with `@[deprecated] alias`es, no name clash, and compiles.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-33f49b","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.pow_map_zero_of_le","line":132,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"map-zero-token-misused","claim":"The name reads as a `pow` analogue of `map_zero`/`iterate_map_zero` (`f^[n] 0 = 0`), but the statement is `k ≤ l → (f ^ k) m = 0 → (f ^ l) m = 0`. Mathlib names lemmas of exactly this shape `pow_mul_eq_zero_of_le` (`a ^ m * b = 0 → a ^ n * b = 0`) and `Matrix.pow_row_eq_zero_of_le`, so the convention-following name is `pow_apply_eq_zero_of_le`. It has 11 qualified consumers (Lie/Weights/Basic, Lie/Weights/Chain, Lie/EngelSubalgebra, LinearAlgebra/Eigenspace/Basic).","fix":"Rename to `Module.End.pow_apply_eq_zero_of_le` and keep a deprecated alias.","ev":"hunts/linearmap-end/batch2/Probe1.lean (`#check @Module.End.pow_map_zero_of_le` : k ≤ l → (f ^ k) m = 0 → (f ^ l) m = 0); compare origin/master Mathlib/Algebra/Group/Hom/Defs.lean:1103 `iterate_map_one` (to_additive `iterate_map_zero` : f^[n] 0 = 0), Mathlib/Algebra/GroupWithZero/Basic.lean:239 `pow_mul_eq_zero_of_le`, Mathlib/Data/Matrix/Mul.lean:1157 `pow_row_eq_zero_of_le`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-ad477a","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.commute_pow_left_of_commute","line":136,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"commute-name-for-semiconj","claim":"Neither the hypothesis nor the conclusion is a `Commute`. The hypothesis `g₂ ∘ₛₗ f = f ∘ₛₗ g` is an intertwining (semiconjugacy) between endomorphisms of two different modules, and the conclusion raises both `g` and `g₂` to the k-th power, whereas Mathlib's `Commute.pow_left` raises only the left factor. When M₂ = M and σ = id, the statement is exactly `SemiconjBy.pow_right`; for a general `f` it is `Function.Semiconj.iterate_right` through `coe_pow`. No docstring says this. It has 9 consumers.","fix":"Rename to something like `Module.End.pow_comp_eq_comp_pow`, keeping a deprecated alias, and add a docstring calling it the intertwining/semiconjugacy statement.","ev":"hunts/linearmap-end/batch2/Probe2.lean (A): `example (f g g₂ : Module.End R M) (h : g₂.comp f = f.comp g) (k : ℕ) : (g₂ ^ k).comp f = f.comp (g ^ k) := ((SemiconjBy.pow_right (show SemiconjBy f g g₂ from h.symm) k)).symm` compiles; hunts/linearmap-end/batch2/Probe1.lean (4): the general semilinear statement by `ext x; simpa [Module.End.pow_apply] using (Semiconj.iterate_right (f := f) (fun x ↦ congr($h x).symm) k x).symm` compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-25d5a4","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.iterate_succ","line":151,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"iterate-name-for-pow","claim":"Mathlib uses `iterate` for `f^[n]` (the naming dictionary maps `^` to `pow`), and `Function.iterate_succ : f^[n.succ] = f^[n] ∘ f` already owns the name. The statement here is `f' ^ (n + 1) = (f' ^ n) ∘ₗ f'`, which is `pow_succ f' n` up to defeq. With `open Function Module.End`, the unqualified name silently resolves to `Function.iterate_succ`: `rw [iterate_succ]` fails and `simp only [iterate_succ]` makes no progress. With only `open Module.End`, the same rewrite works.","fix":"Rename to e.g. `Module.End.pow_succ_eq_comp` and keep a deprecated alias.","ev":"hunts/linearmap-end/batch2/Probe3.lean: B' (`open Module.End in ... rw [iterate_succ]`) compiles; B'' (`open Function Module.End in ... rw [iterate_succ]`) fails with 'did not find ?f^[Nat.succ ?n]'; B''' `simp only [iterate_succ]` gives '`simp` made no progress'. hunts/linearmap-end/batch2/Probe1.lean (1): `example (f : Module.End R M) (n : ℕ) : f ^ (n + 1) = .comp (f ^ n) f := pow_succ f n` compiles","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-3b1353","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.iterate_succ'","line":152,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"iterate-name-for-pow","claim":"This has the same problem as `iterate_succ`. The statement `f' ^ (n + 1) = f' ∘ₗ f' ^ n` is about `^` (it is `pow_succ' f' n` up to defeq), but the name is `Function.iterate_succ'` (`f^[n.succ] = f ∘ f^[n]`). With `open Function Module.End`, `rw [iterate_succ']` silently picks the `Function` lemma and fails, while the fully qualified name works.","fix":"Rename to e.g. `Module.End.pow_succ_eq_comp'` and keep a deprecated alias.","ev":"hunts/linearmap-end/batch2/Probe4.lean: `open Function Module.End in example ... := by rw [iterate_succ']` fails ('did not find ?f^[Nat.succ ?n]'); control `rw [Module.End.iterate_succ']` compiles. hunts/linearmap-end/batch2/Probe1.lean (1): `... := pow_succ' f n` compiles","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-0e1932","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.iterate_surjective","line":154,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"iterate-name-for-pow","claim":"The name says `iterate`, which Mathlib reserves for `f^[n]` (`Function.Surjective.iterate : Surjective f → Surjective f^[n]`), but the statement is about the monoid power: `Surjective f' → Surjective ⇑(f' ^ n)`. The naming dictionary maps `^` to `pow`.","fix":"Rename to e.g. `Module.End.surjective_pow` and keep a deprecated alias, along with the rest of the `iterate_*` family.","ev":"hunts/linearmap-end/batch2/Probe1.lean `#check @Module.End.iterate_surjective` : Surjective ⇑f' → ∀ (n : ℕ), Surjective ⇑(f' ^ n); Probe2.lean `#check @Function.Surjective.iterate` : Surjective f → ∀ n, Surjective f^[n]","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-d72025","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.iterate_injective","line":160,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"iterate-name-for-pow","claim":"The name says `iterate`, which Mathlib reserves for `f^[n]` (`Function.Injective.iterate : Injective f → Injective f^[n]`), but the statement is about the monoid power: `Injective f' → Injective ⇑(f' ^ n)`. The naming dictionary maps `^` to `pow`.","fix":"Rename to e.g. `Module.End.injective_pow` and keep a deprecated alias, along with the rest of the `iterate_*` family.","ev":"hunts/linearmap-end/batch2/Probe1.lean `#check @Module.End.iterate_injective` : Injective ⇑f' → ∀ (n : ℕ), Injective ⇑(f' ^ n); Probe2.lean `#check @Function.Injective.iterate` : Injective f → ∀ n, Injective f^[n]","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-e0f2b6","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.iterate_bijective","line":166,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"iterate-name-for-pow","claim":"The name says `iterate`, which Mathlib reserves for `f^[n]` (`Function.Bijective.iterate : Bijective f → Bijective f^[n]`), but the statement is about the monoid power: `Bijective f' → Bijective ⇑(f' ^ n)`. The naming dictionary maps `^` to `pow`.","fix":"Rename to e.g. `Module.End.bijective_pow` and keep a deprecated alias, along with the rest of the `iterate_*` family.","ev":"hunts/linearmap-end/batch2/Probe1.lean `#check @Module.End.iterate_bijective` : Bijective ⇑f' → ∀ (n : ℕ), Bijective ⇑(f' ^ n); Probe2.lean `#check @Function.Bijective.iterate` : Bijective f → ∀ n, Bijective f^[n]","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-750d37","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.injective_of_iterate_injective","line":172,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"roundabout-nat-pred-detour","claim":"The proof detours through `Nat.succ_pred_eq_of_pos (show 0 < n by lia)` where `Nat.succ_pred_eq_of_ne_zero hn` applies directly. Its twin `surjective_of_iterate_surjective` makes the same argument by a different route (`pow_succ'`/`coe_mul` and `Nat.pos_iff_ne_zero.mpr hn`, against `iterate_succ`/`coe_comp` and `lia` here).","fix":"Use `rw [← Nat.succ_pred_eq_of_ne_zero hn, pow_succ, coe_mul] at h; exact h.of_comp`, mirroring the surjective twin.","ev":"hunts/linearmap-end/batch2/SrcEdited.lean (the replacement proof inside a copy of src.lean) compiles; also hunts/linearmap-end/batch2/Probe1.lean (3)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-03ff8e","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.injective_of_iterate_injective","line":172,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"iterate-name-for-pow","claim":"The name says `iterate` for a statement about `f' ^ n`: `n ≠ 0 → Injective ⇑(f' ^ n) → Injective ⇑f'`. Mathlib's naming dictionary maps `^` to `pow`.","fix":"Rename to e.g. `Module.End.injective_of_injective_pow` and keep a deprecated alias.","ev":"hunts/linearmap-end/batch2/Probe1.lean `#check @Module.End.injective_of_iterate_injective`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-00d677","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.surjective_of_iterate_surjective","line":177,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"roundabout-nat-pred-detour","claim":"The proof detours through `Nat.succ_pred_eq_of_pos (Nat.pos_iff_ne_zero.mpr hn)` where `Nat.succ_pred_eq_of_ne_zero hn` applies directly. It makes the same argument as `injective_of_iterate_injective` by a different route, and writes `Surjective.of_comp h` instead of `h.of_comp`.","fix":"Use `rw [← Nat.succ_pred_eq_of_ne_zero hn, pow_succ', coe_mul] at h; exact h.of_comp`.","ev":"hunts/linearmap-end/batch2/SrcEdited.lean (the replacement proof inside a copy of src.lean) compiles; also hunts/linearmap-end/batch2/Probe1.lean (3)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-1ce6c6","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.surjective_of_iterate_surjective","line":177,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"iterate-name-for-pow","claim":"The name says `iterate` for a statement about `f' ^ n`: `n ≠ 0 → Surjective ⇑(f' ^ n) → Surjective ⇑f'`. Mathlib's naming dictionary maps `^` to `pow`.","fix":"Rename to e.g. `Module.End.surjective_of_surjective_pow` and keep a deprecated alias.","ev":"hunts/linearmap-end/batch2/Probe1.lean `#check @Module.End.surjective_of_iterate_surjective`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-2822fd","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.smulLeft","line":182,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-omits-key-hypothesis","claim":"The docstring 'Scalar multiplication on the left, as a linear map.' omits the hypothesis that makes the definition exist: `α` must be central (`hα : α ∈ Set.center R`). For a module over a noncommutative ring, multiplying by a scalar on the left is not linear in general.","fix":"Say 'Multiplication by a central scalar `α`, as an `R`-linear endomorphism.' (moot if the def is deprecated).","ev":"src.lean line 182: `/-- Scalar multiplication on the left, as a linear map. -/`; line 183 signature takes `(hα : α ∈ Set.center R)`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-b817ac","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"Module.End.smulLeft_eq","line":188,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"shadowed-section-variable","claim":"`smulLeft_eq` rebinds `{R : Type*} [CommSemiring R] [Module R M]` inside a section that already declares `R`, `[Semiring R]` and `[Module R M]`. This shadows the section variable, and the resulting signature orders the binders `{M} [AddCommMonoid M] {R} [CommSemiring R] [Module R M]`, with `M` before `R`, unlike every other declaration in the file.","fix":"Drop the local rebinding: use the section's `R` with `[SMulCommClass R R M]` (see the generality finding), or move the lemma to a `CommSemiring` section.","ev":"probe1.lean `#check @Module.End.smulLeft_eq` prints `∀ {M : Type u_1} [inst : AddCommMonoid M] {R : Type u_2} [inst_1 : CommSemiring R] [inst_2 : Module R M] (α : R) (hα : autoParam (α ∈ Set.center R) _) , End.smulLeft α hα = α • LinearMap.id`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-4d1dde","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"DistribSMul.toLinearMap","line":237,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-stale-after-generalisation","claim":"The docstring says 'Each element of the monoid defines a linear map', but the definition only needs `[DistribSMul S M]`, with no monoid structure on `S`. The section variable `[Monoid S]` is not included in its signature.","fix":"Write 'Each `s : S` acting distributively on `M` (commuting with `R`) defines an `R`-linear map.'","ev":"probe1.lean `#check @DistribSMul.toLinearMap` prints `(R : Type u_1) → {S : Type u_2} → (M : Type u_3) → [Semiring R] → [AddCommMonoid M] → [Module R M] → [DistribSMul S M] → [SMulCommClass S R M] → S → M →ₗ[R] M` (no `Monoid S`).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-81ce00","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"LinearMap.applyₗ","line":376,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-section-variables","claim":"The `section CommSemiring` that opens with `applyₗ` declares `[AddCommMonoid M₃] [Module R M₃]` and `variable (f : M →ₗ[R] M₂)` (L376-378), none of which is used by any declaration of the section (`smulRightₗ_apply`/`_apply_apply` bind their own `f : M₂ →ₗ[R] R`).","fix":"Delete `[AddCommMonoid M₃]`, `[Module R M₃]` and `variable (f : M →ₗ[R] M₂)` from the section header.","ev":"hunts/linearmap-end/batch5/srccopy.lean: copy of src.lean with L376-378 replaced by `variable [CommSemiring R] [AddCommMonoid M] [AddCommMonoid M₂]` / `variable [Module R M] [Module R M₂]` compiles with no warnings","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-05737a","file":"Mathlib/Algebra/Module/LinearMap/End.lean","decl":"LinearMap.smulRightₗ_apply","line":413,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-type-ascription","claim":"The statement carries a redundant full type ascription `(smulRightₗ : (M₂ →ₗ[R] R) →ₗ[R] M →ₗ[R] M₂ →ₗ[R] M) f x` (a port leftover); `smulRightₗ f x = smulRight f x` elaborates without it, as the neighbouring `smulRightₗ_apply_apply` already does.","fix":"State it as `smulRightₗ f x = smulRight f x`.","ev":"hunts/linearmap-end/batch5/srccopy.lean (lemma restated as `theorem smulRightₗ_apply (f : M₂ →ₗ[R] R) (x : M) : smulRightₗ f x = smulRight f x := rfl`, file compiles) and hunts/linearmap-end/batch5/probe1.lean `example (f : M₂ →ₗ[R] R) (x : M) : smulRightₗ f x = smulRight f x := rfl`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261006-8bc707","file":"Mathlib/Algebra/Module/LinearMap/Index.lean","decl":"LinearMap.index","line":39,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-drops-hypothesis","claim":"`index` is defined over any `Ring` and documented as 'dim ker - dim coker', but over a non-division ring `finrank` is a rank and the usual index laws fail even for finite modules (R = ℤ/4, S = 2R: finrank S = finrank (R/S) = 0 while finrank R = 1, so f = 0 → S and g = S ↪ R have index 0, 0 but g ∘ f has index -1); the docstring warns only about infinite rank.","fix":"Add: 'over rings that are not division rings this is a difference of ranks, and the index laws below need extra hypotheses'.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-606f97","file":"Mathlib/Algebra/Module/LinearMap/Index.lean","decl":"LinearMap.index_eq_of_finiteDimensional","line":102,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"reprovable-from-existing-api","claim":"The proof's `h₂` + `h₃` (quotient by the kernel) re-derive the imported `LinearMap.finrank_range_add_finrank_ker`.","fix":"`have := f.finrank_range_add_finrank_ker; have := f.range.finrank_quotient_add_finrank; lia`.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-b92ddc","file":"Mathlib/Algebra/Module/LinearMap/Index.lean","decl":"LinearMap.index_smul","line":141,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`index_smul` is not `@[simp]`, unlike the neighbouring `index_neg`, `index_id`, `index_mkQ`, `index_subtype`.","fix":"Tag it `@[simp]` (with `ht` as a side condition, or via the unit version).","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-f12df4","file":"Mathlib/Algebra/Module/StablyFree/FreeOfInvertible.lean","decl":"exteriorPower.cofactorLinear","line":28,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"leftover-hygiene","claim":"`cofactorLinear` is marked `noncomputable` but compiles without it (its basis is data; `Basis.det` is computable). Separately, the main proof passes `exteriorPower.finrank_eq` to `simp` although it is already `@[simp]`: `by simp [hp]` suffices.","fix":"Drop `noncomputable` from `cofactorLinear` and the redundant simp argument.","ev":"hunts/stably-free-inv/computable.lean (src with `def exteriorPower.cofactorLinear`) and simphp.lean (`by simp [hp]`) both compile, exit 0, no warnings.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-8c6488","file":"Mathlib/Algebra/Module/StablyFree/FreeOfInvertible.lean","decl":"exteriorPower.cofactorToLeft","line":34,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-overstates","claim":"The docstring calls the domain 'the top exterior power of `M × N`', but `⋀[R]^(n + 1) (M × N)` is the top power only under the main theorem's rank-one hypothesis (its `hp`). As defined, `M` is arbitrary: for `M = ℚ²`, `N = ℚ¹`, `n = 1` the domain is `⋀²ℚ³`, not `⋀³ℚ³`. The helper is module-private, so only readers of this file are affected.","fix":"Say 'the `(n + 1)`-st exterior power of `M × N`'.","ev":"src L34-37: docstring 'from the top exterior power of `M × N`' on `⋀[R]^(n + 1) (M × N) →ₗ[R] M` with only `bN : Basis (Fin n) R N` fixed.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-22d8fc","file":"Mathlib/Algebra/Order/Star/Basic.lean","decl":"StarRingHomClass.instOrderHomClass","line":465,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"namespace-of-nonexistent-class","claim":"The instance `StarRingHomClass.instOrderHomClass` lives in the namespace `StarRingHomClass`, which names no class (there are `NonUnitalStarRingHomClass` and `StarRingEquivClass`, never `StarRingHomClass`). The name is referenced nowhere in Mathlib, so it could be anonymous or `StarHomClass.instOrderHomClass`.","fix":"Make the instance anonymous or rename it `StarHomClass.instOrderHomClass` (no deprecation alias needed for an unreferenced instance name).","ev":"hunts/star-ringhom/cleanup/order/Probe1.lean compiles (the instance resolves structurally); `git grep -n 'class StarRingHomClass' -- Mathlib` is empty and `git grep -n instOrderHomClass -- Mathlib` finds only this declaration.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-5e6492","file":"Mathlib/Algebra/Order/Sub/Unbundled/Hom.lean","decl":"(file)","line":13,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"stale-docstring","claim":"The module docstring ('Lemmas about subtraction in unbundled canonically ordered monoids') does not describe this file: it is about additive homomorphisms and order isomorphisms preserving or bounding truncated subtraction, and nothing in it is about canonically ordered monoids. Formatting: no blank line between the last import and the docstring, and double blank lines after `public section` and after the `### Preorder` header.","fix":"Say 'Lemmas about how additive homomorphisms interact with truncated subtraction', and normalize the blank lines.","ev":"src L12-19, L58-60.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d6cddf","file":"Mathlib/Algebra/Order/Sub/Unbundled/Hom.lean","decl":"le_mul_tsub","line":31,"sev":"NIT","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`le_mul_tsub` assumes `[Distrib R]`, but only left distributivity is used (`[Mul R] [Add R] [LeftDistribClass R]`).","fix":"Use `[Mul R] [Add R] [LeftDistribClass R]`.","ev":"-- hunts/ordsub-hom/P2.lean: `example [Mul R] [Add R] [LeftDistribClass R] [Preorder R] [Sub R] [OrderedSub R] [MulLeftMono R] : a * b - a * c ≤ a * (b - c) := by rw [tsub_le_iff_right, ← mul_add]; exact mul_le_mul_right le_tsub_add a` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c3000e","file":"Mathlib/Algebra/Order/Sub/Unbundled/Hom.lean","decl":"map_tsub_of_le","line":41,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-breaks-convention","claim":"`map_tsub_of_le` states `f a - f b = f (a - b)`, the reverse of the `map_*` orientation (`map_add`, `map_sub`, and `OrderIso.map_tsub` in this file all have `f (a ∘ b) = f a ∘ f b`), so `rw [map_tsub_of_le]` and `exact` need `.symm`.","fix":"Flip the equation (deprecating the old orientation).","ev":"src L44 vs L52.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-adbb16","file":"Mathlib/Algebra/Polynomial/Smeval.lean","decl":"Polynomial.smul_pow","line":52,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"def-shadows-root-lemma","claim":"The helper `def Polynomial.smul_pow : ℕ → R → S` (data, snake_case) has the same final name as the root lemma `smul_pow : (r • x) ^ n = r ^ n • x ^ n`, so inside `namespace Polynomial` the lemma is shadowed: `smul_pow r x n` resolves to the def and fails to elaborate.","fix":"Rename the def to `smulPow` (lowerCamelCase, as data) with a deprecated alias.","ev":"probe1.lean: inside `namespace Polynomial`, `smul_pow r x n` → Application type mismatch (expects `ℕ`) / failed to synthesize `AddCommMonoid M`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-cd6110","file":"Mathlib/Algebra/Polynomial/Smeval.lean","decl":"Polynomial.leval_eq_smeval.linearMap","line":140,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"dotted-theorem-name","claim":"`theorem leval_eq_smeval.linearMap` puts a lemma in a spurious namespace `Polynomial.leval_eq_smeval` (dotted name); the convention would be `leval_eq_smevalLinearMap`. `smeval_X_mul` and `smeval_mul_X` also indent their `induction` line by 4 spaces (L211, L244).","fix":"Rename with a deprecated alias; fix the indentation.","ev":"Source L140, L211, L244.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-492e20","file":"Mathlib/Algebra/Polynomial/Smeval.lean","decl":"Polynomial.smeval_mul","line":266,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"module-doc-omits-hypotheses","claim":"The module overview says `smeval_mul`, `smeval_comp` hold \"given power-associativity\", omitting the `[Module R S] [IsScalarTower R S S] [SMulCommClass R S S]` hypotheses that do real work (with `R = S = M₂(ℤ)` acting on the left, `(X * C E₁₂).smeval E₂₁ = E₁₁ ≠ E₂₂`), and refers to `Algebra.Polynomial.Eval` and to `Mathlib/Algebra/Algebra/Basic.lean`, neither of which holds the cited material any more.","fix":"Name the scalar compatibility hypotheses; update the file references.","ev":"Source L18, L31, L172; `ls Mathlib/Algebra/Polynomial/Eval.lean` → no such file.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-9c9957","file":"Mathlib/Algebra/Polynomial/Smeval.lean","decl":"Polynomial.smeval_commute","line":295,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"unnecessary-induction","claim":"Two inductions are unnecessary: `smeval_commute` is `smeval_commute_left R p (smeval_commute_left R q hc.symm).symm` (instead of a 15-line double induction), and `smeval_monomial_mul` is `rw [← C_mul_X_pow_eq_monomial, mul_assoc, smeval_C_mul, smeval_X_pow_mul]` (its induction hypotheses are unused).","fix":"Replace both proofs by the one-liners.","ev":"probe2.lean: both one-line proofs compile.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-99266a","file":"Mathlib/Algebra/Ring/SumsOfSquares.lean","decl":"(file)","line":1,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring","claim":"Public declarations without docstrings: `IsSumSq.one`, `IsSumSq.sum_sq`, `IsSumSq.natCast`, `Nat.isSumSq`, and the `mem_sumSq`/`coe_sumSq`/`closure_isSquare`/`sumSq_to*` lemmas of the three `sumSq` namespaces.","fix":"Add one-line docstrings.","ev":"Measured: source.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-3efcee","file":"Mathlib/Algebra/Ring/SumsOfSquares.lean","decl":"(file)","line":12,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-import","claim":"`import Mathlib.Algebra.Ring.Parity -- Algebra.Group.Even can't prove IsSquare 0 by simp` is redundant: `Mathlib.Algebra.Order.Ring.Basic` (already a public import) publicly imports it (Astra A1 item 5).","fix":"Delete the import and its comment.","ev":"hunts/sums-of-squares/probe-noparity.lean: module copy without the import compiles; Algebra/Order/Ring/Basic.lean:9 `public import Mathlib.Algebra.Ring.Parity`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-68d503","file":"Mathlib/Algebra/Ring/SumsOfSquares.lean","decl":"(file)","line":35,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"linter-suppression-for-alignment","claim":"Four `set_option linter.style.whitespace false in -- manual alignment is not recognised` (L35, L46, L70, L219) only to column-align constructor/field text; and the general one-liner `Submonoid.square_subsemiringClosure` (L183) is `private` in this file.","fix":"Drop the alignment and the `set_option`s; make the lemma public in the `Submonoid` file or inline it.","ev":"Measured: source L35, L46, L70, L183, L219.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-a202de","file":"Mathlib/Algebra/Star/MonoidHom.lean","decl":"StarMulEquiv.ofBijective","line":338,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"redundant-structure-instance-override","claim":"The body of `StarMulEquiv.ofBijective` ascribes `(hf : Function.Bijective (f : A → B))` and overrides `toFun := f`, both redundant: `{ MulEquiv.ofBijective f hf with map_star' := map_star f }` elaborates and `coe_ofBijective`/`ofBijective_apply` stay `rfl`.","fix":"Replace the body by `{ MulEquiv.ofBijective f hf with map_star' := map_star f }`.","ev":"hunts/star-ringhom/cleanup/ofbij/Probe5.lean (section 2, `sMul`) compiles with exit 0, including the two `rfl` coe/apply checks.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-144164","file":"Mathlib/Algebra/Star/StarAlgHom.lean","decl":"StarAlgEquiv.ofBijective","line":1075,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"redundant-structure-instance-override","claim":"The body of `StarAlgEquiv.ofBijective` ascribes `(hf : Function.Bijective (f : A → B))` (identical elaborated term without it) and overrides `toFun := f` (already the source's `toFun`), with `{` on a line of its own. `{ RingEquiv.ofBijective f hf with map_star' := map_star f, map_smul' := map_smul f }` elaborates and `coe_ofBijective`/`ofBijective_apply` stay `rfl`.","fix":"Replace the body by `{ RingEquiv.ofBijective f hf with map_star' := map_star f, map_smul' := map_smul f }`.","ev":"hunts/star-ringhom/cleanup/ofbij/Probe5.lean (section 1, `sAlg`) compiles with exit 0, including the two `rfl` coe/apply checks.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-18be25","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"Simps.apply","line":104,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-custom-simps-apply","claim":"The custom projection `NonUnitalStarRingHom.Simps.apply` is redundant. `initialize_simps_projections NonUnitalStarRingHom (toFun → apply)` finds the `DFunLike.coe` projection automatically, and deleting the def gives a byte-identical `@[simps]` lemma. The analogues `NonUnitalRingHom`, `RingHom`, `NonUnitalStarAlgHom` and `StarAlgHom` define no `Simps.apply`.","fix":"Delete `def Simps.apply` (L103-104) and keep the `initialize_simps_projections` line.","ev":"hunts/star-ringhom/batch0/probe1.lean P5 and hunts/star-ringhom/batch0/src_gen.lean (Simps.apply deleted) both run `@[simps] def P5id : A →⋆ₙ+* A` + `set_option pp.explicit true in #check @P5id_apply`; both print the identical statement `@Eq A (@DFunLike.coe (@NonUnitalStarRingHom A A inst inst_1 inst inst_1) A (fun x ↦ A) (@NonUnitalStarRingHom.instFunLike A A inst inst_1 inst inst_1) (@P5id A inst inst_1) x) x`; src_gen.lean compiles with exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-9b8b44","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"NonUnitalStarRingHom.id","line":153,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-id-apply","claim":"`id` lacks `id_apply` and `toNonUnitalRingHom_id`, which `NonUnitalRingHom` has in the form `@[simp] NonUnitalRingHom.id_apply`, `toAddMonoidHom_id`, `coe_mulHom_id`. `id_apply` is simp-provable through `coe_id`, so that gap only affects `rw`; `(NonUnitalStarRingHom.id A).toNonUnitalRingHom = NonUnitalRingHom.id A` is not provable by `simp`.","fix":"Add `@[simp] id_apply` and `@[simp] toNonUnitalRingHom_id` (both rfl).","ev":"hunts/star-ringhom/batch1/P1.lean: `example (x : A) : NonUnitalStarRingHom.id A x = x := by simp` compiles; `example : (NonUnitalStarRingHom.id A).toNonUnitalRingHom = NonUnitalRingHom.id A := by fail_if_success (simp; done); rfl` compiles (simp fails outright); `#check @NonUnitalStarRingHom.id_apply` / `toNonUnitalRingHom_id` give `Unknown constant`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-5a2cd0","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"NonUnitalStarRingHom.comp","line":165,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"duplicate-simp-argument","claim":"`map_star' := fun a => by simp [map_star, map_star]` lists `map_star` twice (and the `fun a =>` binder is unnecessary); a single `map_star` is needed (plain `simp` does not close the goal) and sufficient.","fix":"Replace the field with `map_star' := by simp [map_star]`.","ev":"measured: src.lean L165 reads `map_star' := fun a => by simp [map_star, map_star] }`. hunts/star-ringhom/batch1/Copy.lean with `map_star' := by simp [map_star] }` compiles with no warnings; hunts/star-ringhom/batch1/P2.lean shows `fail_if_success (simp; done)` succeeds on the obligation and `simp [map_star]` closes it.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-3f6b74","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"StarRingEquiv.coe_toNonUnitalStarRingHom","line":327,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"binders-duplicating-section-variables","claim":"Re-declares `{A B : Type*} [NonUnitalSemiring A] [StarRing A] [NonUnitalSemiring B] [StarRing B]` verbatim although the enclosing section (L314) already declares exactly these variables; the duplicate binders shadow them and must be edited separately when the section is generalised.","fix":"Drop the binders: `lemma coe_toNonUnitalStarRingHom (f : A ≃⋆+* B) : (f.toNonUnitalStarRingHom : A → B) = f := rfl`.","ev":"hunts/star-ringhom/batch2/copyA.lean L329 (binders removed, file compiles); src.lean L314 vs L327-328","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-3a9ac7","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"StarRingEquiv.Simps.apply","line":369,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-custom-simps-projection","claim":"The custom projection `StarRingEquiv.Simps.apply` is redundant: `initialize_simps_projections` finds the `DFunLike.coe` coercion for `toFun → apply` without it. With the definition deleted, the file still compiles, and the `@[simps]` lemmas on `ofStarRingHom` come out identical: `ofStarRingHom_apply : (ofStarRingHom f g h₁ h₂) a = f a` and `ofStarRingHom_symm_apply`. `RingEquiv`, `MulEquiv`, `Equiv` and `StarAlgEquiv` all omit it (`AlgEquiv` and `LinearEquiv` keep one). Nothing in Mathlib refers to `StarRingEquiv.Simps.apply`.","fix":"Delete `StarRingEquiv.Simps.apply`, keeping only `Simps.symm_apply`, as in `RingEquiv` and `StarAlgEquiv`.","ev":"hunts/star-ringhom/batch3/probe2_src.lean (src.lean without lines 368–369, plus `#check @StarRingEquiv.ofStarRingHom_apply`) compiles. The printed statements of `ofStarRingHom_apply`/`ofStarRingHom_symm_apply` are identical to those printed for the real Mathlib declarations in hunts/star-ringhom/batch3/probe1.out. `git grep 'StarRingEquiv.Simps' origin/master -- Mathlib` finds no uses.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-4f1276","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"StarRingEquiv.trans","line":406,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"uncommented-show-in-proof","claim":"The `map_star'` field is proved by an uncommented `show e₂.toFun (e₁.toFun (star a)) = star (e₂.toFun (e₁.toFun a)) by rw [e₁.map_star', e₂.map_star']`, restating the unfolded goal and rewriting with the primed structure fields; the term `(congrArg e₂ (map_star e₁ a)).trans (map_star e₂ (e₁ a))` closes it through the public `map_star` API with no `show`. (The same pattern is copied in `StarAlgEquiv.trans` for `map_smul'`.)","fix":"Replace the field proof with `map_star' a := (congrArg e₂ (map_star e₁ a)).trans (map_star e₂ (e₁ a))`.","ev":"hunts/star-ringhom/batch4/probe1.lean P6: `example (e₁ : A ≃⋆+* B) (e₂ : B ≃⋆+* C) : A ≃⋆+* C := { e₁.toRingEquiv.trans e₂.toRingEquiv with map_star' a := (congrArg e₂ (map_star e₁ a)).trans (map_star e₂ (e₁ a)) }` compiles (a `by simp [map_star]` variant does not)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-3c627f","file":"Mathlib/Algebra/Star/StarRingHom.lean","decl":"StarRingEquiv.ofStarRingHom","line":452,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"constructor-name-signature-mismatch","claim":"The name follows the `of<Hom>` pattern of `RingEquiv.ofRingHom`, `RingEquiv.ofNonUnitalRingHom`, `StarAlgEquiv.ofStarAlgHom` and `StarAlgEquiv.ofNonUnitalStarAlgHom`, which all take two bundled homs with `g.comp f = .id`/`f.comp g = .id` laws (e.g. `def ofRingHom (f : R →+* S) (g : S →+* R) (h₁ : f.comp g = RingHom.id S) (h₂ : g.comp f = RingHom.id R)`, Mathlib/Algebra/Ring/Equiv.lean:944), but this one takes an unbundled `f : F` and an arbitrary `g : G` with pointwise laws, and there is no `StarRingHom` type (the bundled hom is `NonUnitalStarRingHom`). It has no uses in Mathlib (`git grep ofStarRingHom origin/master -- Mathlib` hits only its definition).","fix":"Either rename to reflect the unbundled signature (e.g. `ofHomInv`-style) or add a bundled `ofNonUnitalStarRingHom (f : A →⋆ₙ+* B) (g : B →⋆ₙ+* A) (h₁ : g.comp f = .id A) (h₂ : f.comp g = .id B)` matching the analogues.","ev":"git -C mathlib4 grep -n 'def ofRingHom\\|def ofNonUnitalRingHom' origin/master -- Mathlib/Algebra/Ring/Equiv.lean (lines 919, 944); StarAlgHom.lean:945 `def ofNonUnitalStarAlgHom (f : A₁ →⋆ₙₐ[R] A₂) (g : A₂ →⋆ₙₐ[R] A₁) (h₁ : g.comp f = .id R A₁) ...` and :1037 `def ofStarAlgHom`; `git grep -n ofStarRingHom origin/master -- Mathlib` -> only StarRingHom.lean:452","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-f87a62","file":"Mathlib/Algebra/Tropical/Basic.lean","decl":"MinTropical.injective_trop","line":144,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `MinTropical.injective_trop` (Algebra.Tropical.Basic), `MinTropical.trop_injective` (Algebra.Tropical.Basic) state exactly the same thing (Lean-checked). Reviewer: Same file, both @[to_dual] `Injective trop`, proved separately (`tropEquiv.injective` vs `fun _ _ => id`). `trop_injective` follows the `f_injective` convention and has ~30 uses; `injective_trop` has none. Deprecate `injective_trop` (likewise `injective_untrop` and the MaxTropical duals).","fix":"Deprecate `MinTropical.injective_trop` in favour of `MinTropical.trop_injective`.","ev":"dupscan/Check.lean: `example := (@MinTropical.trop_injective : type_of% @MinTropical.injective_trop)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 49, rating MAJOR): Both have the same translation attribute and calling convention. Deriving the later theorem from `tropEquiv` does not give it an additional mathematical or tactical role.","pr":null,"res":"Re-graded MAJOR→NIT on 2026-10-07 after the user asked whether these are useful API: to_additive/to_dual image of the same source duplicate as RT-20261007-008a8d; counted once there.","at":"2026-10-07","commit":""},{"id":"RT-20261007-93dd5c","file":"Mathlib/Algebra/Tropical/Basic.lean","decl":"MaxTropical.injective_untrop","line":148,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `MaxTropical.untrop_injective` (Algebra.Tropical.Basic), `MaxTropical.injective_untrop` (Algebra.Tropical.Basic) state exactly the same thing (Lean-checked). Reviewer: The MinTropical sources `untrop_injective` (`fun _ _ => id`) and `injective_untrop` (`tropEquiv.symm.injective`) state the same `Function.Injective untrop`, and the MaxTropical copies come from @[to_dual]. The same pair exists for trop_injective/injective_trop. Keep the `f_injective` naming and deprecate injective_untrop (and injective_trop) at the MinTropical source.","fix":"Deprecate `MaxTropical.injective_untrop` in favour of `MaxTropical.untrop_injective`.","ev":"dupscan/Check.lean: `example := (@MaxTropical.injective_untrop : type_of% @MaxTropical.untrop_injective)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup0 item 50, rating MAJOR): The retained `untrop_injective` and its source already provide the complete injectivity API; dual generation does not justify the second spelling.","pr":null,"res":"Re-graded MAJOR→NIT on 2026-10-07 after the user asked whether these are useful API: to_additive/to_dual image of the same source duplicate as RT-20261007-d2fb1b; counted once there.","at":"2026-10-07","commit":""},{"id":"RT-20261006-3d29bf","file":"Mathlib/AlgebraicGeometry/AlgebraicCycle/Basic.lean","decl":"(file)","line":32,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-variable","claim":"`universe v` and the section variables `(c : AlgebraicCycle X R) (x : X) (z : Y)` are unused (a copy without them compiles); `mapCoeff` re-binds `{Y : Scheme}` shadowing the section's `Y`, and the Weil section re-declares `{R : Type*}`. Small reuse: `degree.map_add'` rebuilds `Function.support_smul_subset_right`, and `degree_eq_map_of_unique` commutes a cast by hand instead of `nsmul_eq_mul'`.","fix":"Delete the unused universe/variables and the shadowing binders; use the existing lemmas.","ev":"-- hunts/alg-cycle/ProbeHyg.lean (no `universe v`, no `c x z` variables) compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-e98620","file":"Mathlib/AlgebraicGeometry/Morphisms/FlatRank.lean","decl":"(file)","line":45,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-variable","claim":"Unused names: `hu` in `finrank_eq_finrank_snd_of_isAffine`, `hg` and `hzl` in `one_le_finrank_map`; `open … TensorProduct` is unused. `clear hu` / `clear hg hzl` after the destructuring and dropping `TensorProduct` from `open` leave the file compiling.","fix":"Replace the names by `_` and drop `TensorProduct` from `open`.","ev":"-- hunts/flat-rank/ProbeAstra.lean: src with `clear hu`, `clear hg hzl`, `open CategoryTheory Limits TopologicalSpace` — compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-3af48f","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"Path.Homotopy.reflTransSymmAux_mem_I","line":48,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"golfable-interval-membership","claim":"The nine-line split_ifs/constructor/apply/grind proof can be one line in the style of its siblings transReflReparamAux_mem_I and transAssocReparamAux_mem_I: `unfold reflTransSymmAux; split_ifs <;> constructor <;> nlinarith [x.1.2.1, x.1.2.2, x.2.2.1, x.2.2.2]`. This compiles in place within the file.","fix":"Replace the proof with `unfold reflTransSymmAux; split_ifs <;> constructor <;> nlinarith [x.1.2.1, x.1.2.2, x.2.2.1, x.2.2.2]`.","ev":"hunts/fundgroupoid/batch0/probe1.lean (section P1) and in-file in hunts/fundgroupoid/batch0/SrcV1.lean (exit 0 with Mathlib linters)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ded01b","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"Path.Homotopy.reflTransSymm","line":61,"sev":"NIT","status":"confirmed","cat":"api","pattern":"homotopy-direction-against-use","claim":"reflTransSymm : Homotopy (refl x₀) (p.trans p.symm) and reflSymmTrans point from the trivial path to the composite. Their siblings transRefl and reflTrans point the other way, from composite to simple. Every consumer reverses them: Basic.lean L183, L187, L294 and L295 apply `.symm`, and Topology/Homotopy/Lifting.lean L524 rewrites with `← eq.2 ⟨.reflTransSymm _⟩`. The name also reads as `refl.trans symm`.","fix":"Provide transSymm : Homotopy (p.trans p.symm) (refl x₀) and symmTrans, in the direction of transRefl/reflTrans, so that consumers drop the `.symm`; deprecate the old ones.","ev":"git grep -n -E 'reflTransSymm|reflSymmTrans' origin/master -- Mathlib: all 5 uses are reversed (Basic.lean:183,187,294,295 `.symm`; Topology/Homotopy/Lifting.lean:524 `← eq.2 ⟨.reflTransSymm _⟩`)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7611ba","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"Path.Homotopy.trans_refl_reparam","line":101,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"removable-backward-compat-option","claim":"`set_option backward.isDefEq.respectTransparency.types false in` (left by the v4.33.0-rc1 toolchain bump, #41779) is needed only because `unfold transReflReparamAux` runs before `simp only [coe_reparam]`. Without the option and with the original order, `simp` makes no progress because the unfolded term is not type-correct at implicit transparency. With the two tactic lines swapped, the option can go: the whole file compiles with Mathlib's lean options and linters, exit 0.","fix":"Drop the set_option and use `ext; simp only [coe_reparam]; unfold transReflReparamAux; grind`.","ev":"hunts/fundgroupoid/batch0/SrcCopy.lean/SrcCopy.out (option removed, original order: `simp` made no progress) and hunts/fundgroupoid/batch0/SrcV1.lean/SrcV1.lint.out (option removed, lines swapped, compiled with -DmaxSynthPendingDepth=3 -DautoImplicit=false -Dweak.linter.mathlibStandardSet=true: exit 0)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-968bfe","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"Path.Homotopy.trans_refl_reparam","line":102,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"wrong-namespace-for-dot-notation","claim":"This equation of paths, with no homotopy in it, sits in namespace Path.Homotopy, so dot notation on a path fails: `p.trans_refl_reparam` gives `Invalid field trans_refl_reparam: The environment does not contain Path.trans_refl_reparam`. The name also omits `_eq_`. trans_assoc_reparam, in another batch, has the same issue.","fix":"Rename to Path.trans_refl_eq_reparam (with a deprecated alias), or make it a private helper of transRefl.","ev":"hunts/fundgroupoid/batch0/probe1.lean (section N1): `example (p : Path x₀ x₁) : True := by have := p.trans_refl_reparam; trivial` -> error lean.invalidField (probe1.out)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-528b54","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"Path.Homotopy.trans_assoc_reparam","line":146,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"goal-count-dependent-script","claim":"The proof ends `split_ifs; iterate 12 grind; · linarith; · linarith; · grind`, a script tied to the exact number (15) and order of goals `split_ifs` produces. `grind` alone closes the goal after the `simp only` (no `split_ifs`, no `linarith`), so the goal-count-dependent tail is unnecessary.","fix":"Replace the five lines after `simp only [...]` (L153-L157) by a single `grind`.","ev":"hunts/fundgroupoid/batch1/v1_assoc_grind.lean = src.lean with L153-L157 replaced by `  grind`; `lake env lean -DautoImplicit=false -DmaxSynthPendingDepth=3 -Dweak.linter.mathlibStandardSet=true -Dweak.linter.style.longFile=1500 -Dweak.linter.unreachableTactic=false` gives EXIT=0 and no messages (baseline hunts/fundgroupoid/batch1/base.lean, same flags: EXIT=0). hunts/fundgroupoid/batch1/probeA.lean P2: `split_ifs` leaves 15 goals; P4 `split_ifs <;> grind` and P5 `grind` alone both compile; P3 `split_ifs <;> first | grind | linarith` reports the `linarith` branch is never executed.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-5a9d7e","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"Path.Homotopic.trans_symm","line":181,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-convention-clash","claim":"`Path.Homotopic.trans_symm`/`symm_trans` (L181, L185) and `Path.Homotopic.Quotient.trans_symm`/`symm_trans` (L208, L214) state the cancellation laws `p.trans p.symm ~ refl`, `p.symm.trans p ~ refl`. Mathlib's convention for these is `self_trans_symm`/`symm_trans_self` (`Equiv`, `OrderIso`, `Homeomorph`, `PartialEquiv`), and in the neighbouring API the same names mean the anti-distribution law: `Path.Homotopy.symm_trans : (F.trans G).symm = G.symm.trans F.symm` (Topology/Homotopy/Path.lean:130), `Equiv.symm_trans`, `OrderIso.symm_trans`, and `Path.trans_symm : (γ.trans γ').symm = γ'.symm.trans γ.symm` (Topology/Path.lean:295). Inside `Path.Homotopic` the short name `trans_symm` therefore shadows `Path.trans_symm` with a different statement, and the conventional names for the missing quotient anti-distribution lemma are taken.","fix":"Rename the four cancellation lemmas to `self_trans_symm`/`symm_trans_self` (with deprecated aliases).","ev":"git grep -n -E 'theorem (self_trans_symm|symm_trans_self|trans_symm|symm_trans)\\b' origin/master -- Mathlib/Logic/Equiv/Defs.lean Mathlib/Order/Hom/Basic.lean Mathlib/Topology/Homeomorph/Defs.lean Mathlib/Logic/Equiv/PartialEquiv.lean Mathlib/Topology/Path.lean Mathlib/Topology/Homotopy/Path.lean ->\nEquiv/Defs.lean:275 symm_trans (f : α ≃ β) (g : β ≃ γ) : (f.trans g).symm = g.symm.trans f.symm\nEquiv/Defs.lean:313 symm_trans_self (e) : e.symm.trans e = Equiv.refl β ; :315 self_trans_symm (e) : e.trans e.symm = Equiv.refl α\nOrder/Hom/Basic.lean:909 symm_trans (e₁.trans e₂).symm = ... ; :913 self_trans_symm ; :917 symm_trans_self\nHomeomorph/Defs.lean:160 self_trans_symm ; :165 symm_trans_self ; PartialEquiv.lean:742 self_trans_symm ; :750 symm_trans_self\nTopology/Path.lean:295 trans_symm (γ : Path x y) (γ' : Path y z) : (γ.trans γ').symm = γ'.symm.trans γ.symm\nTopology/Homotopy/Path.lean:130 symm_trans (F : Homotopy p₀ p₁) (G : Homotopy p₁ p₂) : (F.trans G).symm = G.symm.trans F.symm","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-123e62","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"FundamentalGroupoid.equiv","line":249,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-wrong-object","claim":"The docstring says the equivalence transfers constructions 'from `X` to `πₓ X`'. `πₓ` is scoped notation, defined at L327, for `fundamentalGroupoidFunctor.obj` on `TopCat`, whereas `equiv` is stated for `FundamentalGroupoid X` with `X : Type*` and no topology.","fix":"Say 'from `X` to `FundamentalGroupoid X`'.","ev":"src.lean L245-249: docstring 'from `X` to `πₓ X`' on `def equiv (X : Type*) : FundamentalGroupoid X ≃ X`; L327 `scoped notation \"πₓ\" => FundamentalGroupoid.fundamentalGroupoidFunctor.obj` (functor `TopCat ⥤ Grpd`).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-aff44a","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"FundamentalGroupoid.instGroupoid","line":286,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"homotopy-equivalence-misnomer","claim":"The module docstring (L15–18), which describes this instance's morphisms, says the paths are 'quotiented by homotopy equivalence'. The relation is `Path.Homotopic`, homotopy rel endpoints (Path.lean:292 says 'by the equivalence relation `Path.Homotopic`'). In Mathlib, 'homotopy equivalence' is the different notion `ContinuousMap.HomotopyEquiv` (Topology/Homotopy/Equiv.lean:43). The module docstring also names none of the file's main declarations (`FundamentalGroupoid`, `fundamentalGroupoidFunctor`, the `π`/`πₓ`/`πₘ` notation).","fix":"Say 'quotiented by homotopy relative to the endpoints (`Path.Homotopic`)', and add a `## Main definitions` list.","ev":"src.lean L15-17: 'morphisms `x ⟶ y` being paths from `x` to `y`, quotiented by homotopy equivalence'. Mathlib/Topology/Homotopy/Path.lean:292: 'The quotient on `Path x₀ x₁` by the equivalence relation `Path.Homotopic`'. Mathlib/Topology/Homotopy/Equiv.lean:43: `structure HomotopyEquiv (X : Type u) (Y : Type v) …`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-553a4b","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"FundamentalGroupoid.comp_eq","line":297,"sev":"NIT","status":"confirmed","cat":"api","pattern":"explicit-inferable-binders","claim":"The objects `(x y z : FundamentalGroupoid X)` are explicit although `p` and `q` determine them, so term-mode use needs `comp_eq _ _ _ p q`. Mathlib makes such objects implicit (`Category.assoc {W X Y Z}`, `Grpd.comp_eq_comp {C D E}`).","fix":"Make `x y z` implicit. The only consumer (InducedMaps.lean:72) uses it in `simp only` and is unaffected.","ev":"hunts/fundgroupoid/batch2/Copy.lean declares `theorem comp_eq {x y z : FundamentalGroupoid X} (p : x ⟶ y) (q : y ⟶ z) : p ≫ q = p.trans q := rfl`, and the file compiles. Probe1 `#check @FundamentalGroupoid.comp_eq` shows the explicit binders.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-46c5f3","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"FundamentalGroupoid.fundamentalGroupoidFunctor","line":318,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"module-doc-missing-main-definitions","claim":"The module docstring (L12-19) describes only the groupoid structure. It does not name the file's main constructions: `FundamentalGroupoid.map`, the functor `fundamentalGroupoidFunctor : TopCat ⥤ Grpd`, or the scoped notations `π`, `πₓ`, `πₘ`. There are no Main definitions or Notation sections.","fix":"Add Main definitions (`FundamentalGroupoid`, `FundamentalGroupoid.map`, `fundamentalGroupoidFunctor`) and Notation (`π`, `πₓ`, `πₘ`) sections to the module docstring.","ev":"src.lean lines 12-19 (read); none of `map`, `fundamentalGroupoidFunctor`, `π`, `πₓ`, `πₘ` occur in the module docstring.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a2fc43","file":"Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean","decl":"FundamentalGroupoid.fromPath","line":351,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-path-vs-homotopy-class","claim":"The docstring says `fromPath` converts \"a path in a topological space\" to an arrow, but its argument is a homotopy class `p : Path.Homotopic.Quotient x₀ x₁`, not a `Path`. The companion `toPath` docstring does say `(i.e., Path.Homotopic.Quotient)`.","fix":"Say \"converting a homotopy class of paths (`Path.Homotopic.Quotient`) in a topological space to an arrow\".","ev":"src.lean lines 349-352 (read): docstring \"converting a path in a topological space\" with binder `(p : Path.Homotopic.Quotient x₀ x₁)`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-3e904d","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"CPolynomialAt_const","line":45,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"uppercase-prop-def-in-theorem-name","claim":"The theorem name writes the Prop-valued def `CPolynomialAt` in UpperCamelCase. Mathlib's convention writes it in lowerCamelCase inside a snake_case theorem name, as the analytic mirror `analyticAt_const` does. This file and CPolynomialDef already do so elsewhere: `HasFiniteFPowerSeriesAt.cpolynomialAt`, `isOpen_cpolynomialAt`, `ContinuousMultilinearMap.cpolynomialAt`, `cpolynomialAt_changeOrigin_of_finite`. `cpolynomialAt_const` does not exist. CPolynomialDef has the same issue in `CPolynomialAt_congr`, `CPolynomialOn_congr'` and `CPolynomialOn_congr` (outside this batch). The statement itself is correct.","fix":"Rename to `cpolynomialAt_const`, keeping a `@[deprecated] alias CPolynomialAt_const`.","ev":"src.lean L45 `theorem CPolynomialAt_const`. In hunts/cpolynomial/batch0/probe1.lean (N), `cpolynomialAt_const` gives \"Unknown identifier\". hunts/cpolynomial/batch0/src-fixed.lean, with the rename plus `@[deprecated (since := \"2026-10-06\")] alias CPolynomialAt_const := cpolynomialAt_const`, compiles (exit 0).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-71de45","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"CPolynomialOn_const","line":48,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"uppercase-prop-def-in-theorem-name","claim":"Same convention break as `CPolynomialAt_const`. The name should be `cpolynomialOn_const`, mirroring `analyticOnNhd_const`. The file already uses lowerCamelCase `cpolynomialOn` in `ContinuousMultilinearMap.cpolynomialOn` and `cpolynomialOn_compContinuousLinearMapCLM`.","fix":"Rename to `cpolynomialOn_const`, keeping a `@[deprecated] alias CPolynomialOn_const`.","ev":"src.lean L48 `theorem CPolynomialOn_const`. In hunts/cpolynomial/batch0/probe1.lean (N), `cpolynomialOn_const` gives \"Unknown identifier\". hunts/cpolynomial/batch0/src-fixed.lean compiles with the rename and a deprecated alias.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-f542f7","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"CPolynomialAt.smul","line":113,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"const-smul-named-smul","claim":"The constant-scalar statement `CPolynomialAt 𝕜 (c • f) x` is named `smul` (with c explicit), while its analytic counterparts are AnalyticAt.const_smul / AnalyticOnNhd.const_smul / HasFPowerSeriesAt.const_smul with {c} implicit, and AnalyticAt.smul is the two-function statement `AnalyticAt 𝕜 (f • g) z` for f : E → A. Mathlib's convention (Continuous.const_smul vs Continuous.smul) reserves `smul` for f • g, so this name takes the slot of the missing two-function CPolynomialAt lemma. Same for CPolynomialOn.smul (L117).","fix":"Rename to CPolynomialAt.const_smul / CPolynomialOn.const_smul (deprecated aliases for the old names), matching AnalyticAt.const_smul.","ev":"hunts/cpolynomial/batch1/Probe1.lean #check output:\n@AnalyticAt.const_smul : ... {R : Type u_8} [NormedRing R] [Module R F] [IsBoundedSMul R F] [SMulCommClass 𝕜 R F] {c : R}, AnalyticAt 𝕜 f x → AnalyticAt 𝕜 (c • f) x\n@AnalyticAt.smul : ... {A} [NormedRing A] [NormedAlgebra 𝕜 A] [Module A F] [IsBoundedSMul A F] [IsScalarTower 𝕜 A F] {f : E → A} {g : E → F} {z : E}, AnalyticAt 𝕜 f z → AnalyticAt 𝕜 g z → AnalyticAt 𝕜 (f • g) z\n@CPolynomialAt.fun_smul : ... {f : E → F} {x : E}, CPolynomialAt 𝕜 f x → ∀ (c : 𝕜), CPolynomialAt 𝕜 (fun i => c • f i) x","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b2da33","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"CPolynomialAt.smul","line":114,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-parentheses","claim":"Redundant double parentheses in the proof: `ContinuousLinearMap.comp_cpolynomialAt ((ContinuousLinearMap.lsmul 𝕜 𝕜 c)) hf`.","fix":"Write `(ContinuousLinearMap.lsmul 𝕜 𝕜 c).comp_cpolynomialAt hf` (moot if the lemma is generalised as in the generality finding).","ev":"src.lean line 114: `  ContinuousLinearMap.comp_cpolynomialAt ((ContinuousLinearMap.lsmul 𝕜 𝕜 c)) hf`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-3a9dcd","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"ContinuousMultilinearMap.hasFiniteFPowerSeriesOnBall","line":153,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"repeated-single-degree-series-proof","claim":"The proof (.mk' + Finset.sum_eq_single_of_mem on range (d+1) + two dite rewrites) is repeated almost verbatim in ContinuousLinearMap.hasFiniteFPowerSeriesOnBall_uncurry_of_multilinear (L313-323). Both are instances of one fact: a series concentrated in degree d with p d (fun _ ↦ y) = f y is a finite expansion of f at 0 with bound d+1 and radius ⊤. With that helper (5 lines) each proof becomes 2 lines; the edited copy compiles.","fix":"Factor out `HasFiniteFPowerSeriesOnBall.of_single (hp : ∀ m, m ≠ d → p m = 0) (hf : ∀ y, p d (fun _ ↦ y) = f y) : HasFiniteFPowerSeriesOnBall f p 0 (d + 1) ⊤` and use it in both proofs.","ev":"hunts/cpolynomial/batch1/CopyA.lean (compiles):\ntheorem HasFiniteFPowerSeriesOnBall.of_single {d : ℕ} (hp : ∀ m, m ≠ d → p m = 0)\n    (hf : ∀ y, p d (fun _ ↦ y) = f y) : HasFiniteFPowerSeriesOnBall f p 0 (d + 1) ⊤ :=\n  .mk' (fun m hm ↦ hp m (by omega)) ENNReal.zero_lt_top fun y _ ↦ by\n    rw [Finset.sum_eq_single_of_mem _ (Finset.self_mem_range_succ _), zero_add, hf]\n    intro m _ ne; rw [hp m ne]; rfl\nprotected theorem hasFiniteFPowerSeriesOnBall :\n    HasFiniteFPowerSeriesOnBall f f.toFormalMultilinearSeries 0 (Fintype.card ι + 1) ⊤ :=\n  .of_single (fun _ hm ↦ dite_eq_right hm.symm) fun _ ↦ by\n    rw [toFormalMultilinearSeries, dite_eq_left rfl]; rfl","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-5dd71d","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"ContinuousMultilinearMap.cpolynomialAt","line":160,"sev":"NIT","status":"confirmed","cat":"api","pattern":"inconsistent-point-explicitness","claim":"ContinuousMultilinearMap.{cpolynomialAt, cpolynomialOn, analyticOnNhd, analyticOn, analyticAt, analyticWithinAt} (L160-172) and ContinuousAlternatingMap.{cpolynomialAt, cpolynomialOn} (L180-183) take the point/set implicitly ({x}, {s}), while the sibling API for continuous linear maps (Analytic/Linear.lean: ContinuousLinearMap.cpolynomialAt (f) (x), cpolynomialOn (f) (s), analyticAt (f) (x), analyticOnNhd (f) (s)) takes them explicitly, so `f.cpolynomialAt x` works for a CLM but not for a multilinear map.","fix":"Make x and s explicit in the multilinear/alternating variable blocks (or document the choice), matching ContinuousLinearMap.cpolynomialAt/analyticAt.","ev":"hunts/cpolynomial/batch1/Probe1.lean #check output:\n@ContinuousMultilinearMap.cpolynomialAt : ... (f : ContinuousMultilinearMap 𝕜 Em F) {x : (i : ι) → Em i}, CPolynomialAt 𝕜 (⇑f) x\n@ContinuousMultilinearMap.analyticOnNhd : ... (f : ContinuousMultilinearMap 𝕜 Em F) {s : Set ((i : ι) → Em i)}, AnalyticOnNhd 𝕜 (⇑f) s\n@ContinuousAlternatingMap.cpolynomialAt : ... (f : E [⋀^ι]→L[𝕜] F) {x : ι → E}, CPolynomialAt 𝕜 (⇑f) x\n@ContinuousLinearMap.cpolynomialAt : ... (f : E →L[𝕜] F) (x : E), CPolynomialAt 𝕜 (⇑f) x\n@ContinuousLinearMap.cpolynomialOn : ... (f : E →L[𝕜] F) (s : Set E), CPolynomialOn 𝕜 (⇑f) s\n@ContinuousLinearMap.analyticAt : ... (f : E →L[𝕜] F) (x : E), AnalyticAt 𝕜 (⇑f) x","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-603d49","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"ContinuousAlternatingMap.cpolynomialAt_smul_compContinuousLinearMapCLM","line":195,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"unbound-variable-in-docstring","claim":"Three docstrings, at L193 (cpolynomialAt_smul_…), L239 (cpolynomialAt_…) and L265 (cpolynomialOn_…), all say \"Precomposition on spaces of `n`-alternating maps\", but no `n` occurs in these statements: the index type is `ι` and the degree is `Fintype.card ι`. L265 also uses the jargon \"is cpolynomial\". The L239 docstring does not mention the `[CharZero 𝕜]` hypothesis, which is the substantive assumption and is explained only in a proof comment.","fix":"Say \"alternating maps indexed by `ι`\" (degree `Fintype.card ι`), write \"continuously polynomial\" at L265, and add \"over a field of characteristic zero\" to the L239 and L265 docstrings.","ev":"grep -n 'n`-alternating' src.lean\n193:/-- Precomposition on spaces of `n`-alternating maps, as a continuous linear map, is continuously\n239:/-- Precomposition on spaces of `n`-alternating maps, as a continuous linear map, is continuously\n265:/-- Precomposition on spaces of `n`-alternating maps, as a continuous linear map, is cpolynomial. -/\n(no binder named `n` in the statements at L195, L241, L266)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-31aa4e","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"ContinuousAlternatingMap.cpolynomialAt_smul_compContinuousLinearMapCLM","line":195,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-omission","claim":"The factorial-scaled statement (`(card ι)! • compContinuousLinearMapCLM` is continuously polynomial) is trivially true whenever the characteristic divides `(card ι)!`, since the scaled map is then `0`. This is an intended limitation, but the docstring does not say that the result carries no information in that case (e.g. characteristic 2, `ι = Fin 2`).","fix":"Note in the docstring that the statement is vacuous when `((card ι)! : 𝕜) = 0`, and point to the `CharZero` version.","ev":"src: the conclusion is about `((Fintype.card ι)! : 𝕜) • …`; `(2! : ZMod 2) = 0` (Astra A1 check).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-363631","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"ContinuousLinearMap.toFormalMultilinearSeriesOfMultilinear","line":307,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"The public def `toFormalMultilinearSeriesOfMultilinear` has no coefficient lemmas: none for vanishing off degree `card ι + 1`, none for diagonal evaluation. Its own proof unfolds it and manipulates `dite` branches. Its docstring also does not say that this is the expansion at `0` of the uncurried map, supported in one degree, with a non-symmetric coefficient.","fix":"Add `_apply_of_ne` / diagonal-evaluation simp lemmas and expand the docstring.","ev":"src: the definition and its single use in `hasFiniteFPowerSeriesOnBall_uncurry_of_multilinear`; git grep finds no other lemma about it.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-aaa50d","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"ContinuousMultilinearMap.cpolynomialAt_apply","line":387,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"misleading-binder-name","claim":"The point of `ContinuousMultilinearMap 𝕜 Em F × (Π i, Em i)` is bound as `{f : …}`. That shadows the section variable `f : ContinuousMultilinearMap 𝕜 Em (G →L[𝕜] F)` (L356) and gives a (map, vector) pair a function's name, so named-argument use reads `analyticAt_apply (f := (φ, v))`. The same binder appears at `analyticAt_apply` (L404), `analyticWithinAt_apply` (L409) and in the `ContinuousAlternatingMap` block (L456). The `compContinuousLinearMap` lemmas a few lines later name their point `q` (L414).","fix":"Rename the point binder in the `*_apply` lemmas to `q` (as at L414) or `x`.","ev":"hunts/cpolynomial/batch3/probe1.lean section (A): `#check @ContinuousMultilinearMap.cpolynomialAt_apply` prints `… {f : ContinuousMultilinearMap 𝕜 Em F × ((i : ι) → Em i)}, CPolynomialAt 𝕜 (fun p => p.1 p.2) f`, and likewise for `analyticAt_apply`. Source: L387, L404, L409, L456 vs L356 and L414.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ae7aa2","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"ContinuousMultilinearMap.analyticWithinAt_apply","line":408,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"misleading-binder-name","claim":"The base point of the evaluation lemmas, a pair (map, vector), is named `f`: `{f : (ContinuousMultilinearMap 𝕜 Em F) × (Π i, Em i)}` at L387/L404/L409, shadowing the section variable `(f : ContinuousMultilinearMap 𝕜 Em (G →L[𝕜] F))` (L356), and the section variable `{f : (E [⋀^ι]→L[𝕜] F) × (ι → E)}` (L456) for the alternating ones; elsewhere the file names base points `x`/`q`. The two `analyticWithinAt_apply` lemmas also order their implicits differently (`{s} {f}` for multilinear, `{f} {s}` for alternating).","fix":"Rename the base point to `q` (or `x`) in L387-L411 and L456 and put the set before the point in both `analyticWithinAt_apply` lemmas.","ev":"measured: src.lean L356, L387, L404, L409, L456; `#check` in hunts/cpolynomial/batch4/Golf.lean prints `@ContinuousMultilinearMap.analyticWithinAt_apply : ∀ … {s : Set …} {f : ContinuousMultilinearMap 𝕜 Em F × ((i : ι) → Em i)}, …` and `@ContinuousAlternatingMap.analyticWithinAt_apply : ∀ … {f : E [⋀^ι]→L[𝕜] F × (ι → E)} {s : Set …}, …`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c84226","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"ContinuousMultilinearMap.cpolynomialAt_uncurry_compContinuousLinearMap","line":416,"sev":"NIT","status":"confirmed","cat":"api","pattern":"inconsistent-argument-order","claim":"The six `_uncurry_compContinuousLinearMap` lemmas take the pair in the order (linear maps, multilinear map): `fun p : (Π i, Fm i →L[𝕜] Em i) × ContinuousMultilinearMap 𝕜 Em G ↦ p.2.compContinuousLinearMap p.1`. Mathlib's derivative of the same map uses the opposite order, `ContinuousMultilinearMap.hasStrictFDerivAt_compContinuousLinearMap (fg : ContinuousMultilinearMap 𝕜 G H × ∀ i, F i →L[𝕜] G i) : HasStrictFDerivAt (fun fg ↦ fg.1.compContinuousLinearMap fg.2) …` (FDeriv/ContinuousMultilinearMap.lean L60-L62), as do this file's own evaluation lemmas (map first). The order here is an artefact of the proof via `cpolynomialAt_uncurry_of_linear`; combining the analytic and derivative statements needs a `Prod.swap`.","fix":"State the family on `ContinuousMultilinearMap 𝕜 Em G × (Π i, Fm i →L[𝕜] Em i)` with `p.1.compContinuousLinearMap p.2` (compose with `prodComm` in the proof); there are no consumers to update.","ev":"measured: src.lean L416-L418 vs `git show origin/master:Mathlib/Analysis/Calculus/FDeriv/ContinuousMultilinearMap.lean` L60-L66 (statements quoted in the claim); `#check @ContinuousMultilinearMap.cpolynomialAt_uncurry_compContinuousLinearMap` in hunts/cpolynomial/batch4/Golf.lean prints `{q : ((i : ι) → Fm i →L[𝕜] Em i) × ContinuousMultilinearMap 𝕜 Em G}, CPolynomialAt 𝕜 (fun p ↦ p.2.compContinuousLinearMap p.1) q`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ccad6e","file":"Mathlib/Analysis/Analytic/CPolynomial.lean","decl":"ContinuousMultilinearMap.cpolynomialAt_uncurry_compContinuousLinearMap","line":416,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"undocumented-lemma-family","claim":"The block L351-L492 (multilinear-into-linear uncurrying, the evaluation maps `_apply` for multilinear and alternating maps, and the joint `compContinuousLinearMap` family) has no docstring and no section header (0 `/--` and 0 `/-!` in those lines). The nearest header (L293-L298) describes only `G →L[𝕜] ContinuousMultilinearMap` uncurried, and the module docstring (L15-L23) mentions neither evaluation maps, joint composition with linear maps, nor alternating maps, so the lead lemmas of these two families are undocumented.","fix":"Add a `/-! ### … -/` header before L351 and L454 and one-sentence docstrings on `cpolynomialAt_uncurry_compContinuousLinearMap` and `ContinuousAlternatingMap.cpolynomialAt_apply` (e.g. \"`(L, c) ↦ c.compContinuousLinearMap L` is continuously polynomial\"), and name them in the module docstring.","ev":"measured: `sed -n '351,492p' src.lean | grep -c '/--'` → 0; `grep -c '/-!'` → 0; module docstring L15-L23 and header L293-L298 read in full.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-bfe3ce","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"norm_cfcHom","line":62,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"outparam-in-lemma-binder","claim":"`variable {p : outParam (A → Prop)}` (L58, and again at L236, L257 and L629) puts `outParam` on a lemma binder, where it means nothing. `outParam` matters only on class parameters, and the classes already declare `p` as one. On a lemma binder it just leaks into every signature: `#check @norm_cfcHom`, `@norm_cfc_le`, `@nnnorm_cfc_le` and `@IsGreatest.norm_cfc` all print `{p : outParam (A → Prop)}`. This file is the only place in Mathlib with `{p : outParam` in a binder. The neighbouring sections (L41, L187) and Unital.lean/NonUnital.lean write `{p : A → Prop}`.","fix":"Write `{p : A → Prop}` in the variable lines at L58, L236, L257 and L629.","ev":"hunts/cfc-isometric/batch0/Probe1.lean (`#check @norm_cfcHom` etc. print `{p : outParam (A → Prop)}`); `git -C mathlib4 grep -n '{p : outParam' refs/remotes/origin/master -- Mathlib` gives exactly Isometric.lean:58, :236, :257 and :629.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-6247a8","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"norm_cfcHom","line":62,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"refine-without-holes","claim":"The proof is `by refine isometry_cfcHom a |>.norm_map_of_map_zero (map_zero _) f`: a `refine` with no `?_` holes, so it is a term proof wrapped in tactic mode. The twin `norm_cfcₙHom` at L267 does the same.","fix":"Use the term directly: `:= isometry_cfcHom a |>.norm_map_of_map_zero (map_zero _) f`.","ev":"hunts/cfc-isometric/batch0/GenAlg.lean L62–64: `lemma norm_cfcHom ... : ‖cfcHom (show p a from ha) f‖ = ‖f‖ := isometry_cfcHom a |>.norm_map_of_map_zero (map_zero _) f` compiles (exit 0, no messages).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-327cf7","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"nnnorm_cfc_le","line":133,"sev":"NIT","status":"confirmed","cat":"api","pattern":"explicit-arg-determined-by-hypothesis","claim":"`nnnorm_cfc_le` takes `(c : ℝ≥0)` explicitly even though `h : ∀ x ∈ σ 𝕜 a, ‖f x‖₊ ≤ c` determines it. Its siblings `norm_cfc_le {c : ℝ}` and `nnnorm_cfc_lt {c : ℝ≥0}`, and its non-unital twin `nnnorm_cfcₙ_le {c : ℝ≥0}`, all take `c` implicitly, so the unital and non-unital pair are called differently. The lemma has no consumer in Mathlib, so changing the binder costs nothing.","fix":"Make the binder implicit, `{c : ℝ≥0}`, as in `nnnorm_cfcₙ_le` and `nnnorm_cfc_lt`.","ev":"hunts/cfc-isometric/batch0/Probe1.lean: `#check @nnnorm_cfc_le` gives `... {f : 𝕜 → 𝕜} {a : A} (c : ℝ≥0), (∀ x ∈ spectrum 𝕜 a, ‖f x‖₊ ≤ c) → ‖cfc f a‖₊ ≤ c`; `#check @nnnorm_cfcₙ_le` gives `... {f : 𝕜 → 𝕜} {a : A} {c : ℝ≥0}, (∀ x ∈ quasispectrum 𝕜 a, ‖f x‖₊ ≤ c) → ‖cfcₙ f a‖₊ ≤ c`; `#check @nnnorm_cfc_lt` gives `{c : ℝ≥0}`. `git grep -nP 'nnnorm_cfc_le(?![_\\w])' refs/remotes/origin/master -- Mathlib` finds only the declaration (L133).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-07e64d","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"CFC.norm_pow","line":171,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"unused-pattern-binder","claim":"In the proof, `have ⟨⟨x, hx, hx'⟩, h₂⟩ := isGreatest_norm_spectrum ..` (L176) binds `h₂`, which is never used. The unused-variables linter does not catch it. The same leftover is at L376 in `norm_cfcₙ_pow`.","fix":"Replace `h₂` by `_` (or take `.1` of the `IsGreatest`).","ev":"hunts/cfc-isometric/batch1/probe_pow.lean (second `example`: the proof of `CFC.norm_pow` with `h₂` replaced by `_` compiles); `grep -n h₂ src.lean` finds only the binding sites L176 and L376","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-7704df","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"CFC.norm_pow","line":171,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-nnnorm-twin","claim":"Every norm lemma in this file has an `nnnorm` twin (`norm_cfcHom`/`nnnorm_cfcHom`, `IsGreatest.norm_cfc`/`IsGreatest.nnnorm_cfc`, `norm_spectrum_le`/`nnnorm_spectrum_le`, ...), but `CFC.norm_pow` does not: `CFC.nnnorm_pow` is an unknown identifier, though it follows in one line.","fix":"Add `protected lemma CFC.nnnorm_pow (a : A) (n : ℕ) (hn : n ≠ 0) (ha : p a := by cfc_tac) : ‖a ^ n‖₊ = ‖a‖₊ ^ n := by ext; simpa using CFC.norm_pow 𝕜 a n hn ha`.","ev":"hunts/cfc-isometric/batch1/probe_pow.lean: `example (a : A) (n : ℕ) (hn : n ≠ 0) (ha : p a) : ‖a ^ n‖₊ = ‖a‖₊ ^ n := by ext; simpa using CFC.norm_pow 𝕜 a n hn ha` compiles; `#check @CFC.nnnorm_pow` gives `Unknown identifier`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-e2ba64","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"SpectrumRestricts.isometric_cfc","line":197,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"class-name-split-in-theorem-name","claim":"The theorem concludes the Prop-class `IsometricContinuousFunctionalCalculus R A p`, so the naming convention wants the class name in lowerCamelCase. Its direct siblings in Restrict.lean are `SpectrumRestricts.cfc`, `SpectrumRestricts.closedEmbeddingCFC` and `QuasispectrumRestricts.nonUnitalClosedEmbeddingCFC`. The snake_case `isometric_cfc` splits a single concept (the non-unital `QuasispectrumRestricts.isometric_cfc` at L408 matches it).","fix":"Rename to `SpectrumRestricts.isometricCFC` (and `QuasispectrumRestricts.nonUnitalIsometricCFC`) with deprecated aliases.","ev":"git grep: Restrict.lean:117 `protected theorem cfc`, :184 `protected theorem closedEmbeddingCFC`, :361 `protected theorem nonUnitalClosedEmbeddingCFC`; Isometric.lean:197/408 `protected theorem isometric_cfc`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-5a870d","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"SpectrumRestricts.isometric_cfc","line":197,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring-on-constructor-theorem","claim":"This instance-building theorem has no docstring. Its siblings `SpectrumRestricts.cfc` (Restrict.lean:113) and `SpectrumRestricts.closedEmbeddingCFC` (Restrict.lean:180) both have one, explaining the shape of `p` (`q a` plus spectrum restriction via `f`) and the role of `halg` and `h0`.","fix":"Add a docstring mirroring `SpectrumRestricts.cfc`'s, saying the restricted calculus is isometric when `algebraMap R S` is an isometry.","ev":"src.lean L195-197: `set_option ... in` / `open scoped ... in` / `protected theorem isometric_cfc` with no `/-- -/`; Restrict.lean L113 and L180 open with `/-- Given a ContinuousFunctionalCalculus S A q ...`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-e3cbd8","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"norm_cfcₙHom","line":265,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"refine-without-holes","claim":"The proof is `by refine isometry_cfcₙHom a |>.norm_map_of_map_zero (map_zero _) f`, a `refine` with no `?_` holes. The term itself is the whole proof. The unital `norm_cfcHom` (L62-64) has the same pattern.","fix":"Use the term-mode proof `isometry_cfcₙHom a |>.norm_map_of_map_zero (map_zero _) f`.","ev":"hunts/cfc-isometric/batch1/probe_gen2.lean (L266-267 rewritten to `:= isometry_cfcₙHom a |>.norm_map_of_map_zero (map_zero _) f`; compiles, exit 0)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-137c3d","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"IsGreatest.norm_cfcₙ","line":274,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring-headline-lemma","claim":"The headline lemma of the non-unital section, ‖cfcₙ f a‖ = max of ‖f x‖ over the quasispectrum, has no docstring, and its `IsGreatest` phrasing hides that it computes the norm as a supremum. The module docstring names none of the norm results, and no lemma in batch 2 has a docstring. Mathlib does not require lemma docstrings, so this is cosmetic.","fix":"Add a docstring saying that `‖cfcₙ f a‖` is the maximum of `‖f x‖` over `x ∈ σₙ 𝕜 a` (and is attained), under continuity, `f 0 = 0` and `p a`.","ev":"src.lean lines 273-276: `set_option ... in` / `lemma IsGreatest.norm_cfcₙ ...` with no `/--` docstring; `grep -c '^/--' src.lean` finds only the two classes and `toNonUnital` documented.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-ef92c1","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"NonUnitalIsometricContinuousFunctionalCalculus.nnnorm_quasispectrum_le","line":365,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"nnnorm-lemma-via-cfc-detour","claim":"The statement `‖x‖₊ ≤ ‖a‖₊` is definitionally `‖x‖ ≤ ‖a‖`, so `norm_quasispectrum_le a hx ha` closes it directly. The current proof detours through `nnnorm_apply_le_nnnorm_cfcₙ (id) a hx` and a `simpa only [cfcₙ_id 𝕜 a] using!` rewrite. The unital twin `nnnorm_spectrum_le` (L165) has the same detour. The sibling lemmas `nnnorm_apply_le_nnnorm_cfc(ₙ)` already use the term-mode style.","fix":"Replace the proof by `norm_quasispectrum_le a hx ha`.","ev":"batch3/probe1.lean S2c: `example {𝕜 B : Type*} {p : B → Prop} [RCLike 𝕜] [NonUnitalNormedRing B] [StarRing B] [NormedSpace 𝕜 B] [IsScalarTower 𝕜 B B] [SMulCommClass 𝕜 B B] [NonUnitalIsometricContinuousFunctionalCalculus 𝕜 B p] (a : B) ⦃x : 𝕜⦄ (hx : x ∈ quasispectrum 𝕜 a) (ha : p a) : ‖x‖₊ ≤ ‖a‖₊ := NonUnitalIsometricContinuousFunctionalCalculus.norm_quasispectrum_le a hx ha` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-748d1c","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"norm_cfcₙ_pow","line":372,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-nnnorm-twin","claim":"`norm_cfcₙ_pow` has no `nnnorm` twin. Every other norm lemma in the file is paired with an `nnnorm` version (`norm_cfcHom`/`nnnorm_cfcHom`, `norm_cfcₙ_le`/`nnnorm_cfcₙ_le`, …); the exceptions are this lemma, `CFC.norm_pow` and `CFC.norm_mul_self`. The twin is a one-liner.","fix":"Add `nnnorm_cfcₙ_pow : ‖cfcₙ (· ^ n : 𝕜 → 𝕜) a‖₊ = ‖a‖₊ ^ n := NNReal.eq <| by simpa using norm_cfcₙ_pow 𝕜 a n hn` (and likewise `CFC.nnnorm_pow`).","ev":"batch3/probe1.lean S2a: `variable {A : Type*} [NonUnitalCStarAlgebra A]`; `example (a : A) [IsStarNormal a] (n : ℕ) (hn : n ≠ 0) : ‖cfcₙ (· ^ n : ℂ → ℂ) a‖₊ = ‖a‖₊ ^ n := NNReal.eq <| by simpa using norm_cfcₙ_pow ℂ a n hn` compiles; `git grep nnnorm_cfcₙ_pow origin/master -- Mathlib` is empty.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-76cbf3","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"CFC.norm_mul_self","line":383,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-nnnorm-twin","claim":"`CFC.norm_mul_self` (‖a * a‖ = ‖a‖ ^ 2) has no `nnnorm` twin. The C⋆-ring analogue does come as a pair: `IsSelfAdjoint.norm_mul_self`/`IsSelfAdjoint.nnnorm_mul_self` (CStarAlgebra/Basic.lean:153-159). The twin is a one-liner. The lemma also has no consumer in Mathlib.","fix":"Add `CFC.nnnorm_mul_self : ‖a * a‖₊ = ‖a‖₊ ^ 2 := NNReal.eq <| by simpa using CFC.norm_mul_self 𝕜 a`.","ev":"batch3/probe1.lean S2a: `example (a : A) [IsStarNormal a] : ‖a * a‖₊ = ‖a‖₊ ^ 2 := NNReal.eq <| by simpa using CFC.norm_mul_self ℂ a` compiles (A a NonUnitalCStarAlgebra); `git grep 'CFC.norm_mul_self\\|nnnorm_mul_self' origin/master -- Mathlib` finds only the IsSelfAdjoint pair and the definition.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-bbafe9","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"QuasispectrumRestricts.isometric_cfc","line":394,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-open","claim":"`open NonUnitalIsometricContinuousFunctionalCalculus` at L394, which opens the `QuasispectrumRestricts` section whose only declaration is `isometric_cfc`, is unused. The proof uses only the root-level `isometry_cfcₙHom`. With the line deleted, the whole file still compiles, including the downstream `Nonneg.instNonUnitalIsometricContinuousFunctionalCalculus`.","fix":"Delete `open NonUnitalIsometricContinuousFunctionalCalculus` at L394.","ev":"batch3/IsometricCopy3.lean: copy of src.lean with L394 replaced by a comment (V5). The only errors in IsometricCopy3.out are in the separate test lemma V4 (L497-506); no error in the QuasispectrumRestricts section or later instances.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-e550e1","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"QuasispectrumRestricts.isometric_cfc","line":408,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"undocumented-instance-constructor","claim":"`QuasispectrumRestricts.isometric_cfc` has no docstring, and the module docstring does not mention it. Yet it is the mechanism behind the ℝ and ℝ≥0 isometric instances, which the module docstring calls 'the main purpose' of the file (used in Basic.lean:213 and at L467). Its non-isometric sibling `QuasispectrumRestricts.cfc` (Restrict.lean:285-288) documents what `f` and the predicate `p` mean. The unital twin `SpectrumRestricts.isometric_cfc` (L197) is likewise undocumented.","fix":"Add a docstring modelled on `QuasispectrumRestricts.cfc`'s: an isometric `S`-calculus restricts along an isometric `algebraMap R S` to an isometric `R`-calculus for `p a ↔ q a ∧ QuasispectrumRestricts a f`.","ev":"measured: src.lean L406-408 has no `/-- -/` before `protected theorem isometric_cfc`; `git show origin/master:Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Restrict.lean` L285-288 has the docstring for `QuasispectrumRestricts.cfc`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-5bf797","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"IsGreatest.nnnorm_cfcₙ_nnreal","line":562,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"inconsistent-autoparam-hypothesis-names","claim":"The `f 0 = 0` hypothesis is named `hf0` in `IsGreatest.nnnorm_cfcₙ_nnreal` (L562), `apply_le_nnnorm_cfcₙ_nnreal` (L572) and `MonotoneOn.nnnorm_cfcₙ` (L617), but `hf₀` in the other 10 lemmas of the file, including the adjacent `nnnorm_cfcₙ_nnreal_le_iff` and `nnnorm_cfcₙ_nnreal_lt_iff`. A caller passing it by name (`(hf₀ := h)`) breaks on exactly these three.","fix":"Rename `hf0` to `hf₀` in these three lemmas to match the rest of the file.","ev":"hunts/cfc-isometric/batch4/probe2.lean: `nnnorm_cfcₙ_nnreal_le_iff f a c hc (hf₀ := h0) ha` compiles, but `IsGreatest.nnnorm_cfcₙ_nnreal f a hc (hf₀ := h0) ha` fails with 'Invalid argument name `hf₀` for function `IsGreatest.nnnorm_cfcₙ_nnreal` ... Perhaps you meant `hf0`', and the same error appears for `MonotoneOn.nnnorm_cfcₙ`. `grep -c` on src.lean: 3 × `hf0 : f 0 = 0`, 10 × `hf₀ : f 0 = 0`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-ba69d6","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"apply_le_nnnorm_cfcₙ_nnreal","line":574,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"leftover-revert","claim":"The proof `revert hx; exact (IsGreatest.nnnorm_cfcₙ_nnreal f a hf hf0 ha |>.2 ⟨x, ·, rfl⟩)` is copied from the unital `apply_le_nnnorm_cfc_nnreal`. There the `revert` exists only so that `nontriviality A` can run first. This proof has no `nontriviality`, so the `revert` is an unexplained leftover. The term `IsGreatest.nnnorm_cfcₙ_nnreal f a hf hf0 ha |>.2 ⟨x, hx, rfl⟩`, the form the sibling `norm_apply_le_norm_cfcₙ` (L298) uses, is enough.","fix":"Replace the tactic block by the term `IsGreatest.nnnorm_cfcₙ_nnreal f a hf hf0 ha |>.2 ⟨x, hx, rfl⟩`.","ev":"hunts/cfc-isometric/batch4/src_edit.lean (diff vs src.lean at L573-574): `... : f x ≤ ‖cfcₙ f a‖₊ := IsGreatest.nnnorm_cfcₙ_nnreal f a hf hf0 ha |>.2 ⟨x, hx, rfl⟩`. The whole file compiles (exit 0, no output).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-cbf3c8","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"IsometricContinuousFunctionalCalculus.toNonUnital","line":634,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-typo","claim":"The docstring has a grammar error: 'An isometric continuous functional calculus on a unital algebra yields to a non-unital one.' Here 'yields to' means 'gives way to'; the intended reading is 'yields a non-unital one'.","fix":"Change 'yields to a non-unital one' to 'yields a non-unital one'.","ev":"src.lean L634: `/-- An isometric continuous functional calculus on a unital algebra yields to a non-unital one. -/`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-87f8ea","file":"Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean","decl":"IsometricContinuousFunctionalCalculus.toNonUnital","line":637,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"redundant-compactspace-have","claim":"The 4-line `have : CompactSpace (σₙ 𝕜 a) := by have h_cpct … ; simp only [← isCompact_iff_compactSpace, quasispectrum_eq_spectrum_union_zero] at h_cpct ⊢; exact h_cpct |>.union isCompact_singleton` re-proves, verbatim, the `compactSpace_quasispectrum` field of `ContinuousFunctionalCalculus.toNonUnital` (NonUnital.lean:876-878). Opening the `NonUnitalContinuousFunctionalCalculus` scope exposes that field as an instance. The proof also uses two `change` steps (L646, L654) without a comment.","fix":"Delete the `have` and write `open scoped ContinuousFunctionalCalculus NonUnitalContinuousFunctionalCalculus in`.","ev":"hunts/cfc-isometric/batch4/src_edit.lean (diff vs src.lean at L632-635): with `open scoped ContinuousFunctionalCalculus NonUnitalContinuousFunctionalCalculus in` and the 4-line `have` deleted, the whole file compiles (exit 0, no output).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-0f4bd5","file":"Mathlib/Analysis/Complex/BranchLogRoot.lean","decl":"Complex.exists_continuousOn_eqOn_exp_comp","line":48,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"confusing-binder-names","claim":"`obtain ⟨g, hg⟩ : ∃ g : X → ℂ, …` shadows the input function `g` with the constructed logarithm, while `hf` still refers to the input `g`, so the last steps are hard to read. Renaming the witness to `F` compiles unchanged.","fix":"Rename the extension to `F`.","ev":"-- hunts/branch-log/ProbeGen.lean uses `obtain ⟨F, hg⟩` — compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c67c3f","file":"Mathlib/Analysis/Complex/Conformal.lean","decl":"(file)","line":34,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-overstates","claim":"Several prose claims overstate their theorems. (1) 'holomorphic/antiholomorphic at that point' is used for complex-differentiability at one point; e.g. `f z = z + conj z ^ 2` is conformal at `0` but not holomorphic on any neighbourhood. (2) The `HasFDerivWithinAt.complexOfReal` docstring says the complex derivative *equals* `complexOfReal`, but the lemma only provides a derivative witness: for `s = {0}` the selected `fderivWithin` is `0`. (3) The module intro speaks of maps 'between complex vector spaces', but the results have source (and, for the classification, target) `ℂ`. (4) The theorem docstring says 'the map is nonvanishing' for 'nonzero'.","fix":"Say 'complex-differentiable at the point', 'is a complex derivative within `s`', and restrict the intro to maps out of `ℂ`.","ev":"src L34-40, L243-246, L17-21, L115-116.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-be0e27","file":"Mathlib/Analysis/Complex/Conformal.lean","decl":"(file)","line":107,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"leftover-hygiene","claim":"The file has Lean 3 leftovers: a commented-out `-- let rot := c • (a : ℂ) • ContinuousLinearMap.id ℂ ℂ,` (with a Lean 3 trailing comma) at L107, and a double blank line at L58-59.","fix":"Delete the comment and the extra blank line.","ev":"src L107, L58-59.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-988514","file":"Mathlib/Analysis/Complex/Conformal.lean","decl":"HasFDerivAt.complexOfReal_hasFDerivAt","line":297,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-breaks-convention","claim":"The naming is inconsistent: `HasFDerivWithinAt.complexOfReal` versus `HasFDerivAt.complexOfReal_hasFDerivAt` (redundant suffix), and `IsConformalMap.is_complex_or_conj_linear` (snake-case `is_` for a Prop-valued conclusion). Orientation is inconsistent too: `complexOfReal_fderivWithin` states `fderivWithin ℂ f s x = complexOfReal …`, but `complexOfReal_fderiv` states `complexOfReal … = fderiv ℂ f x`. Three `complexOfReal_*` docstrings are copy-pastes that do not match their `HasDerivAt`/`deriv` statements.","fix":"Rename to `HasFDerivAt.complexOfReal`, align the two `complexOfReal_fderiv*` orientations, and write per-lemma docstrings.","ev":"src L247 vs L297; L100; L256-258 vs L325-327; L263-266, L302-305.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-46f807","file":"Mathlib/Analysis/Complex/Conformal.lean","decl":"complexOfReal_hasDerivAt","line":306,"sev":"NIT","status":"confirmed","cat":"api","pattern":"statement-not-in-simp-normal-form","claim":"`complexOfReal_hasDerivAt`/`WithinAt` state their derivative as `((fderiv ℝ f x).complexOfReal h₂) 1`, which is definitionally `fderiv ℝ f x 1`, so the public statement exposes the construction. Their proofs re-derive `HasFDerivAt.hasDerivAt`/`HasFDerivWithinAt.hasDerivWithinAt` via `hasDerivAt_iff_hasFDerivAt`. The algebraic `LinearMap.complexOfReal` and `real_linearMap_map_smul_complex` only need `[AddCommGroup E] [Module ℂ E]`.","fix":"State the derivative as `fderiv ℝ f x 1`, prove via `.hasDerivAt`, and weaken the algebraic helper's classes.","ev":"src L267-271, L306-310, L189-209.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-ff66c7","file":"Mathlib/Analysis/Complex/Harmonic/Analytic.lean","decl":"HarmonicAt.analyticAt_complex_partial","line":61,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-detour","claim":"`analyticAt_complex_partial` rebuilds the neighbourhood argument through `DifferentiableOn.analyticAt` on the set `{x | HarmonicAt f x}`; `Complex.analyticAt_iff_eventually_differentiableAt.2 (hf.eventually.mono …)` says it directly. In `exists_analyticOnNhd_ball_re_eq`, `(by aesop : (fun z ↦ (F z).re) = Complex.reCLM ∘ F)` (L84) is `rfl` (Astra A1 items 7, 9).","fix":"Use `analyticAt_iff_eventually_differentiableAt` and `rfl`.","ev":"hunts/harmonic-analytic/probe2.lean: both replacements compile, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-8681ed","file":"Mathlib/Analysis/Complex/Harmonic/Analytic.lean","decl":"InnerProductSpace.HarmonicOnNhd.exists_analyticOnNhd_ball_re_eq","line":71,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"shadowed-binder","claim":"Binder hygiene: in `exists_analyticOnNhd_ball_re_eq` the bound variable of `fun z ↦ (F z).re` shadows the centre `z` of `ball z R` in the same statement, and `exists_analyticOnNhd_univ_re_eq` re-binds `{f : ℂ → ℝ}` although the section declares `variable {f : ℂ → ℝ}` (L27); `differentiableAt_complex_partial` also leans on `repeat rw [fderiv_comp]; all_goals try fun_prop` and a mid-proof `ring_nf` (L41, L44).","fix":"Rename the bound variable (`fun w ↦ (F w).re`), drop the redundant binder, and make the rewrite chain explicit.","ev":"Measured: L73, L110 vs L27, L41, L44.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-eb4a5b","file":"Mathlib/Analysis/Complex/Harmonic/Analytic.lean","decl":"InnerProductSpace.HarmonicOnNhd.exists_analyticOnNhd_ball_re_eq","line":71,"sev":"NIT","status":"suspected","cat":"api","pattern":"statement-discards-witness","claim":"Both existence theorems drop what their proofs construct: the witness `F` has `HasDerivAt F (∂f/∂1 - I ∂f/∂I) z` and is normalised (`F z₀ = f z₀`), neither of which is returned (with `f ≡ 0`, `F ≡ I` satisfies the published conclusion); and the derivative comparison goes through `fderivWithin` and back where `IsOpen.eqOn_of_fderiv_eq` / `eq_of_fderiv_eq` apply directly (Astra A1 items 4, 6; not compiled).","fix":"Add a companion returning the derivative and normalisation; use `IsOpen.eqOn_of_fderiv_eq`/`eq_of_fderiv_eq`.","ev":"Suspected: Astra A1 items 4, 6; not compiled.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-b4e159","file":"Mathlib/Analysis/Complex/Harmonic/Analytic.lean","decl":"(file)","line":103,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"expired-deprecation","claim":"The deprecated aliases `harmonic_is_realOfHolomorphic` (L103) and `InnerProductSpace.harmonic_is_realOfHolomorphic_univ` (L136), dated 2026-03-03, are past Mathlib's six-month deprecation window and have no uses in Mathlib.","fix":"Delete both aliases.","ev":"Measured: `since := \"2026-03-03\"` at L103, L136; `grep -rn harmonic_is_realOfHolomorphic Mathlib` finds only these lines.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-edf48b","file":"Mathlib/Analysis/Complex/Harmonic/Analytic.lean","decl":"HarmonicAt.analyticAt","line":144,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"wrong-namespace-for-dot-notation","claim":"`HarmonicAt` is `InnerProductSpace.HarmonicAt`, but `HarmonicAt.differentiableAt_complex_partial`, `HarmonicAt.analyticAt_complex_partial` and `HarmonicAt.analyticAt` are declared in the root `HarmonicAt` namespace, so dot notation (`hf.analyticAt`) fails and every caller writes the full name (L64, L78, L115 here). The two `HarmonicOnNhd` theorems in the same file correctly use `InnerProductSpace.HarmonicOnNhd`.","fix":"Rename to `InnerProductSpace.HarmonicAt.*` with deprecated aliases.","ev":"hunts/harmonic-analytic/probe1.lean: `example (hf : HarmonicAt f x) : AnalyticAt ℝ f x := hf.analyticAt` fails with `Invalid field 'analyticAt': The environment does not contain 'And.analyticAt'` (same for `analyticAt_complex_partial`).","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-fb4b70","file":"Mathlib/Analysis/Complex/Harmonic/Analytic.lean","decl":"HarmonicAt.analyticAt","line":144,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-set-level-corollary","claim":"There is no `HarmonicOnNhd.analyticOnNhd` (`HarmonicOnNhd f s → AnalyticOnNhd ℝ f s`), the set-level form of `HarmonicAt.analyticAt`; it is a one-liner.","fix":"Add `InnerProductSpace.HarmonicOnNhd.analyticOnNhd`.","ev":"hunts/harmonic-analytic/probe1.lean: `example {s : Set ℂ} (hf : HarmonicOnNhd f s) : AnalyticOnNhd ℝ f s := fun x hx ↦ HarmonicAt.analyticAt (hf x hx)` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261006-826a84","file":"Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Truncated.lean","decl":"(file)","line":23,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-import","claim":"`open … Metric Real …` opens two unused namespaces, and `truncatedLogCounting_eval_zero` passes `[truncatedLogCounting_top, truncatedLogCounting_coe]` to `simp` although both are already `local simp`. A copy with `open Filter Function MeromorphicOn Set` and `cases a <;> simp` compiles.","fix":"Drop `Metric Real` from `open`; use `cases a <;> simp`.","ev":"-- hunts/trunc-logcount/ProbeCopy.lean compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ce84c2","file":"Mathlib/Analysis/Complex/ValueDistribution/SecondMainTheorem.lean","decl":"Real.exists_sum_posLog_inv_norm_sub_le","line":49,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"junk-value-presented-as-fact","claim":"The docstring says closeness to a point of s 'is detected' by `log⁺ ‖∑ (· - a)⁻¹‖`, without noting that exactly at a point of s the junk value `0⁻¹ = 0` makes both sides 0 (detection is near, not at, the points); the private helper's comment omits its hypothesis `0 < c` (false for c = 0: s = {0}, w = 1/2 gives log 2 ≤ 0).","fix":"Mention the `w ∈ s` convention; add 'for `c > 0`' to the helper comment.","ev":"example : ∑ a ∈ ({0} : Finset ℝ), Real.posLog ‖(0:ℝ) - a‖⁻¹ = 0 := by simp","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-004962","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.derivCLM","line":41,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"duplicate-variable-binder","claim":"The file-level `variable {ι 𝕜 D E F V F F₁ F₂ F₃ : Type*}` (line 41), inherited by derivCLM as the file's first declaration, declares `F` twice. The first `F` is shadowed and never used: its universe u_5 appears in no declaration (`SchwartzMap.derivCLM.{u_2, u_7}`, with F = u_7).","fix":"Write `variable {ι 𝕜 D E F V F₁ F₂ F₃ : Type*}`.","ev":"hunts/schwartz-deriv/batch0/Probe1.lean: `#print SchwartzMap.derivCLM` shows `SchwartzMap.derivCLM.{u_2, u_7}` (u_1 ι, u_2 𝕜, u_3 D, u_4 E, u_5 first F (unused), u_6 V, u_7 second F). hunts/schwartz-deriv/batch0/CopyA.lean with the duplicate removed compiles.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-c9ab83","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.lineDerivOpCLM_eq","line":122,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-open","claim":"`open LineDeriv` at line 122, just before lineDerivOpCLM_eq, repeats `open LineDeriv` at line 74 of the enclosing `section Derivatives` (`section fderiv` is nested inside it), so it has no effect.","fix":"Delete line 122.","ev":"hunts/schwartz-deriv/batch0/CopyA.lean: line 122 commented out; the whole file compiles (exit 0), including lineDerivOpCLM_eq and every later use of `∂`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-a215b7","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.iteratedLineDerivOp_eq_iteratedFDeriv","line":130,"sev":"NIT","status":"confirmed","cat":"api","pattern":"all-implicit-equation-lemma","claim":"All of `{n} {m} {f} {x}` are implicit in a hypothesis-free equation lemma, so it cannot be instantiated positionally (`iteratedLineDerivOp_eq_iteratedFDeriv m f x` fails with `Function expected`); its siblings `lineDerivOp_apply (m f x)` and `tsupport_iteratedLineDerivOp_subset (m f)` take these explicitly.","fix":"Make `m`, `f` and `x` explicit binders (keep `n` implicit).","ev":"-- hunts/schwartz-deriv/batch1/Probe1.lean (section F)\nexample {n : ℕ} (m : Fin n → E) (f : 𝓢(E, F)) (x : E) :\n    ∂^{m} f x = iteratedFDeriv ℝ n f x m := iteratedLineDerivOp_eq_iteratedFDeriv m f x\n-- error: Function expected at iteratedLineDerivOp_eq_iteratedFDeriv","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-9f6fce","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.iteratedLineDerivOp_eq_iteratedFDeriv","line":130,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"imprecise-module-doc-entry","claim":"The module docstring (line 29-30) describes this lemma as 'the iterated directional derivative is given by the applied Fréchet derivative'; the right-hand side is the n-th *iterated* Fréchet derivative `iteratedFDeriv ℝ n f x` applied to `m`.","fix":"Change the module-doc entry to 'is given by the iterated Fréchet derivative applied to the directions'.","ev":"grep -n 'applied Fréchet' src.lean  =>  30:  by the applied Fréchet derivative of a Schwartz function.\nstatement: (∂^{m} f) x = (iteratedFDeriv ℝ n (⇑f) x) m","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-e17832","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.tsupport_derivCLM_subset","line":157,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"roundabout-proof-existing-lemma","claim":"The 3-line proof uses an uncommented `change` and detours through `fderiv` (`simp_rw [← fderiv_apply_one_eq_deriv]; exact tsupport_fderiv_apply_subset ℝ 1`), although Mathlib's `tsupport_deriv_subset : tsupport (deriv f) ⊆ tsupport f` (Mathlib/Analysis/Calculus/Deriv/Support.lean:57) closes the goal as a term, exactly as `tsupport_fderivCLM_subset` is proved by `tsupport_fderiv_subset ℝ`.","fix":"Replace the proof by the term `tsupport_deriv_subset`.","ev":"-- hunts/schwartz-deriv/batch1/Probe1.lean (section C), compiles\nexample {𝕜 F : Type*} [RCLike 𝕜] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F]\n    (f : 𝓢(ℝ, F)) : tsupport (derivCLM 𝕜 F f) ⊆ tsupport f := tsupport_deriv_subset","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-b7d712","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.laplacianCLM_eq","line":202,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"apply-lemma-named-eq","claim":"The statement `laplacianCLM 𝕜 E 𝓢(E, F) f = Δ f` is an evaluation lemma for a bundled map, so Mathlib's convention is `_apply`; the identical-shape sibling is `TemperedDistribution.laplacianCLM_apply` (TemperedDistribution.lean:429), and the framework uses `LineDeriv.lineDerivOpCLM_apply` / `iteratedLineDerivOpCLM_apply`. `_eq` reads as an equality of CLMs.","fix":"Rename to `SchwartzMap.laplacianCLM_apply` with a deprecated alias `laplacianCLM_eq`.","ev":"#check @SchwartzMap.laplacianCLM_eq  -- (laplacianCLM 𝕜 E 𝓢(E, F)) f = Δ f\n#check @TemperedDistribution.laplacianCLM_apply  -- (laplacianCLM ℂ E 𝓢'(E, F)) f = Δ f\n(hunts/schwartz-deriv/batch1/Probe1.lean section A, output in Probe1.out)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-92f694","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.integral_mul_deriv_eq_neg_deriv_mul","line":237,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"inconsistent-sibling-name","claim":"The name breaks the scheme of the other 11 integration-by-parts lemmas in this file, which all read `integral_<pairing>_<operator>_right_eq_neg_left` / `_right_eq_left` (including its direct analogues `integral_mul_lineDerivOp_right_eq_neg_left` and `integral_mul_laplacian_right_eq_left` and its 1-D siblings `integral_bilinear_deriv_right_eq_neg_left`, `integral_smul_deriv_right_eq_neg_left`); this one alone is `integral_mul_deriv_eq_neg_deriv_mul`. The statement itself is correct, so this is cosmetic.","fix":"Rename to `integral_mul_deriv_right_eq_neg_left` and keep a `@[deprecated]` alias (no Mathlib consumer uses the old name).","ev":"git -C mathlib4 grep -n '^theorem integral_' origin/master -- Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean  => 12 lemmas (L226..L352); 11 end in `_right_eq_neg_left`/`_right_eq_left`, only L237 is `integral_mul_deriv_eq_neg_deriv_mul`. `git grep -n integral_mul_deriv_eq_neg_deriv_mul origin/master -- Mathlib` => only the declaration itself (no consumers).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-51d853","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.integral_clm_comp_deriv_right_eq_neg_left","line":253,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"clm-comp-names-application","claim":"The statement is about *application* of an operator-valued Schwartz function, `f x (deriv g x)`, not composition. Mathlib's convention is `clm_apply` for `fun x => (f x) (g x)` (`HasFDerivAt.clm_apply`, `fderiv_clm_apply`, `ContDiff.clm_apply`, `norm_iteratedFDeriv_clm_apply`) and `clm_comp` for `fun x => (g x).comp (f x)` (`HasFDerivAt.clm_comp`, `ContDiff.clm_comp`, `Continuous.clm_comp`). The statement is correct, so NIT.","fix":"Rename to `integral_clm_apply_deriv_right_eq_neg_left` with a `@[deprecated]` alias.","ev":"Mathlib/Analysis/Calculus/FDeriv/CompCLM.lean:114 `theorem HasFDerivAt.clm_apply` (for `fun y => (c y) (u y)`), :61 `theorem HasFDerivAt.clm_comp` (for `fun y => (c y).comp (d y)`); Mathlib/Analysis/Calculus/ContDiff/Comp.lean:495 `ContDiff.clm_apply … : ContDiff 𝕜 n fun x => (f x) (g x)`, :472 `ContDiff.clm_comp … : ContDiff 𝕜 n fun x => (g x).comp (f x)`; the lemma's conclusion is `∫ x, f x (deriv g x) = -∫ x, deriv f x (g x)`. No Mathlib consumer of the `integral_clm_comp_*` names (git grep finds only the declarations).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-3349b3","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.integral_clm_comp_lineDerivOp_right_eq_neg_left","line":298,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"clm-comp-names-application","claim":"The statement is about *application* of an operator-valued Schwartz function, `f x (∂_{v} g x)`, not composition. Mathlib's convention is `clm_apply` for `fun x => (f x) (g x)` (`HasFDerivAt.clm_apply`, `fderiv_clm_apply`, `ContDiff.clm_apply`, `norm_iteratedFDeriv_clm_apply`) and `clm_comp` for `fun x => (g x).comp (f x)` (`HasFDerivAt.clm_comp`, `ContDiff.clm_comp`, `Continuous.clm_comp`). The statement is correct, so NIT.","fix":"Rename to `integral_clm_apply_lineDerivOp_right_eq_neg_left` with a `@[deprecated]` alias.","ev":"Mathlib/Analysis/Calculus/FDeriv/CompCLM.lean:114 `theorem HasFDerivAt.clm_apply` (for `fun y => (c y) (u y)`), :61 `theorem HasFDerivAt.clm_comp` (for `fun y => (c y).comp (d y)`); Mathlib/Analysis/Calculus/ContDiff/Comp.lean:495 `ContDiff.clm_apply … : ContDiff 𝕜 n fun x => (f x) (g x)`, :472 `ContDiff.clm_comp … : ContDiff 𝕜 n fun x => (g x).comp (f x)`; the lemma's conclusion is `∫ x, f x (∂_{v} g x) ∂μ = -∫ x, ∂_{v} f x (g x) ∂μ`. No Mathlib consumer of the `integral_clm_comp_*` names (git grep finds only the declarations).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-07eed0","file":"Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean","decl":"SchwartzMap.integral_clm_comp_laplacian_right_eq_left","line":352,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"clm-comp-names-application","claim":"The statement is about *application* of an operator-valued Schwartz function, `f x (Δ g x)`, not composition. Mathlib's convention is `clm_apply` for `fun x => (f x) (g x)` (`HasFDerivAt.clm_apply`, `fderiv_clm_apply`, `ContDiff.clm_apply`, `norm_iteratedFDeriv_clm_apply`) and `clm_comp` for `fun x => (g x).comp (f x)` (`HasFDerivAt.clm_comp`, `ContDiff.clm_comp`, `Continuous.clm_comp`). The statement is correct, so NIT.","fix":"Rename to `integral_clm_apply_laplacian_right_eq_left` with a `@[deprecated]` alias.","ev":"Mathlib/Analysis/Calculus/FDeriv/CompCLM.lean:114 `theorem HasFDerivAt.clm_apply` (for `fun y => (c y) (u y)`), :61 `theorem HasFDerivAt.clm_comp` (for `fun y => (c y).comp (d y)`); Mathlib/Analysis/Calculus/ContDiff/Comp.lean:495 `ContDiff.clm_apply … : ContDiff 𝕜 n fun x => (f x) (g x)`, :472 `ContDiff.clm_comp … : ContDiff 𝕜 n fun x => (g x).comp (f x)`; the lemma's conclusion is `∫ x, f x (Δ g x) ∂μ = ∫ x, Δ f x (g x) ∂μ`. No Mathlib consumer of the `integral_clm_comp_*` names (git grep finds only the declarations).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-251838","file":"Mathlib/Analysis/FunctionalSpaces/BesselPotentialSpace.lean","decl":"BesselPotentialSpace","line":47,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"stale-docstring","claim":"The structure is documented as 'also known as the Sobolev space' without the module's 'Fourier-theoretic' qualifier (H^{s,p} ≠ W^{k,p} at p = 1, ∞); the field `toLp` is documented as 'The underlying Lp function', but it is J_s u, not u (e.g. δ₀ ∈ H^{-1,2}(ℝ) is no function); the norm uses the multiplier (1 + ‖ξ‖²)^{s/2}, i.e. (1 - Δ/4π²)^{s/2} under Mathlib's Fourier convention, which this file does not mention.","fix":"Qualify 'Sobolev', describe `toLp` as the Lp representative of the Bessel potential, note the normalization.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-469048","file":"Mathlib/Analysis/FunctionalSpaces/BesselPotentialSpace.lean","decl":"BesselPotentialSpace.injective_toLp","line":110,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-order-nonstandard","claim":"`injective_toLp` inverts Mathlib's `f_injective` order (the same file has `coeAddMonoidHom_injective`), and `toLpₗᵢ_symm_apply` is named as an application lemma but states an equality of coercions to `𝓢'`. Also `coeAddMonoidHom` is named after the coercion rather than the projection `toDistr` (`toDistrAddMonoidHom`), and `MemSobolev.toBesselPotentialSpace_toDistr` reverses the outer-first order of `toDistr_ofLp`.","fix":"`toLp_injective`; `coe_toLpₗᵢ_symm_apply`.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-7563ce","file":"Mathlib/Analysis/FunctionalSpaces/BesselPotentialSpace.lean","decl":"BesselPotentialSpace.instSMul","line":170,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"style-indentation","claim":"The SMul section redeclares `{p : ℝ≥0∞} [hp : Fact (1 ≤ p)]`, shadowing the identical variables declared above in the same section; `memSobolev_toDistr` has a double space before `:=`; `toDistr_copy`/`toLp_copy` indent their statement lines by 2 instead of 4. Proof terms wrap with `(by exact …)` and `by rfl` where the term suffices.","fix":"Delete the duplicate variables; fix spacing and indentation.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-126dae","file":"Mathlib/Analysis/FunctionalSpaces/BesselPotentialSpace.lean","decl":"BesselPotentialSpace.instNormedSpaceComplex","line":244,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"reprovable-from-existing-api","claim":"The `NormedSpace ℂ` and `InnerProductSpace ℂ` instances are built by hand where `NormedSpace.induced ℂ _ _ (toLpₗ E F s p)` and `InnerProductSpace.induced` apply; `norm_fourier_toLp_eq` is proved via the implementation field `LinearIsometryEquiv.norm_map'` instead of `Lp.norm_fourier_eq`; `toDistr_copy`/`toLp_copy` take `hs` but do not pass it, so `copy`'s `grind` autoParam re-proves it during elaboration.","fix":"Use the `induced` constructors and `Lp.norm_fourier_eq`; write `f.copy s' hs`.","ev":"example : NormedSpace ℂ H^{s, p}(E, F) := NormedSpace.induced ℂ _ _ (toLpₗ E F s p)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261007-e9bac1","file":"Mathlib/Analysis/InnerProductSpace/Dual.lean","decl":"(file)","line":104,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"duplicated-local-notation","claim":"The local notations `⟪x, y⟫` and `†` are declared twice (L57-59 and L104-106), once per section; `†` is used once (L167). `innerSL_norm`, `ext_inner_*_basis` and the `continuousLinearMapOfBilin` lemmas have no docstrings, and `ext_inner_left_basis`/`ext_inner_right_basis` (pure inner-product facts used only by Adjoint.lean) sit in the Riesz file only because their proof uses `toDualMap`.","fix":"Declare the notation once before both sections; add docstrings; consider moving the basis ext lemmas next to `ext_inner_left` (InnerProductSpace/Basic.lean:324).","ev":"Measured: L57-59 vs L104-106; L167; git grep uses of ext_inner_right_basis in Adjoint.lean:695,706.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-c2655a","file":"Mathlib/Analysis/InnerProductSpace/Dual.lean","decl":"ext_inner_left_basis","line":113,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-detour","claim":"`ext_inner_left_basis`/`ext_inner_right_basis` go through `toDualMap`, coercion injectivity and two `conv_rhs` conjugations; `Basis.ext` on the semilinear `innerₛₗ 𝕜 x` gives each in one term (`ext_inner_right 𝕜 fun z ↦ DFunLike.congr_fun (b.ext h : innerₛₗ 𝕜 x = innerₛₗ 𝕜 y) z`), which also removes their dependence on this file (Astra A1 item 10). The Riesz proof in `toDual` uses `haveI` for an equation and `field` for one cancellation (item 15).","fix":"Use the `Basis.ext` proofs and move the lemmas next to `ext_inner_left`.","ev":"hunts/ips-dual/probe1.lean (D): the one-term `ext_inner_right_basis` proof compiles, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-47f25c","file":"Mathlib/Analysis/InnerProductSpace/Dual.lean","decl":"continuousLinearMapOfBilin","line":193,"sev":"NIT","status":"suspected","cat":"api","pattern":"api-narrower-than-construction","claim":"Astra A1 items 5, 6, 11, 12 (not compiled here): `continuousLinearMapOfBilin` works for `B : V →L⋆[𝕜] StrongDual 𝕜 H` with only `H` Hilbert (rectangular version); it is `LinearIsometry.postcomp` of `(toDual 𝕜 E).symm`, which would give additivity/norm-preservation (`‖B♯‖ = ‖B‖`) for free; `Bilin` is a misnomer for a sesquilinear form; `unique_continuousLinearMapOfBilin` is a pointwise uniqueness lemma with a hypothesis misleadingly named `is_lax_milgram`.","fix":"Generalise to `V →L[𝕜] H`, bundle via `postcomp`, document the slot convention.","ev":"Suspected: Astra A1 items 5, 6, 11, 12; not compiled.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261006-03a5c9","file":"Mathlib/Analysis/InnerProductSpace/NormDet.lean","decl":"LinearMap.normDet_smul","line":241,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-detour","claim":"Proof detours: `normDet_eq_zero_iff_ker_ne_bot` proves nonvanishing of the determinant via adjoints where `LinearEquiv.isUnit_det` applies; `normDet_smul` case-splits and transports bases where `c • f = f ∘ₗ c • id` plus `normDet_comp_of_finrank_eq` and `det_smul` suffice; `normDet_comp_of_finrank_eq`'s second branch re-derives what `normDet_comp` gives.","fix":"Use the cited lemmas.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-4a29b5","file":"Mathlib/Analysis/InnerProductSpace/NormDet.lean","decl":"LinearMap.normDet_eq_prod_singularValues","line":374,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-typo","claim":"Docs: the module opening calls normDet a generalisation of 'the determinant of a square matrix' (it generalises its absolute value/norm); the 'Gram determinant' bullet says the name is used by `Matrix.gram`, which is the Gram matrix; 'normDet equals the product of singular values' omits that exactly `finrank 𝕜 U` values are multiplied, zeros included (for ℝ² → ℝ, (x, y) ↦ x the product is 1·0 = 0, not the product over nonzero singular values); `normDet_eq_zero_iff_rank_range_ne` compares `finrank`s, not `rank`s.","fix":"Qualify the three docs; rename to `normDet_eq_zero_iff_finrank_range_ne`.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261013-8ce57b","file":"Mathlib/Analysis/Normed/Affine/MazurUlam.lean","decl":"IsometryEquiv.midpoint_fixed","line":47,"sev":"NIT","status":"confirmed","cat":"api","pattern":"binders-after-colon","claim":"`midpoint_fixed {x y : PE} : ∀ e : PE ≃ᵢ PE, e x = x → e y = y → …` puts its main explicit argument and both hypotheses after the colon (so the proof can `set` before introducing them); Mathlib style puts binders before the colon.","fix":"State it as `theorem midpoint_fixed (e : PE ≃ᵢ PE) {x y : PE} (hx : e x = x) (hy : e y = y) : …` and generalise inside the proof.","ev":"Measured: source L47-48; `#check @midpoint_fixed` in hunts/mazur-ulam/probe.lean shows `{x y : PE} (e : PE ≃ᵢ PE), e x = x → e y = y → …`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-04035d","file":"Mathlib/Analysis/Normed/Affine/MazurUlam.lean","decl":"IsometryEquiv.map_midpoint","line":97,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"unneeded-explicit-at","claim":"The last rewrite of `map_midpoint` uses `@pointReflection_fixed_iff`; the `@` is unnecessary.","fix":"Write `pointReflection_fixed_iff`.","ev":"hunts/mazur-ulam/copy.lean: the file with `@pointReflection_fixed_iff` replaced by `pointReflection_fixed_iff` compiles with the Mathlib linter set, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-23e4cb","file":"Mathlib/Analysis/Normed/Affine/MazurUlam.lean","decl":"IsometryEquiv.toRealAffineIsometryEquiv","line":141,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"redundant-normalisation","claim":"The linear part of `toRealAffineIsometryEquiv` is `v ↦ f (v +ᵥ p) -ᵥ f p`, which already sends `0` to `0`, yet the definition passes it through `toRealLinearIsometryEquiv`, which subtracts its value at `0` a second time; the file's own `toRealLinearIsometryEquivOfMapZero (by simp)` builds it directly.","fix":"Use `(… ).toRealLinearIsometryEquivOfMapZero (by simp)` for the linear part.","ev":"hunts/mazur-ulam/copyR.lean: the definition built with `toRealLinearIsometryEquivOfMapZero (by simp)` compiles, and `coeFn_toRealAffineIsometryEquiv` (`rfl`) and `coe_toRealAffineIsometryEquiv` (`ext; rfl`) still compile, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-52ca76","file":"Mathlib/Analysis/Normed/Affine/MazurUlam.lean","decl":"IsometryEquiv.coe_toRealAffineIsometryEquiv","line":150,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"inconsistent-coe-naming","claim":"The file uses `coe_` for two different things: `coe_toRealLinearIsometryEquivOfMapZero` is about `⇑`, but for the affine version the `⇑` lemma is `coeFn_toRealAffineIsometryEquiv` and `coe_toRealAffineIsometryEquiv` is `f.toRealAffineIsometryEquiv.toIsometryEquiv = f`, a projection, not a coercion.","fix":"Rename to `coe_toRealAffineIsometryEquiv` (for `⇑`) and `toIsometryEquiv_toRealAffineIsometryEquiv` (for the projection), with deprecated aliases.","ev":"Measured: source L112-113 (`⇑… = f` named `coe_`), L146 (`⇑… = f` named `coeFn_`), L150-151 (`.toIsometryEquiv = f` named `coe_`).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261006-8eb2f9","file":"Mathlib/Analysis/Normed/Operator/Fredholm/Basic.lean","decl":"ContinuousLinearMap.FredholmPackage.isQuasiInverse","line":212,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"copied-docstring","claim":"The lemma's docstring is a verbatim copy of the docstring of the def `FredholmPackage.quasiInverse` above it; it should state the lemma (`pkg.quasiInverse` is a quasi-inverse of `u`).","fix":"'`pkg.quasiInverse` is a (continuous) quasi-inverse of `u`.'","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-288cb8","file":"Mathlib/Analysis/Normed/Operator/Fredholm/Basic.lean","decl":"ContinuousLinearMap.IsFredholm.id","line":420,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`IsFredholm.id` and `ContinuousLinearEquiv.isFredholm` are not `@[simp]`, although the file makes `isFredholm_comp_equiv`/`isFredholm_equiv_comp` simp lemmas that reduce to them.","fix":"Tag both `@[simp]`.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-f8fd0f","file":"Mathlib/Analysis/Normed/Operator/Fredholm/Open.lean","decl":"ContinuousLinearMap.IsFredholm.index_continuousAt","line":97,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-order-nonstandard","claim":"`IsFredholm.index_continuousAt` and `index_continuousOn_isFredholm` put the function before the predicate; Mathlib names a `ContinuousAt f x` / `ContinuousOn f s` conclusion `continuousAt_f` / `continuousOn_f` (146 `continuousOn_*` theorems vs 17 `*_continuousOn`).","fix":"Rename to `IsFredholm.continuousAt_index` and `continuousOn_index_isFredholm` (with deprecated aliases).","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-f71a6f","file":"Mathlib/Analysis/Normed/Operator/Fredholm/Open.lean","decl":"ContinuousLinearMap.IsFredholm.index_continuousAt","line":97,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"reprovable-from-existing-api","claim":"The proof `tendsto_const_nhds.congr' <| .symm hT₀.eventually_nhds_index_eq` re-derives `Filter.EventuallyEq.continuousAt`.","fix":"`hT₀.eventually_nhds_index_eq.continuousAt`.","ev":"example ... (hT₀ : T₀.IsFredholm) : ContinuousAt (fun (T : E →L[𝕜] F) ↦ T.index) T₀ :=\n  Filter.EventuallyEq.continuousAt hT₀.eventually_nhds_index_eq","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-634f52","file":"Mathlib/Analysis/Normed/Operator/Fredholm/Open.lean","decl":"ContinuousLinearMap.index_continuousOn_isFredholm","line":104,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-typo","claim":"Docstring typos: 'Banach spaces..' (double period) and 'i.e locally constant' (twice, also in the module docstring). The module and declaration docstrings say 'between two Banach spaces', but only the domain is assumed complete (`[CompleteSpace E]`); the codomain may be any normed space.","fix":"Fix the typos; say 'from a Banach space to a normed space' or note that only `E` needs to be complete.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261007-04401f","file":"Mathlib/Analysis/ODE/Transform.lean","decl":"(imports)","line":10,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-import","claim":"The direct imports `Mathlib.Analysis.Calculus.FDeriv.Add` and `Mathlib.Analysis.Calculus.FDeriv.Equiv` are already provided by `Mathlib.Analysis.Calculus.Deriv.Mul` (via `FDeriv.Mul`, `FDeriv.Analytic`, `ContDiff.FTaylorSeries`); the file compiles without them, and nothing from `FDeriv.Equiv` is used directly.","fix":"Drop `import Mathlib.Analysis.Calculus.FDeriv.Equiv` (and optionally `FDeriv.Add`, which is used directly via `hasFDerivWithinAt_comp_add_right`).","ev":"hunts/ode-transform/probe4_imports.lean (the file without those two imports) compiles with exit 0. Raised by Astra's A1 pass (item 5).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-05b729","file":"Mathlib/Analysis/ODE/Transform.lean","decl":"(file)","line":15,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstrings","claim":"18 of the 19 declarations have no docstring, and the module docstring has no main-results list and does not say that `Mathlib/Geometry/Manifold/IntegralCurve/Transform.lean` mirrors it (the manifold file does say so).","fix":"Add one-line docstrings and a short main-results list (translation by `dt`, scaling by `a`, the `a ≠ 0` iff forms).","ev":"Doc-only finding: only L166 carries a docstring; L15-24 module docstring.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-100823","file":"Mathlib/Analysis/ODE/Transform.lean","decl":"isIntegralCurveOn_comp_mul_ne_zero","line":114,"sev":"NIT","status":"confirmed","cat":"api","pattern":"inconsistent-set-spelling","claim":"The rescaled domain is spelled two ways: `IsIntegralCurveOn.comp_mul` concludes on `{t | t * a ∈ s}` while its iff `isIntegralCurveOn_comp_mul_ne_zero` uses `a⁻¹ • s` (its own proof needs a `heq` to bridge them), and the manifold twin's iff keeps `{t | t * a ∈ s}`. Rewriting with the iff after applying the implication therefore needs a set-equality step.","fix":"Use one spelling in both lemmas (and in the manifold mirror), e.g. `a⁻¹ • s`, matching the translation lemmas' `-dt +ᵥ s`.","ev":"hunts/ode-transform/probe2.lean P5: `a⁻¹ • s = {t | t * a ∈ s}` needs `mem_inv_smul_set_iff₀ ha, smul_eq_mul, mul_comm` (the file's own `heq`, L116-119). Exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-21e68c","file":"Mathlib/Analysis/ODE/Transform.lean","decl":"IsIntegralCurveAt.comp_mul_ne_zero","line":130,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"hypothesis-in-name-as-conclusion","claim":"The `_ne_zero` suffix names the hypothesis `a ≠ 0` as if it were part of the conclusion (`comp_mul_ne_zero` reads 'the composite is nonzero'); Mathlib omits such hypotheses from names or writes `_of_ne_zero`. For the implication `IsIntegralCurveAt.comp_mul_ne_zero` the hypothesis is not even needed, so the name also breaks the `IsIntegralCurveOn.comp_mul` / `IsIntegralCurve.comp_mul` pattern.","fix":"Rename the implication to `IsIntegralCurveAt.comp_mul` and the iffs to `isIntegralCurve{On,At,}_comp_mul` (or `_comp_mul_of_ne_zero`), with deprecated aliases; mirror in the manifold file.","ev":"Name-only finding: L114, L130, L140, L156 of the audited file; `git grep -n 'comp_mul_ne_zero' -- Mathlib` shows the same names only here and in Geometry/Manifold/IntegralCurve/Transform.lean.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-49d651","file":"Mathlib/Analysis/ODE/Transform.lean","decl":"isIntegralCurve_comp_mul_ne_zero","line":156,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"duplicated-proof-blocks","claim":"The three scaling iffs repeat the same `convert hγ.comp_mul… a⁻¹` with two identical `ext t; simp only [comp_apply, (Pi.smul_apply,) mul_assoc, inv_mul_eq_div, div_self ha, mul_one, …]` blocks. `isIntegralCurve_comp_mul_ne_zero` in particular reduces to `isIntegralCurveOn_comp_mul_ne_zero` through `isIntegralCurveOn_univ` in three lines, exactly as its translation sibling `isIntegralCurve_comp_add` does.","fix":"Prove `isIntegralCurve_comp_mul_ne_zero` by `simp_rw [← isIntegralCurveOn_univ]; convert isIntegralCurveOn_comp_mul_ne_zero ha; simp [smul_set_univ₀ (inv_ne_zero ha)]`, or factor the two rescaling identities into helper lemmas.","ev":"hunts/ode-transform/probe2.lean P4 compiles. Exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-88b3c7","file":"Mathlib/Analysis/ODE/Transform.lean","decl":"isIntegralCurve_const","line":166,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-wrong-variable","claim":"The docstring of `isIntegralCurve_const` speaks of `x₀` ('vanishes at `x₀` … the constant curve at `x₀`') but the binder is `x`.","fix":"Write `x` in the docstring.","ev":"Doc-only finding: L166-168 `/-- If the vector field `v` vanishes at `x₀` … -/ lemma isIntegralCurve_const {x : E} (h : ∀ t, v t x = 0)`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-54df86","file":"Mathlib/Analysis/ODE/Transform.lean","decl":"isIntegralCurve_const","line":168,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"misplaced-declaration","claim":"`isIntegralCurve_const` (constant curves at zeros of the field are integral curves) has nothing to do with translating or scaling time, yet sits in `section Scaling` of this file and is not mentioned in its module docstring; it belongs with the basic API in `Mathlib/Analysis/ODE/Basic.lean` (the manifold mirror makes the same choice).","fix":"Move `isIntegralCurve_const` to `Mathlib/Analysis/ODE/Basic.lean` (and its manifold mirror to `IntegralCurve/Basic.lean`).","ev":"Placement-only finding: L104-171 `section Scaling … lemma isIntegralCurve_const`; the module docstring (L15-24) covers translation and scaling only.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261006-da6278","file":"Mathlib/Analysis/SpecialFunctions/Bessel.lean","decl":"Complex.besselJ","line":55,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-modifier","claim":"`noncomputable def besselJ` repeats `noncomputable` inside the enclosing `noncomputable section`. Also: `open Nat FormalMultilinearSeries` is unused (the file compiles without it) and `besselJ` has no explicit result type.","fix":"Drop the modifier.","ev":"sed 's/^open Nat FormalMultilinearSeries$//' Bessel.lean > Probe_noopen.lean; lake env lean Probe_noopen.lean  -- exit 0","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-cf9393","file":"Mathlib/Analysis/SpecialFunctions/Bessel.lean","decl":"Complex.besselJ_neg_int","line":83,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-detour","claim":"The local identity `h` in `besselJ_neg_int` is proved by splitting on `x = 0` and `a = 0` and `cpow_add`; it is two rewrites with `inv_mul_mul_self`, which holds at 0. `analyticAt_besselJ_int`'s negative branch could transport along `besselJ_neg_comm` instead of inverting a sign.","fix":"`simp only [cpow_neg, cpow_natCast]; rw [pow_right_comm y 2 n, pow_two, ← mul_assoc, inv_mul_mul_self]`.","ev":"example (y : ℂ) (n : ℕ) : y ^ (n : ℂ) = y ^ (-(n : ℂ)) * (y ^ 2) ^ n := by\n  simp only [cpow_neg, cpow_natCast]\n  rw [pow_right_comm y 2 n, pow_two, ← mul_assoc, inv_mul_mul_self]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-c90252","file":"Mathlib/Analysis/SpecialFunctions/Bessel.lean","decl":"Complex.besselJ_zero","line":118,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`besselJ_zero` is not `@[simp]`: `simp` makes no progress on `besselJ 0 0 = 1`.","fix":"Tag it `@[simp]` (or add `besselJ_zero_zero` / `besselJ_zero_of_ne` simp lemmas).","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-f4278e","file":"Mathlib/Analysis/SpecialFunctions/FrullaniIntegral.lean","decl":"(file)","line":30,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-variable","claim":"`set C := |log (b / a)| with hC_def` (in `tendsto_integral_inv_smul_of_tendsto_uniform`) and `set g := … with hg` (in `integral_Ioi_eq`) name equations that are never used; the `variable` line's continuation `{a b c : ℝ} {L R : E}` is indented 9 spaces instead of 4.","fix":"Drop the two `with` clauses; re-indent the variable continuation.","ev":"-- hunts/frullani/ProbeHyg.lean: src without `with hC_def` and `with hg` — compiles, no warnings","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-77a257","file":"Mathlib/Analysis/SpecialFunctions/RegularizedHypergeometric.lean","decl":"(file)","line":62,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-variable","claim":"`variable {p q : ℕ}` is never used (the parameters are multisets); `regularizedHGFunCoeff_add_one`'s statement has a double space ('.prod  * (n + 1)'). The section variable `k : ℂ` (and `j`, `n`, `m` partly) is unused too, and `tendsto_multiset_prod_div_add_one` has an unused `hi`.","fix":"Delete the variable line; single space.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-17d4eb","file":"Mathlib/Analysis/SpecialFunctions/RegularizedHypergeometric.lean","decl":"Complex.regularizedHGFunCoeff_add_one_div_self","line":114,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-detour","claim":"The negative branch of `regularizedHGFunCoeff_add_one_div_self` is impossible (`h : C n ≠ 0` already gives every b ≠ -n) but is proved at length; `tendsto_multiset_prod_div_multiset_prod_mul` ends with `simp only`/`congr`/`simp` where `simpa using this` suffices; `regularizedHGFun_zero_singleton_neg_nat_add_one` reindexes via summability where `Function.Injective.tsum_eq` needs none.","fix":"Derive `hb` from `h` and keep one branch; `simpa`; reindex with `Injective.tsum_eq`.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-823ad5","file":"Mathlib/Analysis/SpecialFunctions/RegularizedHypergeometric.lean","decl":"Complex.regularizedHGFunSeries","line":156,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"Missing basic API: no radius-0 result for a.card > b.card + 1 (non-terminating); no analyticity for terminating series (`radius_…_eq_top_of_finite` is not carried to `AnalyticOnNhd`); no `regularizedHGFunCoeff a b 0 = (b.map Gamma).prod⁻¹` simp lemma; no Gaussian wrappers (`regularizedGaussHGFun a b c 0 = (Gamma c)⁻¹`, analyticity on the unit disk); the series identity `(Gamma c)⁻¹ • ordinaryHypergeometricSeries ℂ a b c = regularizedGaussHGFunSeries a b c` is not exported; no unconditional multiplicative recurrence.","fix":"Add the listed lemmas.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-cf4bce","file":"Mathlib/Analysis/SpecialFunctions/RegularizedHypergeometric.lean","decl":"Complex.regularizedGaussHGFunSeries","line":355,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-typo","claim":"Docstring slips: `regularizedGaussHGFunSeries` is documented as 'The regularized Gaussian hypergeometric function' (copied from the function below; it is the series); the module docstring's display sums over j but writes zⁿ, and has 'are divides by' and 'only appears in the literature only'.","fix":"'…hypergeometric series'; fix the display index and typos.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261007-1c8c8b","file":"Mathlib/Analysis/SpecialFunctions/Trigonometric/Sinc.lean","decl":"(file)","line":1,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring","claim":"No docstrings on `sinc_apply`, `sinc_zero`, `sinc_of_ne_zero`, `sinc_eq_dslope`, `sinc_neg`, `abs_sinc_le_one`, `sinc_le_one`, `neg_one_le_sinc`, `sin_div_le_inv_abs`, `sinc_le_inv_abs`.","fix":"Add one-line docstrings.","ev":"Measured: source.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-933ac8","file":"Mathlib/Analysis/SpecialFunctions/Trigonometric/Sinc.lean","decl":"sin_div_le_inv_abs","line":71,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"long-case-split","claim":"`sin_div_le_inv_abs` is a 9-line case split on the sign of `x` with `ring_nf` and manual inverse cancellations; it follows from `abs_sin_le_one` via `div_le_div_of_nonneg_left`-style API on `|sin x / x| ≤ 1 / |x|` (and holds at `x = 0` only through the junk value `0 / 0 = 0 ≤ 0⁻¹ = 0`, which the statement does not flag).","fix":"Prove via `le_abs_self` and `abs_div` with `abs_sin_le_one`.","ev":"Measured: source L71-80.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-2751be","file":"Mathlib/CategoryTheory/Monoidal/Mon.lean","decl":"CategoryTheory.Mon.tensor_one","line":706,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CategoryTheory.Mon.tensorObj_one` (CategoryTheory.Monoidal.Mon), `CategoryTheory.Mon.tensor_one` (CategoryTheory.Monoidal.Mon) state exactly the same thing (Lean-checked). Reviewer: Both @[to_additive (attr := simp)] rfl lemmas `η[(X ⊗ Y).X] = (λ_ (𝟙_ C)).inv ≫ (η[X.X] ⊗ₘ η[Y.X])` in the same section, 30 lines apart, no comment. Keep tensorObj_one (tensorUnit_one/tensorObj_X family) and deprecate tensor_one.","fix":"Deprecate `CategoryTheory.Mon.tensor_one` in favour of `CategoryTheory.Mon.tensorObj_one`.","ev":"dupscan/Check.lean: `example := (@CategoryTheory.Mon.tensor_one : type_of% @CategoryTheory.Mon.tensorObj_one)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 26, rating MAJOR): There is no differing simp orientation or registration to preserve. Deprecate the redundant multiplicative/additive pair together. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/Monoidal/Mon.lean#L705).","pr":null,"res":"Re-graded MAJOR→NIT on 2026-10-07 after the user asked whether these are useful API: to_additive/to_dual image of the same source duplicate as RT-20261007-452f0d; counted once there.","at":"2026-10-07","commit":""},{"id":"RT-20261007-29b7e7","file":"Mathlib/CategoryTheory/Monoidal/Mon.lean","decl":"CategoryTheory.AddMon.tensor_add","line":709,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `CategoryTheory.AddMon.tensor_add` (CategoryTheory.Monoidal.Mon), `CategoryTheory.AddMon.tensorObj_add` (CategoryTheory.Monoidal.Mon) state exactly the same thing (Lean-checked). Reviewer: Additive images of `Mon.tensor_mul` (709) and `Mon.tensorObj_mul` (678): same file, both @[to_additive (attr := simp)] rfl, identical statements, no comment. The `tensor_one`/`tensorObj_one` pair at 706/675 duplicates the same way. Keep the `tensorObj_*` names (match `tensorUnit_*`), deprecate `tensor_mul`/`tensor_add`/`tensor_one`/`tensor_zero`.","fix":"Deprecate `CategoryTheory.AddMon.tensor_add` in favour of `CategoryTheory.AddMon.tensorObj_add`.","ev":"dupscan/Check.lean: `example := (@CategoryTheory.AddMon.tensorObj_add : type_of% @CategoryTheory.AddMon.tensor_add)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 27, rating MAJOR): The additive duplicate follows mechanically from the redundant `tensor_mul` source. Keeping one multiplicative/additive naming pair retains the automation. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/CategoryTheory/Monoidal/Mon.lean#L708).","pr":null,"res":"Re-graded MAJOR→NIT on 2026-10-07 after the user asked whether these are useful API: to_additive/to_dual image of the same source duplicate as RT-20261007-dbc1cf; counted once there.","at":"2026-10-07","commit":""},{"id":"RT-20261006-9ed049","file":"Mathlib/CategoryTheory/Monoidal/Widesubcategory.lean","decl":"CategoryTheory.MorphismProperty.IsStableUnderAssociator","line":38,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"The new stability classes have no closure instances (e.g. `(⊤ : MorphismProperty C).IsStableUnderAssociator` fails), unlike the multiplicativity API, and there is no `tensorδ_hom` companion to `tensorμ_hom`. The standalone associator/unitor classes also only need `MonoidalCategoryStruct`.","fix":"Add `⊤`/`⊓` instances and `tensorδ_hom`; state the elementary classes under `MonoidalCategoryStruct`.","ev":"-- hunts/monoidal-widesub/P2.lean: `example : (⊤ : MorphismProperty C).IsStableUnderAssociator := by infer_instance` fails; `#check @WideSubcategory.tensorδ_hom` is an unknown constant.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-deb21f","file":"Mathlib/CategoryTheory/Monoidal/Widesubcategory.lean","decl":"CategoryTheory.MorphismProperty.IsStableUnderBraiding","line":59,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-omission","claim":"`IsStableUnderBraiding` bundles all of `IsMonoidalStable` (identities, composition, tensoring, associators, unitors), unlike its siblings `IsStableUnderAssociator`/`IsStableUnderUnitor`, which are bare membership predicates. Also, the `IsMonoidalStable` docstring ('stable under tensoring, associators, and unitors') omits that it requires multiplicativity (identities and composition) via `IsMonoidal`.","fix":"Say 'a multiplicative property closed under tensoring and containing the coherence isomorphisms'; consider naming the bundle `IsBraidedStable`.","ev":"src L54-62: `class IsMonoidalStable : Prop extends IsMonoidal P, ...`; `class IsStableUnderBraiding ... extends IsMonoidalStable P`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-5b7530","file":"Mathlib/CategoryTheory/ObjectProperty/Comma.lean","decl":"CategoryTheory.ObjectProperty.comma","line":26,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-typo","claim":"The `comma` docstring is ungrammatical ('this is the property of objects in `Comma F₁ F₂` satisfying by the objects corresponding to…'), and the module docstring is only a title.","fix":"'…the property of comma objects whose left and right components satisfy `P₁` and `P₂`'; add a module description.","ev":"-- ObjectProperty/Comma.lean:26-29, :10-13","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-3f3f97","file":"Mathlib/CategoryTheory/Shift/Pullback.lean","decl":"CategoryTheory.NatTrans.PullbackShift.natIsoId","line":232,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"declaration-in-wrong-namespace","claim":"`PullbackShift.natIsoId` and `PullbackShift.natIsoComp` are declared inside `namespace NatTrans`, so their full names are `NatTrans.PullbackShift.natIsoId`/`natIsoComp`, unlike their siblings `PullbackShift.functor`, `PullbackShift.natTrans`, `PullbackShift.adjunction`; `PullbackShift.adjunction` has to spell them `NatTrans.PullbackShift.…`. The instance on `natIsoComp` (L257) also has a plain `/- … -/` comment where its sibling (L236) has a docstring.","fix":"Move both definitions out of `namespace NatTrans` (deprecated aliases for the old names); make the L257 comment a docstring.","ev":"Source L211–277, L287–290.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-c6e7a8","file":"Mathlib/CategoryTheory/Shift/Pullback.lean","decl":"CategoryTheory.Adjunction.commShiftPullback","line":307,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"reproves-derivable-field","claim":"`Adjunction.commShiftPullback` proves both `commShift_unit` and `commShift_counit`, but `Adjunction.CommShift.mk'` builds the structure from the unit half alone.","fix":"`by apply Adjunction.CommShift.mk'; dsimp [PullbackShift.adjunction]; infer_instance`.","ev":"probe2.lean final `example` (via `Adjunction.CommShift.mk'`) compiles.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-fa5dc6","file":"Mathlib/CategoryTheory/Sites/Hypercover/ZeroFamily.lean","decl":"(file)","line":21,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-universe","claim":"`universe w' w v u` declares `w'` and `w`, which nothing in the file uses (every universe annotation is `max u v`).","fix":"Use `universe v u`.","ev":"hunts/hypercover-zerofam/nouniv.lean (src with `universe v u`) compiles with the lakefile options, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-18f2c1","file":"Mathlib/CategoryTheory/Sites/Hypercover/ZeroFamily.lean","decl":"CategoryTheory.PreZeroHypercoverFamily","line":29,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-omission","claim":"The docstrings say 'invariant under deduplication' without saying that this means invariance under re-presenting the same presieve (`shrink`), not under isomorphism of the components. Two isomorphic singleton covers `{1}`, `{g}` in a one-object group category can be distinguished by a valid family. The base-change constructor, whose extra `IsClosedUnderIsomorphisms` hypothesis exists for exactly this reason, has no docstring.","fix":"Explain 'deduplication' as `iff_shrink` and document why the base-change constructor needs `h₁`.","ev":"src L13-16, L29-34; L99 lemma has no docstring.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ec9026","file":"Mathlib/CategoryTheory/Sites/Hypercover/ZeroFamily.lean","decl":"CategoryTheory.PreZeroHypercoverFamily.mem_precoverage_iff","line":55,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"Membership in `P.precoverage` has only the existential form `∃ E, P E ∧ R = E.presieve₀`. The canonical form `R ∈ P.precoverage X ↔ P R.preZeroHypercover` (via the imported `Presieve.preZeroHypercover`) is missing, and so are simp lemmas for the equivalence round-trips and for `P E.shrink ↔ P E`.","fix":"Add `mem_precoverage_iff_preZeroHypercover` and `@[simp]` round-trip and shrink lemmas.","ev":"-- hunts/hypercover-zerofam/P2.lean: `example (R : Presieve X) : R ∈ P.precoverage X ↔ P R.preZeroHypercover := by simpa only [Presieve.presieve₀_preZeroHypercover] using presieve₀_mem_precoverage_iff (E := R.preZeroHypercover)` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-9846f5","file":"Mathlib/Combinatorics/Enumerative/Pentagonal/Basic.lean","decl":"pentagonal","line":31,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-omission","claim":"The docstring of `pentagonal` and the 'Main definitions' entry say 'pentagonal numbers', but this is the generalized sequence (e.g. `pentagonal (-1) = 2`, which is not an ordinary pentagonal number). The module intro explains it, but the declaration docstring does not.","fix":"Say 'generalized pentagonal numbers'.","ev":"src L22, L31; pentagonal (-1) = (-1)(-4)/2 = 2.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b48872","file":"Mathlib/Combinatorics/Enumerative/Pentagonal/Basic.lean","decl":"pentagonal","line":32,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`pentagonal` has no simp lemmas for small values: `simp` makes no progress on `pentagonal 0 = 0` or `pentagonal 1 = 1`. There are no `pentagonal_zero`/`pentagonal_one`/`pentagonal_neg_one` lemmas.","fix":"Add `@[simp] pentagonal_zero`, `pentagonal_one`, `pentagonal_neg_one`.","ev":"-- hunts/pentagonal/P.lean: `example : pentagonal 0 = 0 := by simp` and `example : pentagonal 1 = 1 := by simp` both fail (`simp` made no progress).","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-84894e","file":"Mathlib/Combinatorics/Hypergraph/Basic.lean","decl":"Hypergraph","line":72,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-drops-hypothesis","claim":"The docs never say that the empty set is allowed as an edge (many references require nonempty hyperedges), although it shapes the API: `IsComplete` puts ∅ in the edge set, so `completeOn ∅` has the edge ∅ and no vertices yet is `IsNonempty`; likewise `Adj x x` holds for every non-isolated x (unlike `SimpleGraph.Adj`). Also 'If a edge'. Also: `trivialOn` is documented as 'the trivial hypergraph' but `trivialOn ∅ = ⊥` is not trivial; the module doc says 'edges are defined as Set (Set α)' (that is the edge family) and 'without repeated edge'.","fix":"State that ∅ may be an edge and that `Adj` is reflexive on non-isolated vertices; 'an edge'.","ev":"example : (completeOn (∅ : Set ℕ)).IsNonempty ∧ V(completeOn (∅ : Set ℕ)) = ∅ ∧ (∅ : Set ℕ) ∈ E(completeOn (∅ : Set ℕ)) :=\n  ⟨(IsComplete.completeOn _).isNonempty, rfl, by simp⟩","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-f4fe50","file":"Mathlib/Combinatorics/Hypergraph/Basic.lean","decl":"Hypergraph.Adj.symm","line":126,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"API gaps: `Adj.symm`/`EAdj.symm` are neither `@[symm]` nor `Std.Symm` instances (unlike `Graph.Adj`); no `Adj.left_mem`/`right_mem`; no `image_id`, `trivialOn_empty` (= ⊥), simp form `(trivialOn s).IsTrivial ↔ s.Nonempty`; `IsLinear` alone lacks `@[expose]` among the file's predicates.","fix":"Add the attributes/instances and the listed lemmas; expose `IsLinear` or say why not.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-0472df","file":"Mathlib/Combinatorics/Hypergraph/Basic.lean","decl":"Hypergraph.sUnion_edgeSet_eq_vertexSet_iff_all_vertex_not_isolated","line":176,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-too-long","claim":"Unidiomatic names: `sUnion_edgeSet_eq_vertexSet_iff_all_vertex_not_isolated` (57 characters, restates the RHS); `isLoop_iff_mem_edgeSet_and_singleton` is the definitional unfolding (`isLoop_iff`/`isLoop_def`); `edgeSet.ext_iff` lives in the namespace of the structure projection `edgeSet` next to the generated `Hypergraph.ext_iff`.","fix":"`sUnion_edgeSet_eq_vertexSet_iff`, `isLoop_iff`, `eq_iff_of_mem_edgeSet`.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-ee8469","file":"Mathlib/Combinatorics/Hypergraph/Basic.lean","decl":"Hypergraph.eq_bot_or_isNonempty","line":222,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"style-indentation","claim":"`eq_bot_or_isNonempty` wraps its `cases` branches in parenthesised tactic blocks `=> ( … )`, not Mathlib style; there is a double blank line after the notation block. Several proofs take detours: `eq_bot_or_isNonempty` is `eq_or_ne` + `ne_bot_iff`; `IsTrivial.trivialOn` is `⟨hf, rfl⟩`; `IsTrivial.isNonempty` is `.inl h.1`; `IsComplete.mem_iff` is `⟨subset_vertexSet_of_mem_edgeSet, h e⟩`.","fix":"Plain indented branches (or `rcases … with h | h`).","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261007-a931ca","file":"Mathlib/Combinatorics/SimpleGraph/Dart.lean","decl":"(file)","line":1,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring","claim":"Public lemmas without docstrings: `Dart.ext_iff`, `fst_ne_snd`, `snd_ne_fst`, `toProd_injective`, the `Dart.fintype` instance, `edge_mk`, `edge_mem`, `symm_mk`, `edge_symm`, `edge_comp_symm`, `symm_symm`, `symm_involutive`, `symm_ne`, the `dart_edge_eq_*` lemmas, `dartOfNeighborSet_injective`, `nonempty_dart_top`.","fix":"Add one-line docstrings.","ev":"Measured: source.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-ce43f2","file":"Mathlib/Combinatorics/SimpleGraph/Dart.lean","decl":"Dart.ext_iff","line":34,"sev":"NIT","status":"confirmed","cat":"api","pattern":"hand-written-ext-iff","claim":"`Dart.ext_iff` is hand-written with explicit arguments `(d₁ d₂ : G.Dart)` before `@[ext] Dart.ext`, against the convention (implicit `{d₁ d₂}`, generated by `@[ext]`); every use passes it to `simp`/`rw` unapplied, so the explicit binders buy nothing.","fix":"Let `@[ext]` generate `ext_iff` (or make its arguments implicit).","ev":"hunts/sg-dart/probe1.lean: `#check @SimpleGraph.Dart.ext_iff` shows explicit `(d₁ d₂ : G.Dart)`; uses at Walk/Traversal.lean:224,228 are unapplied.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-3fb617","file":"Mathlib/Combinatorics/SimpleGraph/Dart.lean","decl":"dart_edge_eq_mk'_iff","line":103,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"wrong-namespace-for-dot-notation","claim":"`dart_edge_eq_iff`, `dart_edge_eq_mk'_iff`, `dart_edge_eq_mk'_iff'` live in `SimpleGraph` rather than `SimpleGraph.Dart` (so no dot notation `d.edge_eq_iff`), refer to the retired `Sym2.mk'` spelling (the statements use `s(u, v)`), and the primed/double-primed pair differ only in conclusion shape.","fix":"Rename to `Dart.edge_eq_iff`, `Dart.edge_eq_mk_iff`, `Dart.edge_eq_mk_iff'` with deprecated aliases.","ev":"Measured: source L94-108; uses at Walk/Operations.lean:496, Acyclic.lean:330.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-da9672","file":"Mathlib/Combinatorics/SimpleGraph/Dart.lean","decl":"dartOfNeighborSet","line":126,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-overstates","claim":"`dartOfNeighborSet`'s docstring calls it 'the bijective map from the neighbor set at `v` to the darts `d` with `d.fst = v`', but its codomain is all of `G.Dart`, where it is only injective (not surjective, e.g. on `⊤ : SimpleGraph (Fin 3)` at `v = 0` it misses the dart `(1, 0)`); the bijection onto `{d // d.fst = v}` is not provided.","fix":"Say 'injective map … whose range is the darts starting at `v`', or add the corestricted equivalence.","ev":"hunts/sg-dart/probe1.lean: `¬ Function.Surjective ((⊤ : SimpleGraph (Fin 3)).dartOfNeighborSet 0)` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-b3835c","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsMatching.toEdge.surjective","line":78,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"function-namespace-surjective-name","claim":"The name `IsMatching.toEdge.surjective` puts the lemma in the namespace of the function `toEdge`, so it cannot be used with dot notation: `h.toEdge.surjective` fails ('The environment does not contain `Function.surjective`'), and `h.toEdge_surjective` does not exist. Mathlib's convention is `foo_surjective`: about 820 declarations use `_surjective`, against 3 others with the `.f.surjective` shape (`AffineMap.restrict.surjective`, `Minpoly.toAdjoin.surjective`, …).","fix":"Rename to `IsMatching.toEdge_surjective`, keeping a `@[deprecated]` alias.","ev":"batch0/probe1.lean (output batch0/probe1.out) P3: `example (h : M.IsMatching) : Surjective h.toEdge := h.toEdge.surjective` -> error 'Invalid field `surjective`: The environment does not contain `Function.surjective`'; `:= h.toEdge_surjective` -> 'Invalid field `toEdge_surjective`'; `:= IsMatching.toEdge.surjective h` compiles. Counts from `git grep` on origin/master.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-9c434e","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsMatching.mem_coe_toEdge","line":87,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-rebound-section-variable","claim":"`mem_coe_toEdge` re-binds `{v : V}`, although the section already declares `variable … {u v w : V}` (L59). It is the only lemma in the batch to re-declare a section variable.","fix":"Delete the `{v : V}` binder.","ev":"src.lean L59 `variable {V W : Type*} {G G' : SimpleGraph V} {M M' : Subgraph G} {u v w : V}`; L87 `theorem IsMatching.mem_coe_toEdge (h : M.IsMatching) {v : V} (hv : v ∈ M.verts) :`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-c3b277","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsMatching.iSup","line":140,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"sort-underscore-binder","claim":"Binder style: `{ι : Sort _}` is the only `Sort _` in Combinatorics/SimpleGraph (Mathlib-wide 79 `Sort _` vs 1341 `Sort*`), and the hypothesis is written as a Pi-arrow `(hM : (i : ι) → (f i).IsMatching)` instead of `(hM : ∀ i, (f i).IsMatching)`.","fix":"Write `{ι : Sort*}` and `(hM : ∀ i, (f i).IsMatching)`.","ev":"`git grep -c 'Sort _' origin/master -- Mathlib` sums to 79, `Sort\\*` to 1341; `git grep -n 'Sort _' origin/master -- Mathlib/Combinatorics/SimpleGraph` hits only Matching.lean:140 (and a comment at :312)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-7f2d7e","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsMatching.map","line":202,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"rebinds-section-variable","claim":"Three lemmas re-bind `M`, which the section already declares (`variable … {M M' : Subgraph G}` at L59): `IsMatching.map {G' : SimpleGraph W} {M : Subgraph G}` (L202), `Iso.isMatching_map {G' : SimpleGraph W} {M : Subgraph G}` (L213) and `IsMatching.verts_eq_biUnion_edgeSet {M : G.Subgraph}` (L218, also switching to `G.Subgraph` spelling). The `{G' : SimpleGraph W}` re-binding is needed; the `M` ones are leftovers.","fix":"Drop the redundant `{M : Subgraph G}` / `{M : G.Subgraph}` binders.","ev":"src.lean L59 `variable {V W : Type*} {G G' : SimpleGraph V} {M M' : Subgraph G} {u v w : V}` vs L202, L213, L218","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-a668ae","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.Iso.isMatching_map","line":213,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"phantom-namespace-breaks-dot-notation","claim":"Declared as `Iso.isMatching_map` inside `namespace Subgraph`, so its full name is `SimpleGraph.Subgraph.Iso.isMatching_map`, in a namespace with no type (`SimpleGraph.Subgraph.Iso` does not exist). Dot notation on `f : G ≃g G'` therefore cannot find it (`f.isMatching_map` errors: 'The environment does not contain `RelIso.isMatching_map`'), and `SimpleGraph.Iso.isMatching_map` is unknown. The sibling lemma for induced subgraphs is `Subgraph.isInduced_map_iso` (Subgraph.lean), so the names are also inconsistent.","fix":"Rename to `SimpleGraph.Subgraph.isMatching_map_iso` (matching `isInduced_map_iso`), with a deprecated alias.","ev":"batch1/probe1.lean P1: `#check @SimpleGraph.Subgraph.Iso.isMatching_map` succeeds; P9: `#check @SimpleGraph.Iso.isMatching_map` -> 'Unknown constant'; `example (f : G ≃g G') : (M.map f.toHom).IsMatching ↔ M.IsMatching := f.isMatching_map` -> 'Invalid field `isMatching_map`: The environment does not contain `RelIso.isMatching_map`' (batch1/probe1.out)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-273300","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsPerfectMatching","line":236,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-typo","claim":"The docstring reads 'every vertex `G` is matched' (missing 'of'); otherwise it matches the definition `M.IsMatching ∧ M.IsSpanning`.","fix":"Change 'every vertex `G` is matched' to 'every vertex of `G` is matched'.","ev":"src.lean L233-234: 'The subgraph `M` of `G` is a perfect matching on `G` if it's a matching and every vertex `G` is\\nmatched.'","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-3352ce","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.ConnectedComponent.odd_matches_node_outside","line":320,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"nonstandard-name-no-dot-notation","claim":"The name uses non-Mathlib vocabulary ('node', 'matches', 'outside') instead of describing the conclusion, the lemma has no docstring, and the `ConnectedComponent` namespace buys nothing: `c` is an element of the set `oddComponents` (a `Subtype`) and the hypothesis is `M.IsPerfectMatching`, so neither `c.odd_matches_node_outside` nor `hM.odd_matches_node_outside` resolves.","fix":"Rename to e.g. `Subgraph.IsPerfectMatching.exists_adj_mem_of_mem_oddComponents` (deprecated alias for the old name) and add a docstring.","ev":"hunts/sg-matching/batch3/probe2.lean: both `c.odd_matches_node_outside hM` and `hM.odd_matches_node_outside c` fail with `Invalid field odd_matches_node_outside` (`Subtype.odd_matches_node_outside` / `And.odd_matches_node_outside` not found).","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-484792","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.IsMatchingFree","line":349,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-omits-qualifier","claim":"`IsMatchingFree` means 'has no perfect matching' (`K₃` satisfies it but has a one-edge matching); its docstring's justification ('every graph has a matching') is imprecise.","fix":"Rename to `IsPerfectMatchingFree` (with a deprecated alias) and fix the docstring.","ev":"hunts/sg-matching/verify6/p2_isMatchingFree_name.lean: compiles `(⊤ : SimpleGraph (Fin 3)).IsMatchingFree` (via `IsPerfectMatching.even_card`) together with a one-edge matching `subgraphOfAdj` in it, plus `(⊥ : G.Subgraph).IsMatching` for every G and that every matching of `⊥ : SimpleGraph (Fin 2)` has empty edge set; so the name means 'perfect-matching-free' and the docstring's 'any non-trivial graph has [matchings]' is loose (true only if 'non-trivial' means 'has an edge'). NIT.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-1c4b3b","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.exists_maximal_isMatchingFree","line":361,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"maximal-hand-unfolded","claim":"The lemma is `Finite.exists_le_maximal h` with `Maximal IsMatchingFree Gmax` hand-unfolded (and `¬ IsMatchingFree` unfolded to `∃ M, M.IsPerfectMatching`); stated with `Maximal` it is that term exactly. The unfolded form also writes `∀ G', G' > Gmax → ...` where Mathlib style prefers `Gmax < G'`.","fix":"State the conclusion as `∃ Gmax, G ≤ Gmax ∧ Maximal IsMatchingFree Gmax` (proof `Finite.exists_le_maximal h`), or at least use `Gmax < G'`.","ev":"hunts/sg-matching/batch3/probe1.lean section (E) (compiled with `lake env lean -DmaxSynthPendingDepth=3 -DautoImplicit=false -Dpp.unicode.fun=true -Dlinter.mathlibStandardSet=true -Dlinter.style.longFile=1500`, exit 0):\n/-! (E) `exists_maximal_isMatchingFree` is `Finite.exists_le_maximal` with `Maximal` unfolded. -/\n\nexample [Finite V] (h : G.IsMatchingFree) : ∃ Gmax, G ≤ Gmax ∧ Maximal IsMatchingFree Gmax :=\n  Finite.exists_le_maximal h","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-3fe73a","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.IsCycles.other_adj_of_adj","line":381,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"existential-name-missing-exists","claim":"The conclusion is the existential `∃ w', w ≠ w' ∧ G.Adj v w'`, but the name (`other_adj_of_adj`) does not describe it with `exists_`; its sibling at L388 for the `∃!` version is correctly named `existsUnique_ne_adj`.","fix":"Rename to `IsCycles.exists_ne_adj` (with a deprecated alias).","ev":"measured: L381 `lemma IsCycles.other_adj_of_adj (h : G.IsCycles) (hadj : G.Adj v w) : ∃ w', w ≠ w' ∧ G.Adj v w'` vs L388 `lemma IsCycles.existsUnique_ne_adj ... : ∃! w', w ≠ w' ∧ G.Adj v w'`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-f1c875","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.IsCycles.toSimpleGraph","line":398,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"theorem-named-like-def","claim":"A theorem named like a conversion function (`toSimpleGraph`, the name of the def `ConnectedComponent.toSimpleGraph`); its conclusion is `c.toSimpleGraph.spanningCoe.IsCycles`, so the snake_case name describing it would be `isCycles_spanningCoe_toSimpleGraph` (e.g. `IsCycles.isCycles_spanningCoe_toSimpleGraph` or `ConnectedComponent.isCycles_spanningCoe_toSimpleGraph`); it also omits `spanningCoe`. The component `c` comes before the hypothesis `h`.","fix":"Rename to `IsCycles.spanningCoe_toSimpleGraph` / `ConnectedComponent.isCycles_spanningCoe_toSimpleGraph` with a deprecated alias.","ev":"measured: L398 `lemma IsCycles.toSimpleGraph (c : G.ConnectedComponent) (h : G.IsCycles) : c.toSimpleGraph.spanningCoe.IsCycles`; only caller Tutte.lean:203 `hcycles.toSimpleGraph (cycles.connectedComponentMk c)`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-bd6eac","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Walk.IsCycle.adj_toSubgraph_iff_of_isCycles","line":427,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"equiv-via-cardinal-for-set-equality","claim":"The proof builds an Equiv between the two neighbour sets from equal ncards via `Cardinal.eq`/`Set.cast_ncard`/`Nonempty.some`, only to feed `Subgraph.adj_iff_of_neighborSet_equiv`, which immediately turns it back into a card comparison. `Set.eq_of_subset_of_ncard_le` gives the neighbour-set equality directly (3 lines, no Cardinal). The same detour recurs at L461-466 and L544-546 (snd_of_mem_support_of_isPath_of_adj, exists_cycle_toSubgraph_verts_eq_connectedComponentSupp).","fix":"Replace the Cardinal detour by `Set.eq_of_subset_of_ncard_le (p.toSubgraph.neighborSet_subset v) _ _` (or add a `Subgraph.neighborSet_eq_of_ncard_eq` helper and use it at all three sites).","ev":"hunts/sg-matching/batch4/copy.lean L424-431 (shown in the generality finding) compiles in place of the original 8-line proof","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-4eff23","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.IsCycles.snd_of_mem_support_of_isPath_of_adj","line":461,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"equiv-via-cardinal-for-set-equality","claim":"Same Cardinal.eq / Classical.ofNonempty detour as in adj_toSubgraph_iff_of_isCycles to build an Equiv `e` that only serves `adj_iff_of_neighborSet_equiv`; `Set.eq_of_subset_of_ncard_le` does it directly.","fix":"Use `Set.eq_of_subset_of_ncard_le (p.toSubgraph.neighborSet_subset _)` instead of constructing `e`.","ev":"hunts/sg-matching/batch4/copy.lean L449-461 (shown in the generality finding) compiles in place of the original proof","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-c941d1","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.IsCycles.reachable_sdiff_toSubgraph_spanningCoe_aux","line":469,"sev":"NIT","status":"confirmed","cat":"api","pattern":"private-aux-identical-to-public-wrapper","claim":"The private `_aux` has exactly the same binders, hypotheses ([Finite V]) and conclusion as the public `IsCycles.reachable_sdiff_toSubgraph_spanningCoe` (L511), which merely forwards to it after an unused `have : Fintype V := Fintype.ofFinite V`. The split is a leftover; the recursion can live in the public lemma.","fix":"Prove `IsCycles.reachable_sdiff_toSubgraph_spanningCoe` directly by the well-founded recursion and delete the `_aux`.","ev":"hunts/sg-matching/batch4/copy.lean L503-506: wrapper replaced by the term `reachable_sdiff_toSubgraph_spanningCoe_aux hcyc p hp` without the `have : Fintype V`; copy compiles (exit 0)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-192964","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.IsCycles.reachable_sdiff_toSubgraph_spanningCoe_aux","line":477,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-obtain-binding","claim":"`obtain ⟨w', ⟨hw'1, hw'2⟩, hwu⟩ := hcyc.existsUnique_ne_adj ...` binds the uniqueness part `hwu`, which is never used; `other_adj_of_adj` (existence only) suffices. After this, `existsUnique_ne_adj` has no consumer in Mathlib.","fix":"Use `obtain ⟨w', hw'1, hw'2⟩ := hcyc.other_adj_of_adj (p.toSubgraph_adj_snd hpn).adj_sub`.","ev":"hunts/sg-matching/batch4/copy.lean L471: `obtain ⟨w', hw'1, hw'2⟩ := hcyc.other_adj_of_adj (p.toSubgraph_adj_snd hpn).adj_sub`; copy compiles (exit 0)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-c35b97","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.IsCycles.reachable_sdiff_toSubgraph_spanningCoe_aux","line":479,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"stale-proof-comment","claim":"Inline comment says \"The edge (v, w) can't be in p, because then it would be the second node\", but the following `have hnpvw' : ¬ p.toSubgraph.Adj v w'` is about the edge (v, w'), not (v, w).","fix":"Change the comment to \"The edge (v, w') can't be in p, because then w' would be the second vertex\".","ev":"measured: src.lean L479-480 `-- The edge (v, w) can't be in p, because then it would be the second node` / `have hnpvw' : ¬ p.toSubgraph.Adj v w' := by`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-f2158d","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.IsCycles.reachable_deleteEdges","line":516,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"defeq-show-rfl-golfable","claim":"The 7-line proof rebuilds `fromEdgeSet {s(v, w)} = hadj.toWalk.toSubgraph.spanningCoe` by hand and unfolds `deleteEdges` with `rw [show G.deleteEdges {s(v, w)} = G \\ fromEdgeSet {s(v, w)} by rfl]`. Existing simp API (`Adj.toSubgraph_toWalk`, `Subgraph.spanningCoe_subgraphOfAdj`) gives a 2-line proof without the defeq `show`.","fix":"Prove it as `simpa [deleteEdges, hadj.toSubgraph_toWalk] using (hcyc.reachable_sdiff_toSubgraph_spanningCoe hadj.toWalk (.of_adj hadj)).symm`.","ev":"example [Finite V] (hadj : G.Adj v w) (hcyc : G.IsCycles) :\n    (G.deleteEdges {s(v, w)}).Reachable v w := by\n  simpa [deleteEdges, hadj.toSubgraph_toWalk] using\n    (hcyc.reachable_sdiff_toSubgraph_spanningCoe hadj.toWalk (.of_adj hadj)).symm\n-- hunts/sg-matching/batch5/evidence.lean E3","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-0df859","file":"Mathlib/Combinatorics/SimpleGraph/Matching.lean","decl":"SimpleGraph.Subgraph.IsPerfectMatching.symmDiff_of_isAlternating","line":599,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-detour","claim":"Proof hygiene: in `symmDiff_of_isAlternating` the second `other_adj_of_adj` call (producing `w''`) is unnecessary; `IsMatchingFree.mono` uses `by_contra` on a `¬ P` goal; the `other_adj_of_adj` docstring says 'a vertex with one edge' (it means one chosen incident edge); the `IsCycles` docstring says 'connected to' for 'adjacent to', and 'cycles of length 0' conflicts with `Walk.not_isCycle_nil`.","fix":"Apply the direct contradiction, `intro x hc`, and reword the docstrings.","ev":"hunts/sg-matching/verify6/p6_hygiene_docs.lean: (a) symmDiff_of_isAlternating compiles with the `w''` branch replaced by `by_contra hne; exact hr.2 ((hG' hne hr.1 hw'.2).mpr (hmadj.mp hw.1))`, and also by just deleting the `obtain ⟨w'', hw''⟩` line; (b) IsMatchingFree.mono compiles with `intro x hc` and no `by_contra`; docstring facts checked: (c) under IsCycles an edge at v forces ncard (neighborSet v) = 2, (d) cycleGraph 4 is IsCycles and connected (every vertex reachable from 4, adjacent to 2), (e) `⊥` is IsCycles while `Walk.not_isCycle_nil` says nil isn't a cycle. NIT.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-693d94","file":"Mathlib/Combinatorics/SimpleGraph/VertexCover.lean","decl":"(file)","line":23,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"minimal-vs-minimum","claim":"The module docstring calls `vertexCoverNum` \"e.g. the size of a minimal vertex cover\": a *minimal* (inclusion-minimal) vertex cover can be strictly larger than the vertex cover number, which is the size of a *minimum* cover; \"e.g.\" should be \"i.e.\".","fix":"\"i.e. the size of a minimum vertex cover\".","ev":"Source L23 vs. the definition L91–93 (an infimum of `encard` over all vertex covers).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-232531","file":"Mathlib/Combinatorics/SimpleGraph/VertexCover.lean","decl":"SimpleGraph.exists_of_le_vertexCoverNum","line":109,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-reverses-hypothesis","claim":"`exists_of_le_vertexCoverNum` assumes `vertexCoverNum G ≤ n` (and `n ≤ ENat.card V`), the opposite of what `_of_le_vertexCoverNum` suggests; `vertexCoverNum_exists` does not follow the `exists_…` naming convention (e.g. `exists_isVertexCover_encard_eq_vertexCoverNum`).","fix":"Rename to `exists_isVertexCover_encard_eq_of_vertexCoverNum_le` / `exists_isVertexCover_encard_eq_vertexCoverNum`, with deprecated aliases.","ev":"Source L103–110.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-c7b7d4","file":"Mathlib/Data/Finsupp/MonomialOrder.lean","decl":"(file)","line":11,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring","claim":"Missing docstrings on public `le_add_right`, `bot_eq_zero`, `zero_le`, `eq_zero_iff`, `toSyn_eq_zero_iff`, `toSyn_lt_iff_ne_zero`, `toSyn_strictMono`, the `toWithBotSyn_*` lemmas, `lex_le_iff`/`lex_lt_iff`(`_of_unique`), the `AddCancelCommMonoid`/`OrderBot` instances; the module docstring says '`MonomialOrder.wellFoundedLT_syn` asserts that `MonomialOrder.syn` is well founded' (it asserts `WellFoundedLT`, i.e. the order is a well-order since it is linear) and does not mention `toWithBotSyn` or the `≺'[m]`/`≼'[m]` notations.","fix":"Add docstrings; list `toWithBotSyn` and the primed notations.","ev":"Measured: source.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-6cd9cb","file":"Mathlib/Data/Finsupp/MonomialOrder.lean","decl":"zero_le","line":115,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"unprotected-root-name","claim":"`MonomialOrder.zero_le`, `MonomialOrder.le_add_right` and `MonomialOrder.eq_zero_iff` are not `protected` although they reuse root names with different statements (`le_add_right` in root is `a ≤ b → a ≤ b + c`), so `open MonomialOrder` (done in `Combinatorics/Nullstellensatz.lean:139`) shadows them; `eq_zero_iff : a = 0 ↔ a ≤ 0` also runs against the root convention `nonpos_iff_eq_zero`/`le_bot_iff`.","fix":"Mark them `protected`; consider `nonpos_iff_eq_zero` orientation.","ev":"Measured: source L100, L115, L117; `open MonomialOrder` at Combinatorics/Nullstellensatz.lean:139.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-59856f","file":"Mathlib/Data/Finsupp/MonomialOrder.lean","decl":"(file)","line":168,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"tests-in-library-file","claim":"Three `example`s with docstrings (`/-- for the lexicographic ordering, X 0 * X 1 < X 0 ^ 2 -/ example …`, L189-199) live in the library file; docstrings on `example` are not rendered, and these are tests that belong in `MathlibTest/`.","fix":"Move them to `MathlibTest/`.","ev":"Measured: source L189-199.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-8c26b3","file":"Mathlib/Data/Finsupp/MonomialOrder.lean","decl":"(file)","line":190,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"weak-regression-examples","claim":"The three `example`s use `ℕ` indices, where the lexicographic order on `ℕ →₀ ℕ` is not a monomial order (X₀ > X₁ > X₂ > … descends forever), and none mentions `MonomialOrder.lex`, so they would survive its deletion or replacement by graded lex; `toWithBotSyn_symm_apply_eq_bot` is an iff without `_iff`; small proofs (`orderBot.bot_le`, `toSyn_strictMono`, `toWithBotSyn_*_eq_bot`) can use `simpa`/the term/`WithBot.map_eq_bot_iff` directly (Astra A1 items 3, 4, 8, 9). Astra's item 7 (`toWithBotSyn` need not be `noncomputable`) is false: it depends on `Finsupp.instAdd` (probe2 (4) fails to compile).","fix":"Use `Fin 2` indices and `≺[MonomialOrder.lex]` in the examples; add `_iff`; shorten the proofs.","ev":"Measured: source L190-199, L156; hunts/monomial-order/probe2.lean (4) shows `noncomputable` is required.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261006-959a93","file":"Mathlib/Data/Fintype/OfMap.lean","decl":"(file)","line":18,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"ambiguous-direction-doc","claim":"The module docstring's \"a type is finite if there is a bi/in/surjection from/to a finite type\" leaves the directions unstated, and a wrong reading is false (`Empty.elim : Empty → ℕ` is injective, `fun _ : ℕ => ()` is surjective). It means: an injection into, a surjection from, or a bijection with a finite type. The comment above `univ_ofSubsingleton` also says \"required unification\" for \"requires\".","fix":"Spell out the three directions; fix the tense.","ev":"Source L18–19, L82.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-f373a6","file":"Mathlib/Data/Fintype/OfMap.lean","decl":"(file)","line":28,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-universe","claim":"`universe u v` (L28) is never used: every type in the file is bound with `Type*`.","fix":"Delete L28.","ev":"`grep -n 'Type u\\|Type v\\|.{u\\|.{v'` on the file: no hits.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-147f7d","file":"Mathlib/Data/Fintype/OfMap.lean","decl":"Fintype.ofMultiset","line":36,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"data-called-proof","claim":"The docstrings of `Fintype.ofMultiset` and `Fintype.ofList` say \"Construct a proof of `Fintype α`\", but `Fintype α` is data (its `univ` is `s.toFinset`, resp. `l.toFinset`, and different inputs give different instances), and both lack a final period. The sibling docstrings (`ofBijective`, `ofSurjective`) describe the construction instead.","fix":"\"Construct a `Fintype α` instance whose `univ` is `s.toFinset`, from a multiset containing every element.\" (and likewise for lists).","ev":"Source L36, L41.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b34781","file":"Mathlib/Data/Fintype/OfMap.lean","decl":"Fintype.ofInjective","line":67,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"unneeded-inhabited-from-nonempty","claim":"`Fintype.ofInjective` builds `letI := Classical.inhabited_of_nonempty hα` (L67), but `invFun` and `invFun_surjective` need only `[Nonempty α]`, which the `if hα : Nonempty α` branch already provides as a local instance. The line can be deleted.","fix":"Delete L67.","ev":"probe1.lean: the definition with L67 removed compiles (only the expected `@[instance_reducible]` reminder for a probe `def`).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-8e53b6","file":"Mathlib/Data/Fintype/OfMap.lean","decl":"Fintype.univ_ofSubsingleton","line":83,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"instance-specific-lemma-undocumented","claim":"`univ_ofSubsingleton` is a statement about the specific instance `Fintype.ofSubsingleton a`, not about `univ` for an arbitrary `Fintype α`, but unlike its sibling `univ_ofIsEmpty` it has no docstring saying so or pointing to the general lemma (`Finset.singleton_eq_univ`, `Finset.univ_unique`).","fix":"Add a docstring like `univ_ofIsEmpty`'s, pointing to `Finset.univ_unique`/`Finset.singleton_eq_univ`.","ev":"Source L81–84 vs L92–95.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-f36d47","file":"Mathlib/Data/List/Pairwise.lean","decl":"(file)","line":17,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"stale-docstring","claim":"The module docstring says the definitions of `List.Pairwise` and `List.pwFilter` are 'in `Data.List.Defs`', but they are in core and Batteries (`Batteries/Data/List/Basic.lean:581` for `pwFilter`). It also does not mention the `TFAE` section (L153–200), which makes up a third of the file, and the file has only one `pwFilter` result (an alias).","fix":"Point to core/Batteries and mention the TFAE lemmas.","ev":"src L17-18; `def pwFilter` at .lake/packages/batteries/Batteries/Data/List/Basic.lean:581; Mathlib/Data/List/Defs.lean only uses `pwFilter`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-1fbac2","file":"Mathlib/Data/List/Pairwise.lean","decl":"(file)","line":34,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"leftover-hygiene","claim":"`open Nat` (L34) is unused. Several lemmas re-bind section variables (`pairwise_iff_forall_infix` re-binds `{α} {l} {R}`; `pairwise_cons_cons_iff_of_trans`, `Pairwise.cons_cons_of_trans`, `rel_get_of_lt`, `rel_get_of_le` re-bind `{l}`/`{a b}`). Also, `rel_get_of_le` packs two tactics on one line with `;`, and `Pairwise.decide` uses `refine` where `exact` is meant.","fix":"Drop `open Nat` and the re-bound binders; one tactic per line; `exact`.","ev":"hunts/list-pairwise/noopen.lean (src without `open Nat`) compiles with the lakefile options, exit 0; src L38 vs L44, L132, L136, L141, L145; L147; L151.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7431e0","file":"Mathlib/Data/List/Pairwise.lean","decl":"List.pairwise_of_reflexive_of_forall_ne","line":65,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"reprovable-from-existing-api","claim":"The 7-line case-split proof of `pairwise_of_reflexive_of_forall_ne` is `pairwise_of_forall_mem_list fun a ha b hb => Std.Refl.rel_of_ne_imp (h a ha b hb)`. Similarly, `Pairwise.head!_le` re-derives `Pairwise.rel_head`, and `Pairwise.decide` is `by simpa using h`. Separately, the 'Pairwise filtering' section holds five declarations that have nothing to do with `pwFilter`.","fix":"Use the one-line proofs and move the non-filtering lemmas under a general heading.","ev":"-- hunts/list-pairwise/P2.lean: the one-line `pairwise_of_forall_mem_list ... Std.Refl.rel_of_ne_imp` proof of the same statement compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-bec468","file":"Mathlib/Data/List/Pairwise.lean","decl":"List.Pairwise.head!_le","line":117,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-breaks-convention","claim":"`Pairwise.head!_le` concludes `R l.head! a` for an arbitrary reflexive relation `R`, not `≤`. Its siblings are `rel_head`/`rel_getLast`, so `rel_head!` is the consistent name. It has one consumer (`Topology/Category/Profinite/Nobeling/Basic.lean:341`).","fix":"Rename to `Pairwise.rel_head!` (deprecated alias).","ev":"src L117-118 `theorem Pairwise.head!_le [Inhabited α] [Std.Refl R] (h : l.Pairwise R) (ha : a ∈ l) : R l.head! a`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a5cb1c","file":"Mathlib/Data/List/Pairwise.lean","decl":"List.Pairwise.decide","line":149,"sev":"NIT","status":"confirmed","cat":"api","pattern":"explicit-inferable-binder","claim":"`Pairwise.decide` takes `(l : List α)` explicitly, although `h : Pairwise R l` determines it. As a result `h.decide` needs an extra underscore, unlike every other `Pairwise.*` lemma in the file.","fix":"Make `l` implicit.","ev":"src L149 `theorem Pairwise.decide [DecidableRel R] (l : List α) (h : Pairwise R l)`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-f96371","file":"Mathlib/Data/Multiset/Count.lean","decl":"Multiset.ext'_iff","line":189,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `Multiset.ext'_iff` (Data.Multiset.Count), `Multiset.ext` (Data.Multiset.Count) state exactly the same thing (Lean-checked). Reviewer: @[ext] on `ext'` (l.188) auto-generates `ext'_iff`, which duplicates the manual iff `Multiset.ext : s = t ↔ ∀ a, count a s = count a t`. Keep Multiset.ext, which is used and legacy, and suppress the generated copy with `@[ext (iff := false)]`. A longer-term option is to rename ext' to ext and the iff to ext_iff.","fix":"Deprecate `Multiset.ext'_iff` in favour of `Multiset.ext`.","ev":"dupscan/Check.lean: `example := (@Multiset.ext : type_of% @Multiset.ext'_iff)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup1 item 49, rating NIT): Suppressing the generated iff preserves both the established `Multiset.ext` theorem and the `ext'` tactic registration. This is cosmetic generator cleanup. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Data/Multiset/Count.lean#L183).","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261006-eb41dd","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"(file)","line":34,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-open","claim":"`Nat` in `open List Subtype Nat Function` (L34) is unused; the file compiles without it.","fix":"Drop `Nat` from the `open`.","ev":"hunts/multiset-mapfold/noopen.lean (`open List Subtype Function`) compiles with the lakefile options, 0 errors.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-1275b1","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.forall_mem_map_iff","line":61,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"iff-suffix-inconsistent-with-siblings","claim":"The `_iff` suffix breaks the sibling naming. `List.forall_mem_map` (core Init/Data/List/Lemmas.lean:1134), `Finset.forall_mem_map` (Data/Finset/Image.lean:89) and `Option.forall_mem_map` (Data/Option/Basic.lean:56) state the same iff without it, as does the same-namespace `Multiset.forall_mem_cons` (Data/Multiset/ZeroCons.lean:182). There is no one-directional `Multiset.forall_mem_map` to disambiguate from, so the name the List/Finset analogy predicts does not exist.","fix":"Rename to `Multiset.forall_mem_map`, keeping a `@[deprecated]` alias `forall_mem_map_iff`.","ev":"git -C mathlib4 grep -nE 'theorem forall_mem_map\\b|theorem forall_mem_cons\\b' origin/master -- Mathlib/Data/Multiset Mathlib/Data/Finset/Image.lean Mathlib/Data/Option/Basic.lean  → Finset/Image.lean:89, Option/Basic.lean:56, Multiset/ZeroCons.lean:182 (no Multiset.forall_mem_map); core List.forall_mem_map at Init/Data/List/Lemmas.lean:1134","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7123f4","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.map_eq_singleton","line":119,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"list-lemma-lift-golf","claim":"The 8-line two-direction proof can be replaced by a one-line lift of core's `List.map_eq_singleton_iff`.","fix":"Prove it as `Quotient.inductionOn s fun _ => by simp [coe_eq_singleton]`.","ev":"example {f : α → β} {s : Multiset α} {b : β} :\n    Multiset.map f s = {b} ↔ ∃ a : α, s = {a} ∧ f a = b :=\n  Quotient.inductionOn s fun _ => by simp [Multiset.coe_eq_singleton]\n(hunts/multiset-mapfold/batch1/ProbeA.lean P4b)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-fcaa45","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.map_eq_cons","line":129,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"iff-sides-reversed-vs-name","claim":"The iff is stated backwards relative to its name. The name says the left side is `map f s = b ::ₘ t`, but the left side is actually `∃ a ∈ s, f a = b ∧ (s.erase a).map f = t`, the reverse of core's `List.map_eq_cons_iff`. So `rw [map_eq_cons] at h` fails on `h : s.map f = b ::ₘ t`. Its four explicit binders (`f s t b`) are also unusual for an iff lemma. Nothing in Mathlib uses it.","fix":"Swap the sides to `s.map f = b ::ₘ t ↔ ∃ a ∈ s, …` with implicit binders, and optionally add the `DecidableEq`-free List-style form `∃ a u, s = a ::ₘ u ∧ f a = b ∧ u.map f = t`.","ev":"example [DecidableEq α] (f : α → β) (s : Multiset α) (t : Multiset β) (b : β)\n    (h : s.map f = b ::ₘ t) : ∃ a ∈ s, f a = b ∧ (s.erase a).map f = t := by\n  rw [Multiset.map_eq_cons] at h  -- error: did not find an occurrence of the pattern ∃ a, a ∈ ?s ∧ …\n-- `rwa [← Multiset.map_eq_cons] at h` works; the DecidableEq-free form also compiles (ProbeA.lean P5b)\n(hunts/multiset-mapfold/batch1/ProbeB.lean P5)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-91a6a4","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.map_eq_cons","line":129,"sev":"NIT","status":"confirmed","cat":"generality","pattern":"missing-characteristic-api","claim":"`map_eq_cons` is stated through `erase`, which forces `[DecidableEq α]`. The constructive form `s.map f = b ::ₘ t ↔ ∃ a u, s = a ::ₘ u ∧ f a = b ∧ u.map f = t` needs no decidability. Separately, the file has no `foldl_map`/`foldr_map` fusion lemmas, and `coe_foldl`/`coe_foldr` use the opposite word order from the file's `map_coe`.","fix":"Add the decidability-free decomposition and `foldl_map`/`foldr_map` (lifted from `List.foldl_map`/`foldr_map`).","ev":"src: `theorem map_eq_cons [DecidableEq α] ...` uses `s.erase a`; `git grep 'Multiset.foldl_map\\|Multiset.foldr_map' origin/master -- Mathlib` finds nothing.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6d6f5b","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.map_mono","line":182,"sev":"NIT","status":"confirmed","cat":"api","pattern":"duplicate-gcongr-registration","claim":"`@[gcongr]` on `map_mono : Monotone (map f)` is redundant. The gcongr attribute unfolds `Monotone` and registers exactly the pattern `s ≤ t → map f s ≤ map f t` already registered by `@[gcongr] map_le_map`. The gcongr table under key `(LE.le, Multiset.map, 4)` holds both lemmas.","fix":"Drop `@[gcongr]` from `map_mono` and keep it on `map_le_map`.","ev":"open Mathlib.Tactic.GCongr Lean in\n#eval show CoreM _ from do\n  let le ← findGCongrLemmas? ``LE.le ``Multiset.map ``Multiset.map 4\n  return le.map (·.declName)   -- [`Multiset.map_mono, `Multiset.map_le_map]\n(hunts/multiset-mapfold/batch1/ProbeB.lean P9; Mathlib/Tactic/GCongr/Core.lean:396-401 unfolds Monotone-like conclusions)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-46bc78","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.map_strictMono","line":185,"sev":"NIT","status":"confirmed","cat":"api","pattern":"duplicate-gcongr-registration","claim":"`@[gcongr]` on `map_strictMono : StrictMono (map f)` is redundant. It registers the same `s < t → map f s < map f t` lemma as `@[gcongr] map_lt_map`, and the gcongr table under key `(LT.lt, Multiset.map, 4)` holds both. `map_strictMono` has no other use in Mathlib.","fix":"Drop `@[gcongr]` from `map_strictMono` and keep it on `map_lt_map`.","ev":"open Mathlib.Tactic.GCongr Lean in\n#eval show CoreM _ from do\n  let lt ← findGCongrLemmas? ``LT.lt ``Multiset.map ``Multiset.map 4\n  return lt.map (·.declName)   -- [`Multiset.map_strictMono, `Multiset.map_lt_map]\n(hunts/multiset-mapfold/batch1/ProbeB.lean P9)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ad0d03","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.map_erase","line":192,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"list-lemma-lift-golf","claim":"The 6-line `Multiset.induction_on` proof repeats Mathlib's `List.map_erase` and can be a one-line lift of it.","fix":"Prove it as `Quot.inductionOn s fun l => congr_arg ((↑) : List β → Multiset β) (List.map_erase hf l)`.","ev":"example [DecidableEq α] [DecidableEq β] (f : α → β) (hf : Function.Injective f) (x : α)\n    (s : Multiset α) : (s.erase x).map f = (s.map f).erase (f x) :=\n  Quot.inductionOn s fun l => congr_arg ((↑) : List β → Multiset β) (List.map_erase hf l)\n(hunts/multiset-mapfold/batch1/ProbeA.lean P6b)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2213b5","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.map_erase_of_mem","line":200,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"golfable-proof","claim":"The 5-line induction (with rcases/replace/rw chain through erase_cons_tail_of_mem) can be replaced by a 2-line proof: decompose s = x ::ₘ t and let simp finish (erase_cons_head, map_cons).","fix":"Replace the proof by `obtain ⟨t, rfl⟩ := exists_cons_of_mem h; simp`.","ev":"batch2/copy.lean (copy of src.lean, compiled clean incl. `#lint only simpNF`; output batch2/copy.out): theorem map_erase_of_mem [DecidableEq α] [DecidableEq β] (f : α → β) (s : Multiset α) {x : α} (h : x ∈ s) : (s.erase x).map f = (s.map f).erase (f x) := by\n  obtain ⟨t, rfl⟩ := exists_cons_of_mem h\n  simp","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-057bb7","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.map_surjective_of_surjective","line":208,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"golfable-proof","claim":"The 7-line Multiset.induction_on proof redoes what `Function.Surjective.list_map` (Mathlib/Data/List/Basic.lean:777) already gives; it lifts in one line.","fix":"Use `fun s => Quot.inductionOn s fun l => let ⟨l', h⟩ := hf.list_map l; ⟨l', congrArg ofList h⟩`.","ev":"batch2/copy.lean (copy of src.lean, compiled clean incl. `#lint only simpNF`; output batch2/copy.out): theorem map_surjective_of_surjective {f : α → β} (hf : Function.Surjective f) : Function.Surjective (map f) :=\n  fun s => Quot.inductionOn s fun l => let ⟨l', h⟩ := hf.list_map l; ⟨l', congrArg ofList h⟩","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-04467c","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.attach_map_val'","line":335,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-mismatch-with-list-counterpart","claim":"The name is out of step with core List. `Multiset.attach_map_val'` states `(s.attach.map fun i => f i.val) = s.map f`, which is `List.attach_map_val`, while `Multiset.attach_map_val` states the `Subtype.val` case, which is `List.attach_map_subtype_val`. So `List.attach_map_val` and `Multiset.attach_map_val` are different statements under the same name.","fix":"Rename to `attach_map_val` (f-version) and `attach_map_subtype_val` (val-version) to match core List, with `@[deprecated]` aliases.","ev":"measured: core Init/Data/List/Attach.lean:149 `theorem attach_map_val {l : List α} {f : α → β} : (l.attach.map fun (i : {i // i ∈ l}) => f i) = l.map f` and :154 `theorem attach_map_subtype_val (l : List α) : l.attach.map Subtype.val = l`; MapFold.lean:335 `attach_map_val' ... : (s.attach.map fun i => f i.val) = s.map f`, :339 `attach_map_val ... : s.attach.map Subtype.val = s`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4e4eea","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.attach_map_val","line":339,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-mismatch-with-list-counterpart","claim":"Same mismatch seen from the other lemma: `Multiset.attach_map_val` is the `Subtype.val` statement, which core calls `List.attach_map_subtype_val`. The name `List.attach_map_val` belongs to the general f-version, which Multiset calls `attach_map_val'`.","fix":"Rename to `attach_map_subtype_val` (deprecated alias `attach_map_val`), and give the f-version the unprimed name.","ev":"measured: see finding on Multiset.attach_map_val' (core List/Attach.lean:149,154 vs MapFold.lean:335,339)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ece80f","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.erase_attach_map_val","line":355,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"dead-section-variable","claim":"The section variable `{s : Multiset α}` (L353) is dead: both lemmas in the section (`erase_attach_map_val`, `erase_attach_map`) rebind an explicit `(s : Multiset α)`. Deleting it changes nothing; the file compiles and the signatures stay explicit in `s`.","fix":"Change L353 to `variable [DecidableEq α]`.","ev":"hunts/multiset-mapfold/batch3/copyB.lean (L353 → `variable [DecidableEq α]`) EXIT=0; probeA `#check @Multiset.erase_attach_map_val : ∀ {α} [DecidableEq α] (s : Multiset α) (x : {x // x ∈ s}), ...`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d8aa96","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.sub_eq_fold_erase","line":371,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-cites-wrong-constant","claim":"The name says `fold`, but the right-hand side is `Multiset.foldl`. `Multiset.fold` is a different operation (Data/Multiset/Fold.lean:31), and the List lemma used in the proof is `List.diff_eq_foldl`.","fix":"Rename to `sub_eq_foldl_erase` with a `@[deprecated]` alias.","ev":"measured: MapFold.lean:371 `lemma sub_eq_fold_erase (s t : Multiset α) : s - t = foldl erase s t`; Data/Multiset/Fold.lean:31 `def fold : α → Multiset α → α`; core/Mathlib `List.diff_eq_foldl`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-3d0bb4","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.sub_eq_fold_erase","line":371,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"unexplained-change","claim":"The proof unfolds `-` and the coercion with an unexplained `change ofList (l₁.diff l₂) = ...` inside `Quotient.inductionOn₂`. A direct induction through the existing simp lemma `sub_cons` compiles without any defeq abuse.","fix":"Prove by `induction t using Multiset.induction_on generalizing s with | empty => exact Multiset.sub_zero s | cons a t ih => rw [sub_cons, ih, foldl_cons]` (or `<;> simp [*]`).","ev":"hunts/multiset-mapfold/batch3/probeA.lean P4 (both variants compile) and hunts/multiset-mapfold/batch3/copyB.lean (replacement in the module file) EXIT=0","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-8f76fa","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.sub_eq_fold_erase","line":371,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"dead-section-variable","claim":"The section variables `{s t : Multiset α}` (L369) are dead: the only lemma in `section sub` rebinds explicit `(s t : Multiset α)`.","fix":"Change L369 to `variable [DecidableEq α]`.","ev":"hunts/multiset-mapfold/batch3/copyB.lean (L369 → `variable [DecidableEq α]`) EXIT=0; probeA `#check @Multiset.sub_eq_fold_erase : ∀ {α} [DecidableEq α] (s t : Multiset α), s - t = foldl erase s t`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-bc160c","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.map_eq_map","line":403,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"injectivity-iff-not-named-inj","claim":"`map_eq_map (hf : Injective f) : s.map f = t.map f ↔ s = t` is an injectivity iff, which Mathlib names `_inj`: the analogues are `Finset.map_inj : s₁.map f = s₂.map f ↔ s₁ = s₂` (Data/Finset/Image.lean:158) and core `List.map_inj_right : (∀ x y, f x = f y → x = y) → (List.map f l = List.map f l' ↔ l = l')`; `Multiset.map_inj`/`Multiset.map_inj_right` do not exist, and `map_eq_map` reads like an unconditional equation.","fix":"Rename to `Multiset.map_inj` (or `map_inj_right` to match core `List`) and keep a deprecated `map_eq_map` alias.","ev":"hunts/multiset-mapfold/batch4/probe1.lean (run_cmd block: Multiset.map_inj: false, Multiset.map_inj_right: false, List.map_inj_right: true; #check @List.map_inj_right) + git grep Finset/Image.lean:158","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-1cfa3e","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.exists_multiset_eq_map_quot_mk","line":419,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-repeats-namespace","claim":"`Multiset.exists_multiset_eq_map_quot_mk` and `Multiset.induction_on_multiset_quot` (L424) repeat their namespace: the full names say `multiset` twice.","fix":"Drop the inner `multiset` (e.g. `Multiset.exists_eq_map_quot_mk`, `Multiset.induction_on_quot`), keeping deprecated aliases.","ev":"full names at src.lean L419 and L424 inside `namespace Multiset`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-392471","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.Nodup.map","line":442,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"rebinds-section-variable","claim":"Port leftover: the section declares `variable {s : Multiset α}` (L433), yet six declarations re-bind `{s : Multiset α}` themselves: `Nodup.map` (L442), `inj_on_of_nodup_map` (L453), `nodup_map_iff_inj_on` (L457), `Nodup.pmap` (L461), `nodup_attach` (L466), `map_eq_map_of_bij_of_nodup` (L471).","fix":"Delete the redundant `{s : Multiset α}` binders and use the section variable.","ev":"awk 'NR>=431 && NR<=484 && /\\{s : Multiset α\\}/' src.lean -> lines 433 (variable), 442, 453, 457, 461, 466, 471","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-9d6016","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.inj_on_of_nodup_map","line":453,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"inj-on-spelled-snake-case","claim":"`nodup_map_iff_of_inj_on` (L445), `inj_on_of_nodup_map` (L453) and `nodup_map_iff_inj_on` (L457) spell the `InjOn` concept `inj_on`; current Mathlib writes `injOn` (193 theorem/lemma names contain `injOn`, 19 contain `inj_on`). The names copy `List.inj_on_of_nodup_map`/`List.nodup_map_iff_inj_on`.","fix":"Rename to `injOn_of_nodup_map`, `nodup_map_iff_injOn`, `nodup_map_iff_of_injOn` (together with the `List` versions) with deprecated aliases.","ev":"git grep -hE '^(@\\[[^]]*\\] )?(protected )?(theorem|lemma) [A-Za-z_.]*injOn' origin/master -- Mathlib | wc -l  -> 193; same with inj_on -> 19","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2ca1b8","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.nodup_attach","line":466,"sev":"NIT","status":"confirmed","cat":"api","pattern":"alias-drops-direction","claim":"`protected alias ⟨_, Nodup.attach⟩ := nodup_attach` (L469) discards the forward direction, so `Multiset.Nodup.of_attach` does not exist although `List.Nodup.of_attach` does.","fix":"Use `protected alias ⟨Nodup.of_attach, Nodup.attach⟩ := nodup_attach`, as in `Mathlib/Data/List/Nodup.lean`.","ev":"hunts/multiset-mapfold/batch4/probe1.lean run_cmd: Multiset.Nodup.of_attach: false, List.Nodup.of_attach: true; example {s : Multiset α} (h : s.attach.Nodup) : s.Nodup := Multiset.nodup_attach.1 h","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7b3793","file":"Mathlib/Data/Multiset/MapFold.lean","decl":"Multiset.map_eq_map_of_bij_of_nodup","line":471,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"calc-detour-through-pmap","claim":"The closing `calc` detours through `pmap` (`pmap_eq_map`, `pmap_eq_map_attach`) to reach `s.attach.map fun x => f x.1`, which is exactly `attach_map_val'` (same file, L335); the 4-line calc becomes 2 lines.","fix":"Replace the calc by `rw [this, map_map, ← attach_map_val' s f]; exact map_congr rfl fun x _ => h _ _`.","ev":"example (f : α → γ) (g : β → γ) {s : Multiset α} {t : Multiset β}\n    (hs : s.Nodup) (ht : t.Nodup) (i : ∀ a ∈ s, β) (hi : ∀ a ha, i a ha ∈ t)\n    (i_inj : ∀ a₁ ha₁ a₂ ha₂, i a₁ ha₁ = i a₂ ha₂ → a₁ = a₂)\n    (i_surj : ∀ b ∈ t, ∃ a ha, i a ha = b) (h : ∀ a ha, f a = g (i a ha)) :\n    s.map f = t.map g := by\n  have : t = s.attach.map fun x => i x.1 x.2 := by\n    rw [ht.ext]\n    · aesop\n    · exact hs.attach.map fun x y hxy ↦ Subtype.ext <| i_inj _ x.2 _ y.2 hxy\n  rw [this, Multiset.map_map, ← Multiset.attach_map_val' s f]\n  exact Multiset.map_congr rfl fun x _ => h _ _","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-5d018a","file":"Mathlib/Data/Nat/Factorial/DoubleFactorial.lean","decl":"(imports)","line":8,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"public-import-only-for-proofs","claim":"`public import Mathlib.Tactic.Ring` is only used inside proofs (`ring`, `by ring`); the file compiles with it as a plain `import`, so it need not be re-exported. Conversely `Nat.factorial`, used in public statements, is not imported directly (`Mathlib.Data.Nat.Factorial.Basic` arrives transitively through the tactic imports).","fix":"Make it `import Mathlib.Tactic.Ring` (after checking downstream importers that might rely on the re-export).","ev":"hunts/double-factorial/probe2_imports.lean (the file with that import made private) compiles with exit 0. Downstream importers not rebuilt.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-96a112","file":"Mathlib/Data/Nat/Factorial/DoubleFactorial.lean","decl":"(file)","line":12,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstrings","claim":"Only the definition and the positivity extension have docstrings, and the definition's docstring only repeats its name; none of the seven lemmas has one. The module docstring's `n‼ := n * (n - 2) * (n - 4) * ...` omits the stopping rule and the convention `0‼ = 1‼ = 1` (over `ℕ`, continuing the subtraction would reach a factor `0`), does not list the lemmas, and does not say that the `‼` notation is scoped (`open scoped Nat`) and typed `\\!!`.","fix":"Add one-line docstrings and mention the scoped notation and the main identities in the module docstring.","ev":"Doc-only finding: L12-21 module docstring; L40-80 lemmas without docstrings.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-19b041","file":"Mathlib/Data/Nat/Factorial/DoubleFactorial.lean","decl":"doubleFactorial","line":31,"sev":"NIT","status":"confirmed","cat":"api","pattern":"simp-def-instead-of-named-lemmas","claim":"`doubleFactorial` is `@[simp]`, so its auto-generated equation lemmas (`doubleFactorial.eq_1/2/3`) are simp lemmas, but there are no named `doubleFactorial_zero`/`doubleFactorial_one` for `rw`, and the named `doubleFactorial_add_two` duplicates the simp equation `doubleFactorial.eq_3` without being simp itself; there is also no `doubleFactorial_ne_zero`. `Nat.factorial` instead exposes named `factorial_zero`/`factorial_succ`/`factorial_ne_zero`, and keeps `factorial_succ` out of the simp set, whereas here plain `simp` expands `(n + 4)‼` to `(n + 4) * ((n + 2) * n‼)`.","fix":"Add `@[simp] doubleFactorial_zero : 0‼ = 1` and `@[simp] doubleFactorial_one : 1‼ = 1` (and consider dropping `@[simp]` from the def in favour of named lemmas).","ev":"hunts/double-factorial/probe1.lean P2: `simp` proves `0‼ = 1`, `7‼ = 105`, `(n + 2)‼ = (n + 2) * n‼` through the def's equations; `#check Nat.doubleFactorial_zero` / `_one` fail (unknown constant); probe3.lean: `#check Nat.doubleFactorial_ne_zero` fails while `Nat.factorial_ne_zero` exists. Exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-e4d0c1","file":"Mathlib/Data/Nat/Factorial/DoubleFactorial.lean","decl":"factorial_eq_mul_doubleFactorial","line":52,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"rw-with-definition","claim":"`factorial_eq_mul_doubleFactorial` (L52) and `doubleFactorial_two_mul` (L63) rewrite with the definition `factorial` (unfolding its equation lemma) instead of the API lemma `Nat.factorial_succ`, coupling the proofs to the definition's shape.","fix":"Use `Nat.factorial_succ` in both `rw` chains.","ev":"Proof-only finding: L52 `rw [doubleFactorial_add_two, factorial, …]`, L63 `rw [mul_add, mul_one, doubleFactorial_add_two, factorial, …]`; `Nat.factorial_succ : (n + 1)! = (n + 1) * n !` exists. Raised by Astra's A1 pass (item 5).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-84979e","file":"Mathlib/Data/Nat/Factorial/DoubleFactorial.lean","decl":"(file)","line":97,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"test-example-in-library","claim":"A test `example (n : ℕ) : 0 < n‼ := by positivity` is left in the library file (L97, inside `namespace Mathlib.Meta.Positivity`); positivity-extension tests live in `MathlibTest/positivity.lean`. `open Nat` (L26) directly before `namespace Nat` is also redundant.","fix":"Move the `example` to `MathlibTest/positivity.lean` and drop the redundant `open Nat`.","ev":"Hygiene-only finding: L26 `open Nat` / L28 `namespace Nat`; L97 `example (n : ℕ) : 0 < n‼ := by positivity`; `git grep -n '^example' -- Mathlib/Data/Nat/Factorial/` finds only this one.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261006-8dc267","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.squarefree_iff_prime_squarefree","line":47,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-misdescribes-conclusion","claim":"The name reads 'squarefree iff prime is squarefree', but the statement `Squarefree n ↔ ∀ x, Nat.Prime x → ¬x * x ∣ n` says no prime square divides `n`; the same file calls the ℤ analogue `Int.squarefree_iff_prime_sq_not_dvd` (L409, stated with `p ^ 2`).","fix":"Rename to `Nat.squarefree_iff_prime_sq_not_dvd` (keeping a deprecated alias) to match the `Int` version.","ev":"measured: probe1.lean `#check @Nat.squarefree_iff_prime_squarefree` prints `∀ {n : ℕ}, Squarefree n ↔ ∀ (x : ℕ), Nat.Prime x → ¬x * x ∣ n`; src.lean L409-410 `Int.squarefree_iff_prime_sq_not_dvd : Squarefree n ↔ ∀ p : ℕ, p.Prime → ¬ (p : ℤ) ^ 2 ∣ n`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-05ae78","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.squarefree_iff_prime_squarefree","line":47,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"rebinds-section-variable","claim":"Seven theorems re-bind `{n : ℕ}`/`{n m : ℕ}`/`{n k : ℕ}` although L45 already declares `variable {s : Finset ℕ} {m n p : ℕ}`: `squarefree_iff_prime_squarefree`, `natFactorization_le_one`, `squarefree_of_factorization_le_one`, `squarefree_iff_factorization_le_one`, `Squarefree.ext_iff`, `squarefree_pow_iff`, `squarefree_and_prime_pow_iff_prime`.","fix":"Drop the redundant implicit binder and use the section variable.","ev":"measured: src.lean L45 and L47.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-9d4f08","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.Squarefree.ext_iff","line":78,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"pseudo-namespace-breaks-dot-notation","claim":"Declared inside `namespace Nat` without `_root_`, so the full name is `Nat.Squarefree.ext_iff`, which is not a type namespace: `hn.ext_iff hm` fails both at top level and inside `namespace Nat` ('Invalid field `ext_iff`: The environment does not contain `Function.ext_iff`') and only resolves under `open Nat`. It has no consumers in Mathlib.","fix":"Rename to `_root_.Squarefree.natEq_iff` (mirroring `Squarefree.natFactorization_le_one`) or to a plain name such as `Nat.eq_iff_prime_dvd_iff_of_squarefree`, keeping a deprecated alias.","ev":"hunts/nat-squarefree/batch0/probe1.lean L13-25: `example {n m : ℕ} (hn : Squarefree n) (hm : Squarefree m) : n = m ↔ ∀ p, Nat.Prime p → (p ∣ n ↔ p ∣ m) := hn.ext_iff hm` errors at top level (L15) and inside `namespace Nat` (L24); compiles in a section with `open Nat` (L20). `#check @Nat.Squarefree.ext_iff` confirms the full name.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7b799f","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.squarefree_and_prime_pow_iff_prime","line":101,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"predicate-name-not-lowercamel","claim":"The hypothesis `IsPrimePow n` is spelled `prime_pow` in the name; the naming convention turns `IsPrimePow` into `isPrimePow` (cf. `isPrimePow_nat_iff`, `Prime.isPrimePow`, `isPrimePow_iff_card_primeFactors_eq_one`), so `prime_pow` reads as `Prime ∧ pow`/`p ^ k`.","fix":"Rename to `Nat.squarefree_and_isPrimePow_iff_prime` with a deprecated alias.","ev":"measured: src.lean L101 `theorem squarefree_and_prime_pow_iff_prime {n : ℕ} : Squarefree n ∧ IsPrimePow n ↔ Prime n`; Mathlib/Algebra/IsPrimePow.lean:59 `Prime.isPrimePow`, :74 `isPrimePow_nat_iff`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6ba9f9","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.minSqFacAux","line":110,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"port-leftover-formatting","claim":"Leftovers from the port: a redundant `by exact` in `have ... := by exact Nat.minFac_lemma n k h` (L114-115), the continuation line L119 is not indented under its `have` (L118), and the single-arm `| n, k =>` match should be binders `(n k : ℕ)`.","fix":"Drop `by exact`, indent L119, and write `def minSqFacAux (n k : ℕ) : Option ℕ :=`.","ev":"measured: src.lean L110-122.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-3d0f83","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.MinSqFacProp","line":135,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"imprecise-docstring","claim":"The docstring says 'If `some d`, then `d` is a minimal square factor of `n`', but `d` is not a square factor: the clause says `d` is the least prime with `d * d ∣ n`.","fix":"Say 'if `some d`, then `d` is the least prime whose square divides `n`'.","ev":"measured: src.lean L132-137 (docstring vs `| some d => Prime d ∧ d * d ∣ n ∧ ∀ p, Prime p → p * p ∣ n → d ≤ p`).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-23448d","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.minSqFac_dvd","line":213,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-omits-part-of-statement","claim":"`minSqFac_dvd` concludes `d * d ∣ n` and `minSqFac_le_of_dvd` takes `m * m ∣ n`, but their names say `dvd`, which suggests `d ∣ n`. `minSqFac_sq_dvd` and `minSqFac_le_of_sq_dvd` (or `_mul_self_dvd`) would match the statements.","fix":"Rename to `minSqFac_mul_self_dvd` / `minSqFac_le_of_mul_self_dvd` (deprecated aliases).","ev":"src: `theorem minSqFac_dvd {n d : ℕ} (h : n.minSqFac = some d) : d * d ∣ n`, `theorem minSqFac_le_of_dvd {n d : ℕ} (h : n.minSqFac = some d) {m} (m2 : 2 ≤ m) (md : m * m ∣ n) : d ≤ m`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4a3717","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.squarefree_iff_minSqFac","line":226,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"iff-name-omits-eq-none","claim":"The name reads as 'squarefree iff minSqFac', but `minSqFac n : Option ℕ` is not a Prop. The right-hand side is `n.minSqFac = none`, which the name omits.","fix":"Rename to `squarefree_iff_minSqFac_eq_none`, with a deprecated alias.","ev":"src.lean L226: `theorem squarefree_iff_minSqFac {n : ℕ} : Squarefree n ↔ n.minSqFac = none`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ea0a74","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.squarefree_two","line":238,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"roundabout-proof-of-numeral-fact","claim":"The proof goes through `squarefree_iff_nodup_primeFactorsList` and `simp`, but the statement is one term from the general API: `Nat.prime_two.squarefree` (`Irreducible.squarefree`). Its only use is in the commented-out norm_num block (L566).","fix":"Prove it as `Nat.prime_two.squarefree`.","ev":"hunts/nat-squarefree/batch1/p1.lean, P5:\nexample : Squarefree 2 := Nat.prime_two.squarefree\nexample : Squarefree 2 := Irreducible.squarefree Nat.prime_two","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-1d77af","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.divisors_filter_squarefree_of_squarefree","line":241,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"hand-rolled-ext-instead-of-filter-true-of-mem","claim":"The proof hand-rolls `Finset.ext` with the positional-underscore application `@Finset.filter_subset _ _ _ _ d`, which breaks if the argument order changes. The statement is exactly `Finset.filter_true_of_mem`.","fix":"`filter_true_of_mem fun _ hd => hn.squarefree_of_dvd (dvd_of_mem_divisors hd)`.","ev":"hunts/nat-squarefree/batch1/p1.lean, P6:\nexample {n : ℕ} (hn : Squarefree n) : {d ∈ n.divisors | Squarefree d} = n.divisors :=\n  filter_true_of_mem fun _ hd => hn.squarefree_of_dvd (dvd_of_mem_divisors hd)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b544d4","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.divisors_filter_squarefree","line":248,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-qualification-after-open","claim":"`open UniqueFactorizationMonoid` (L246) is followed by fully qualified `UniqueFactorizationMonoid.normalizedFactors`, `.squarefree_iff_nodup_normalizedFactors` and `.factors_unique` at L250, 258, 262, 277, 283, 288 and 301 (the last in `sum_divisors_filter_squarefree`). Meanwhile L264-294 use the same namespace unqualified (`normalizedFactors_mul`, `prod_normalizedFactors`, `irreducible_of_normalized_factor`).","fix":"Drop the `UniqueFactorizationMonoid.` prefixes, or drop the `open` once the lemmas are restated with `primeFactors`.","ev":"grep -n 'UniqueFactorizationMonoid\\.' src.lean -> L250, 258, 262, 277, 283, 288, 301 after `open UniqueFactorizationMonoid` at L246","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-3cf446","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.sq_mul_squarefree_of_pos","line":312,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"existential-name-missing-exists","claim":"The conclusion is an existential, but the name lacks `exists_`. The general lemma it is derived from was named `exists_sq_mul_squarefree` in the same 2026-08-17 change. The same applies to `sq_mul_squarefree_of_pos'`.","fix":"Rename to `exists_sq_mul_squarefree_of_ne_zero`, with a deprecated alias, together with the api fix.","ev":"names at src.lean L312, L317 vs `exists_sq_mul_squarefree` (Mathlib/Algebra/Squarefree/Basic.lean:283)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-1aa2c8","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.squarefree_mul","line":325,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"stale-cross-reference-in-docstring","claim":"The docstring says \"See `Squarefree.of_mul_left` and `Squarefree.of_mul_right` above for auxiliary lemmas\", but neither lemma is in this file: both live in Mathlib/Algebra/Squarefree/Basic.lean (lines 78 and 81, `theorem Squarefree.of_mul_left [Monoid R] {m n : R} (hmn : Squarefree (m * n)) : Squarefree m`). The word \"above\" is a leftover from an older layout.","fix":"Replace \"above\" with \"in `Mathlib/Algebra/Squarefree/Basic.lean`\", or drop the word.","ev":"grep: `git grep -n 'theorem Squarefree.of_mul_left\\|theorem Squarefree.of_mul_right' origin/master -- Mathlib` -> only Mathlib/Algebra/Squarefree/Basic.lean:78,81; neither name is declared in Mathlib/Data/Nat/Squarefree.lean.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-5c6ebc","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.coprime_of_squarefree_mul","line":329,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"nat-specialisation-reproves-general-lemma","claim":"This repeats the argument of the general `IsRelPrime.of_squarefree_mul [CommMonoid R] {m n : R} (h : Squarefree (m * n)) : IsRelPrime m n` (Mathlib/Algebra/Squarefree/Basic.lean:45, already imported), going through `squarefree_iff_prime_squarefree` and `coprime_of_dvd` again. A `Nat.Coprime` form is fine to keep, but it should just transport the general lemma, as its siblings `Nat.squarefree_mul` and `Nat.squarefree_mul_iff` already do.","fix":"Prove it as `coprime_iff_isRelPrime.2 (.of_squarefree_mul h)`.","ev":"hunts/nat-squarefree/batch2/probeA.lean (P3) and in-file hunts/nat-squarefree/batch2/Copy.lean:\nexample {m n : ℕ} (h : Squarefree (m * n)) : m.Coprime n :=\n  Nat.coprime_iff_isRelPrime.2 (.of_squarefree_mul h)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d9ae60","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.squarefree_and_primeFactors_card_eq_two_iff","line":346,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"reversed-card-name-order","claim":"`#n.primeFactors` is `card (primeFactors n)`, so the naming convention gives `card_primeFactors`. The sibling lemma `Nat.isPrimePow_iff_card_primeFactors_eq_one` (Mathlib/Data/Nat/Factorization/PrimePow.lean:52) and `IsCarmichael.three_le_card_primeFactors` both use that order. Only this lemma and `isPGroup_iff_primeFactors_card_subset` use `primeFactors_card`.","fix":"Rename to `squarefree_and_card_primeFactors_eq_two_iff` and keep a deprecated alias (one consumer: NumberTheory/CarmichaelNumber.lean:152).","ev":"git grep -E '(theorem|lemma) [A-Za-z_.]*card_primeFactors' origin/master -- Mathlib -> PrimePow.lean:52 `isPrimePow_iff_card_primeFactors_eq_one`, CarmichaelNumber.lean:144; `primeFactors_card` -> only this lemma and PGroup.lean:157.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-bd632c","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.prod_primeFactors_invOn_squarefree","line":390,"sev":"NIT","status":"confirmed","cat":"api","pattern":"statement-not-in-simp-normal-form","claim":"The statement uses `fun n ↦ (factorization n).support`. That is not simp-normal: `@[simp] Nat.support_factorization : n.factorization.support = n.primeFactors` holds by `rfl`. It also disagrees with the name, which says `primeFactors`. Stated with `n.primeFactors`, the same proof term still works.","fix":"State it with `fun n : ℕ ↦ n.primeFactors`; the proof is unchanged.","ev":"hunts/nat-squarefree/batch2/probeA.lean (P5) and in-file hunts/nat-squarefree/batch2/Copy.lean:\nexample : Set.InvOn (fun n : ℕ ↦ n.primeFactors) (fun s ↦ ∏ p ∈ s, p)\n    {s | ∀ p ∈ s, p.Prime} {n | Squarefree n} :=\n  ⟨fun _s ↦ Nat.primeFactors_prod, fun _n ↦ Nat.prod_primeFactors_of_squarefree⟩","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-807b51","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Nat.prod_primeFactors_sdiff_of_squarefree","line":395,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-unfolds-definition-instead-of-api","claim":"The proof obtains positivity through `prime_of_mem_primeFactorsList (List.mem_toFinset.mp (ht hp))`. That relies on `primeFactors` unfolding to `primeFactorsList.toFinset`. The API lemma `Nat.pos_of_mem_primeFactors (ht hp)` says the same thing directly. The parentheses around `n.primeFactors \\ t` in the statement are also redundant.","fix":"Use `fun p hp => pos_of_mem_primeFactors (ht hp)`.","ev":"hunts/nat-squarefree/batch2/probeA.lean (P4) and in-file hunts/nat-squarefree/batch2/Copy.lean:\n  refine symm <| Nat.div_eq_of_eq_mul_left (prod_pos fun p hp ↦ Nat.pos_of_mem_primeFactors (ht hp)) ?_\n  rw [prod_sdiff ht, Nat.prod_primeFactors_of_squarefree hn]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b81096","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Tactic.NormNum.squarefree_bit10","line":432,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"dead-commented-out-lean3-code","claim":"Every declaration in this batch is part of a 182-line block comment (lines 416-597, opened by '-- Porting note: comment out NormNum tactic, to be moved to another file.'). It holds the Lean 3 `norm_num` extension for `Squarefree`, written with `bit0`/`bit1` numerals, `refine'`, Lean 3 `tactic expr` meta code (`mk_instance_cache`, `prove_mul_nat`, `match_numeral`, `false_intro`) and `unsafe def`. None of this vocabulary exists in Lean 4 Mathlib: `bit0`, `bit1` and `Nat.bit1` are unknown identifiers. The block also could not be uncommented as written. `squarefreeHelper_2` calls a nonexistent `squarefree_helper_1` (see F:2), and `eval_squarefree` does `match n with | some d | none` on `n : ℕ`, which has lost the `minSqFac` scrutinee. The block has gone unported since the port commit of 2023-05-25 (175 of its 182 lines). Its other 7 lines changed only in repo-wide mechanical sweeps (#15222 fix-comments, #9171 cases', #13934, #24775), so it costs maintenance and does nothing. The 'to be moved to another file' note is stale.","fix":"Delete lines 416-597, together with the matching commented-out tests in MathlibTest/Tactic/NormNum/Ext.lean. If a decision procedure is wanted, write it from scratch as in F:1, not by uncommenting.","ev":"hunts/nat-squarefree/batch3/probe1.lean lines 6-9: `#check @bit1`, `#check @bit0`, `#check @Nat.bit1`, `#check @Tactic.NormNum.SquarefreeHelper` -> 'Unknown identifier `bit1`', 'Unknown identifier `bit0`', 'Unknown constant `Nat.bit1`', 'Unknown identifier `Tactic.NormNum.SquarefreeHelper`' (output in probe1.out). `git grep -n -E '^(protected )?(def|abbrev|theorem|lemma) (Nat\\.)?bit[01]\\b' origin/master -- Mathlib` finds only Num/ZNum/NzsNum/SNum versions. `git grep -n -i squarefree origin/master -- Mathlib/Tactic` is empty. Line provenance came from a git blame of L416-597 run before the no-history rule arrived: 175 lines from a1c58a9b32 'feat: port Data.Nat.Squarefree (#4278)' 2023-05-25, plus 4 lines from 26b8d0d1e0 (#15222), 1 from 3fca282c58 (#9171), 1 from 7ce2b09f07 (#13934) and 1 from 827b149f0d (#24775).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-5ba444","file":"Mathlib/Data/Nat/Squarefree.lean","decl":"Tactic.NormNum.squarefreeHelper_2","line":464,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"dangling-reference-in-commented-code","claim":"The renaming during the port stopped halfway. Lean 3 `squarefree_helper_1..4` became `squarefreeHelper_1..4`, but `squarefree_helper_0` kept its old name, and the proof of `squarefreeHelper_2` (line 466) still calls `squarefree_helper_1`, which exists nowhere, not even inside the comment. So the commented code is not an accurate record of the Lean 3 source either.","fix":"Moot if the block is deleted (F:0). Otherwise change the call to `squarefreeHelper_1`.","ev":"grep -n 'squarefree_helper_\\|squarefreeHelper_' src.lean -> 445 `theorem squarefree_helper_0`, 456 `theorem squarefreeHelper_1`, 466 `refine' squarefree_helper_1 _ _ _ e (fun _ => _) h`. `git grep -n 'squarefree_helper_1\\|squarefreeHelper_1' origin/master -- .` finds only lines 456 and 466 of this file.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-ca7472","file":"Mathlib/Data/Set/Card/Arithmetic.lean","decl":"(imports)","line":10,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"public-import-only-for-proofs","claim":"`public import Mathlib.Algebra.Order.BigOperators.Group.Finset` is needed only inside proofs (`Finset.apply_union_le_sum`); no public statement mentions its API, so it could be a plain `import` and stop being re-exported.","fix":"Change it to `import Mathlib.Algebra.Order.BigOperators.Group.Finset` (after checking the two downstream importers still build).","ev":"hunts/set-card-arith/probe4_imports.lean (the file with that one `public import` made private) compiles with exit 0. Downstream importers not rebuilt. Raised by Astra's A1 pass (item 12).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-d1c351","file":"Mathlib/Data/Set/Card/Arithmetic.lean","decl":"(module docstring)","line":15,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"module-doc-stale","claim":"The module docstring describes the file as 'results using cardinal arithmetic' and lists only the two even-splitting results, but 15 of the 19 declarations are `ncard`/`encard` bounds and identities for (bounded) indexed unions and `finsum_one`, which use no cardinal arithmetic (they are here for the `Finprod` import).","fix":"Extend the module docstring with a section listing `finsum_one` and the `ncard`/`encard` lemmas for `⋃ i ∈ t, s i` and `⋃ i, s i`, and say why they live here.","ev":"Doc-only finding: L15-26 vs the declarations at L47-159.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-e6c314","file":"Mathlib/Data/Set/Card/Arithmetic.lean","decl":"Finset.exists_disjoint_union_of_even_card_iff","line":40,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"iff-named-as-implication","claim":"The two iff lemmas are named like implications and hide their left side: `Finset.exists_disjoint_union_of_even_card_iff : Even #s ↔ ∃ t u, …` (an `_of_…_iff`) and `Set.exists_union_disjoint_cardinal_eq_iff : Even s.ncard ↔ ∃ t u, …` (no mention of `even`/`ncard`). The Finset and Set families also use opposite word orders (`exists_disjoint_union` vs `exists_union_disjoint`) for the same conclusion `t ∪ u = s ∧ Disjoint t u`.","fix":"Rename to `Finset.even_card_iff_exists_disjoint_union` and `Set.even_ncard_iff_exists_union_disjoint_cardinal_eq` and use one word order in both families.","ev":"Name-only finding: statements at L40-41 and L99-100 of the audited file.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-9932f9","file":"Mathlib/Data/Set/Card/Arithmetic.lean","decl":"finsum_one","line":47,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-misses-mem","claim":"`finsum_one` is a `∑ᶠ i ∈ s` lemma in the root namespace; Mathlib names those `finsum_mem_*` (`finsum_mem_congr`, `finsum_mem_insert`, `finsum_mem_univ`, …). `finsum_one` reads as `∑ᶠ i, 1 = …` over a type.","fix":"Rename to `finsum_mem_one` (or `Set.finsum_mem_one_eq_ncard`) with a deprecated alias.","ev":"Name-only finding: `git grep -n 'theorem finsum_mem_\\|lemma finsum_mem_' Mathlib/Algebra/BigOperators/Finprod.lean` lists the `finsum_mem_*` convention; the statement is `∑ᶠ i ∈ s, 1 = s.ncard` (L47).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-979a48","file":"Mathlib/Data/Set/Card/Arithmetic.lean","decl":"finsum_one","line":50,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"dead-case-split","claim":"The proof of `finsum_one` case-splits on `h : 1 = 0` in `ℕ`, where the first branch is unreachable (`(1 : ℕ) ≠ 0` by `decide`); the split is a leftover of a general-`M` statement. In `ℕ` the infinite case is `finsum_mem_eq_zero_of_infinite (by simpa [Function.support_const one_ne_zero])`.","fix":"Either generalise the statement (finding on `finsum_one` generality), or drop the `by_cases` and use `one_ne_zero`.","ev":"hunts/set-card-arith/probe1.lean P1d `example : ¬ ((1 : ℕ) = 0) := by decide` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-b7da71","file":"Mathlib/Data/Set/Card/Arithmetic.lean","decl":"set_ncard_biUnion_le","line":57,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"wrong-namespace-prefix-workaround","claim":"`Finset.set_ncard_biUnion_le` / `Finset.set_encard_biUnion_le` are statements about `Set.ncard`/`Set.encard` filed in the `Finset` namespace with a `set_` prefix to dodge `Finset.card_biUnion_le`; the `Set` siblings in the same file are `Set.Finite.ncard_biUnion_le` etc.","fix":"Rename to `Set.ncard_biUnion_finset_le` / `Set.encard_biUnion_finset_le` (or similar `Set.*` names) with deprecated aliases.","ev":"Name-only finding: L55-65 `namespace Finset … lemma set_ncard_biUnion_le (t : Finset ι) (s : ι → Set α) : (⋃ i ∈ t, s i).ncard ≤ …`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-0ea464","file":"Mathlib/Data/Set/Card/Arithmetic.lean","decl":"Infinite.exists_union_disjoint_cardinal_eq_of_infinite","line":73,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"redundant-name-suffix","claim":"`Set.Infinite.exists_union_disjoint_cardinal_eq_of_infinite` says `infinite` twice: the `Set.Infinite` namespace (for `h.exists_…` dot notation) already names the hypothesis, so the `_of_infinite` suffix is redundant.","fix":"Rename to `Set.Infinite.exists_union_disjoint_cardinal_eq` with a deprecated alias.","ev":"Name-only finding: L73 `theorem Infinite.exists_union_disjoint_cardinal_eq_of_infinite (h : s.Infinite)` inside `namespace Set`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-8221cb","file":"Mathlib/Data/Set/Card/Arithmetic.lean","decl":"exists_union_disjoint_ncard_eq_of_even","line":94,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring-junk-case","claim":"No declaration in the file has a docstring. For the even-splitting lemmas this hides a junk-value subtlety: `Even s.ncard` holds for every infinite `s` (its `ncard` is `0`), so `exists_union_disjoint_ncard_eq_of_even` and `exists_union_disjoint_cardinal_eq_iff` apply to all infinite sets, where the `ncard` conclusion `t.ncard = u.ncard` is `0 = 0` and is met by the unbalanced split `t = s`, `u = ∅` (the cardinal version `exists_union_disjoint_cardinal_eq_of_even` keeps the genuine guarantee).","fix":"Add one-line docstrings, noting for the `Set` even-splitting lemmas that the hypothesis is automatic for infinite sets.","ev":"hunts/set-card-arith/probe2.lean P5: `Even s.ncard` from `s.Infinite` by `simp [hs.ncard]`, and `exists_union_disjoint_ncard_eq_of_even` applied to `Set.univ : Set ℕ`, compile; probe3.lean P10 `⟨Set.univ, ∅, by simp [Set.infinite_univ.ncard]⟩` proves the `ncard` conclusion for `Set.univ : Set ℕ`. Exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-730425","file":"Mathlib/Data/Set/Card/Arithmetic.lean","decl":"exists_union_disjoint_cardinal_eq_iff","line":101,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"use-for-iff-intro","claim":"The forward direction of the iff is supplied with `use exists_union_disjoint_cardinal_eq_of_even` (relying on `use` to apply `Iff.intro`); the standard form is `refine ⟨exists_union_disjoint_cardinal_eq_of_even, ?_⟩`.","fix":"Start the proof with `refine ⟨exists_union_disjoint_cardinal_eq_of_even, ?_⟩`.","ev":"hunts/set-card-arith/probe2.lean P6: `⟨exists_union_disjoint_cardinal_eq_of_even, …⟩` elaborates as the anonymous-constructor form. Exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-d0d499","file":"Mathlib/Data/Set/Card/Arithmetic.lean","decl":"ncard_iUnion_of_finite","line":118,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-detour","claim":"`ncard_iUnion_of_finite` is proved by a detour through `finite_univ.ncard_biUnion` and `finsum_mem_univ`; `finsum_mem_iUnion` gives it in one rewrite: `rw [← finsum_one, finsum_mem_iUnion h hs, finsum_congr fun i ↦ finsum_one]`.","fix":"Use `rw [← finsum_one, finsum_mem_iUnion h hs, finsum_congr fun i ↦ finsum_one]` (unless the finiteness hypothesis is dropped, which needs the general proof).","ev":"hunts/set-card-arith/probe3.lean P9 compiles. Exit 0. Raised by Astra's A1 pass (item 8).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261006-53c4cf","file":"Mathlib/Data/Set/Countable.lean","decl":"Set.Countable.toEncodable","line":19,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"module-doc-points-at-wrong-decl","claim":"The module docstring says \"For a noncomputable conversion to `Encodable s`, use `Set.Countable.nonempty_encodable`.\" That alias has type `s.Countable → Nonempty (Encodable ↑s)`, so it does not give an `Encodable s`. The conversion the sentence describes is `Set.Countable.toEncodable : s.Countable → Encodable ↑s` (L74), and the module docstring never mentions it.","fix":"Point the module docstring at `Set.Countable.toEncodable`, mentioning `Set.Countable.nonempty_encodable` only as the `Nonempty` form.","ev":"hunts/set-countable/batch0/probe1.lean P3: `#check @Set.Countable.nonempty_encodable` gives `∀ {α} {s : Set α}, s.Countable → Nonempty (Encodable ↑s)`, and `#check @Set.Countable.toEncodable` gives `{α} → {s : Set α} → s.Countable → Encodable ↑s`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-f4f5db","file":"Mathlib/Data/Set/Countable.lean","decl":"Countable.to_set","line":55,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"shared-alias-docstring-wrong-direction","claim":"`alias ⟨_root_.Countable.to_set, Countable.to_subtype⟩ := countable_coe_iff` (L55) gives both aliases the one docstring \"Restate `Set.Countable` as a `Countable` instance.\" That describes `Set.Countable.to_subtype : s.Countable → Countable s`, but is backwards for `Countable.to_set : Countable s → s.Countable`.","fix":"Split the alias into two `alias` commands with their own docstrings.","ev":"Source L54–55; `countable_coe_iff : Countable s ↔ s.Countable`, so `.mp` (`to_set`) goes `Countable s → s.Countable`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-d2f5bf","file":"Mathlib/Data/Set/Countable.lean","decl":"Set.subset_range_enumerate","line":86,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"lemma-name-omits-def-suffix","claim":"`Set.subset_range_enumerate` is about `Set.enumerateCountable`: its statement is `s ⊆ range (enumerateCountable h default)`. Its siblings all carry the full name (`range_enumerateCountable_subset`, `range_enumerateCountable_of_mem`, `enumerateCountable_mem`). Mathlib also has a different definition, `Set.enumerate : (Set α → Option α) → Set α → ℕ → Option α` (Mathlib/Data/Set/Enumerate.lean:37), so the name reads as a lemma about `Set.enumerate`. The lemma is used only inside this file (L123).","fix":"Rename it to `Set.subset_range_enumerateCountable` and keep a `@[deprecated]` alias.","ev":"hunts/set-countable/batch0/probe1.lean P8: `#check @Set.enumerate` gives `{α} → (Set α → Option α) → Set α → ℕ → Option α`, and `#check @Set.subset_range_enumerate` gives `… s ⊆ range (enumerateCountable h default)`. `git grep subset_range_enumerate origin/master -- Mathlib` finds only Data/Set/Countable.lean (L86 and L123).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c941c5","file":"Mathlib/Data/Set/Countable.lean","decl":"Set.range_enumerateCountable_subset","line":91,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"tactic-match-restates-instance","claim":"The proof uses a tactic-mode `match @decode s (Countable.toEncodable h) n with`, which has to spell out the exact `Encodable` instance path so that it matches the unfolded `enumerateCountable`. That makes it brittle if the definition changes how it gets its instance. A 3-line proof with no restated instance compiles: `rintro _ ⟨n, rfl⟩; rw [enumerateCountable]; split <;> simp`.","fix":"Replace the `refine`/`match` proof with `rintro _ ⟨n, rfl⟩; rw [enumerateCountable]; split <;> simp`.","ev":"hunts/set-countable/batch0/probe2.lean P9: `example {α : Type u} {s : Set α} (h : s.Countable) (default : α) : range (enumerateCountable h default) ⊆ insert default s := by rintro _ ⟨n, rfl⟩; rw [enumerateCountable]; split <;> simp` (exit 0)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7b17e1","file":"Mathlib/Data/Set/Countable.lean","decl":"Set.enumerateCountable_mem","line":105,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"convert-for-eq-subset","claim":"The proof `convert mem_range_self n; exact (range_enumerateCountable_of_mem h h_mem).symm` uses `convert` to transport membership along an equation of sets. The term `(range_enumerateCountable_of_mem h h_mem).subset (mem_range_self n)` proves it directly.","fix":"Use the term proof `(range_enumerateCountable_of_mem h h_mem).subset (mem_range_self n)`.","ev":"hunts/set-countable/batch0/probe1.lean P5: `example {α : Type u} {s : Set α} (h : s.Countable) {default : α} (h_mem : default ∈ s) (n : ℕ) : enumerateCountable h default n ∈ s := (range_enumerateCountable_of_mem h h_mem).subset (mem_range_self n)` (no error)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-8d1992","file":"Mathlib/Data/Set/Countable.lean","decl":"Set.Infinite.exists_subset_countable_infinite","line":164,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-binder-shadowing-variable","claim":"The signature rebinds `{α : Type u}`, which only duplicates the file-level `variable {α : Type u}` (line 36). No other declaration in the file does this; it looks like a leftover from a move. Removing the binder leaves the declaration and the file compiling unchanged.","fix":"Drop the `{α : Type u}` binder from the signature.","ev":"hunts/set-countable/batch1/probeB.lean (copy of src.lean with line 164 changed to `theorem Infinite.exists_subset_countable_infinite {s : Set α} (hs : s.Infinite) :`) compiles; `#check` gives the same type `∀ {α : Type u_1} {s : Set α}, s.Infinite → ∃ t ⊆ s, t.Countable ∧ t.Infinite`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-565ede","file":"Mathlib/Data/Set/Countable.lean","decl":"Set.exists_seq_iSup_eq_top_iff_countable","line":186,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring-nonobvious-theorem","claim":"No docstring on a non-obvious equivalence (sequence with iSup = top vs countable set with sSup = top). The side hypothesis `h : ∃ x, p x` matters only in the degenerate case: it is needed exactly when the lattice is trivial, where S = ∅ satisfies the right-hand side. Nothing tells the reader this.","fix":"Add a docstring stating the equivalence and noting that `h` is only used for the trivial lattice (S = ∅, sSup ∅ = ⊤).","ev":"src.lean line 185 is blank (no `/--` above line 186). hunts/set-countable/batch2/probe1.lean P1 compiles and shows `h` is needed: `example : ¬ ((∃ s : ℕ → Unit, (∀ _n : ℕ, False) ∧ ⨆ n, s n = ⊤) ↔ ∃ S : Set Unit, S.Countable ∧ (∀ s ∈ S, False) ∧ sSup S = ⊤) := by intro h; obtain ⟨s, hs, -⟩ := h.2 ⟨∅, countable_empty, by simp, Subsingleton.elim _ _⟩; exact hs 0`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-adac0a","file":"Mathlib/Data/Set/Countable.lean","decl":"Set.exists_seq_cover_iff_countable","line":203,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring-nonobvious-theorem","claim":"No docstring. It is the `Set α` (covering) specialisation of `exists_seq_iSup_eq_top_iff_countable` and is used downstream (SFinite.lean:559, SigmaCompact.lean:184), but nothing says so.","fix":"Add a docstring: a family of sets satisfying `p` covers `α` through a sequence iff it does through a countable subfamily, provided some set satisfies `p`.","ev":"src.lean line 202 is blank (no `/--` above line 203); git grep shows uses at Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean:559 and Mathlib/Topology/Compactness/SigmaCompact.lean:184","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-9dc35f","file":"Mathlib/Data/Set/Countable.lean","decl":"Set.countable_of_injective_of_countable_image","line":208,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-says-injective-hyp-is-injon","claim":"The name says `injective` but the hypothesis is the weaker `InjOn f s`. It is also a non-dot root name, so `hs.of_countable_image hf` is not available. The `Set.Finite` analogue is `Set.Finite.of_finite_image (h : (f '' s).Finite) (hi : InjOn f s)`.","fix":"Rename to `Set.Countable.of_countable_image` (hypotheses ordered as in `Finite.of_finite_image`) and keep a deprecated alias.","ev":"hunts/set-countable/batch2/probe1.lean `#check @countable_of_injective_of_countable_image` prints `∀ {α β} {s : Set α} {f : α → β}, InjOn f s → (f '' s).Countable → s.Countable`; Mathlib/Data/Set/Finite/Basic.lean:585 `theorem Finite.of_finite_image {s : Set α} {f : α → β} (h : (f '' s).Finite) (hi : Set.InjOn f s)`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ee93c5","file":"Mathlib/Data/Set/Countable.lean","decl":"Set.countable_isBot","line":267,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-to-dual","claim":"`countable_isBot` is a hand-written copy of `countable_isTop` with IsTop replaced by IsBot, whereas its direct siblings `subsingleton_isTop` (Mathlib/Data/Set/Subsingleton.lean:100) and `finite_isTop` (Mathlib/Order/Preorder/Finite.lean:112), from which it is proved, are tagged `@[to_dual]` and generate their IsBot versions. Tagging `countable_isTop` with `@[to_dual]` generates `countable_isBot` with the identical statement.","fix":"Tag `countable_isTop` with `@[to_dual]` and delete the hand-written `countable_isBot`.","ev":"hunts/set-countable/batch3/Copy.lean (copy of src.lean with `@[to_dual]` on `countable_isTop` at L264 and `countable_isBot` deleted; the whole file compiles with no warnings). `#check @Set.countable_isBot` prints `countable_isBot : ∀ (α : Type u_1) [inst : PartialOrder α], {x | IsBot x}.Countable`, and `example (α : Type*) [PartialOrder α] : { x : α | IsBot x }.Countable := Set.countable_isBot α` compiles (output in batch3/Copy.out).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-75884c","file":"Mathlib/Data/Set/Countable.lean","decl":"Set.Countable.of_preimage_singleton","line":291,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"namespace-mismatches-conclusion","claim":"The lemma is named `Set.Countable.of_preimage_singleton`, but its conclusion is the type class `_root_.Countable α` rather than a `Set.Countable` fact. No argument has type `Set.Countable _` (the fibre hypothesis is a ∀), so dot notation can never apply, and the name wrongly suggests a set-countability result.","fix":"Rename to `_root_.Countable.of_countable_fibers` (or move it to the root `Countable` namespace) with a deprecated alias.","ev":"src.lean L291-292, inside `namespace Set`: `theorem Countable.of_preimage_singleton {f : α → β} [Countable β] (h : ∀ (b : β), (f ⁻¹' {b}).Countable) : Countable α`. hunts/set-countable/batch3/Probe.lean L42-43: `example {f : α → β} [Countable β] (h : ∀ b, (f ⁻¹' {b}).Countable) : _root_.Countable α := Set.Countable.of_preimage_singleton h` compiles. `git grep` finds no use of it outside its definition.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-42c794","file":"Mathlib/Data/Set/Countable.lean","decl":"Set.countable_ofPred_nonempty_of_disjoint","line":315,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"golfable-proof","claim":"The 15-line tactic proof (`choose`, a hand-made injectivity argument, `by_contra`) re-derives what `Set.Countable.biUnion`, `Set.Subsingleton.countable` and `Pairwise.eq` already give: `{t | (f t).Nonempty} ⊆ ⋃ x ∈ s, {t | x ∈ f t}`, and each piece is a subsingleton by disjointness. A 2-line term proof compiles in place in the file.","fix":"Replace the proof by `(hs.biUnion fun x _ ↦ Subsingleton.countable (s := {t | x ∈ f t}) fun _ ht _ ht' ↦ hf.eq (not_disjoint_iff.2 ⟨x, ht, ht'⟩)).mono fun t ⟨_, hx⟩ ↦ mem_biUnion (h'f t hx) hx`.","ev":"hunts/set-countable/batch3/Copy.lean L313-317 (in-file replacement; the whole copy compiles without warnings):\ntheorem countable_ofPred_nonempty_of_disjoint {f : β → Set α}\n    (hf : Pairwise (Disjoint on f)) {s : Set α} (h'f : ∀ t, f t ⊆ s) (hs : s.Countable) :\n    Set.Countable {t | (f t).Nonempty} :=\n  (hs.biUnion fun x _ ↦ Subsingleton.countable (s := {t | x ∈ f t}) fun _ ht _ ht' ↦\n    hf.eq (not_disjoint_iff.2 ⟨x, ht, ht'⟩)).mono fun t ⟨_, hx⟩ ↦ mem_biUnion (h'f t hx) hx","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-0dbca0","file":"Mathlib/Data/String/Basic.lean","decl":"(file)","line":19,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"module-doc-incomplete","claim":"The module docstring \"Supplementary theorems about the `String` type\" omits that the file defines `String.ltb` and registers the `LinearOrder String` instance, its main content.","fix":"Mention `String.ltb` and the `LinearOrder String` instance.","ev":"Source L16–20, L27, L141.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-b330be","file":"Mathlib/Data/String/Basic.lean","decl":"String.ltb","line":26,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-overstates-domain","claim":"`String.ltb`'s docstring \"This coincides with `<` on strings as lists\" is only true for iterators at the start of their strings: in general `ltb` compares the remaining characters from the current positions (and at non-UTF-8-aligned raw positions reads the default character). `String.head_empty` restates what `String.toList_empty` and `List.head!_nil` already simp to.","fix":"Say that `ltb` is the lexicographic order of the remaining suffixes from valid positions; drop or deprecate `head_empty`.","ev":"Source L26–34; probe2.lean: `\"\".toList.head! = default := by simp only [String.toList_empty, List.head!_nil]` compiles.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-a6252e","file":"Mathlib/Data/String/Basic.lean","decl":"String.ltb.inductionOn","line":37,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"dead-code","claim":"`String.ltb.inductionOn` (a 20-line `@[no_expose] def`) has no use anywhere in Mathlib: the only proof by induction on `ltb`, `ltb_cons_addChar'`, uses `fun_induction ltb s₁ s₂` instead.","fix":"Delete it (with a deprecation if external users are a concern).","ev":"`git grep -nw 'ltb.inductionOn' origin/master -- Mathlib`: only its definition (L37).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-483740","file":"Mathlib/Dynamics/Ergodic/Action/Regular.lean","decl":"(file)","line":12,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-omission","claim":"The module docstring says 'the left and right actions of a group on itself are ergodic' with no measure. The instances need an s-finite measure that is left-invariant (for the left action) or right-invariant (for the right action), on a group with measurable multiplication and inversion. For example, `Measure.dirac 0` on `ZMod 2` is not ergodic for translation. The instances have no docstrings.","fix":"State the measure hypotheses in the module docstring and give each instance a one-line docstring.","ev":"src L12-16 vs the instance binders `[μ.IsMulLeftInvariant]` / `[μ.IsMulRightInvariant]`, `[SFinite μ]`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a5b89b","file":"Mathlib/Dynamics/Ergodic/Action/Regular.lean","decl":"(file)","line":20,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-open","claim":"`open scoped Pointwise` and the `Set` in `open MeasureTheory Measure Filter Set` are unused. In the right instance, `hs ⟨b⟩` builds the opposite element from its representation, where `MulOpposite.op b` is the API spelling.","fix":"Drop the unused opens and write `hs (MulOpposite.op b)`.","ev":"hunts/ergodic-regular/noopen.lean (src without `open scoped Pointwise` and without `Set`) compiles with the lakefile options, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-05173b","file":"Mathlib/Dynamics/Ergodic/Action/Regular.lean","decl":"(file)","line":42,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"duplicated-proof","claim":"The two instances (left action, L27-39; right action via `Gᵐᵒᵖ`, L42-54) have the same 12-line proof, differing only in the multiplication order, `fst`/`snd`, and `hs b` vs `hs ⟨b⟩`. L39 also writes `MeasureTheory.quasiMeasurePreserving_mul_right` although `MeasureTheory` is open (L54 uses the unqualified `quasiMeasurePreserving_mul_left`).","fix":"Factor the shared argument into a lemma parametrised by the action (or derive the right version via `MeasureTheory.Measure.map` along `MulOpposite`); drop the redundant `MeasureTheory.` prefix.","ev":"src L27-39 vs L42-54; L39 vs L54.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-32611c","file":"Mathlib/Dynamics/SymbolicDynamics/Basic.lean","decl":"SymbolicDynamics.FullShift.Subshift","line":233,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"proof-detour","claim":"`Subshift` is written out by hand and then linked with `@[to_additive existing]` instead of being generated; the additive `occursInAt_eq_cylinder` docstring names `IsLeftCancelMul`; both forbidden docstrings say 'if and only it'; the 'Patterns and occurrences' section opens with the subshift structures; proofs take detours (`finite_setOfPred_pattern_support_eq` via `Fintype` where `Finite.of_equiv` suffices, `contrapose` in `mapsTo_mulShift_mulForbidden`, manual intersection rewriting in `isClosed_mulForbidden`).","fix":"Generate `Subshift` with `@[to_additive Subshift]`; fix the typos; shorten the proofs.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-ba3452","file":"Mathlib/Dynamics/SymbolicDynamics/Basic.lean","decl":"SymbolicDynamics.FullShift.Pattern.mulShift","line":376,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-describes-wrong-shape","claim":"`Pattern.mulShift p v` pushes a pattern forward (its label at w lands at v * w), whereas `FullShift.mulShift v x` pulls a configuration back ((mulShift v x) h = x (v * h)): the same name for opposite directions; and `Pattern.mulShift` returns a bare configuration, discarding the translated support.","fix":"Rename (e.g. `Pattern.translateConfig`) or add a bundled `Pattern.translate` keeping the support.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-a4a857","file":"Mathlib/Dynamics/SymbolicDynamics/Basic.lean","decl":"SymbolicDynamics.FullShift.Pattern.fromConfig","line":393,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-modifier","claim":"`Pattern.mulShift` and `Pattern.fromConfig` repeat `noncomputable` inside `noncomputable section`; `fromConfig` (which needs no monoid) sits in the left-cancellative section; the comment in `mulOccursInAt_eq_cylinder` says '-- want: x ( w * g)' while the code proves `x (g * w)`.","fix":"Drop the modifiers, move `fromConfig`, fix the comment.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-2270f5","file":"Mathlib/Geometry/Convex/ConvexSpace/Barycenter.lean","decl":"(module docstring)","line":10,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"stale-docstring","claim":"The module docstring is only a title (`# The barycenter of the standard simplex`) with no description of the construction, the equal-weight formula, or the finite/nonempty hypotheses.","fix":"Add a short description and main-definition list.","ev":"-- Barycenter.lean lines 10-13: `/-! # The barycenter of the standard simplex -/`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-125fae","file":"Mathlib/Geometry/Euclidean/Inversion/Calculus.lean","decl":"(file)","line":12,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-import","claim":"`import Mathlib.Tactic.AdaptationNote` (L12) is unused: the file contains no `#adaptation_note`, and compiles without the import.","fix":"Delete L12.","ev":"Copy.lean (L12 removed): no error outside the separately modified L66.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-9e3a08","file":"Mathlib/Geometry/Euclidean/Inversion/Calculus.lean","decl":"DifferentiableAt.inversion","line":74,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-fun-prop-attribute","claim":"The eight composition lemmas (`ContDiff*.inversion`, `Differentiable*.inversion`) are not tagged `@[fun_prop]`, so `fun_prop` cannot see through `inversion`; and `hasFDerivAt_inversion` has no `HasStrictFDerivAt` companion, although it follows from `ContDiffAt.hasStrictFDerivAt'`. The file also opens `Set`, `Topology` and `RealInnerProductSpace` without using them.","fix":"Tag the eight lemmas `@[fun_prop]`; add `hasStrictFDerivAt_inversion`; trim the `open`s.","ev":"Source: no `fun_prop` attribute in the file (L43–83); L31–32 opens.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-8c2d44","file":"Mathlib/Geometry/Euclidean/Volume/Def.lean","decl":"Affine.Simplex.volume","line":29,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-drops-hypothesis","claim":"The docstring says the volume is 'defined using base-and-height formula from the 0-th vertex' but omits the base case (a 0-simplex has volume 1, an intrinsic 0-dimensional volume, not ambient Lebesgue measure), and its 'base-and-height formula from any vertex' pointer (`volume_eq`) holds only in positive dimension; copyedits ('a `n`-dimensional', 'are put to', 'for connection').","fix":"'The unsigned intrinsic n-dimensional volume; a 0-simplex has volume 1; in positive dimension defined by the base-and-height formula at vertex 0.'","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-90eada","file":"Mathlib/Geometry/Group/WordMetric.lean","decl":"Group.Generators.groupNorm","line":120,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"API gaps: no `groupNorm_apply` / norm and `dist g h = wordLength (g⁻¹ * h)` lemmas for `normedGroup`; no minimality characterisation of `IsGeodesic`; no generator-length lemmas (`wordLength (P.val i) ≤ 1`); no compatibility with `Generators.reindex`/`map`; no comparison with `FreeGroup.norm` or `CoxeterSystem.length`. Also 'less or equal' in `wordLength_le_iff`'s docstring.","fix":"Add the evaluation and characterisation lemmas; 'less than or equal'.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261007-4944e6","file":"Mathlib/GroupTheory/GroupAction/SubMulAction/Combination.lean","decl":"(file)","line":22,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"module-doc-stale","claim":"The module docstring cites `Set.powerSetCard.mulActionHom_of_embedding` (capital `S` in `powerSetCard`) and describes `Set.powersetCard.compl` as 'an equivariant map', while the equivariant map in this file is `mulActionHom_compl` (`compl` lives in `Data/Set/PowersetCard`); it lists neither the preprimitivity results nor `fixedPoints_ne_univ_of_faithfulSMul`. The `isPretransitive_alternatingGroup` docstring says 'transitively' although the statement includes empty combination spaces ('pretransitively'); smaller slips: `Finsetα` in the additive `subMulAction` docstring, 'aka arrangement' (singular), 'a consequence that' in `isPreprimitive_perm`, and its last proof comment reads `Nat.card α ≠ 2 * s` for `2 * n` (Astra A1 items 20-22). Most theorems (`coe_smul`, `stabilizer_coe`, `mulAction_faithful`, `isPretransitive*`, the `mulActionHom_compl` lemmas, `fixedPoints_ne_univ_of_faithfulSMul`, `mulActionHom_singleton_bijective`) have no docstring.","fix":"Fix the two names in the module docstring, list the main results, and add one-line docstrings.","ev":"Doc-only finding: L22 `Set.powerSetCard.mulActionHom_of_embedding`; L31-33 `Set.powersetCard.compl … equivariant map`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-7201d8","file":"Mathlib/GroupTheory/GroupAction/SubMulAction/Combination.lean","decl":"(file)","line":48,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"section-scaffolding-and-heavy-import","claim":"The outer `variable … {s : powersetCard α n}` is unused, `include hm` is redundant (every statement in that section mentions `hm`), several declarations re-bind the section's `{n : ℕ}`, and the generic action API (`subMulAction`, the embedding and singleton maps) imports `Alternating.MaximalSubgroups` (and through it the permutation maximal-subgroup and Jordan theory) only for the primitivity applications at the end of the file.","fix":"Drop the unused variable and `include hm`, stop re-binding `n`, and split the primitivity results into a separate file so the basic action API does not import the maximal-subgroup theory.","ev":"Hygiene-only finding: L48-49 `{s : powersetCard α n}`, L152 `include hm`, L69/L74/L186/L221/L279 re-bind `n`; L10 `public import Mathlib.GroupTheory.SpecificGroups.Alternating.MaximalSubgroups`. Raised by Astra's A1 pass (items 23-24).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-8ecb76","file":"Mathlib/GroupTheory/GroupAction/SubMulAction/Combination.lean","decl":"mulAction_faithful","line":80,"sev":"NIT","status":"confirmed","cat":"api","pattern":"inconsistent-cardinality-api","claim":"Cardinality hypotheses are inconsistent across the file: `mulAction_faithful` and `faithfulSMul` use `n < ENat.card α`, while `fixedPoints_ne_univ_of_faithfulSMul`, `isPreprimitive_perm`, `isPretransitive_alternatingGroup` and `isPreprimitive_alternatingGroup` use `Nat.card α` (and `fixedPoints_ne_univ_of_faithfulSMul` converts back with `ENat.card_eq_coe_natCard`); positivity is spelled `1 ≤ n`, `0 < n` and `3 ≤ n`.","fix":"Use `ENat.card` where infinite types make sense and one positivity spelling (`1 ≤ n`).","ev":"API-shape finding: L80, L101 (`ENat.card`); L187, L221, L252, L280 (`Nat.card`); L80/L187/L280 (`1 ≤ n`/`0 < n`/`3 ≤ n`).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-a33d96","file":"Mathlib/GroupTheory/GroupAction/SubMulAction/Combination.lean","decl":"mulActionHom_of_embedding","line":115,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"def-snake-case","claim":"The data-valued definitions `mulActionHom_of_embedding`, `mulActionHom_compl` and `mulActionHom_singleton` (and their additive versions) use underscores instead of lowerCamelCase; all five are listed as `defsWithUnderscore` exceptions in `scripts/nolints.json`, so this is a known style exception. The additive name `isPretransitive_of_isMultiplyPretransitive'` (a prime instead of an `add` name) is also unusual.","fix":"Rename to `mulActionHomOfEmbedding`, `mulActionHomCompl`, `mulActionHomSingleton` (deprecated aliases) and drop the nolints entries.","ev":"Name-only finding: scripts/nolints.json L399-403 exempt the five defs; L139 `@[to_additive isPretransitive_of_isMultiplyPretransitive']`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-72941a","file":"Mathlib/GroupTheory/GroupAction/SubMulAction/Combination.lean","decl":"mulActionHom_compl_bijective","line":176,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"reproves-existing-lemma","claim":"Three lemmas re-prove what the underlying equivalences already give: `mulActionHom_of_embedding_surjective` repeats `ofFinEmb_surjective`, `mulActionHom_compl_bijective` rebuilds an inverse although `compl hm` is an `Equiv` (`(compl hm).bijective`), and `mulActionHom_singleton_bijective` re-proves `ofSingleton.bijective`; each is a one-term proof.","fix":"Use `ofFinEmb_surjective n α`, `(compl hm).bijective` and `ofSingleton.bijective` as the proofs.","ev":"hunts/submulaction-combination/probe3.lean: the three one-term proofs compile. Exit 0. Raised by Astra's A1 pass (items 6-8).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-9cd767","file":"Mathlib/GroupTheory/GroupAction/SubMulAction/Combination.lean","decl":"fixedPoints_ne_univ_of_faithfulSMul","line":197,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"formatting","claim":"L197 is mis-indented (`·   simpa …`, three spaces after the bullet) and the proof closes its side goals in an order that only works because `rwa … at h` leaves an injectivity goal before the `have`; the structure is hard to follow.","fix":"Indent the bullet normally and prove the injectivity goal explicitly before `rwa`.","ev":"Hygiene-only finding: L194-197.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-9e50da","file":"Mathlib/GroupTheory/GroupAction/SubMulAction/Combination.lean","decl":"mulActionHom_singleton","line":203,"sev":"NIT","status":"suspected","cat":"api","pattern":"api-gaps","claim":"Smaller API gaps raised by Astra and not tested here: `mulActionHom_singleton` is `noncomputable` only because it reuses the `ofSingleton` equivalence (the forward map `a ↦ ⟨{a}, card_singleton a⟩` is computable); the complement maps and `fixedPoints_ne_univ_of_faithfulSMul` lack the `to_additive` versions the rest of the file has; the unconditional `isPretransitive` is not an instance; `mulAction_faithful` states equality of action kernels rather than faithfulness (`toPerm_eq_one_iff` would describe it) and `isPretransitive` omits the acting group (`isPretransitive_perm`).","fix":"Make `mulActionHom_singleton` computable, add the missing `to_additive` attributes, register `isPretransitive` as an instance, and rename the two theorems with deprecated aliases.","ev":"Suspected: Astra's A1 items 11, 16, 17, 19; not compiled here.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261006-356297","file":"Mathlib/Lean/Meta/KAbstractPositions.lean","decl":"Lean.Meta.viewKAbstractSubExpr","line":73,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-omission","claim":"The contracts are under-documented. The `kabstractPositions` docstring ('the positions that `kabstract` would abstract') describes neither its occurrence-selection semantics nor its head-index filter. `viewKAbstractSubExpr` does not say that the occurrence number refers to the returned concrete pattern under the same transparency, or what the nested `Option` means. The non-canonical position `0` reaches `unreachable!`. `kabstractPositions` takes `(p e)`, the reverse of `kabstract`'s `(e p)`, and both arguments are `Expr`, so swapping them silently type-checks.","fix":"Document the semantics and preconditions, reject non-canonical positions with an error, and consider `(e p)` argument order.","ev":"src L34-36, L70-79 (`| unreachable!`), L91.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-8827c7","file":"Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean","decl":"(file)","line":44,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"duplicate-open","claim":"`open Set Function Module Module` (L44) opens `Module` twice; the comment at L107 reads \"mus be smaller\".","fix":"`open Set Function Module`; fix the typo.","ev":"Source L44, L107.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-0b8cd0","file":"Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean","decl":"Module.End.exists_eigenvalue","line":60,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-omits-hypothesis","claim":"The docstring of `exists_eigenvalue` (and its module-summary bullet) says every endomorphism of a finite-dimensional space over an algebraically closed field has an eigenvalue, omitting the `[Nontrivial V]` the statement correctly assumes (the zero space has none). The module TODO's \"maximal chain of invariant subspaces\" also defines nothing: such a chain exists for every endomorphism (e.g. rotation of ℝ², whose only invariant subspaces are `⊥`, `⊤`); a complete invariant flag is meant.","fix":"Say \"of a nonzero finite-dimensional space\"; reword the TODO as a complete flag of invariant subspaces.","ev":"Source L18–19, L33–35, L60–62.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-ac8505","file":"Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean","decl":"Submodule.inf_iSup_genEigenspace","line":144,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"backward-compat-set-option","claim":"`inf_iSup_genEigenspace` needs `set_option backward.isDefEq.respectTransparency.types false in` (L144): without it the `rw [LinearMap.ker_noncommProd_eq_of_supIndep_ker, …]` at L202 fails to see the `let g := … noncommProd …` through the `ker`. The proof relies on a backward-compatibility switch rather than unfolding `g` explicitly.","fix":"Unfold `g` before the rewrite (e.g. `simp only [g]` or `set` with an equation) so the option can go.","ev":"NoOpt.lean (src.lean minus L144): error at its L201: `rewrite` failed, did not find `(Finset.noncommProd ?s ?m ?comm).ker` in `Disjoint ((f.genEigenspace μ) k) (LinearMap.ker g)`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-af1e1f","file":"Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean","decl":"Submodule.eq_iSup_inf_genEigenspace","line":226,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-theorem-docstring","claim":"Three public theorems have no docstring: `exists_hasEigenvalue_of_genEigenspace_eq_top`, `Submodule.inf_iSup_genEigenspace` (the key distributivity result, used by `genEigenspace_restrict_eq_top`) and `Submodule.eq_iSup_inf_genEigenspace`. The module docstring does not mention them either.","fix":"Add one-line docstrings.","ev":"Source L51, L145, L226.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-82e3fb","file":"Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean","decl":"Module.End.genEigenspace_restrict_eq_top","line":235,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-drops-isup","claim":"`Module.End.genEigenspace_restrict_eq_top` and `Module.End.exists_hasEigenvalue_of_genEigenspace_eq_top` drop the `iSup_` of their statement: the first concludes `⨆ μ, genEigenspace (f.restrict h) μ k = ⊤`, the second assumes `⨆ μ, f.genEigenspace μ k = ⊤`, while the sibling `iSup_maxGenEigenspace_eq_top` keeps it. Read literally, the names claim a single generalized eigenspace is `⊤`.","fix":"Rename to `iSup_genEigenspace_restrict_eq_top` (the name the module docstring already uses) and `exists_hasEigenvalue_of_iSup_genEigenspace_eq_top`, with deprecated aliases.","ev":"Source L51–52, L235–238; uses at `Algebra/Lie/Weights/Basic.lean:760`, `LinearAlgebra/Eigenspace/Pi.lean:171`, `Algebra/Lie/LieTheorem.lean:181`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-cc17e7","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.charmatrix","line":49,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-universe-declaration","claim":"File-level leftover just above this declaration: `universe u v w` (line 34) is unused — every type binder in the file is `Type*` and nothing mentions `u`, `v`, `w` as universes (the only `u v` are the term variables of charpoly_vecMulVec). A copy of the file with the line deleted compiles with no errors or warnings under Mathlib's options. Also a doubled blank line at lines 44–45.","fix":"Delete `universe u v w` (and one of the two blank lines before the `charmatrix` docstring).","ev":"batch0/probe2_nouniverse.lean = src.lean with line 34 `universe u v w` removed; `lake env lean -DautoImplicit=false -DmaxSynthPendingDepth=3 -Dweak.linter.mathlibStandardSet=true batch0/probe2_nouniverse.lean` -> exit 0, no messages (log batch0/probe2.log)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b1ed15","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.charmatrix","line":49,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"module-doc-omits-definition","claim":"The module docstring's `## Main definitions` (lines 21–23) lists only `Matrix.charpoly`; the public `@[expose]` definition `Matrix.charmatrix`, which other files use directly (Charpoly/Coeff.lean, Charpoly/FiniteField.lean, Charpoly/Univ.lean, RingTheory/Norm/Transitivity.lean), is not mentioned.","fix":"Add `* \\`Matrix.charmatrix\\` is the characteristic matrix \\`t I - M\\` of a matrix.` to the module docstring's Main definitions.","ev":"src.lean lines 21-23: `## Main definitions` / `* \\`Matrix.charpoly\\` is the characteristic polynomial of a matrix.`; `git grep -n charmatrix origin/master -- Mathlib` hits Coeff.lean:55,152,235,273,301, FiniteField.lean:42, Univ.lean:90, RingTheory/Norm/Transitivity.lean:106","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-1e8d0a","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.charmatrix_zero","line":67,"sev":"NIT","status":"confirmed","cat":"api","pattern":"simp-rhs-not-normal-form","claim":"The `@[simp]` lemma's right-hand side `Matrix.scalar n X` is not in simp normal form: `Matrix.scalar_apply : scalar n a = diagonal fun _ => a` is `@[simp]` (Mathlib/Data/Matrix/Basic.lean:196-197), so simp always rewrites one step further (`simp?` on `charmatrix 0 = diagonal fun _ => X` reports `simp only [charmatrix_zero, scalar_apply]`). Its siblings charmatrix_diagonal/_one/_natCast/_ofNat all state the RHS as a `diagonal`. No file cites `charmatrix_zero` by name, so restating is free.","fix":"State it as `charmatrix (0 : Matrix n n R) = diagonal fun _ => X`.","ev":"batch0/probe1.lean C1:\nexample : charmatrix (0 : Matrix n n R) = diagonal fun _ => X := by simp?\n-- Try this: [apply] simp only [charmatrix_zero, scalar_apply]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-54082c","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.charmatrix_fromBlocks","line":117,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unary-minus-spacing","claim":"The statement writes unary minus with a space, `(- M₁₂.map C)` and `(- M₂₁.map C)`; Mathlib style is `-x` (git grep on origin/master: 104 lines with `(- x` against 4361 with `(-x`).","fix":"Write `(-M₁₂.map C)` and `(-M₂₁.map C)`.","ev":"git -C mathlib4 grep -cE \"\\(- [A-Za-z(]\" origin/master -- 'Mathlib/*.lean' (sum 104) vs grep -cE \"\\(-[A-Za-z(]\" (sum 4361); src.lean:117","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-163553","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.BlockTriangular.charpoly","line":121,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"stale-todo","claim":"The TODO at L121-122 was added in the same commit as this lemma (cc5969c1690). It says the Block import is 'somewhat expensive' and proposes moving block-triangular lemmas such as this one into `Charpoly/Block.lean`. That premise no longer holds. The file needs `Mathlib.LinearAlgebra.Matrix.NonsingularInverse` anyway, for the `⁻¹` in `charpoly_units_conj`. I removed the block-triangular lemmas from a copy and replaced the Block import with NonsingularInverse. That copy compiles with 3619 transitive modules, against 3622 for the file as it stands, so the move would save 3 modules. This lemma is therefore in the right file, and the TODO is stale.","fix":"Delete the TODO comment at L121-122; leave the block-triangular lemmas in this file.","ev":"batch2/Copy3.lean is src plus an `#eval` of `env.header.moduleNames.size`; it prints 'src modules: 3622; Block: true'. batch2/Copy2b.lean is src without charmatrix_blockTriangular_iff and its alias, BlockTriangular.charpoly, and charpoly_of_isUpperTriangular and its alias, with `public import Mathlib.LinearAlgebra.Matrix.Block` replaced by `public import Mathlib.LinearAlgebra.Matrix.NonsingularInverse`. It compiles cleanly and prints 'Copy2b modules: 3619; Block: false'.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-9d635f","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.eval_charpoly","line":136,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-bypasses-existing-api","claim":"The 5-line proof (← coe_evalRingHom, RingHom.map_det, congr, ext, `obtain rfl | hij ... <;> simp [*]`) re-derives what `eval_det (M : Matrix n n R[X]) (r : R) : Polynomial.eval r M.det = (Polynomial.eval (scalar n r) (matPolyEquiv M)).det` (Mathlib/RingTheory/MatrixPolynomialAlgebra.lean:157, imported) plus `matPolyEquiv_charmatrix` (L93) give in one line; it also uses the `simp [*]` smell.","fix":"Replace the proof by `by simp [charpoly, eval_det, matPolyEquiv_charmatrix]`.","ev":"hunts/charpoly-basic/batch1/probe1.lean (P2) and hunts/charpoly-basic/batch1/CopyA.lean (in-file):\nexample (M : Matrix m m R) (t : R) : M.charpoly.eval t = (scalar m t - M).det := by\n  simp [charpoly, eval_det, matPolyEquiv_charmatrix]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-780032","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.charpoly_reindex","line":169,"sev":"NIT","status":"confirmed","cat":"api","pattern":"inconsistent-argument-order","claim":"The adjacent pair takes its explicit arguments in opposite orders: `charmatrix_reindex (M : Matrix n n R) (e : n ≃ m)` (M from the `variable` line, then e) but `charpoly_reindex (e : n ≃ m) (M : Matrix n n R)`.","fix":"Use one order for both (e.g. `(e) (M)` as in `det_reindex_self`).","ev":"-- hunts/charpoly-basic/lead/P.lean\n#check @Matrix.charmatrix_reindex  -- ... (M : Matrix n n R) (e : n ≃ m), ...\n#check @Matrix.charpoly_reindex    -- ... (e : n ≃ m) (M : Matrix n n R), ...","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-261b70","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.charpoly_fromBlocks_zero₁₂","line":181,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-parentheses","claim":"The right-hand side is wrapped in redundant parentheses: `= (M₁₁.charpoly * M₂₂.charpoly)`.","fix":"Write `= M₁₁.charpoly * M₂₂.charpoly`.","ev":"batch2/Copy.lean L199-200: the statement compiles without the parentheses (exit 0). The parentheses are at src.lean L181.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b9f2e7","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.charpoly_fromBlocks_zero₂₁","line":187,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-parentheses","claim":"The right-hand side is wrapped in redundant parentheses: `= (M₁₁.charpoly * M₂₂.charpoly)`.","fix":"Write `= M₁₁.charpoly * M₂₂.charpoly`.","ev":"batch2/Copy.lean L205-206: the statement compiles without the parentheses (exit 0). The parentheses are at src.lean L187.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-e23801","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Matrix.charpoly_mul_comm'","line":242,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"backward-compat-option-removable","claim":"The proof as written still needs `set_option backward.defeqAttrib.useBackward true in`. Removing the option alone breaks the final `rw` at line 263: `dsimp only [charpoly, charmatrix, RingHom.mapMatrix_apply]` no longer turns `C.mapMatrix (A * B)` into `(A * B).map ⇑C`, so the pattern from `hdet_NM` does not match. Writing `simp only` in place of `dsimp only` on line 262 removes the need for the option. This is the only use of the option under Mathlib/LinearAlgebra/Matrix; Mathlib-wide there are 4106 uses in 1076 files.","fix":"Replace `dsimp only [charpoly, charmatrix, RingHom.mapMatrix_apply]` with `simp only [charpoly, charmatrix, RingHom.mapMatrix_apply]` and delete the `set_option backward.defeqAttrib.useBackward true in` line.","ev":"hunts/charpoly-basic/batch3/Copy_noBackward.lean (option removed, nothing else changed; diff in Copy_noBackward.diff) fails with `265:54: error: Tactic rewrite failed: Did not find an occurrence of the pattern (-1) ^ (card m + card n) * (X ^ card m * (scalar n X - (B * A).map ⇑C).det)`. hunts/charpoly-basic/batch3/Copy_mulCommA.lean (option removed and `dsimp only` -> `simp only`; Copy_mulCommA.diff) compiles with exit 0 and no diagnostics. So does Copy_mulCommC.lean (`dsimp only [charpoly, charmatrix]; rw [RingHom.mapMatrix_apply, RingHom.mapMatrix_apply]`). `git grep -c backward.defeqAttrib.useBackward origin/master -- Mathlib`: 1076 files, 4106 occurrences, 1 of them in LinearAlgebra/Matrix.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-e907d3","file":"Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean","decl":"Algebra.aeval_charpoly_leftMulMatrix","line":306,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"This is the same shape as `Matrix.aeval_self_charpoly` (an element is a root of a charpoly), and it is not `@[simp]` either. `simp` makes no progress on `aeval a (Algebra.leftMulMatrix b a).charpoly = 0`. A `@[simp]`-tagged copy passes simpNF and lets `simp` close `aeval a (p * (leftMulMatrix b a).charpoly) = 0`.","fix":"Tag `Algebra.aeval_charpoly_leftMulMatrix` with `@[simp]`, together with `Matrix.aeval_self_charpoly`.","ev":"hunts/charpoly-basic/batch3/probe1.lean lines 32-35: `fail_if_success (simp; done); exact Algebra.aeval_charpoly_leftMulMatrix b a` compiles, and `done` is reported as never executed. hunts/charpoly-basic/batch3/probe2.lean: the `@[simp]` copy `aeval_charpoly_leftMulMatrix_simp` and `example ... : aeval a (p * (Algebra.leftMulMatrix b a).charpoly) = 0 := by simp` compile, and `#lint only simpNF` prints 'All linting checks passed!'.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-52a2af","file":"Mathlib/LinearAlgebra/Matrix/Polynomial.lean","decl":"(file)","line":10,"sev":"NIT","status":"suspected","cat":"hygiene","pattern":"public-import-only-used-in-proofs","claim":"`public import Mathlib.Tactic.ComputeDegree` re-exports a tactic used only inside two proofs (L59, L83); a private `import` may suffice (Astra A1 item 10, not compiled here since it needs a module-system build of the file and its importers).","fix":"Change to `import Mathlib.Tactic.ComputeDegree` and build the module and Adjugate.lean.","ev":"Suspected: Astra A1 item 10; not compiled.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-ccb129","file":"Mathlib/LinearAlgebra/Matrix/Polynomial.lean","decl":"(file)","line":31,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"duplicate-open","claim":"`open Matrix Polynomial` (L31) is repeated as `open Polynomial Matrix Equiv.Perm` (L35), and `public section` is followed by two blank lines (L29-30).","fix":"Merge into one `open Matrix Polynomial Equiv.Perm` and drop the extra blank line.","ev":"Measured: L31 and L35 of the audited file.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-29c3d0","file":"Mathlib/LinearAlgebra/Matrix/Polynomial.lean","decl":"natDegree_det_X_add_C_le","line":39,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-omits-operation","claim":"The names `natDegree_det_X_add_C_le`, `coeff_det_X_add_C_zero`, `coeff_det_X_add_C_card` and `leadingCoeff_det_X_one_add_C` omit the scalar multiplication: the polynomial is `det (X • A.map C + B.map C)`, so `X_add_C` reads like the identity specialisation `X + C` (Astra A1 item 8).","fix":"`natDegree_det_X_smul_add_C_le` etc., with deprecated aliases.","ev":"Measured: statements at L40, L62, L72, L86 all have `(X : α[X]) • _`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-3e9db1","file":"Mathlib/LinearAlgebra/Matrix/Polynomial.lean","decl":"coeff_det_X_add_C_zero","line":61,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-detour","claim":"`coeff_det_X_add_C_zero` has an 8-line permutation-sum proof; evaluating at `0` gives it directly: `rw [coeff_zero_eq_eval_zero, ← coe_evalRingHom, RingHom.map_det]; congr 1; ext; simp`. The general form `(det M).coeff 0 = det (M.map (coeff · 0))` for every polynomial matrix is the one-liner `constantCoeff.map_det M` (Astra A1 item 1).","fix":"Use the evaluation-at-zero proof.","ev":"hunts/matrix-polynomial/probe1.lean: `coeff_det_X_add_C_zero'` with the 4-line proof and the general `example (M : Matrix n n α[X]) : (det M).coeff 0 = det (M.map fun p => p.coeff 0) := (constantCoeff (R := α)).map_det M` compile, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-92bb5a","file":"Mathlib/LinearAlgebra/Matrix/Polynomial.lean","decl":"coeff_det_X_add_C_card","line":71,"sev":"NIT","status":"suspected","cat":"proof","pattern":"convert-heavy-proof","claim":"`coeff_det_X_add_C_card` reaches `coeff_prod_of_natDegree_le` at degree bound 1 through `convert`, a backwards `← mul_one (Fintype.card n)` rewrite and `convert!` with four anonymous arguments; an explicit instantiation would read better (Astra A1 item 5, readability only).","fix":"Instantiate `coeff_prod_of_natDegree_le Finset.univ _ 1` explicitly and finish with `simpa`.","ev":"Suspected: Astra A1 item 5; not compiled.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261006-75b454","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.prod","line":37,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-universe-declaration","claim":"`universe u v w` is declared but never used: every type in the file is `Type*`, and the `v w` on line 181 are term binders.","fix":"Delete the line `universe u v w`.","ev":"batch0/Prod_fix.lean (src.lean with the line removed) compiles with no errors or warnings under -Dlinter.mathlibStandardSet=true; `grep -nE 'Type [uvw]|\\.\\{' src.lean` finds no use.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-5954d9","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.IsometryEquiv.prod","line":61,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"equiv-congr-naming","claim":"The product of two equivalences is called `prodCongr` everywhere else in Mathlib: `LinearEquiv.prodCongr` (LinearAlgebra/Prod.lean:774), `ContinuousLinearEquiv.prodCongr` (Topology/Algebra/Module/Equiv/Prod.lean:38), `MulEquiv.prodCongr` (Algebra/Group/Prod.lean:577), `AlgEquiv.prodCongr` (Algebra/Algebra/Prod.lean:125) and `RingEquiv.prodCongr` (Algebra/Ring/Equiv.lean:576). `IsometryEquiv.prod` breaks this convention, even though its own `toLinearEquiv` is `LinearEquiv.prodCongr`.","fix":"Rename it to `IsometryEquiv.prodCongr`, with a `@[deprecated]` alias `prod`.","ev":"git -C mathlib4 grep -nE '^(protected )?def (prodCongr|prod)\\b' origin/master -- Mathlib (the hits above)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c15203","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.Isometry.inr","line":79,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"misleading-binder-name","claim":"Copy-paste binder names: `map_app' m₁` names an element of `M₂` in `Isometry.inr` (line 79) and an element of `M₁ × M₂` in `Isometry.fst` (line 86) and `Isometry.snd` (line 93).","fix":"Rename the binders to `m₂` (in `inr`) and `x` (in `fst` and `snd`), or to `_`.","ev":"src.lean lines 79, 86 and 93: `map_app' m₁ := by simp`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-54bdc9","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.anisotropic_of_prod","line":139,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"golfable-proof","claim":"The 9-line tactic proof (a `simp_rw … at h` followed by two near-identical bullets) can be replaced by a 2-line term proof.","fix":"Replace the proof with `⟨fun x hx => congr_arg Prod.fst (h (x, 0) (by simp [hx])), fun x hx => congr_arg Prod.snd (h (0, x) (by simp [hx]))⟩`.","ev":"batch0/probe1.lean E1 `example (h : (Q₁.prod Q₂).Anisotropic) : Q₁.Anisotropic ∧ Q₂.Anisotropic := ⟨fun x hx => congr_arg Prod.fst (h (x, 0) (by simp [hx])), fun x hx => congr_arg Prod.snd (h (0, x) (by simp [hx]))⟩` compiles; the same replacement compiles in batch0/Prod_fix.lean together with downstream `posDef_prod_iff`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-318aeb","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.IsOrtho.inl_inr","line":188,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"proof-term-misindented","claim":"The proof term is indented 6 spaces (Mathlib style puts a term proof on the next line at 2 spaces) and is fully qualified as `QuadraticMap.IsOrtho.prod` inside `namespace QuadraticMap`.","fix":"Write `  .prod (.zero_right _) (.zero_left _)` at 2-space indentation (or `IsOrtho.prod ...`).","ev":"src.lean line 188: '      QuadraticMap.IsOrtho.prod (.zero_right _) (.zero_left _)' (6 leading spaces), inside `namespace QuadraticMap` (line 42).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-035577","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.polar_prod","line":212,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"avoidable-backward-compat-option","claim":"`polar_prod` carries the migration shim `set_option backward.defeqAttrib.useBackward true in`, needed only because the proof uses `dsimp [polar]`; a `simp only` proof needs no option. (Dropping the option from the current proof fails, so it is not dead, just avoidable.)","fix":"Drop the `set_option` and prove it by `simp only [polar, prod_apply, Prod.fst_add, Prod.snd_add]; abel`.","ev":"batch1/Probe1.lean (compiles, no option): example (Q₁ : QuadraticMap R M₁ P) (Q₂ : QuadraticMap R M₂ P) (x y : M₁ × M₂) : polar (Q₁.prod Q₂) x y = polar Q₁ x.1 y.1 + polar Q₂ x.2 y.2 := by simp only [polar, prod_apply, Prod.fst_add, Prod.snd_add]; abel. batch1/ProdCopy.lean: removing only the set_option from the original `dsimp [polar]; abel` proof gives 'unsolved goals' at line 213.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-02be00","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.associated_prod","line":229,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-unfolds-def-instead-of-api","claim":"The proof unfolds the definitions `associated`/`associatedHom` with `dsimp` and closes with `rfl` (defeq through the definition of `associatedHom`), where existing API gives a one-line rewrite proof from `associated_comp` and linearity.","fix":"Replace the proof with `rw [prod, map_add, associated_comp, associated_comp]`.","ev":"batch1/Probe1.lean, example (A2-style, under [Invertible (2 : R)]) and theorem associatedHom_prod: `:= by rw [prod, map_add, associated_comp, associated_comp]` closes the exact `associated_prod` statement.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ae8770","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.Isometry.proj_comp_single_of_same","line":289,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"of-in-name-without-hypothesis","claim":"`proj_comp_single_of_same` has no hypothesis, so the `_of_` misreads. The `LinearMap` lemmas it lifts are `LinearMap.proj_comp_single_same` and `LinearMap.proj_comp_single_ne` (Mathlib/LinearAlgebra/Pi.lean:189,192).","fix":"Rename to `Isometry.proj_comp_single_same` (deprecated alias), optionally `proj_comp_single_of_ne` → `proj_comp_single_ne` to match LinearMap.","ev":"git grep on origin/master: Mathlib/LinearAlgebra/Pi.lean:189 `theorem proj_comp_single_same (i : ι) : (proj i).comp (single R φ i) = id`, :192 `theorem proj_comp_single_ne (i j : ι) (h : i ≠ j) : (proj i).comp (single R φ j) = 0`; Prod.lean:289 `theorem Isometry.proj_comp_single_of_same … (i : ι) (Q …)` takes no hypothesis.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-0e08c5","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.nonneg_pi_iff","line":321,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-rebinding-shadows-section-variable","claim":"`nonneg_pi_iff` and `posDef_pi_iff` re-bind `{P} [AddCommMonoid P] … [Module R P]`, shadowing the section's `P` and its `[AddCommMonoid P] [Module R P]` variables (L39, L241-242). This looks like a leftover from the bundled `OrderedAddCommMonoid P` era. The prod analogues just add the order classes. Deleting the re-binding changes nothing else.","fix":"Delete `{P}`, `[AddCommMonoid P]` and `[Module R P]` from both signatures.","ev":"batch2/Prod_mod.lean L327 and L340: both signatures without the re-binding; the whole file compiles, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-5f33c7","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.posDef_pi_iff","line":335,"sev":"NIT","status":"confirmed","cat":"generality","pattern":"pi-variant-stronger-order-classes-than-prod","claim":"`posDef_pi_iff` assumes `[IsOrderedAddMonoid P]`, whereas `posDef_prod_iff` assumes `[AddLeftMono P]`. With `PartialOrder` (which `PosDef` itself needs), `AddLeftMono` suffices: one `have := IsOrderedAddMonoid.of_addLeftMono` in front of the existing proof. The two classes are equivalent on a commutative monoid, so this only aligns the assumptions and gains no new models.","fix":"State `posDef_pi_iff` with `[PartialOrder P] [AddLeftMono P]` and add `have := IsOrderedAddMonoid.of_addLeftMono (α := P)` at the start of the proof.","ev":"batch2/probe1.lean G2 (L84-97) compiles; batch2/Prod_mod.lean L340-342 in-file, whole file compiles (exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d02450","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.Ring.polar_pi","line":351,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"accidental-namespace-instead-of-section","claim":"L351 opens `namespace Ring` rather than `section Ring`. The pi polar lemmas are therefore named `QuadraticMap.Ring.polar_pi`, `QuadraticMap.Ring.polarBilin_pi` and `QuadraticMap.Ring.associated_pi`, while their prod analogues are `QuadraticMap.polar_prod` etc. (the prod part uses `section Ring`, L206). `QuadraticMap.polar_pi` is an unknown constant. With `section Ring` the names become `QuadraticMap.*` and the file compiles. Nothing in Mathlib refers to the `Ring.` names.","fix":"Change `namespace Ring` to `section Ring` (L351), adding deprecated aliases `QuadraticMap.Ring.polar_pi` etc.","ev":"batch2/probe1.lean L7-14: `#check @QuadraticMap.Ring.polar_pi` (and polarBilin_pi, associated_pi) succeed, `#check @QuadraticMap.polar_pi`/`polarBilin_pi`/`associated_pi` -> 'Unknown constant'; batch2/Prod_mod.lean L356 `section Ring` -> `#check @QuadraticMap.polar_pi` etc. succeed, file exit 0; `git grep -E 'polar_pi|polarBilin_pi|associated_pi' origin/master -- Mathlib` hits only Prod.lean.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-cf34dd","file":"Mathlib/LinearAlgebra/QuadraticForm/Prod.lean","decl":"QuadraticMap.Ring.polar_pi","line":356,"sev":"NIT","status":"confirmed","cat":"generality","pattern":"commring-where-commsemiring-suffices","claim":"`polar_pi` holds under `[CommSemiring R]`, with the file's proof verbatim. `polar` needs only additive groups, not `CommRing R`; the `CommRing` comes from the section. This is low value: Basic.lean's own `QuadraticMap` polar lemmas also sit in `CommRing` sections.","fix":"Optionally move `polar_pi` (and `polar_prod`) to a `CommSemiring` section with `AddCommGroup` domains and codomain.","ev":"batch2/probe1.lean G4 (L118-121): `theorem polar_pi' [CommSemiring R] [∀ i, AddCommGroup (Mᵢ i)] [AddCommGroup P] … : polar (pi Q) x y = ∑ i, polar (Q i) (x i) (y i)` with `dsimp [polar]; simp_rw [Finset.sum_sub_distrib, pi_apply, Pi.add_apply]` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-fbb4da","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct","line":16,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"module-docstring-wrong-hypotheses","claim":"The module docstring that introduces `TensorProduct R M N` says \"Given a semiring `R` and modules over it `M` and `N`\". The construction requires `[CommSemiring R]`, as do the module title and the docstring of `TensorProduct`.","fix":"Say \"Given a commutative semiring `R`\".","ev":"src.lean L16: \"Given a semiring `R`\"; p1_basic.lean `#check @TensorProduct` : (R : Type u_1) → [inst : CommSemiring R] → (M N : Type*) → ...","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-54ab77","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.instance@L108","line":107,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-typo","claim":"The `Repr` docstring reads `mₒ ⊗ₜ n₀ + ...`. The first subscript is U+2092 LATIN SUBSCRIPT SMALL LETTER O, not U+2080 SUBSCRIPT ZERO, so it is inconsistent with `n₀`. The instance itself works: #eval prints `1 ⊗ₜ 2 + 3 ⊗ₜ 4`, `0`, `some (1 ⊗ₜ 2 + 3 ⊗ₜ 4)`, `1 ⊗ₜ (2 ⊗ₜ 5)`.","fix":"Replace `mₒ` with `m₀` in the docstring.","ev":"sed -n 107p src.lean | python3 (unicodedata.name per char): 'ₒ' 0x2092 LATIN SUBSCRIPT SMALL LETTER O ... '₀' 0x2080 SUBSCRIPT ZERO","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-31965a","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.inductionOn","line":141,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"superfluous-simpa","claim":"The `add` step `fun ⟨m, n⟩ y ih => by simpa using! add _ _ (tmul ..) ih` runs `simp` and then closes at default transparency (plain `simpa using` fails there). The bare term `add _ _ (tmul m n) ih` already typechecks, so the `simpa using!` is superfluous. The zero step's `simpa using!` does real work (zero_tmul) and is fine.","fix":"Replace the second `by simpa using! add _ _ (tmul ..) ih` with the term `add _ _ (tmul m n) ih`.","ev":"-- hunts/tensor-defs/batch0/p4_proof.lean (compiles, no output)\ntheorem inductionOn_alt {motive : M ⊗[R] N → Prop} (z : M ⊗[R] N)\n    (tmul : ∀ x y, motive <| x ⊗ₜ[R] y)\n    (add : ∀ x y, motive x → motive y → motive (x + y)) : motive z :=\n  AddCon.induction_on z fun x =>\n    FreeAddMonoid.recOn x (by simpa using! tmul 0 0)\n      fun ⟨m, n⟩ y ih => add _ _ (tmul m n) ih\n-- and copy_simpa.lean (using! -> using) fails at both steps, so the simpa there relies on default-transparency closing","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b4c4c1","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.CompatibleSMul.isScalarTower","line":182,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"conv-instead-of-named-lemma","claim":"The four-line proof (`conv_lhs => rw [← one_smul R m]`, `conv_rhs => rw [← one_smul R n]`, `rw [← smul_assoc, ← smul_assoc]`, `exact …`) is a hand-rolled `smul_one_smul`; `rw [← smul_one_smul R r m, ← smul_one_smul R r n]` followed by the same `exact` compiles.","fix":"Replace the `conv_lhs`/`conv_rhs`/`smul_assoc` steps with `rw [← smul_one_smul R r m, ← smul_one_smul R r n]`.","ev":"⟨fun r m n => by\n    rw [← smul_one_smul R r m, ← smul_one_smul R r n]\n    exact Quotient.sound' <| AddConGen.Rel.of _ _ <| Eqv.of_smul _ _ _⟩  -- in hunts/tensor-defs/batch1/c3_isscalartower_proof.lean (EXIT=0)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-cd3172","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.smul_tmul","line":191,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-typo","claim":"Docstring typo: \"`smul` can be moved from one side of the product to the other .\" (space before the full stop).","fix":"Remove the space before the full stop.","ev":"src.lean L190: /-- `smul` can be moved from one side of the product to the other . -/","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-bcdfcb","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.addMonoidWithWrongNSMul","line":197,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"empty-structure-update","claim":"The body `{ (addConGen (TensorProduct.Eqv R M N)).addMonoid with }` is a structure-instance wrapper with no fields; the bare term `(addConGen (TensorProduct.Eqv R M N)).addMonoid` compiles and the rest of the file (including `SMul.aux_of := rfl`) is unaffected.","fix":"Use `(addConGen (TensorProduct.Eqv R M N)).addMonoid` directly.","ev":"hunts/tensor-defs/batch1/c4a_wrongnsmul_direct.lean (diff: c4a_wrongnsmul_direct.diff; EXIT=0)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-bda498","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.SMul.aux","line":202,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-typo","claim":"Docstring grammar: \"Auxiliary function to defining scalar multiplication on tensor product.\"","fix":"Reword as \"Auxiliary function for defining scalar multiplication on the tensor product.\"","ev":"src.lean L201: /-- Auxiliary function to defining scalar multiplication on tensor product. -/","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-864344","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.leftHasSMul","line":223,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"lean3-has-prefix-name","claim":"`leftHasSMul` keeps the Lean 3 `has_smul` name; the class is `SMul`. Only three `*HasSMul` instance names remain in Mathlib (`colimitHasSMul`, `pointwiseHasSMul`, `leftHasSMul`), and `leftHasSMul` is referenced only twice, both in this file (L223, L242), so a rename is cheap.","fix":"Rename to e.g. `TensorProduct.leftSMul` with a deprecated alias.","ev":"git -C mathlib4 grep -n -E \"(instance|def|abbrev) [A-Za-z_.']*HasSMul\" f0d58cda75 -- Mathlib  -> 3 hits; git grep -n leftHasSMul -> Defs.lean:223, 242 only","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a2a2fc","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.addMonoid","line":269,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"simp-for-direct-term","claim":"`nsmul_zero := by simp [TensorProduct.zero_smul]` and `nsmul_succ := by simp only [TensorProduct.one_smul, TensorProduct.add_smul, forall_const]` (where `forall_const` only clears the leftover `∀ n x, True`) are direct: `nsmul_zero := TensorProduct.zero_smul` and `nsmul_succ n x := by rw [TensorProduct.add_smul, TensorProduct.one_smul]` compile. (These term proofs are also what the `leftHasSMul` diamond fix needs.)","fix":"Use `nsmul_zero := TensorProduct.zero_smul` and `nsmul_succ n x := by rw [TensorProduct.add_smul, TensorProduct.one_smul]`.","ev":"hunts/tensor-defs/batch1/c6_addmonoid_proofs.lean (EXIT=0); without forall_const: hunts/tensor-defs/batch1/c6b_no_forall_const.lean.out (unsolved goal ∀ n x, True)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-581186","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"IsAddUnit.tmul_left","line":277,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"manual-proof-replaceable-by-map","claim":"A 3-line manual proof through isAddUnit_iff_exists_neg; it is `hn.map (mk R M N m)` (IsAddUnit.map along the additive map m ⊗ₜ -). The lemma sits in the middle of the instance-construction block and nothing uses it before `mk`.","fix":"Move the lemma after `mk_apply` and prove it as `hn.map (mk R M N m)`.","ev":"batch2/Probe1.lean (Q2): example {n : N} (hn : IsAddUnit n) (m : M) : IsAddUnit (m ⊗ₜ[R] n) := hn.map (mk R M N m); in place after mk_apply in batch2/SrcEdit.lean.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-f13691","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"IsAddUnit.tmul_right","line":282,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"manual-proof-replaceable-by-map","claim":"As for IsAddUnit.tmul_left: the 3-line manual proof is `hm.map ((mk R M N).flip n)`.","fix":"Move the lemma after `mk_apply` and prove it as `hm.map ((mk R M N).flip n)`.","ev":"batch2/Probe1.lean (Q2): example {m : M} (hm : IsAddUnit m) (n : N) : IsAddUnit (m ⊗ₜ[R] n) := hm.map ((mk R M N).flip n); in place in batch2/SrcEdit.lean.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-031763","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.tmul_eq_smul_one_tmul","line":314,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"positional-nth-rw","claim":"The proof `nth_rw 1 [← mul_one s, ← smul_eq_mul, smul_tmul']` depends on occurrence positions; the forward rewrite `rw [smul_tmul', smul_eq_mul, mul_one]` proves it directly.","fix":"Use `rw [smul_tmul', smul_eq_mul, mul_one]`.","ev":"batch2/Probe1.lean (Q1): example {S : Type*} [Semiring S] [Module R S] [SMulCommClass R S S] (s : S) (m : M) : s ⊗ₜ[R] m = s • (1 ⊗ₜ[R] m) := by rw [smul_tmul', smul_eq_mul, mul_one]; also in place in batch2/SrcEdit.lean.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b18d6b","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.tmul_eq_smul_one_tmul","line":314,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"binder-shadows-unused-section-variable","claim":"The binder `{S : Type*}` shadows the section variable `S` (line 41, with `[AddCommMonoid S]` and `[Module R S]` at lines 42/45). That section `S` (like `A` and `P`) is used by no declaration in the file; this lemma is the only other occurrence of `S`.","fix":"Drop the unused section variables `A P S` and their instances (lines 41-45), so the local `{S : Type*}` no longer shadows anything.","ev":"grep -n -w 'S' src.lean -> lines 41, 42, 45 (section variable and its instances) and 314-315 (this lemma's own binder) only; #check @tmul_eq_smul_one_tmul shows a single S with [Semiring S].","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-162e00","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.isScalarTower_right","line":356,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-omits-load-bearing-hypotheses","claim":"The docstring says '`IsScalarTower R'₂ R' N` implies `IsScalarTower R'₂ R' (M ⊗[R] N)`', but the R'₂- and R'-actions on M ⊗[R] N are the ones defined through M (leftHasSMul), so a tower on N alone says nothing about them; the content is carried by the unmentioned hypotheses `[CompatibleSMul R R'₂ M N] [CompatibleSMul R R' M N]` (the proof rewrites with `tmul_smul` for both).","fix":"Say 'Given `CompatibleSMul R R'₂ M N` and `CompatibleSMul R R' M N`, `IsScalarTower R'₂ R' N` implies `IsScalarTower R'₂ R' (M ⊗[R] N)`'.","ev":"#check @TensorProduct.isScalarTower_right  -- hunts/tensor-defs/batch3/probe1.lean; signature ends: [CompatibleSMul R R'₂ M N] [CompatibleSMul R R' M N] [IsScalarTower R'₂ R' N], IsScalarTower R'₂ R' (M ⊗[R] N)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-33aaf1","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.isScalarTower","line":365,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"stale-mathlib3-name-in-docstring","claim":"The docstring ('the common case, where the requirements for the `compatible_smul` instances are sufficient') names the mathlib3 identifier `compatible_smul` (the class is `TensorProduct.CompatibleSMul`; no Lean 4 declaration has that name) and describes the instance through CompatibleSMul although it is just `isScalarTower_left` at R'₂ := R', R' := R and needs only `IsScalarTower R' R M`. Same stale name in Basic.lean:415-417 (`TensorProduct.compatible_smul`).","fix":"Rewrite as 'Shortcut instance: `isScalarTower_left` with `R'₂ := R'`, `R' := R`.' and fix the matching `compatible_smul` mentions in Basic.lean.","ev":"git -C mathlib4 grep -n compatible_smul origin/master -- Mathlib  -> only Defs.lean:365 and Basic.lean:415,417 (docstrings) plus unrelated algebra_compatible_smul; the instance body is `TensorProduct.isScalarTower_left` (src.lean:368). Removing the instance (batch3/copyB.lean) still elaborates `example [SMul R' R] [IsScalarTower R' R M] : IsScalarTower R' R (M ⊗[R] N) := inferInstance`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-519f1b","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.isScalarTower","line":370,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"detached-port-comment","claim":"Orphan comment `-- or right` on its own line (src.lean:370), between the `isScalarTower` instance and `variable (R M N) in` / the docstring of `mk`. It is a trailing remark on the proof term `isScalarTower_left` that mathport detached (already in the port commit 7b9199f9a6, after the `#align`), so it now reads as a comment about `mk`.","fix":"Delete it, or put it back on the proof line as `-- or `isScalarTower_right``.","ev":"src.lean lines 367-373: `instance isScalarTower … := TensorProduct.isScalarTower_left` / blank / `-- or right` / `variable (R M N) in` / `/-- The canonical bilinear map … -/` ; git show 7b9199f9a6:Mathlib/LinearAlgebra/TensorProduct.lean lines 357-362 show the same detached comment after `#align tensor_product.is_scalar_tower`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ffa23e","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.mk","line":374,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"detour-proof-of-rfl-fact","claim":"The second side condition of `LinearMap.mk₂`, `(c • m) ⊗ₜ n = c • (m ⊗ₜ n)`, holds by `rfl` (it is `smul_tmul'`), but it is proved by `simp_rw [smul_tmul, tmul_smul]`, a detour through two `CompatibleSMul` instance searches that moves the scalar to N and back.","fix":"Replace `(fun c m n => by simp_rw [smul_tmul, tmul_smul])` by `(fun _ _ _ => rfl)`.","ev":"example : (LinearMap.mk₂ R (fun (m : M) (n : N) => m ⊗ₜ[R] n) add_tmul (fun _ _ _ => rfl)\n    tmul_add tmul_smul) = mk R M N := rfl\n-- hunts/tensor-defs/batch3/probe1.lean (P1); also in place in hunts/tensor-defs/batch3/copyB.lean, which compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-44ceba","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.ite_tmul","line":381,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"ite-zero-case-without-zero-in-name","claim":"`ite_tmul` is the zero-else case `(if P then x₁ else 0) ⊗ₜ x₂ = if P then x₁ ⊗ₜ x₂ else 0`, but Mathlib reserves `ite_<op>` for the general two-branch lemma (`ite_mul : (if P then a else b) * c = …`) and names the zero-else case `ite_zero_<op>` (`ite_zero_mul`, `ite_zero_smul`). Long-established name (port), so NIT.","fix":"Rename to `ite_zero_tmul` with a deprecated alias (and optionally add the general `ite_tmul`).","ev":"git grep origin/master: Algebra/Notation/Defs.lean:119 `lemma ite_mul (a b c : α) : (if P then a else b) * c = if P then a * c else b * c`; Algebra/Ring/Defs.lean:196 `lemma ite_zero_mul : ite P a 0 * b = ite P (a * b) 0`; Algebra/GroupWithZero/Action/Defs.lean:219 `lemma ite_zero_smul (a : M₀) (b : A) : (if p then a else 0 : M₀) • b = if p then a • b else 0`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-677b02","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.tmul_ite","line":384,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"ite-zero-case-without-zero-in-name","claim":"`tmul_ite` is the zero-else case `x₁ ⊗ₜ (if P then x₂ else 0) = if P then x₁ ⊗ₜ x₂ else 0`; by Mathlib's convention (`mul_ite` general, `mul_ite_zero` / `smul_ite_zero` for the zero-else case) it should carry `_zero`. Long-established name, so NIT.","fix":"Rename to `tmul_ite_zero` with a deprecated alias.","ev":"git grep origin/master: Algebra/Notation/Defs.lean:112 `lemma mul_ite (a b c : α) : (a * if P then b else c) = if P then a * b else a * c`; Algebra/Ring/Defs.lean:198 `lemma mul_ite_zero : a * ite P b 0 = ite P (a * b) 0`; Algebra/GroupWithZero/Action/Defs.lean:62 `lemma smul_ite_zero (p : Prop) [Decidable p] (a : M) (b : A) : (a • if p then b else 0) = if p then a • b else 0`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-a6204d","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.tmul_single","line":387,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"reproves-pi-apply-single","claim":"`tmul_single` is exactly `Pi.apply_single` with `f' j := (x ⊗ₜ[R] ·)` and `hf' := tmul_zero`, but is re-proved by `by_cases h : i = j <;> aesop` (fast, ~15 ms profiled, so only a reuse nit). Its only consumers are TensorProduct/Pi.lean:86,95.","fix":"Prove it as `Pi.apply_single (fun _ => (x ⊗ₜ[R] ·)) (fun _ => tmul_zero _ _) i m j`.","ev":"example {ι : Type*} [DecidableEq ι] {M : ι → Type*} [∀ i, AddCommMonoid (M i)]\n    [∀ i, Module R (M i)] (i : ι) (x : N) (m : M i) (j : ι) :\n    x ⊗ₜ[R] Pi.single i m j = (Pi.single i (x ⊗ₜ[R] m) : ∀ i, N ⊗[R] M i) j :=\n  Pi.apply_single (fun _ => (x ⊗ₜ[R] ·)) (fun _ => tmul_zero _ _) i m j\n-- hunts/tensor-defs/batch3/probe1.lean (P2), in place in copyB.lean; timing in probe2.lean","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-923837","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.single_tmul","line":392,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"reproves-pi-apply-single","claim":"`single_tmul` is exactly `Pi.apply_single` with `f' j := (· ⊗ₜ[R] x)` and `hf' := zero_tmul`, re-proved by `by_cases h : i = j <;> aesop`; it has no consumers anywhere in Mathlib.","fix":"Prove it as `Pi.apply_single (fun _ => (· ⊗ₜ[R] x)) (fun _ => zero_tmul _ _) i m j`.","ev":"example {ι : Type*} [DecidableEq ι] {M : ι → Type*} [∀ i, AddCommMonoid (M i)]\n    [∀ i, Module R (M i)] (i : ι) (x : N) (m : M i) (j : ι) :\n    Pi.single i m j ⊗ₜ[R] x = (Pi.single i (m ⊗ₜ[R] x) : ∀ i, M i ⊗[R] N) j :=\n  Pi.apply_single (fun _ => (· ⊗ₜ[R] x)) (fun _ => zero_tmul _ _) i m j\n-- hunts/tensor-defs/batch3/probe1.lean (P2), in place in copyB.lean; git grep for single_tmul outside Defs.lean: 0 hits","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7c9b8f","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.sum_tmul","line":399,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"manual-induction-instead-of-map-sum","claim":"Proved by a 5-line `classical` `Finset.induction` with two `simp` calls, although `mk` is already defined and the statement is `map_sum` for the linear map `(mk R M N).flip n`.","fix":"Replace the proof by `map_sum ((mk R M N).flip n) m s`.","ev":"example {α : Type*} (s : Finset α) (m : α → M) (n : N) :\n    (∑ a ∈ s, m a) ⊗ₜ[R] n = ∑ a ∈ s, m a ⊗ₜ[R] n :=\n  map_sum ((mk R M N).flip n) m s\n-- hunts/tensor-defs/batch3/probe1.lean (P3), in place in copyB.lean","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-49bef8","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.tmul_sum","line":406,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"manual-induction-instead-of-map-sum","claim":"Proved by a 5-line `classical` `Finset.induction` with two `simp` calls, although the statement is `map_sum` for the linear map `mk R M N m`.","fix":"Replace the proof by `map_sum (mk R M N m) n s`.","ev":"example (m : M) {α : Type*} (s : Finset α) (n : α → N) :\n    (m ⊗ₜ[R] ∑ a ∈ s, n a) = ∑ a ∈ s, m ⊗ₜ[R] n a :=\n  map_sum (mk R M N m) n s\n-- hunts/tensor-defs/batch3/probe1.lean (P3), in place in copyB.lean","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-e9f312","file":"Mathlib/LinearAlgebra/TensorProduct/Defs.lean","decl":"TensorProduct.exists_eq_tmul_of_forall","line":432,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring-opaque-name","claim":"No docstring, and the name's `_of_forall` does not say what the hypothesis is (that every sum of two pure tensors is pure); the statement also spells `TensorProduct R M N` instead of the file's `M ⊗[R] N` notation.","fix":"Add a docstring 'If every sum of two pure tensors is a pure tensor, then every element of `M ⊗[R] N` is a pure tensor.' and use the `M ⊗[R] N` notation.","ev":"src.lean:432-434 (no `/-- … -/` before the theorem; binder `(x : TensorProduct R M N)`).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-143b44","file":"Mathlib/Logic/Function/Conjugate.lean","decl":"Function.Semiconj","line":26,"sev":"NIT","status":"confirmed","cat":"generality","pattern":"type-where-sort-suffices","claim":"`variable {α : Type*} {β : Type*} {γ : Type*}` restricts `Semiconj`, `Commute` and `Semiconj₂` (and all their lemmas except the `option_map` ones) to `Type`, though nothing needs it: `Function.Semiconj (id : True → True) id id` fails to elaborate. `Std.Associative`/`Std.IdempotentOp` already allow `Sort*`.","fix":"Use `Sort*` for the section variables and separate `Type*` binders for the two `option_map` lemmas.","ev":"probe2.lean L3 `#check Function.Semiconj (id : True → True) id id` → type mismatch: `True → True` of sort `Prop`, expected sort `Type`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-740f0d","file":"Mathlib/Logic/Function/Conjugate.lean","decl":"Function.Semiconj.option_map","line":94,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-iff-companion","claim":"Two one-directional APIs have no iff companion: `Option.map f` semiconjugates `Option.map ga` to `Option.map gb` iff `f` semiconjugates `ga` to `gb` (only `→` is stated), and `Semiconj₂ f ga gb ↔ bicompr f ga = bicompl gb f f` (only `Semiconj₂.comp_eq` is stated, unlike the unary `semiconj_iff_comp_eq`). Both iffs are one-line proofs.","fix":"Add `Function.semiconj_option_map_iff` and `Function.semiconj₂_iff_comp_eq`.","ev":"probe2.lean: both iffs compile.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-a925ff","file":"Mathlib/Logic/Function/Conjugate.lean","decl":"Function.Commute","line":101,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-wrong-name","claim":"The docstring of `Function.Commute` writes `h : Function.commute f g` (lower-case, a name that does not exist). `Semiconj.comp_left` still carries a \"Backward compatibility note: before 2024-01-13 …\" about its argument order, long after any deprecation window.","fix":"`Function.Commute`; drop the 2024 note.","ev":"Source L103, L67–68.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-1e144d","file":"Mathlib/Logic/Function/Conjugate.lean","decl":"Function.Semiconj₂.isAssociative_right","line":173,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-after-retired-class","claim":"`isAssociative_right/left` and `isIdempotent_right/left` are named after the retired classes `IsAssociative`/`IsIdempotent`, but their statements now use `Std.Associative` and `Std.IdempotentOp`.","fix":"Rename to `associative_right/left` and `idempotentOp_right/left`, with deprecated aliases (one use, `Logic/Equiv/Basic.lean:1001,1004`).","ev":"Source L173–187.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-042ba1","file":"Mathlib/Logic/Godel/GodelBetaFunction.lean","decl":"(file)","line":12,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-import","claim":"`import Mathlib.Order.Fin.Basic` is unused. The module docstring has a garbled sentence ('and this is hard to prove that for `Encodable.encodeList` ...'), and the Authors line includes prose ('Adapted for mathlib by Hunter Monroe').","fix":"Drop the import, fix the sentence, and list the authors only.","ev":"hunts/godel-beta/drop_Mathlib_Order_Fin_Basic.lean (src without that import) compiles (exit 0); the other four private imports are needed. Docstring L25-26; header L4.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-5848fc","file":"Mathlib/Logic/Godel/GodelBetaFunction.lean","decl":"Nat.coprime_mul_succ","line":52,"sev":"NIT","status":"confirmed","cat":"generality","pattern":"truncated-subtraction-hypothesis","claim":"The hypothesis `m - n ∣ a` uses truncated subtraction, so for `m ≤ n` it forces `a = 0` and the lemma degenerates to `Coprime 1 1`. The symmetric case, e.g. `Coprime (2 * 1 + 1) (1 * 1 + 1)`, is not covered, though `max n m - min n m ∣ a` (or `n.dist m ∣ a`) would cover both orders.","fix":"State it with `Nat.dist n m ∣ a` (or derive the reversed version by `Coprime.symm`).","ev":"src L52; `1 - 2 = 0` in ℕ, so `(1 - 2 : ℕ) ∣ 1` is false while `Coprime 3 2` holds (Astra A1 check, `decide`).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b69850","file":"Mathlib/Logic/Godel/GodelBetaFunction.lean","decl":"Nat.beta_unbeta_coe","line":102,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"The round-trip `beta_unbeta_coe` is not `@[simp]` (plain `simp` leaves `(Nat.unbeta l).beta ↑i = l[↑i]`), and there is no `ℕ`-indexed version (`(hi : i < l.length)`) or `beta_pair` unfolding lemma (`beta (pair a b) i = a % ((i + 1) * b + 1)`).","fix":"Tag it `@[simp]` and add `beta_unbeta` (ℕ index) and `beta_pair`.","ev":"-- hunts/godel-beta/P.lean: `example (l : List ℕ) (i : Fin l.length) : Nat.beta (Nat.unbeta l) i = l[i] := by simp` fails with unsolved goals.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-9a18e6","file":"Mathlib/MeasureTheory/Function/LpSeminorm/ChebyshevMarkov.lean","decl":"(file)","line":10,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstrings","claim":"Only `mul_meas_ge_le_pow_eLpNorm'` has a docstring; the other seven theorems, including the user-facing `meas_ge_le_mul_pow_eLpNorm_enorm` (used by Chebyshev's inequality in Probability/Moments/Variance.lean:385), have none, and the module docstring names none of them; it also calls `eLpNorm` a seminorm, which it is not for `0 < p < 1` or a bare `ContinuousENorm` target (Astra A1 item 3).","fix":"Add one-line docstrings and list the main statements in the module docstring.","ev":"Measured: one `/--` in the file (L47).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-92824b","file":"Mathlib/MeasureTheory/Function/LpSeminorm/ChebyshevMarkov.lean","decl":"mul_meas_ge_le_pow_eLpNorm","line":39,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-detour","claim":"`mul_meas_ge_le_pow_eLpNorm` proves `1 / p.toReal * p.toReal = 1` and rewrites with `rpow_one`/`rpow_mul` by hand; `rw [one_div, ENNReal.rpow_inv_le_iff (ENNReal.toReal_pos hp_ne_zero hp_ne_top)]` on `pow_mul_meas_ge_le_eLpNorm` gives it directly.","fix":"Use `ENNReal.rpow_inv_le_iff`; likewise `mul_meas_ge_le_pow_eLpNorm'` by `simpa only [ENNReal.rpow_le_rpow_iff _]` instead of `convert … using 4` (Astra A1 item 6, compiles), and drop the redundant `ε = ∞` split in `MemLp.meas_ge_lt_top'` (Astra item 5).","ev":"hunts/chebyshev-markov/probe1.lean (C): the 2-line proof compiles, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-209d4a","file":"Mathlib/MeasureTheory/Function/LpSeminorm/ChebyshevMarkov.lean","decl":"meas_ge_le_mul_pow_eLpNorm_enorm","line":55,"sev":"NIT","status":"suspected","cat":"api","pattern":"missing-convenience-wrapper","claim":"There is no finite-threshold (`ε : ℝ≥0`) version of `meas_ge_le_mul_pow_eLpNorm_enorm`, so callers discharge `ε = ∞ → …` by `simp` each time (e.g. Chebyshev's inequality in Probability/Moments/Variance.lean:385) (Astra A1 item 7).","fix":"Add the `ℝ≥0` wrapper.","ev":"Suspected: Astra A1 item 7; not compiled.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-8368f7","file":"Mathlib/MeasureTheory/Function/LpSeminorm/ChebyshevMarkov.lean","decl":"MemLp.meas_ge_lt_top'","line":77,"sev":"NIT","status":"confirmed","cat":"api","pattern":"variant-proliferation","claim":"API shape: `meas_ge_le_mul_pow_eLpNorm_enorm` keeps an `_enorm` suffix although no non-`enorm` sibling exists any more; the four `MemLp.meas_ge_lt_top*` variants use `'` for 'ε : ℝ≥0∞' and `_enorm` for 'ContinuousENorm', and three of them have no use in Mathlib (only `MemLp.meas_ge_lt_top` is used, Probability/Independence/Integrable.lean:44). `MemLp.meas_ge_lt_top'` states its set with the coerced `‖f x‖₊`, which is `rfl`-equal to `‖f x‖ₑ`, so it is the normed-group instance of `meas_ge_lt_top'_enorm` (with `hε'` discharged).","fix":"Rename `meas_ge_le_mul_pow_eLpNorm_enorm` to drop `_enorm`, and keep one `ℝ≥0∞` and one `ℝ≥0` version of `MemLp.meas_ge_lt_top` (deprecating the rest).","ev":"hunts/chebyshev-markov/probe1.lean (D): `((‖x‖₊ : ℝ≥0) : ℝ≥0∞) = ‖x‖ₑ := rfl` compiles; `git grep` finds no use of `meas_ge_lt_top'_enorm`, `meas_ge_lt_top'`, `meas_ge_lt_top_enorm` and no `meas_ge_le_mul_pow_eLpNorm`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-673f34","file":"Mathlib/MeasureTheory/Integral/IntervalIntegral/TrapezoidalRule.lean","decl":"(imports)","line":13,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-import","claim":"`import Mathlib.Analysis.SpecialFunctions.Trigonometric.Arctan` and `import Mathlib.MeasureTheory.Covering.Besicovitch` (a heavy module) are unused: the file compiles without them. They are private imports, so dropping them only shrinks this file's build graph.","fix":"Remove the two imports.","ev":"hunts/trapezoidal/probe2_imports.lean (the file without those two imports) compiles with exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-e7bbdc","file":"Mathlib/MeasureTheory/Integral/IntervalIntegral/TrapezoidalRule.lean","decl":"(file)","line":26,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"broken-markdown-link","claim":"The module docstring's reference uses reversed Markdown link syntax, '(Wikipedia)[https://en.wikipedia.org/wiki/Trapezoidal_rule]', which renders as literal text; its 'Main results' lists only `trapezoidal_error_le`, calls it 'the convergence theorem' although it is a quantitative error bound (no `Tendsto` statement exists), and omits the definitions and `trapezoidal_error_le_of_c2`. Other docstring slips: `sum_trapezoidal_integral_adjacent_intervals` cites `IntervalIntegral.sum_integral_adjacent_intervals` (the namespace is `intervalIntegral`); `trapezoidal_error_le_of_c2` calls the `C^2` case 'slightly weaker' (it is a stronger hypothesis, hence a weaker corollary); the private `trapezoidal_error_le_of_lt` docstring says 'non-empty' for a nondegenerate interval (Astra A1 items 15-17).","fix":"Write `[Wikipedia](https://en.wikipedia.org/wiki/Trapezoidal_rule)` and list the main definitions and both error bounds.","ev":"Doc-only finding: L22-27 of the module docstring.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-aad3d2","file":"Mathlib/MeasureTheory/Integral/IntervalIntegral/TrapezoidalRule.lean","decl":"trapezoidal_integral","line":36,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"junk-value-undocumented","claim":"The definitions' docstrings do not document their totalised behaviour: `trapezoidal_integral f 0 a b = 0` (division by `0`, empty sum) and `trapezoidal_error` subtracts Mathlib's junk `0` integral for non-integrable `f` (e.g. a finite 'error' `1/2` for `x⁻¹` on `0..1`). The docstring also calls `N` trapezoids versus `N + 1` evaluations an 'off-by-one problem', although that is the standard convention.","fix":"Document the `N = 0` and non-integrable conventions (and add a `@[simp] trapezoidal_integral_zero` lemma); drop the 'off-by-one problem' wording.","ev":"hunts/trapezoidal/probe1.lean P3 (`trapezoidal_error (fun _ ↦ 1) 0 0 1 = -1` by `simp [trapezoidal_error, trapezoidal_integral]`) compiles; L36-38 docstring. Raised by Astra's A1 pass (items 4, 8).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-8e03be","file":"Mathlib/MeasureTheory/Integral/IntervalIntegral/TrapezoidalRule.lean","decl":"trapezoidal_integral","line":40,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"def-snake-case","claim":"The definitions `trapezoidal_integral` and `trapezoidal_error` use snake_case and live in the root namespace; Mathlib names data-valued definitions in lowerCamelCase (`trapezoidalIntegral`, `trapezoidalError`). Both are explicitly exempted in `scripts/nolints.json` (`defsWithUnderscore`), so this is a known style exception. The `a = a` lemmas are named `trapezoidal_integral_eq`/`trapezoidal_error_eq`, where Mathlib's convention (`intervalIntegral.integral_same`) is `_same`; `trapezoidal_integral_ext` is a successor/append identity with no extensionality content (`_succ`/`_add_one` would describe it).","fix":"Rename to `trapezoidalIntegral`/`trapezoidalError` (deprecated aliases) and `trapezoidal_integral_eq` → `trapezoidalIntegral_same`, `trapezoidal_error_eq` → `trapezoidalError_same`.","ev":"Name-only finding: L40 `noncomputable def trapezoidal_integral`, L44 `noncomputable def trapezoidal_error`, L69 `trapezoidal_integral_eq … a a = 0`, L74 `trapezoidal_error_eq`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-3a7c9f","file":"Mathlib/MeasureTheory/Integral/IntervalIntegral/TrapezoidalRule.lean","decl":"trapezoidal_error_le_of_lt'","line":137,"sev":"NIT","status":"suspected","cat":"proof","pattern":"proof-detour","claim":"Proof refinements suggested by Astra and not tested here: `h_dg` unfolds the whole composite-sum definition at `N = 1` and strips casts/empty sums by hand where `trapezoidal_integral_one` (proved just above) gives the one-panel form directly; the local `key` closes a derivative-restriction goal with `grind` where `(h x (Ico_subset_Icc_self hx)).mono_of_mem_nhdsWithin (Icc_mem_nhdsGE_of_mem hx)` (the `MeanValue` pattern) states it; and the grid-membership argument in `sum_trapezoidal_error_adjacent_intervals` re-derives interval preservation by a sign split on `h` instead of `Set.image_mul_const_uIcc`/`Set.image_const_add_uIcc`.","fix":"Use `trapezoidal_integral_one`, the explicit `mono_of_mem_nhdsWithin` term and the `uIcc` image lemmas.","ev":"Suspected: Astra's A1 items 11-13; replacements not compiled.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-888750","file":"Mathlib/MeasureTheory/Integral/IntervalIntegral/TrapezoidalRule.lean","decl":"trapezoidal_error_le","line":235,"sev":"NIT","status":"confirmed","cat":"api","pattern":"hypothesis-over-wrong-domain","claim":"The error bounds take `fpp_bound : ∀ x, |iteratedDerivWithin 2 f [[a, b]] x| ≤ ζ` over all of `ℝ`, although only `x ∈ [[a, b]]` matters (outside, the within-derivative is `0`); callers with a bound on the interval must re-derive the outside case, as the file itself does in `trapezoidal_error_le_of_lt` (`h7`).","fix":"State the bound as `∀ x ∈ [[a, b]], |iteratedDerivWithin 2 f [[a, b]] x| ≤ ζ`.","ev":"API-shape finding: L235/L253 `fpp_bound : ∀ x, …`; L220-225 `h7` re-derives the out-of-interval case via `derivWithin_zero_of_notMem_closure`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-8d03d5","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.instInvolutiveNeg","line":82,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-negzeroclass","claim":"`Zero` and `InvolutiveNeg` are given separately, with no `NegZeroClass`. As a result `-(0 : JordanDecomposition α) = 0` is not closed by `simp` (no progress), although it holds by `ext rfl rfl`. There is no current consumer.","fix":"Add `instance : NegZeroClass (JordanDecomposition α) where neg_zero := JordanDecomposition.ext rfl rfl` (or upgrade `instInvolutiveNeg` accordingly).","ev":"-- hunts/vm-jordan/batch0/probe2.lean P7b\nexample : -(0 : JordanDecomposition α) = 0 := by simp   -- error: simp made no progress\nexample : NegZeroClass (JordanDecomposition α) where\n  neg_zero := JordanDecomposition.ext rfl rfl            -- compiles","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-2e238c","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.instSMul","line":86,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"defeq-across-scalar-instances","claim":"The `mutuallySingular` field applies `MutuallySingular.smul`, which is stated for `r : ℝ≥0∞`, to an `ℝ≥0`-scaled measure, relying on defeq unification of the two `SMul` instances on `Measure`. The dedicated `MutuallySingular.smul_nnreal` exists (MutuallySingular.lean:143).","fix":"Write the field as `(j.mutuallySingular.symm.smul_nnreal r).symm.smul_nnreal r`.","ev":"-- hunts/vm-jordan/batch0/probe1.lean P8 (compiles)\nexample (r : ℝ≥0) (j : JordanDecomposition α) : r • j.posPart ⟂ₘ r • j.negPart :=\n  (j.mutuallySingular.symm.smul_nnreal r).symm.smul_nnreal r","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-0089c1","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.real_smul_def","line":118,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"shadowed-section-variable","claim":"`real_smul_def` re-binds `(j : JordanDecomposition α)` after `r`, shadowing the section variable `j`, so its explicit arguments are `(r j)` while every sibling (`coe_smul`, `real_smul_nonneg`, `real_smul_posPart_nonneg`, …) takes `(j r)`.","fix":"Drop the explicit `(j : JordanDecomposition α)` binder so the section variable is used, matching the argument order of the sibling lemmas.","ev":"#check @real_smul_def  -- ∀ {α} [MeasurableSpace α] (r : ℝ) (j : JordanDecomposition α), …\n#check @real_smul_nonneg  -- ∀ {α} [MeasurableSpace α] (j : JordanDecomposition α) (r : ℝ), …  (hunts/vm-jordan/batch1/Probe.lean P4)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-f30723","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.coe_smul","line":123,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"coe-smul-misnamed","claim":"In Mathlib `coe_smul` names the coercion of a smul (`↑(r • x) = r • ↑x` / `⇑(r • f) = r • ⇑f`; all ~70 `coe_smul` declarations sampled have that shape), but here it is the coercion of the scalar, `(↑r : ℝ) • j = r • j`, i.e. the reverse of `NNReal.smul_def`.","fix":"Rename to e.g. `coe_nnreal_smul_eq_smul` (or state it as `nnreal_smul_def : r • j = (r : ℝ) • j` mirroring `NNReal.smul_def`) with a deprecated alias.","ev":"git grep -c -E \"(theorem|lemma) coe_smul\\b\" origin/master -- Mathlib  → 70; e.g. Mathlib/Algebra/Module/Submodule/Defs.lean:277 `coe_smul (r : R) (x : p) : ((r • x : p) : M) = r • (x : M)`, Mathlib/Basic/ENNReal/Action.lean:73 `(↑(r • s) : ℝ≥0∞) = r • (s : ℝ≥0∞)`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-f84b9d","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.real_smul_nonneg","line":126,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"dite-lemma-on-ite","claim":"`real_smul_nonneg := dite_eq_left hr` and `real_smul_neg := dite_eq_right (not_le.2 hr)` apply `dite` lemmas to an `if … then … else` (an `ite`) hidden behind `instSMulReal`, typechecking only by unfolding `ite` to `dite`; the matching `ite_eq_left`/`ite_eq_right` (used by the sibling proofs at lines 124, 134, 138, 142, 146) work directly.","fix":"Use `ite_eq_left hr` and `ite_eq_right (not_le.2 hr)`.","ev":"example (j : JordanDecomposition α) (r : ℝ) (hr : 0 ≤ r) : r • j = r.toNNReal • j :=\n  ite_eq_left hr\nexample (j : JordanDecomposition α) (r : ℝ) (hr : r < 0) : r • j = -((-r).toNNReal • j) :=\n  ite_eq_right (not_le.2 hr)   -- hunts/vm-jordan/batch1/Probe.lean P3","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-509111","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.real_smul_neg","line":129,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"hypothesis-named-as-conclusion","claim":"The real-scalar case lemmas name their hypothesis as if it were the conclusion, without `_of_`: `real_smul_nonneg` (hyp `0 ≤ r`, reads as `0 ≤ r • j`), `real_smul_neg` (hyp `r < 0`; clashes with Mathlib's `smul_neg : r • -x = -(r • x)`), `real_smul_posPart_nonneg`, `real_smul_negPart_nonneg`, `real_smul_posPart_neg` (and `real_smul_negPart_neg`, batch 2).","fix":"Rename to `real_smul_of_nonneg`, `real_smul_of_neg` (or `_of_nonpos` after weakening), `real_smul_posPart_of_nonneg`, etc., with deprecated aliases.","ev":"#check @real_smul_nonneg  -- ∀ (j) (r : ℝ), 0 ≤ r → r • j = r.toNNReal • j  (hunts/vm-jordan/batch1/Probe.lean P4); Mathlib/Algebra/GroupWithZero/Action/Defs.lean:407 `theorem smul_neg (r : M) (x : A) : r • -x = -(r • x)`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-640e0a","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.real_smul_negPart_neg","line":144,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"hypothesis-named-as-conclusion-suffix","claim":"The trailing `_neg` names the hypothesis `r < 0`, not anything in the conclusion `(r • j).negPart = (-r).toNNReal • j.posPart`. Under Mathlib's convention a hypothesis is named with `_of_` (cf. `abs_of_neg`), and a bare `_neg` suffix normally means a negation in the conclusion. The sibling `real_smul_negPart_nonneg` has the same problem, where `_nonneg` usually means a `0 ≤ _` conclusion.","fix":"Rename it to `real_smul_negPart_of_neg` (or `_of_nonpos` after weakening), with a deprecated alias.","ev":"measured: statement at src.lean L144-145; hypothesis `hr : r < 0` is the only thing `_neg` can refer to","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-9c0eba","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.toSignedMeasure_zero","line":152,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"rw-chain-replaceable-by-simp","claim":"The proof is `ext1` followed by a 7-lemma `rw` chain that ends with `FunLike.coe_zero, Pi.zero_apply`, a two-step stand-in for `zero_apply`. `simp [toSignedMeasure]` proves the statement in one line.","fix":"Replace the proof with `simp [toSignedMeasure]`.","ev":"`theorem toSignedMeasure_zero : (0 : JordanDecomposition α).toSignedMeasure = 0 := by simp [toSignedMeasure]` in hunts/vm-jordan/batch2/src_edit.lean (diff vs src.lean in hunts/vm-jordan/batch2/src_edit.diff; compiled with the prompt's -D flags: no errors or warnings, `#lint only simpNF` passes, `#print axioms` shows no sorryAx; negative control with a broken proof does error)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-25837d","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.toSignedMeasure_neg","line":157,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"rw-chain-replaceable-by-simp","claim":"The proof is `ext1` followed by an 8-lemma `rw` chain that unfolds `toSignedMeasure` twice. `simp [toSignedMeasure]` proves the statement in one line, using `neg_posPart`, `neg_negPart` and `neg_sub`.","fix":"Replace the proof with `simp [toSignedMeasure]`.","ev":"`theorem toSignedMeasure_neg : (-j).toSignedMeasure = -j.toSignedMeasure := by simp [toSignedMeasure]` in hunts/vm-jordan/batch2/src_edit.lean (diff vs src.lean in hunts/vm-jordan/batch2/src_edit.diff; compiled with the prompt's -D flags: no errors or warnings, `#lint only simpNF` passes, `#print axioms` shows no sorryAx; negative control with a broken proof does error)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-20a506","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.toSignedMeasure_smul","line":162,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"rw-chain-ending-in-defeq-rfl","claim":"The proof is `ext1`, a 10-lemma `rw` chain and then a bare `rfl` with no comment. The `rfl` closes the goal the chain leaves by a definitional check rather than a named lemma, so the proof depends on that defeq. `simp [toSignedMeasure, smul_sub]` proves the statement in one line.","fix":"Replace the proof with `simp [toSignedMeasure, smul_sub]`.","ev":"`theorem toSignedMeasure_smul (r : ℝ≥0) : (r • j).toSignedMeasure = r • j.toSignedMeasure := by simp [toSignedMeasure, smul_sub]` in hunts/vm-jordan/batch2/src_edit.lean (diff vs src.lean in hunts/vm-jordan/batch2/src_edit.diff; compiled with the prompt's -D flags: no errors or warnings, `#lint only simpNF` passes, `#print axioms` shows no sorryAx; negative control with a broken proof does error)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-d53c4c","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.exists_compl_positive_negative","line":170,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"inline-reproof-of-measure-mono-null","claim":"Both bullets reprove `measure_mono_null` inline as `nonpos_iff_eq_zero.1 (hS₂ ▸ measure_mono hA₁)` and then run 7- and 9-step `rw` chains (`ENNReal.toReal_zero, zero_sub, neg_le, zero_apply, neg_zero`, then `exact ENNReal.toReal_nonneg`). Each bullet closes in one line with `simp` given an apply lemma for `toSignedMeasure`, `measureReal_def` and `measure_mono_null hA₁ hS₂`. The same inline reproof appears four more times in `toSignedMeasure_injective` (L368-374, L383-389).","fix":"Use `measure_mono_null hA₁ hS₂` (resp. `hS₃`) and close each bullet with one `simp` call.","ev":"hunts/vm-jordan/batch2/probe1.lean L56-57 (`measure_mono_null hA₁ hS₂ : μ A = 0`); the one-line bullets `simp [toSignedMeasure_apply_of_measurableSet _ hA, measureReal_def, measure_mono_null hA₁ hS₂]` (and `hS₃`) in hunts/vm-jordan/batch2/src_edit.lean (diff vs src.lean in hunts/vm-jordan/batch2/src_edit.diff; compiled with the prompt's -D flags: no errors or warnings, `#lint only simpNF` passes, `#print axioms` shows no sorryAx; negative control with a broken proof does error)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-54c88f","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.exists_compl_positive_negative","line":170,"sev":"NIT","status":"confirmed","cat":"api","pattern":"orientation-inconsistent-with-same-named-lemma","claim":"It shares its short name with the Hahn lemma `SignedMeasure.exists_compl_positive_negative : ∃ i, MeasurableSet i ∧ 0 ≤[i] s ∧ s ≤[iᶜ] 0` (Hahn.lean L367) but states the opposite orientation (`j.toSignedMeasure ≤[S] 0 ∧ 0 ≤[Sᶜ] j.toSignedMeasure`, with `S` negative). `toJordanDecomposition_spec` also uses the Hahn orientation. Its only consumer, `toSignedMeasure_injective` (L357-359), has to convert with `hS₁.compl` and `(compl_compl S).symm ▸ hS₂` before it can call `of_symmDiff_compl_positive_negative`.","fix":"State it in the Hahn orientation (`0 ≤[S] j.toSignedMeasure ∧ j.toSignedMeasure ≤[Sᶜ] 0 ∧ j.negPart S = 0 ∧ j.posPart Sᶜ = 0`, using `j.mutuallySingular.symm`), so the consumer can pass it directly.","ev":"hunts/vm-jordan/batch2/probe1.lean L50-53: getting the Hahn orientation from this lemma needs `⟨Sᶜ, hS.compl, h₂, (compl_compl S).symm ▸ h₁⟩`; both statements quoted from origin/master","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-fcaf8e","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.toJordanDecomposition","line":200,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-instance-field-in-structure-instance","claim":"The structure instance spells out `posPart_finite := inferInstance` and `negPart_finite := inferInstance`. These are instance-implicit fields (`[posPart_finite : IsFiniteMeasure posPart]`), which structure-instance notation fills by typeclass inference, so the two lines are redundant.","fix":"Delete the two `… := inferInstance` lines.","ev":"`toJordanDecomposition` without the two fields in hunts/vm-jordan/batch2/src_edit.lean (diff vs src.lean in hunts/vm-jordan/batch2/src_edit.diff; compiled with the prompt's -D flags: no errors or warnings, `#lint only simpNF` passes, `#print axioms` shows no sorryAx; negative control with a broken proof does error); all downstream declarations in the file still compile","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-3df5ed","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.toJordanDecomposition_spec","line":212,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring-on-interface-lemma","claim":"This is the only interface to the choice-based definition: it is used at L231, L490, L518-519 and L537 here and in Variation/SignedMeasure.lean L67. It has no docstring saying that the parts are `s` restricted to the two halves of a Hahn decomposition `i`/`iᶜ`, or that `i` is the positive half.","fix":"Add a docstring: 'The positive and negative parts of `s.toJordanDecomposition` are `s` restricted to the positive set `i` and to `-s` restricted to the negative set `iᶜ` of some Hahn decomposition.'","ev":"measured: src.lean L211-212 has no `/-- … -/` before the declaration; uses found by grep","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-46ef39","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.subset_positive_null_set","line":246,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"proof-rederives-existing-lemma","claim":"The 8-line proof re-derives existing plumbing by hand: the first `have` (`s v + s (w \\ v) = 0`, via `of_union` and set rewrites) is `hw₁ ▸ of_add_of_sdiff hv hw hwt`, and the final `linarith` is `VectorMeasure.of_nonneg_disjoint_union_eq_zero` (Basic.lean:170: `(h : Disjoint A B) (hA₁ : MeasurableSet A) (hB₁ : MeasurableSet B) (hA₂ : 0 ≤ s A) (hB₂ : 0 ≤ s B) (hAB : s (A ∪ B) = 0) : s A = 0`). The proof becomes a single term.","fix":"Replace the proof with the `of_nonneg_disjoint_union_eq_zero` term shown in the evidence.","ev":"theorem subset_positive_null_set (hu : MeasurableSet u) (hv : MeasurableSet v)\n    (hw : MeasurableSet w) (hsu : 0 ≤[u] s) (hw₁ : s w = 0) (hw₂ : w ⊆ u) (hwt : v ⊆ w) :\n    s v = 0 :=\n  of_nonneg_disjoint_union_eq_zero Set.disjoint_sdiff_right hv (hw.diff hv)\n    (nonneg_of_zero_le_restrict _ (zero_le_restrict_subset _ hu (hwt.trans hw₂) hsu))\n    (nonneg_of_zero_le_restrict _ (zero_le_restrict_subset _ hu (sdiff_subset.trans hw₂) hsu))\n    (by rwa [Set.union_sdiff_cancel hwt])\n-- drop-in replacement in hunts/vm-jordan/batch3/Jordan3.lean lines 245-252; the whole copy compiles (downstream in-file uses unchanged)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-ef736e","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.subset_positive_null_set","line":246,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-describes-hypotheses-not-conclusion","claim":"The name is a noun phrase about the hypotheses (\"subset of a positive null set\") and says nothing about the conclusion `s v = 0`; Mathlib theorem names describe the conclusion (e.g. `apply_eq_zero_of_subset_of_zero_le_restrict`-style, cf. `measure_mono_null`). Statement is correct, so NIT only.","fix":"If the file is touched, rename to a conclusion-first name such as `apply_eq_zero_of_subset_of_zero_le_restrict` with a deprecated alias.","ev":"name `subset_positive_null_set` vs statement `... : s v = 0` (src.lean:246-248)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-d194ab","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.subset_negative_null_set","line":259,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-describes-hypotheses-not-conclusion","claim":"Same as `subset_positive_null_set`: the name describes the hypotheses, not the conclusion `s v = 0`.","fix":"Rename alongside the positive version (e.g. `apply_eq_zero_of_subset_of_restrict_le_zero`) with a deprecated alias.","ev":"name `subset_negative_null_set` vs statement `... : s v = 0` (src.lean:259-261)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-1d9faf","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.of_sdiff_eq_zero_of_symmDiff_eq_zero_positive","line":271,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"on-goal-side-goal-assumption-cleanup","claim":"The 13-line proof is oddly structured: `rw [restrict_le_restrict_iff] at hsu hsv` spawns `MeasurableSet` side goals that are wrapped with `on_goal 1 =>` and closed by two trailing `assumption`s, and the arithmetic re-derives `add_eq_zero_iff_of_nonneg` with two `linarith`s. A 3-line proof via `of_union` + `add_eq_zero_iff_of_nonneg` + `zero_le_restrict_subset` works.","fix":"Replace the proof with the 3-line version in the evidence.","ev":"theorem of_sdiff_eq_zero_of_symmDiff_eq_zero_positive (hu : MeasurableSet u) (hv : MeasurableSet v)\n    (hsu : 0 ≤[u] s) (hsv : 0 ≤[v] s) (hs : s (u ∆ v) = 0) : s (u \\ v) = 0 ∧ s (v \\ u) = 0 := by\n  rw [Set.symmDiff_def, of_union disjoint_sdiff_sdiff (hu.diff hv) (hv.diff hu)] at hs\n  exact (add_eq_zero_iff_of_nonneg\n    (nonneg_of_zero_le_restrict _ (zero_le_restrict_subset _ hu sdiff_subset hsu))\n    (nonneg_of_zero_le_restrict _ (zero_le_restrict_subset _ hv sdiff_subset hsv))).1 hs\n-- drop-in replacement in hunts/vm-jordan/batch3/Jordan3.lean lines 266-272; compiles, and the negative version and all downstream uses still compile","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-32b198","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.of_inter_eq_of_symmDiff_eq_zero_positive","line":303,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring-in-documented-family","claim":"No docstring, while every other lemma in this section (`subset_*_null_set`, `of_sdiff_eq_zero_of_symmDiff_eq_zero_*`) has one; the statement (two positive sets with null symmetric difference give the same measure on `w ∩ ·`) is not obvious from the name.","fix":"Add a docstring, e.g. \"If two positive sets have null symmetric difference, then they meet every measurable set in sets of equal measure.\"","ev":"src.lean:302-303: line 302 is blank, line 303 starts `theorem of_inter_eq_of_symmDiff_eq_zero_positive`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-680e34","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.of_inter_eq_of_symmDiff_eq_zero_negative","line":319,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring-in-documented-family","claim":"No docstring (same as the positive version), unlike its documented siblings.","fix":"Add a docstring mirroring the positive version, for negative sets.","ev":"src.lean:318-319: line 318 is blank, line 319 starts `theorem of_inter_eq_of_symmDiff_eq_zero_negative`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-fc2f8f","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.JordanDecomposition.toJordanDecomposition_toSignedMeasure","line":401,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"explicit-at-application","claim":"The proof `(@toSignedMeasure_injective _ _ j j.toSignedMeasure.toJordanDecomposition (by simp)).symm` spells out all implicit arguments with `@` and proves the reversed equation only to take `.symm`; `toSignedMeasure_injective (toSignedMeasure_toJordanDecomposition _)` proves the statement directly.","fix":"Use `toSignedMeasure_injective (toSignedMeasure_toJordanDecomposition _)`.","ev":"hunts/vm-jordan/astra/probe.lean A17 compiles. Exit 0. Raised by Astra's A1 pass (item 17).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-913ad1","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.toJordanDecomposition_smul_real_nonneg","line":435,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"redundant-private-helper","claim":"Private helper used only by `toJordanDecomposition_smul_real`; its proof ends with a bare `rfl` that closes `((↑r : ℝ) • s).toJordanDecomposition = (r • s).toJordanDecomposition` by unfolding the ℝ≥0 and ℝ scalar actions on `VectorMeasure` (defeq across the coercion, no comment). `NNReal.smul_def` states it, and the whole helper is unnecessary once the main proof is golfed.","fix":"Delete the helper (inline as `rw [coe_smul, ← toJordanDecomposition_smul, NNReal.smul_def]`).","ev":"hunts/vm-jordan/batch4/GolfCopy.lean: the file with the helper removed and `toJordanDecomposition_smul_real` reproved without it compiles (exit 0); Probe1.lean `smul_real_golf₁` compiles standalone","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-c6c654","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.toJordanDecomposition_smul_real","line":441,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"mirror-branch-rw-chain","claim":"The 13-line proof (L441-453) runs two mirror-image `ext1` branches, each a 7-step `rw` chain closed by `all_goals exact Left.nonneg_neg_iff.2 hr.le`, and needs the private helper `toJordanDecomposition_smul_real_nonneg`; a 6-line proof via `real_smul_neg`, `toJordanDecomposition_smul`, `toJordanDecomposition_neg` and `NNReal.smul_def` needs no helper and no `ext`.","fix":"Replace the proof by the 6-line `rcases le_or_gt 0 r` version below and delete the private helper.","ev":"theorem toJordanDecomposition_smul_real (s : SignedMeasure α) (r : ℝ) :\n    (r • s).toJordanDecomposition = r • s.toJordanDecomposition := by\n  rcases le_or_gt 0 r with hr | hr\n  · lift r to ℝ≥0 using hr\n    rw [coe_smul, ← toJordanDecomposition_smul, NNReal.smul_def]\n  · rw [real_smul_neg _ _ hr, ← toJordanDecomposition_smul, ← toJordanDecomposition_neg,\n      NNReal.smul_def, Real.coe_toNNReal _ (neg_nonneg.2 hr.le), neg_smul, neg_neg]\n-- substituted into a full copy of the file with the private helper deleted: hunts/vm-jordan/batch4/GolfCopy.lean compiles with exit 0 and no warnings","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-ec922b","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.toJordanDecomposition_eq","line":455,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-iff-characterisation","claim":"Only the one-directional form `s = j.toSignedMeasure → s.toJordanDecomposition = j` exists; the characterising iff `s.toJordanDecomposition = j ↔ s = j.toSignedMeasure` is missing (one line from `toJordanDecompositionEquiv`), and downstream proofs re-derive this lemma by hand via `toSignedMeasure_injective` + `toSignedMeasure_toJordanDecomposition` (Lebesgue.lean L135-139 `singularPart_totalVariation`, JordanSub.lean L118-121 `toJordanDecomposition_toSignedMeasure_sub`).","fix":"Add `toJordanDecomposition_eq_iff` and use it/`toJordanDecomposition_eq` at the downstream re-derivations.","ev":"hunts/vm-jordan/batch4/Probe1.lean P3: `toJordanDecomposition_eq_iff` -> Unknown identifier; hunts/vm-jordan/batch4/Probe2.lean: `example {s : SignedMeasure α} {j : JordanDecomposition α} : s.toJordanDecomposition = j ↔ s = j.toSignedMeasure := (toJordanDecompositionEquiv α).eq_symm_apply.symm` compiles (also added as a theorem in GolfCopy.lean, exit 0)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-c29577","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.totalVariation","line":460,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"uninformative-docstring","claim":"Docstring 'The total variation of a signed measure.' does not say how it is defined (`s.toJordanDecomposition.posPart + s.toJordanDecomposition.negPart`) nor point to the equal supremum-based `VectorMeasure.variation` / `totalVariation_eq_variation`; the module docstring's 'Main definitions' omits `totalVariation`, although Lebesgue.lean, RadonNikodym.lean and Variation/SignedMeasure.lean build on it.","fix":"Docstring: 'The total variation `|s| = s⁺ + s⁻` of a signed measure, from its Jordan decomposition; equal to `VectorMeasure.variation` (see `totalVariation_eq_variation`).' and list it under Main definitions.","ev":"measured: src.lean L459 docstring text; module docstring L22-31 lists only JordanDecomposition, toJordanDecomposition, toJordanDecompositionEquiv","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-4c0631","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.absolutelyContinuous_ennreal_iff","line":486,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-measure-form-lemma","claim":"Its only consumer (RadonNikodym.lean:31) applies it at `μ.toENNRealVectorMeasure` and must immediately rewrite `(_ : μ.toENNRealVectorMeasure.ennrealToMeasure = μ)`; a `Measure`-form `s ≪ᵥ μ.toENNRealVectorMeasure ↔ s.totalVariation ≪ μ` is missing.","fix":"Add `absolutelyContinuous_toENNRealVectorMeasure_iff : s ≪ᵥ μ.toENNRealVectorMeasure ↔ s.totalVariation ≪ μ`.","ev":"hunts/vm-jordan/batch5/probe2.lean: `theorem absolutelyContinuous_toENNRealVectorMeasure_iff' … := by rw [SignedMeasure.absolutelyContinuous_ennreal_iff, VectorMeasure.ennrealToMeasure_toENNRealVectorMeasure]`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-937a6e","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.absolutelyContinuous_ennreal_iff","line":486,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring","claim":"No docstring on this characterisation of `≪ᵥ` by the total variation (used by RadonNikodym.lean), and the module docstring does not mention it.","fix":"Add a one-line docstring stating the characterisation.","ev":"measured: Jordan.lean L485-486 has no `/-- … -/` before `theorem absolutelyContinuous_ennreal_iff`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-6e6203","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.mutuallySingular_iff","line":513,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"stale-todo","claim":"Stale TODO: `-- TODO: Generalize to vector measures once total variation on vector measures is defined` — total variation on vector measures is now defined (`VectorMeasure.variation`, Variation/Defs.lean:51) and linked to `totalVariation` by `totalVariation_eq_variation` (Variation/SignedMeasure.lean:64), so the stated precondition no longer holds.","fix":"Do the generalisation in Variation/Basic.lean (see the generality finding) and delete or update the TODO.","ev":"measured: `git grep -n TODO origin/master -- …/Jordan.lean` → L513; `noncomputable def variation (μ : VectorMeasure X V) : Measure X` at Variation/Defs.lean:51","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-536411","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.mutuallySingular_iff","line":514,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"repeated-reasoning","claim":"The 18-line proof repeats the same `rw [totalVariation, Measure.add_apply, …, toMeasureOfZeroLE_apply, toMeasureOfLEZero_apply]; simp` block twice (and it recurs in `absolutelyContinuous_ennreal_iff` and `mutuallySingular_ennreal_iff`); with the missing `totalVariation_apply_eq_zero_iff` it is a 5-line proof.","fix":"Factor the repeated block into `totalVariation_apply_eq_zero_iff` and reprove from it.","ev":"hunts/vm-jordan/batch5/probe1.lean section P4: 5-line reproof `constructor <;> rintro ⟨u, hu, h₁, h₂⟩ · exact ⟨u, hu, (totalVariation_apply_eq_zero_iff' s hu).2 h₁, (totalVariation_apply_eq_zero_iff' t hu.compl).2 h₂⟩ · …`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-2bc08b","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.mutuallySingular_iff","line":514,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring","claim":"No docstring (only the TODO comment) on this characterisation of `⟂ᵥ` by total variations; the module docstring's Main definitions/results omit `totalVariation` and all the ≪/⟂ characterisations at L459-555.","fix":"Add a docstring and list the total-variation characterisations in the module docstring.","ev":"measured: Jordan.lean L513-514 (comment, no docstring); module docstring L12-43 names no totalVariation lemma","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-b2e566","file":"Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean","decl":"MeasureTheory.SignedMeasure.mutuallySingular_ennreal_iff","line":533,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring","claim":"No docstring on this characterisation of `⟂ᵥ` against an ℝ≥0∞-valued vector measure, used four times in Lebesgue.lean.","fix":"Add a one-line docstring stating the characterisation.","ev":"measured: Jordan.lean L532-533 has no `/-- … -/` before `theorem mutuallySingular_ennreal_iff`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-442b89","file":"Mathlib/MeasureTheory/VectorMeasure/Relations.lean","decl":"MeasureTheory.VectorMeasure.AbsolutelyContinuous","line":43,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-wrong-variable","claim":"The docstring of `VectorMeasure.AbsolutelyContinuous` speaks of \"a measure `μ`\" and \"`μ s = 0`\", but the definition is between two vector measures `v` and `w`; there is no `μ`.","fix":"\"…with respect to a vector measure `w` if `w s = 0` implies `v s = 0` for all sets `s`.\"","ev":"Source L43–46.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-c9af97","file":"Mathlib/MeasureTheory/VectorMeasure/Relations.lean","decl":"MeasureTheory.VectorMeasure.AbsolutelyContinuous.smul","line":100,"sev":"NIT","status":"confirmed","cat":"api","pattern":"inconsistent-explicitness","claim":"The scalar is implicit in `AbsolutelyContinuous.smul {r : R}` but explicit in `MutuallySingular.smul_left (r : R)`/`smul_right (r : R)`; `AbsolutelyContinuous.ennrealToMeasure` is an `iff` whose name lacks `_iff`.","fix":"Make `r` explicit in `AbsolutelyContinuous.smul`; rename to `absolutelyContinuous_ennrealToMeasure_iff` with a deprecated alias.","ev":"Source L100, L113, L184, L189.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-8cf3dd","file":"Mathlib/MeasureTheory/VectorMeasure/Relations.lean","decl":"MeasureTheory.VectorMeasure.MutuallySingular.mono_ac","line":141,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-sibling-lemma","claim":"There is no vector-measure `MutuallySingular.mono_ac` (`v ⟂ᵥ w → v' ≪ᵥ v → w' ≪ᵥ w → v' ⟂ᵥ w'`), the analogue of `Measure.MutuallySingular.mono_ac`; it is a one-line term reusing the witness.","fix":"Add `VectorMeasure.MutuallySingular.mono_ac`.","ev":"Copy.lean final example compiles.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-91bcce","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"(module docstring)","line":14,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-overstates","claim":"The module docstring defines variation as 'the supremum over partitions `{Eᵢ}` of `E`, of the quantity `∑ᵢ, ‖μ(Eᵢ)‖`'. That holds only for measurable `E` with measurable finite partitions and `‖·‖ₑ`; on non-measurable sets `variation` is the outer-measure extension, and `ennrealVariation` is `0` there.","fix":"Say 'for measurable `E`, the supremum over finite measurable partitions of `∑ ‖μ Eᵢ‖ₑ`, extended to all sets as a measure'.","ev":"src L16-19 vs Defs.lean: `variation` is `(ennrealPreVariation μ).toMeasure`-style extension of a function defined on `Subtype MeasurableSet` (see `variation_apply`, `ennrealVariation_apply`).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-219a39","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.absolutelyContinuous","line":27,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"module-doc-ill-typed-statement","claim":"The module docstring's Main results entry says `absolutelyContinuous`: `μ ≪ᵥ μ.variation`. That does not elaborate (`variation` is a `Measure`, `≪ᵥ` needs a `VectorMeasure`). The lemma states `μ ≪ᵥ μ.ennrealVariation`. The lemma itself has no docstring.","fix":"Change the module-doc entry to `μ ≪ᵥ μ.ennrealVariation` (and the name, see the naming finding).","ev":"example (μ : VectorMeasure X V) : μ ≪ᵥ μ.variation := absolutelyContinuous μ\n-- error: Application type mismatch: μ.variation has type Measure X but is expected to have type VectorMeasure X ?m\n-- hunts/vm-variation/batch0/probe2.lean (Q1), output probe2.out line 1","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-cfbdd7","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.le_variation","line":64,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"unresolved-docstring-reference","claim":"Docstring `Measure version of `sum_le_preVariationFun_of_subset`.` does not state what the lemma says. Its cross-reference does not resolve from `MeasureTheory.VectorMeasure` (the lemma is `MeasureTheory.preVariation.sum_le_preVariationFun_of_subset`), so it renders without a link. The cited lemma is about a `Finpartition` of a measurable `s₁ ⊆ s₂`, not an arbitrary disjoint finset of possibly non-measurable subsets.","fix":"State the content (a finite disjoint family of subsets of `s` has total enorm at most `μ.variation s`) and cite `preVariation.sum_le_preVariationFun_of_subset` with its namespace.","ev":"namespace MeasureTheory.VectorMeasure\n#check sum_le_preVariationFun_of_subset   -- error: Unknown identifier\n#check preVariation.sum_le_preVariationFun_of_subset  -- ok\n-- hunts/vm-variation/batch0/probe2.lean (Q2), output probe2.out line 9","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2da997","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.le_variation","line":65,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-omits-lhs","claim":"The name `le_variation` does not describe the left-hand side (`∑ p ∈ P, ‖μ p‖ₑ`) and is easily confused with its single-set sibling `enorm_measure_le_variation`. The parent API names the same inequality `preVariation.sum_le` (PreVariation.lean:79), as does `eVariationOn.sum_le` (BoundedVariation.lean:94).","fix":"Rename to `sum_enorm_le_variation` (with a deprecated alias).","ev":"measured: `git grep -n 'lemma sum_le\\|theorem sum_le'` -> MeasureTheory/Measure/PreVariation.lean:79 `preVariation.sum_le`, Topology/EMetricSpace/BoundedVariation.lean:94 `eVariationOn.sum_le`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2e0a5d","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.exists_lt_sum_of_lt_variation","line":93,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"noop-simp-location","claim":"Leftovers. In `simp only [...] at ha ⊢` (L93–94) the `⊢` location is a no-op, because the goal contains no `variation`; removing it still compiles. Also a double space in `intro i hi  j hj hij` (L103), copied to L128.","fix":"Change `at ha ⊢` to `at ha` and fix the double space (both disappear if the proof is refactored as in the `exists_variation_le_add'` finding).","ev":"pointer: hunts/vm-variation/batch0/hyg.lean = src.lean with L94 `at ha ⊢` -> `at ha`; compiles with no errors (hyg.out empty)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-f9604b","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.variation_apply_le_of_forall_enorm_le","line":167,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"inline-reproof-of-file-lemma","claim":"The 17-line proof re-derives inline (calc steps 2–3, 8 lines: `measure_biUnion_finset` to `m (i.parts.sup Subtype.val)`, then `measure_mono` back to `m s`, although the sup is exactly `s`) the additivity over a Finpartition that the file's own `sum_finpartition` provides for `m.toENNRealVectorMeasure`. With the missing iSup formula it is four lines.","fix":"Use `sum_finpartition` on `m.toENNRealVectorMeasure` (and the iSup formula from the `variation_apply` api finding).","ev":"example {μ : VectorMeasure X V} {s : Set X} {m : Measure X} (hs : MeasurableSet s)\n    (h : ∀ E, MeasurableSet E → E ⊆ s → ‖μ E‖ₑ ≤ m E) :\n    μ.variation s ≤ m s := by\n  rw [variation_apply_of_measurableSet μ hs]\n  refine iSup_le fun P => (sum_le_sum fun (p : Subtype MeasurableSet) hp => h p p.2 (P.le hp)).trans_eq ?_\n  rw [← Measure.toENNRealVectorMeasure_apply_measurable hs, ← m.toENNRealVectorMeasure.sum_finpartition P]\n  exact sum_congr rfl fun p _ => (Measure.toENNRealVectorMeasure_apply_measurable p.2).symm\n-- hunts/vm-variation/batch0/probe1.lean (P4)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-e7a1f7","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.variation_map_le","line":253,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"simp-unfolds-def-instead-of-api-lemma","claim":"The non-measurable branch closes with `simp [VectorMeasure.map, hφ, Measure.zero_le]`, unfolding the definition of `VectorMeasure.map` although the API lemma `VectorMeasure.map_not_measurable (hf : ¬Measurable f) : v.map f = 0` (Mathlib/MeasureTheory/VectorMeasure/Operations.lean:199) exists.","fix":"Use `simp [map_not_measurable μ hφ, Measure.zero_le]` in the `swap` branch.","ev":"hunts/vm-variation/batch1/probe1.lean (P4):\nexample : (μ.map φ).variation ≤ μ.variation.map φ := by\n  by_cases hφ : Measurable φ; swap\n  · simp [map_not_measurable μ hφ, Measure.zero_le]\n  apply variation_le_of_forall_enorm_le (fun s hs ↦ ?_)\n  simp [VectorMeasure.map_apply _ hφ hs, Measure.map_apply hφ hs, enorm_measure_le_variation]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-0c7739","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.variation_apply_singleton","line":289,"sev":"NIT","status":"confirmed","cat":"generality","pattern":"too-strong-typeclass","claim":"`variation_apply_singleton` assumes `[MeasurableSingletonClass X]`, but the proof needs only `MeasurableSet {x}`; the class excludes e.g. measurable atoms in a countably generated space with non-measurable other singletons.","fix":"Add a `(hx : MeasurableSet {x})` version and derive the simp lemma from it.","ev":"-- hunts/vm-variation/lead/P.lean section B: `example {x : X} (hx : MeasurableSet {x}) : μ.variation {x} = ‖μ {x}‖ₑ` proved with the same argument plus `Measure.dirac_apply' _ hx`; compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b038f4","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.VectorMeasure.norm_measure_le_variation","line":302,"sev":"NIT","status":"confirmed","cat":"api","pattern":"inconsistent-explicit-args-between-norm-and-enorm-versions","claim":"`μ` and `E` are implicit (only the auto-param `hE` is explicit), whereas the `‖·‖ₑ` version `enorm_measure_le_variation (μ) (E)` in the same file and Mathlib's `SignedMeasure.norm_le_totalVariation (s) (i)` take them explicitly, so `norm_measure_le_variation μ E` does not typecheck.","fix":"Make `μ` and `E` explicit, as in `enorm_measure_le_variation`.","ev":"hunts/vm-variation/batch1/probe2_fail.lean:\nexample (μ : VectorMeasure X V) (E : Set X) : ‖μ E‖ₑ ≤ μ.variation E :=\n  enorm_measure_le_variation μ E   -- ok\nexample (μ : VectorMeasure X V) [IsFiniteMeasure μ.variation] (E : Set X) :\n    ‖μ E‖ ≤ μ.variation.real E :=\n  norm_measure_le_variation μ E\n-- error: Application type mismatch: The argument μ has type VectorMeasure X V but is expected to have type autoParam ((variation ?m.29) ?m.30 ≠ ⊤) norm_measure_le_variation._auto_1","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d30fc0","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.SignedMeasure.exists_subset_lt_enorm_apply_of_lt_variation","line":362,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-omits-constant-factor","claim":"The name says `a < ‖μ t‖ₑ`, but the statement only gives `a < 2 * ‖μ t‖ₑ`. The statement the name describes is false: for μ = δ_false − δ_true on Bool, `μ.variation univ ≥ 2` but `‖μ t‖ₑ ≤ 1` for every t. The docstring is correct ('up to a factor of 2'). The same naming pattern recurs in Semivariation.lean (`exists_subset_lt_enorm_apply_of_lt_semivariation`, also `a < 2 * ‖μ t‖ₑ`); that one is suspected, not audited here.","fix":"Rename to `SignedMeasure.exists_subset_lt_two_mul_enorm_apply_of_lt_variation` (dated deprecated alias), together with the semivariation lemma; update Semivariation.lean's module docstring and uses.","ev":"-- hunts/vm-variation/batch2/P3.lean (recompiled by the lead, exit 0)\nexample : ¬ ∀ (μ : SignedMeasure Bool) {s : Set Bool}, MeasurableSet s → ∀ {a : ℝ≥0∞},\n    a < μ.variation s → ∃ t ⊆ s, MeasurableSet t ∧ a < ‖μ t‖ₑ  -- μ := dirac false 1 - dirac true 1, a := 1","evr":"compiles","astraV":"agrees","astraS":"A2: agrees, MAJOR under the stated criterion. The name conventionally reads as transferring the bound to ‖μ t‖ₑ, and the omitted two_mul is an essential weakening, since rescaling a cannot recover it. The Bool counterexample is valid, and it also refutes the semivariation analogue, since the identity functional is admissible. Statements and proofs are fine; rename both and keep deprecated aliases.","pr":null,"res":"Re-graded MAJOR→NIT by the user (2026-10-06): the statement and docstring are right, so a name omitting a constant factor is only a naming nit.","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-de97ba","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean","decl":"MeasureTheory.SignedMeasure.exists_subset_lt_enorm_apply_of_lt_variation","line":375,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"duplicate-simp-argument","claim":"`Real.norm_eq_abs` appears twice in the same `simp only [...]` list (L375 and L377).","fix":"Drop the second `Real.norm_eq_abs` at L377.","ev":"grep -n Real.norm_eq_abs src.lean → 375 and 377 in one simp only; hunts/vm-variation/batch2/srcsmul.lean has the L377 copy removed and compiles with linters","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-49444a","file":"Mathlib/MeasureTheory/VectorMeasure/Variation/Semivariation.lean","decl":"MeasureTheory.VectorMeasure.exists_subset_lt_enorm_apply_of_lt_semivariation","line":94,"sev":"NIT","status":"suspected","cat":"naming","pattern":"name-omits-constant-factor","claim":"This is a sweep hit from the `SignedMeasure.exists_subset_lt_enorm_apply_of_lt_variation` finding. The conclusion is `∃ t ⊆ s, MeasurableSet t ∧ a < 2 * ‖μ t‖ₑ`, but the name has no `two_mul`, so it names the factor-free statement, which is false already for real-valued μ = δ_false − δ_true (semivariation = variation there).","fix":"Rename to `exists_subset_lt_two_mul_enorm_apply_of_lt_semivariation` (with a deprecated alias), together with the `Variation/Basic.lean` lemma.","ev":"Semivariation.lean L94-96: `lemma exists_subset_lt_enorm_apply_of_lt_semivariation (hs : MeasurableSet s) {a : ℝ≥0∞} (ha : a < μ.semivariation s) : ∃ t ⊆ s, MeasurableSet t ∧ a < 2 * ‖μ t‖ₑ`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"Re-graded MAJOR→NIT by the user (2026-10-06): the statement and docstring are right, so a name omitting a constant factor is only a naming nit.","at":"2026-10-06","commit":""},{"id":"RT-20261006-451652","file":"Mathlib/NumberTheory/AlmostPrime.lean","decl":"Nat.IsAtMostAlmostPrime","line":45,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-drops-hypothesis","claim":"`IsAtMostAlmostPrime`'s docstring omits the boundary conventions its sibling states (0 is excluded; 1 satisfies it for every k), and the module docstring says 'Both definitions use … Ω' although three predicates are defined.","fix":"Mention `n ≠ 0` and the value at 1; say 'All three'.","ev":"#print Nat.IsAtMostAlmostPrime\n-- def Nat.IsAtMostAlmostPrime : ℕ → ℕ → Prop := fun k n => n ≠ 0 ∧ Ω n ≤ k","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-54c4aa","file":"Mathlib/NumberTheory/AlmostPrime.lean","decl":"Nat.Prime.isAlmostPrime_one","line":67,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-detour","claim":"`Prime.isAlmostPrime_one` is `simpa using isAlmostPrime_one_iff.mpr hp` and `Prime.mul_isAlmostPrime_two` is `simpa using hp.isAlmostPrime_one.mul hq.isAlmostPrime_one`; both terms already have the goal's type (`1 + 1` is defeq to `2`), so `simpa` is unnecessary.","fix":"Use the terms directly.","ev":"example {p q : ℕ} (hp : p.Prime) (hq : q.Prime) : IsAlmostPrime 2 (p * q) :=\n  hp.isAlmostPrime_one.mul hq.isAlmostPrime_one\nexample {p : ℕ} (hp : p.Prime) : IsAlmostPrime 1 p := isAlmostPrime_one_iff.mpr hp","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-2eb28e","file":"Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean","decl":"(file)","line":1,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring","claim":"No docstrings on `tsum_riemannZetaSummand`, `tsum_dirichletSummand` and `riemannZeta_eq_exp_LSeries`.","fix":"Add one-line docstrings.","ev":"Measured: source.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-6e9f72","file":"Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean","decl":"dirichletSummandHom","line":46,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"shadowed-binder","claim":"`dirichletSummandHom {n : ℕ} (χ : DirichletCharacter ℂ n)` reuses `n` for the bound variable of `toFun n := χ n * (n : ℂ) ^ (-s)`, shadowing the level `n`; every other declaration in the file calls the level `N`.","fix":"Rename the level to `N`.","ev":"Measured: source L46-47.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261006-57e0af","file":"Mathlib/NumberTheory/FundamentalDiscriminant.lean","decl":"Int.isFundamentalDiscr_iff_squarefree","line":64,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-detour","claim":"`simp +contextual only [Int.mul_ediv_cancel_left d four_ne_zero]` does not need `+contextual`: the rewrite is unconditional, and plain `simp only` leaves the proof compiling.","fix":"Drop `+contextual`.","ev":"-- hunts/fund-discr/ProbeCopy.lean compiles with `simp only [Int.mul_ediv_cancel_left d four_ne_zero]`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2cdd15","file":"Mathlib/NumberTheory/ModularForms/LFunction.lean","decl":"CuspForm.hasSum_Λ","line":182,"sev":"NIT","status":"confirmed","cat":"api","pattern":"inconsistent-argument-order","claim":"`CuspForm.hasSum_Λ` re-binds `(hk : 0 < k)` explicitly after `f`, shadowing the section variable, so its arguments are `(f) (hk) (hs)` while `ModularForm.hasSum_Λ` and every other lemma take `(hk) (f)`; the module docstring is only a title (no main definitions/results); `L` has a double space after `:=`.","fix":"Drop the re-bound `hk`; add a module docstring; single space.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-f9c129","file":"Mathlib/NumberTheory/ModularForms/RamanujanFormula.lean","decl":"(module docstring)","line":28,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-drops-hypothesis","claim":"The 'Proof Strategy' says the identities follow by 'showing that the limit of both sides at i∞ agree'; that suffices only because the target spaces are one-dimensional with a generator of nonzero limit (E₄³ and E₆² both tend to 1 but differ). The private helper states both conditions; the overview should too.","fix":"Mention the rank-one space and the generator tending to 1.","ev":"-- module docstring, Proof Strategy paragraph","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-db2a68","file":"Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean","decl":"(file)","line":21,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"module-doc-paraphrase-differs","claim":"The module docstring states `eq_one_or_neg_one_of_unit_of_congruent` for units 'congruent to an integer modulo `3`' while the theorem assumes congruence modulo `λ ^ 2` (equivalent, since `λ ^ 2 = -3 * η`, but the docstring does not say so), and 'Main results' omits the `λ`-divisibility lemmas (`lambda_dvd_or_dvd_sub_one_or_dvd_add_one`, `lambda_pow_four_dvd_cube_sub_one_or_add_one_of_lambda_not_dvd`) that `FLT/Three.lean` uses.","fix":"Say 'modulo `λ ^ 2` (equivalently `3`)' and list the divisibility lemmas.","ev":"Doc-only finding: L25-26 vs L101; consumers of the λ-lemmas in Mathlib/NumberTheory/FLT/Three.lean.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-ec688c","file":"Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean","decl":"(file)","line":34,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-open","claim":"`open … nonZeroDivisors Polynomial` (L34) opens two namespaces the file never uses, and `replace hr : r ∈ Finset.Ico 0 3` (L74) introduces a new hypothesis rather than replacing one (Astra A1 item 12).","fix":"Drop `nonZeroDivisors Polynomial` from the `open` and write `have hr`.","ev":"hunts/cyclo-three/m2.lean (module-mode copy with both opens removed and `have hr`) compiles, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-b4e192","file":"Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean","decl":"coe_eta","line":43,"sev":"NIT","status":"confirmed","cat":"api","pattern":"specialised-wrapper","claim":"`coe_eta` is an instance of the simp lemma `IsUnit.unit_spec`; `IsPrimitiveRoot.toInteger_cube_eq_one`, placed in the general `IsPrimitiveRoot` namespace, is the order-3 case of `hζ.toInteger_isPrimitiveRoot.pow_eq_one`, which holds for every `k`; and the unit `η` is a local notation for `(IsPrimitiveRoot.isUnit … …).unit`, so public statements expose that term and FLT/Three.lean re-declares the same notation (Astra A1 items 8, 11). These wrappers have consumers in FLT/Three.lean, so they are convenience API, not dead code.","fix":"Consider a general `IsPrimitiveRoot.toInteger_pow_eq_one` and a named `IsPrimitiveRoot.toIntegerUnit` with a coercion simp lemma.","ev":"Measured: L43 `coe_eta … := rfl` (= `IsUnit.unit_spec`), L45-46 proof is `hζ.toInteger_isPrimitiveRoot.pow_eq_one`; L40 notation; FLT/Three.lean repeats the notation.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-6f0571","file":"Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean","decl":"Units.mem","line":51,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"uninformative-name","claim":"`IsCyclotomicExtension.Rat.Three.Units.mem` says nothing about its content (the unit group is `{±1, ±η, ±η²}`); the `Units` sub-namespace exists only for this one lemma.","fix":"e.g. `Three.units_mem_list` or `Three.unit_eq_or_eq_neg`, with a deprecated alias.","ev":"Measured: L51; only declaration in `Three.Units`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-aab0a7","file":"Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean","decl":"Units.mem","line":51,"sev":"NIT","status":"suspected","cat":"generality","pattern":"derivable-typeclass","claim":"`[NumberField K]` on the seven declarations after L51 is derivable from `[CharZero K] [IsCyclotomicExtension {3} ℚ K]` via `IsCyclotomicExtension.numberField` (a theorem, not an instance), so it could be weakened to `CharZero` (Astra A1 item 1; Mathlib's usual convention is to assume `NumberField`, hence NIT).","fix":"Optional: assume `[CharZero K]` and install the instance locally.","ev":"Suspected: Astra A1 item 1; not compiled.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-89745e","file":"Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean","decl":"Units.mem","line":66,"sev":"NIT","status":"suspected","cat":"proof","pattern":"proof-detour","claim":"Proof refinements suggested by Astra, not compiled here: in `Units.mem`, L66-73 unpack finite order into an exponent (with a `((⟨n, hnpos⟩ : ℕ+) : ℕ)` detour) and repack it, where `MonoidHom.isOfFinOrder` transports `IsOfFinOrder` through `(𝓞 K)ˣ → K`; in `eq_one_or_neg_one_of_unit_of_congruent` the two negative branches rebuild negated witnesses separately (one via `RingOfIntegers.neg_mk`) where one helper `(∃ n : ℤ, d ∣ -a - n) → ∃ n : ℤ, d ∣ a - n` serves both; `lambda_dvd_or_dvd_sub_one_or_dvd_add_one` translates each quotient value to divisibility by hand where `Ideal.Quotient.eq` does it at once (Astra A1 items 5, 9, 10).","fix":"Apply the three simplifications.","ev":"Suspected: Astra A1 items 5, 9, 10; not compiled.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-bd8fcb","file":"Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean","decl":"lambda_dvd_or_dvd_sub_one_or_dvd_add_one","line":136,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"obsolete-instance-shortcut","claim":"The instance shortcuts `let _ : Ring (𝓞 K ⧸ …) := CommRing.toRing -- to speed up instance synthesis` and `let _ : AddGroup … := AddGroupWithOne.toAddGroup -- ditto` (L136-137) are obsolete: the proof compiles without them and the declaration stays under the 200 ms profiler threshold.","fix":"Delete L136-137.","ev":"Module-mode copy hunts/cyclo-three/m2.lean (the two `let _` lines deleted) compiles, exit 0, with no declaration over 300 ms (`-Dprofiler=true -Dprofiler.threshold=300`); non-module probe1.lean agrees under a 200 ms threshold.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-354dec","file":"Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean","decl":"lambda_pow_four_dvd_cube_sub_one_of_dvd_sub_one","line":180,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"shadowed-variable-binder","claim":"`variable (x : 𝓞 K)` (L128) is shadowed by an implicit `{x : 𝓞 K}` in the last three lemmas (L180, L191, L200), so `x` is explicit in four lemmas and implicit in three.","fix":"Use one convention for `x` (e.g. drop the section variable and bind it per lemma).","ev":"Measured: L128 vs L180, L191, L200.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261006-2b2982","file":"Mathlib/NumberTheory/NumberField/DirichletDensity.lean","decl":"(module docstring)","line":27,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"stale-docstring","claim":"The module docstring's Main results cite `NumberField.primeIdealZetaSum_le_card_of_finite`, `NumberField.hasDirichletDensity_empty`, `NumberField.dirichletDensity_nonneg`, `NumberField.dirichletDensity_le_one`, but the declarations live in `NumberField.Set` (they are designed for dot notation on `S : Set _`).","fix":"Use the `NumberField.Set.` names.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-332d44","file":"Mathlib/NumberTheory/NumberField/DirichletDensity.lean","decl":"NumberField.Set.HasDirichletDensity.le_one","line":131,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-detour","claim":"Small detours: `HasDirichletDensity.nonneg`/`le_one` rebuild `ge_of_tendsto'`/`le_of_tendsto'`; the non-summable branch of `le_one` uses `grw` where `simp [tsum_eq_zero_of_not_summable hs]` closes it; `primeIdealZetaSum` re-binds the section variable `S`; `primeIdealZetaSum_def` is `by rfl`; `replace hS := hS.to_subtype` hides the hypothesis.","fix":"Use the primed limit lemmas, `simp`, and drop the re-bound binder.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-f3ca43","file":"Mathlib/NumberTheory/Padics/Measure/AmiceTransform.lean","decl":"(file)","line":13,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-import","claim":"`open Submodule` is unused and the import `Mathlib.Algebra.Order.Field.Power` is unnecessary: the file compiles with both removed.","fix":"Delete both lines.","ev":"grep -v 'import Mathlib.Algebra.Order.Field.Power\\|open Submodule' AmiceTransform.lean > Probe_noimp.lean; lake env lean Probe_noimp.lean  -- exit 0, no output","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-e72d90","file":"Mathlib/NumberTheory/Padics/Measure/AmiceTransform.lean","decl":"AbstractMeasure.ext_mahler","line":57,"sev":"NIT","status":"confirmed","cat":"api","pattern":"name-overstates","claim":"`AbstractMeasure.ext_mahler` is a zero criterion (`(∀ n, μ (mahler n • 1) = 0) → μ = 0`) under an `ext` name; the usual two-measure extensionality `(∀ n, μ (mahler n • 1) = ν (mahler n • 1)) → μ = ν` is missing, so `apply ext_mahler` does not match `μ = ν`.","fix":"State `ext_mahler` for two measures and keep the zero version as `eq_zero_of_mahler`.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-a53622","file":"Mathlib/NumberTheory/Padics/Measure/AmiceTransform.lean","decl":"AbstractMeasure.amiceTransform","line":77,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-understates-scope","claim":"The module docstring says `amiceTransform` allows 'R to be any normed ℤ_[p]-algebra', but the definition only assumes a topological commutative ring with `[ContinuousSMul ℤ_[p] R]` (the normed, ultrametric, complete hypotheses enter only for injectivity). Also: the module's 'n-th coefficient μ (mahler n)' is literally `μ (mahler n • 1)` for general R; 'the same map bundled as a linear equivalence' is only for R = ℤ_[p]; and 'identify the measures … with the power series ring' holds only as modules — for the `Ring D(ℤ_[p], ℤ_[p])` instance of Measure/Monoid.lean (convolution along *multiplication* of ℤ_[p]) the Amice map is not multiplicative (its value at 1 = dirac 1 is 1 + X).","fix":"'any topological ℤ_[p]-algebra R (injective when R is a complete ultrametric normed algebra)'.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-6ac4fa","file":"Mathlib/NumberTheory/Padics/Measure/AmiceTransform.lean","decl":"AbstractMeasure.coeff_amiceTransform","line":82,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"The characterising lemma `coeff_amiceTransform` is not `@[simp]`, yet every later proof in the file passes it to `simp` by hand (3 times).","fix":"Tag it `@[simp]`.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-90e1cf","file":"Mathlib/NumberTheory/Padics/Measure/AmiceTransform.lean","decl":"AbstractMeasure.injective_amiceTransform","line":93,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-order-nonstandard","claim":"`injective_amiceTransform` inverts Mathlib's `f_injective` order for `Function.Injective f` (1108 `*_injective` theorems vs 179 `injective_*`); and `invTransform` does not say what it inverts (`AbstractMeasure.invTransform F` takes a power series). The private summability lemma `invTransformSummable` is named like a definition (UpperCamelCase-style suffix) rather than a theorem (`summable_mahlerEquiv_mul_coeff`).","fix":"`amiceTransform_injective`; `invTransform` → `amiceTransformInv` (or `ofPowerSeries`).","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-aafd81","file":"Mathlib/NumberTheory/Padics/Measure/AmiceTransform.lean","decl":"AbstractMeasure.invTransform","line":130,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"reprovable-from-existing-api","claim":"Detours: `invTransform`'s 3-step calc through the isometry, the c₀ norm and `toBCF` is `IsUltrametricDist.norm_fwdDiff_iter_apply_le 1 f 0 i`; `amiceTransformEquiv.left_inv` is `injective_amiceTransform (amiceTransform_invTransform _)` rather than `simp [← …eq_iff]`; `invTransformₗ.map_smul'` converts to `•` and back instead of `Summable.tsum_mul_left`.","fix":"Use the direct lemmas.","ev":"example (f : C(ℤ_[p], ℤ_[p])) (i : ℕ) : ‖PadicInt.mahlerEquiv ℤ_[p] f i‖ ≤ ‖f‖ := by\n  simpa only [PadicInt.mahlerEquiv_apply] using IsUltrametricDist.norm_fwdDiff_iter_apply_le 1 f 0 i\nexample (μ : D(ℤ_[p], ℤ_[p])) : invTransform (amiceTransform μ) = μ :=\n  injective_amiceTransform (amiceTransform_invTransform _)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-2fc3d4","file":"Mathlib/NumberTheory/Padics/Measure/Basic.lean","decl":"AbstractMeasure.coe_toCLMEquiv","line":87,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-describes-wrong-shape","claim":"`coe_toCLMEquiv` and `coe_symm_toCLMEquiv` state pointwise evaluations (`toCLMEquiv μ f = μ f`), which Mathlib names `toCLMEquiv_apply`/`toCLMEquiv_symm_apply`; `coe_` is for equalities of coercions.","fix":"Rename to `toCLMEquiv_apply_apply` / `toCLMEquiv_symm_apply_apply` (or state them as function equalities).","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-491f25","file":"Mathlib/NumberTheory/Padics/Measure/Basic.lean","decl":"AbstractMeasure.contractSnd","line":162,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-typo","claim":"Docstring slips: `contractSnd` introduces ν but writes '∫ f(x, y) dμ(y)'; `prodMk_eq_prodMk'` says 'For profinite spaces' though only X must be profinite (Y compact, and R must be T0); the module doc's Iwasawa remark should say bounded measures / ℤ_[p]-coefficients.","fix":"dν(y); 'if X is profinite and Y compact Hausdorff'; clarify the Iwasawa sentence.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-7cd9a2","file":"Mathlib/NumberTheory/Padics/Measure/Basic.lean","decl":"AbstractMeasure.contractFst_apply","line":173,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"deprecated-tactic-continuity","claim":"`contractFst_apply` and `contractSnd_apply` build the continuity proof inside their statements with `by continuity` (26 uses left in Mathlib vs 1546 `by fun_prop`); `fun_prop` is the maintained tactic.","fix":"`by fun_prop` (or `(f.comp ...).continuous`).","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-a270e5","file":"Mathlib/NumberTheory/Padics/Measure/Basic.lean","decl":"AbstractMeasure.contractSndCLM","line":194,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"reprovable-from-existing-api","claim":"The 4-line continuity proof inside `contractSndCLM` (two uncurryings and a `prodAssoc` rewrite) repeats `ContinuousMap.continuous_curry`: it is `(continuous_postcomp (ν : C(C(Y, R), R))).comp continuous_curry`.","fix":"Use the one-line composition.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-477b8e","file":"Mathlib/NumberTheory/Padics/Measure/Basic.lean","decl":"AbstractMeasure.prodMk_apply","line":212,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"style-indentation","claim":"The statement's continuation line is indented 2 spaces instead of Mathlib's 4 (`lemma prodMk_apply ... :` / `  prodMk μ ν f = ...`).","fix":"Indent the statement line by 4 spaces.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-75d0b1","file":"Mathlib/NumberTheory/Padics/Measure/Monoid.lean","decl":"(file)","line":9,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-import","claim":"`public import Mathlib.Analysis.Normed.Ring.Lemmas` is unused (the file compiles without it; nothing normed occurs); the `Algebra` and `CommRing` instances repeat `noncomputable` inside a `noncomputable section`; 'a `R`-algebra'.","fix":"Drop the import and the redundant modifiers; 'an'.","ev":"grep -v 'public import Mathlib.Analysis.Normed.Ring.Lemmas' Monoid.lean > Probe_noimp.lean; lake env lean Probe_noimp.lean  -- exit 0","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-5bc9ea","file":"Mathlib/NumberTheory/Padics/Measure/Monoid.lean","decl":"AbstractMeasure.convolveFunRight","line":41,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-drops-hypothesis","claim":"The module overview says D(G, R) 'inherits a convolution product' for any topological monoid G and only then adds local compactness for the ring; in fact the `Mul` instance itself needs `[LocallyCompactSpace G]`. `convolveFunRight` (x ↦ ∫ f(x y) dμ(y)) is a right-translation average, not the usual right convolution f * μ (which uses x y⁻¹); the docstring formula is right but the name invites the wrong reading.","fix":"Mention local compactness for the product; note the translation convention.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-e6c06c","file":"Mathlib/NumberTheory/Padics/Measure/Monoid.lean","decl":"AbstractMeasure.dirac_mul_dirac","line":97,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-typo","claim":"The docstring says 'Convolution of Dirac measures corresponds to addition in the group', but G is a multiplicative monoid and the statement is `dirac x * dirac y = dirac (x * y)`; the proof line also has a double space (`:=  by`).","fix":"'…corresponds to multiplication in the monoid'; single space.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-340ca1","file":"Mathlib/NumberTheory/Padics/Measure/Monoid.lean","decl":"AbstractMeasure.dirac_mul_dirac","line":98,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-simp-attribute","claim":"`dirac_mul_dirac` is not `@[simp]`: `simp` makes no progress on `dirac R x * dirac R y = dirac R (x * y)`.","fix":"Tag it `@[simp]`.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-9bacac","file":"Mathlib/NumberTheory/Padics/Measure/Monoid.lean","decl":"AbstractMeasure.diracHom","line":115,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"reprovable-from-existing-api","claim":"`Module.mul_smul` re-proves `convolveFunRight_mul` by unfolding (it is `convolveFunRight_mul μ ν f`), and `diracHom`'s fields use `ext; simp` where `rfl` and `(dirac_mul_dirac x y).symm` suffice.","fix":"`mul_smul μ ν f := convolveFunRight_mul μ ν f`; `map_one' := rfl`, `map_mul' x y := (dirac_mul_dirac x y).symm`.","ev":"example (μ ν : D(G, R)) (f : C(G, R)) : (μ * ν) • f = μ • ν • f := convolveFunRight_mul μ ν f\nexample : G →* D(G, R) where\n  toFun := dirac R\n  map_one' := rfl\n  map_mul' x y := (dirac_mul_dirac x y).symm","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-7c995d","file":"Mathlib/NumberTheory/Padics/Measure/Topology.lean","decl":"(file)","line":11,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-import","claim":"The imports `Mathlib.Analysis.Real.Sqrt`, `Mathlib.Data.EReal.Inv` and `Mathlib.Tactic.ContinuousFunctionalCalculus` are unused (the file compiles without them); they were introduced by the automated `lake shake --keep-implied` run #40343, replacing `Mathlib.Topology.ContinuousMap.Compact`. `open ContinuousMap` is unused as well.","fix":"Delete the three imports.","ev":"grep -v the three imports Topology.lean > Probe_noimports.lean; lake env lean Probe_noimports.lean  -- exit 0, no output  (also without 'open ContinuousMap')","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-a5c2b0","file":"Mathlib/NumberTheory/Padics/Measure/Topology.lean","decl":"AbstractMeasure.WeakTopology","line":41,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-casing","claim":"`WeakTopology`/`StrongTopology` are terms of type `TopologicalSpace _`, which Mathlib names in lowerCamelCase; and for vector-valued E the 'weak' topology is pointwise convergence in E's own topology (strong-operator style), not a weak topology — for scalar measures it is weak-*.","fix":"`weakTopology`/`strongTopology` (or `pointwiseTopology`), and say what 'weak' means for vector-valued E.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-a1e7bf","file":"Mathlib/NumberTheory/Padics/Measure/Topology.lean","decl":"AbstractMeasure.StrongTopology","line":48,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-typo","claim":"Both docstrings say `AbstractMeasure G R E`, but the space variable is `X`. The module docstring writes the measure space as `D(X, E)`, but that notation means `AbstractMeasure X E E`; the file works with `AbstractMeasure X R E`.","fix":"`AbstractMeasure X R E`.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261007-82747c","file":"Mathlib/NumberTheory/PrimeCounting.lean","decl":"(file)","line":1,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring","claim":"Most public lemmas lack docstrings (`primeCounting_sub_one`, the monotonicity/surjectivity/tendsto lemmas, `prime_nth_prime`, the `_eq_zero_iff` lemmas, all `primesBelow`/`primesLE` API, `primeCounting_add_le`).","fix":"Add one-line docstrings.","ev":"Measured: source.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-67b7b0","file":"Mathlib/NumberTheory/PrimeCounting.lean","decl":"primesBelow_mono","line":228,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"non-terminal-simp","claim":"`primesBelow_mono`/`primesLE_mono` end with a non-terminal `simp [mem_primesBelow]; grind` on one line (flexible `simp` followed by `grind`); and ten near-identical `primesBelow_eq_filter_I??_{zero,one,two}` lemmas (L176-226) restate the definition with every interval shape, each by `ext; simp`.","fix":"`fun _ _ h _ ↦ by simp only [mem_primesBelow]; grind` or a term proof via `Finset.filter_subset_filter`; keep the interval lemmas only if used.","ev":"Measured: source L228-234, L176-226.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-677569","file":"Mathlib/NumberTheory/PrimeCounting.lean","decl":"notMem_primesLE","line":247,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-hides-shift","claim":"`notMem_primesLE (n) : n + 1 ∉ primesLE n` hides the successor (its sibling `notMem_primesBelow` is about `n` itself); `primesBelow_mono`/`primesLE_mono` vs the file's `monotone_primeCounting` pattern; `prime_nth_prime`/`add_two_le_nth_prime` are nth-prime facts placed in the prime-counting file (moving them to `Data/Nat/Prime/Nth.lean` needs `Nat.infinite_setOfPred_prime` there, which that file does not import) (Astra A1 items 6-8).","fix":"Rename to `add_one_notMem_primesLE`, `monotone_primesBelow`/`monotone_primesLE` with aliases.","ev":"Measured: source L247-248; hunts/prime-counting/probe2.lean: `Nat.prime_nth_prime` and `Nat.infinite_setOfPred_prime` unknown under `import Mathlib.Data.Nat.Prime.Nth`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-a71898","file":"Mathlib/NumberTheory/PrimeCounting.lean","decl":"primesBelow_card_eq_primeCounting'","line":254,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"card-name-order","claim":"`primesBelow_card_eq_primeCounting'`/`primesLE_card_eq_primeCounting` put `card` after the set (Mathlib convention: `card_primesBelow`), and only the `LE` one is `@[simp]` although both are the natural simp normal form `#s = π' n`; the scoped notation `π` (Nat.Prime) collides with the scoped `π` of `Real` and `FundamentalGroupoid` when several scopes are open.","fix":"Rename to `card_primesBelow`/`card_primesLE` with deprecated aliases; make both simp.","ev":"Measured: source L254, L260; scoped notations at PrimeCounting.lean:60, Trigonometric/Basic.lean:132, FundamentalGroupoid/Basic.lean:324.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-8e38e7","file":"Mathlib/Order/Fin/Tuple.lean","decl":"finSuccAboveOrderIso_symm_apply_ne_last","line":223,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `finSuccAboveOrderIso_symm_apply_ne_last` (Order.Fin.Tuple), `finSuccAboveEquiv_symm_apply_ne_last` (Logic.Equiv.Fin.Basic) state exactly the same thing (Lean-checked). Reviewer: Copy-paste bug: `finSuccAboveOrderIso_symm_apply_ne_last` states `(finSuccAboveEquiv p).symm x = ...` (the Equiv, not the OrderIso; compare its `_last` sibling at line 219 which correctly uses `finSuccAboveOrderIso`), so it is a verbatim copy of the Equiv lemma. Keep the Equiv lemma; restate the OrderIso one with `(finSuccAboveOrderIso p).symm x` rather than deprecating.","fix":"Deprecate `finSuccAboveOrderIso_symm_apply_ne_last` in favour of `finSuccAboveEquiv_symm_apply_ne_last`.","ev":"dupscan/Check.lean: `example := (@finSuccAboveEquiv_symm_apply_ne_last : type_of% @finSuccAboveOrderIso_symm_apply_ne_last)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (mis item 19, rating NIT): There is a source-spelling inconsistency, but the named order isomorphism is constructed with `finSuccAboveEquiv p` as its underlying equivalence. Its inverse function is therefore the same one, so the existing Equiv lemma already supplies precisely this computation. Preferred spelling: `(finSuccAboveOrderIso p).symm x = (p.castLT (Fin.val_lt_last h)).predAbove x`. This is cosmetic, not a missing inverse formula. [Source](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Order/Fin/Tuple.lean#L208-L228)","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-444488","file":"Mathlib/Order/Hom/BoundedLattice.lean","decl":"InfTopHom.id_toFun","line":244,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `InfTopHom.id_toFun` (Order.Hom.BoundedLattice), `InfTopHom.id_apply` (Order.Hom.BoundedLattice) state exactly the same thing (Lean-checked). Reviewer: `id_toFun` is generated by `@[to_dual (attr := simps!)]` on SupBotHom.id. Only SupBotHom.id carries simps in the Order/Hom files; every sibling hom type has a manual @[simp] id_apply. That makes the manual non-simp `id_apply` a duplicate. Drop `simps!` from SupBotHom.id and give id_apply `(attr := simp)`; this is the to_dual image of group 43.","fix":"Deprecate `InfTopHom.id_toFun` in favour of `InfTopHom.id_apply`.","ev":"dupscan/Check.lean: `example := (@InfTopHom.id_apply : type_of% @InfTopHom.id_toFun)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"agrees","astraS":"A2 (dup2 item 52, rating NIT): Keeping simp-tagged `id_apply` on both duals and stopping redundant generation is reasonable [generator cleanup](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/Order/Hom/BoundedLattice.lean#L243-L260). Preserve the generated names temporarily as deprecated aliases.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-d5fa6f","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"upperClosure","line":20,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"module-doc-main-decls-incomplete","claim":"This is about the module docstring, which sits directly above `upperClosure`; the docstring of `upperClosure` itself is correct. The module docstring's 'Main declarations' lists only `upperClosure` and `lowerClosure`. It omits the file's other definitions, `giUpperClosureCoe`/`giLowerClosureCoe` (L95, L103) and `UpperSet.sdiff`/`UpperSet.erase` with their `LowerSet` duals (L230, L236), and it does not mention the '### Set Difference' section at all.","fix":"Add the Galois insertions and `UpperSet.sdiff`/`erase` (with their `LowerSet` duals) to the 'Main declarations' list.","ev":"grep -nE '^(def|protected def)|^\\* `|^/-! ###' src.lean gives 22:* `upperClosure`, 23:* `lowerClosure`, 37:def upperClosure, 95:def giUpperClosureCoe, 103:def giLowerClosureCoe, 223:/-! ### Set Difference -/, 230:def sdiff, 236:def erase","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-43bff3","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"IsUpperSet.upperClosure","line":62,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-omits-eq","claim":"`IsUpperSet.upperClosure : IsUpperSet s → ↑(upperClosure s) = s` (dual `IsLowerSet.lowerClosure`) breaks the established `P.upperClosure` pattern of its siblings, where `hs.upperClosure` means that P is preserved by upperClosure: `IsOpen.upperClosure : IsOpen s → IsOpen ↑(upperClosure s)` (Topology/Algebra/Order/UpperLower.lean:70), `IsClosed.upperClosure` (Topology/Order/IsLUB.lean:274) and `Set.Finite.upperClosure : s.Finite → (↑(upperClosure s)).Finite` (Order/UpperLower/LocallyFinite.lean:26). Mathlib's name for this shape is `_eq`, as in `IsClosed.closure_eq : IsClosed s → closure s = s` (Topology/Closure.lean:226) and `ClosureOperator.IsClosed.closure_eq` (Order/Closure.lean:149). It has no consumers outside the file (git grep: 0 hits); inside the file it is used at L63, L67 and L188.","fix":"Rename to `IsUpperSet.upperClosure_eq` (to_dual `IsLowerSet.lowerClosure_eq`) and keep deprecated aliases.","ev":"batch0/probe2.lean: `example (hs : IsUpperSet s) : IsUpperSet (upperClosure s : Set α) := hs.upperClosure` gives a Type mismatch: `IsUpperSet.upperClosure hs` has type `↑(upperClosure s) = s`. The sibling names and the 0-consumer count come from `git -C mathlib4 grep -nE '\\.(upperClosure|lowerClosure)\\b' origin/master -- Mathlib`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-f2a76b","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"upperClosure_image","line":70,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"unneeded-rw-round-trip","claim":"The opening `rw [← f.symm_symm, ← UpperSet.symm_map, f.symm_symm]` (a round trip copied from `UpperSet.mem_map`) is unnecessary: deleting it leaves a proof that still compiles, and so does the to_dual-generated `lowerClosure_image`. The whole 4-line proof can be the single line `ext; simp [-UpperSet.coe_map_apply, f.le_symm_apply]`. Plain `ext; simp` does NOT work inside the file: `UpperSet.coe_map_apply` turns the goal into an image form and leaves `(∃ a ∈ s, f a ≤ x) ↔ ∃ x, (∃ a ∈ s, a ≤ x) ∧ f x = x✝`. An earlier standalone probe passed only because it used the lemma itself.","fix":"Replace the proof by `ext; simp [-UpperSet.coe_map_apply, f.le_symm_apply]`, or at least delete the first `rw` line.","ev":"batch0/Closure_golf.lean: a copy of src.lean in which upperClosure_image is proved by `ext; simp [-UpperSet.coe_map_apply, f.le_symm_apply]`, plus a variant `upperClosure_image'` that is the original proof without its `rw` line (both @[to_dual]). It compiles with the mathlibStandardSet linters and no warnings; `#check @lowerClosure_image` and `#check @lowerClosure_image'` show the correct duals.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-2fdc5b","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"upperClosure_union","line":133,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"needless-explicit-at","claim":"The proof `(@gc_upperClosure_coe α _).l_sup` spells out implicit arguments it does not need: `gc_upperClosure_coe.l_sup` elaborates. The same leftover appears in lowerClosure_union (L137), upperClosure_iUnion (L140) and lowerClosure_iUnion (L144).","fix":"Replace `(@gc_upperClosure_coe α _).l_sup` with `gc_upperClosure_coe.l_sup` (and the same for the l_sup/l_iSup proofs at L137, L140 and L144).","ev":"hunts/upperlower-closure/batch1/src_copy.lean (a copy of src.lean with lines 133, 137, 159, 163 changed to `gc_upperClosure_coe.l_sup`, `gc_lowerClosure_coe.l_sup`, `gc_upperClosure_coe.l_iSup`, `gc_lowerClosure_coe.l_iSup`) compiles with no errors or warnings under the prescribed flags.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-a116bd","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"ordConnected_iff_upperClosure_inter_lowerClosure","line":155,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"wrong-namespace","claim":"Declared in the root namespace although it characterises `Set.OrdConnected`: its forward direction is `Set.OrdConnected.upperClosure_inter_lowerClosure`, and every other `ordConnected_iff*` lemma (`Set.ordConnected_iff`, `Set.ordConnected_iff_uIcc_subset(_left/_right)` in Order/Interval/Set/OrdConnected.lean inside `namespace Set`, `Set.ordConnected_iff_disjoint_Ioo_empty`) lives in `Set`, so `Set.ordConnected_iff_upperClosure_inter_lowerClosure` does not resolve. It has no consumers in Mathlib.","fix":"Rename to `Set.ordConnected_iff_upperClosure_inter_lowerClosure` with a deprecated root alias (no call sites to update).","ev":"hunts/upperlower-closure/batch2/Probe3.lean (F3 block):\n#check @Set.ordConnected_iff  -- resolves\n#check @ordConnected_iff_upperClosure_inter_lowerClosure  -- resolves (root)\nexample : True := by\n  have := @Set.ordConnected_iff_upperClosure_inter_lowerClosure -- error: Unknown constant\n  trivial\ngit grep -n ordConnected_iff_upperClosure_inter_lowerClosure origin/master -- Mathlib: only the declaration itself","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-4999a9","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"upperClosure_eq","line":186,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"iff-name-omits-self","claim":"`upperClosure_eq : ↑(upperClosure s) = s ↔ IsUpperSet s` (dual `lowerClosure_eq`) is named as if it were an unconditional equation for `upperClosure`; the naming convention for `f s = s ↔ P s` wants `_self` (`coe_upperClosure_eq_self`) or the `_iff_` form of the topology analogue `closure_eq_iff_isClosed : closure s = s ↔ IsClosed s`, whose one-way partner `IsClosed.closure_eq` mirrors this file's `IsUpperSet.upperClosure`.","fix":"Rename to `coe_upperClosure_eq_self` (or `upperClosure_eq_iff_isUpperSet`), dual likewise, with deprecated aliases; the one consumer is Mathlib/Topology/Inseparable.lean:321 (`← lowerClosure_eq`).","ev":"git -C mathlib4 grep -nE 'theorem (closure_eq_iff_isClosed|IsClosed.closure_eq)' origin/master -- Mathlib\nMathlib/Topology/Closure.lean:226:theorem IsClosed.closure_eq (h : IsClosed s) : closure s = s :=\nMathlib/Topology/Closure.lean:269:theorem closure_eq_iff_isClosed : closure s = s ↔ IsClosed s :=\n#check @upperClosure_eq  -- ∀ {α} [Preorder α] {s : Set α}, ↑(upperClosure s) = s ↔ IsUpperSet s  (hunts/upperlower-closure/batch2/Probe1.lean)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-f74b40","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"IsAntichain.minimal_mem_upperClosure_iff_mem","line":197,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-unfolds-definition-needlessly","claim":"The first tactic `simp only [upperClosure]` unfolds the definition, against the file's own policy at L44 (\"to respect the abstraction\"), and it does nothing that is needed: the proof compiles unchanged without it, because membership in upperClosure is already defeq to the existential.","fix":"Delete the line `simp only [upperClosure]` (or, better, reprove from a general `minimal_mem_upperClosure_iff`).","ev":"hunts/upperlower-closure/batch3/src_v1.lean = src.lean with line 197 `simp only [upperClosure]` deleted; compiles with exit 0 and no warnings","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-e9bd36","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"UpperSet.sdiff","line":228,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-order-direction-ambiguous","claim":"\"The biggest upper subset of `s` disjoint from `t`\" is right only for inclusion. In `UpperSet α`'s own order (reverse inclusion), s.sdiff t is the LEAST element of {u | s ≤ u ∧ Disjoint ↑u t}, whose greatest element is ⊤ = ∅. The same file uses the opposite convention for `upperClosure` (\"the greatest upper set containing\", which holds only in the UpperSet order), so the reader cannot tell which order is meant. The LowerSet dual's docstring is unambiguous.","fix":"Say \"the largest (for inclusion) upper subset … , i.e. the least element of `UpperSet α` below … \", or similar.","ev":"hunts/upperlower-closure/batch3/probe1.lean section C: `example : IsLeast {u : UpperSet α | s ≤ u ∧ Disjoint (u : Set α) t} (s.sdiff t)` and `example : IsGreatest {u : UpperSet α | s ≤ u ∧ Disjoint (u : Set α) t} ⊤`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-71b8c7","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"UpperSet.sdiff","line":230,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"definition-is-composite-of-existing-ops","claim":"The definition is a composite of existing lattice operations: `s.sdiff t = s ⊔ (lowerClosure t).compl` holds by `rfl` (dually `LowerSet.sdiff s t = s ⊓ (upperClosure t).compl`, and `s.erase a = s ⊔ (LowerSet.Iic a).compl`), but no lemma records it, so the UpperSet lattice API cannot be brought to bear. The named def is still reasonable for its defeq-friendly API.","fix":"Add `sdiff_eq_sup_compl : s.sdiff t = s ⊔ (lowerClosure t).compl := rfl` (with to_dual).","ev":"hunts/upperlower-closure/batch3/probe1.lean section C: `example (s : UpperSet α) (t : Set α) : s.sdiff t = s ⊔ (lowerClosure t).compl := rfl`, `example (s : LowerSet α) (t : Set α) : s.sdiff t = s ⊓ (upperClosure t).compl := rfl`, `example (s : UpperSet α) (a : α) : s.erase a = s ⊔ (LowerSet.Iic a).compl := rfl`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-ff8108","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"UpperSet.erase","line":234,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-order-direction-ambiguous","claim":"\"The biggest upper subset of `s` not containing `a`\" is right only for inclusion. In `UpperSet α`'s order s.erase a is the least u with s ≤ u and a ∉ u (by `erase_le_iff'`), and this conflicts with the file's \"greatest\" for upperClosure, which is meant in the UpperSet order.","fix":"Say \"largest for inclusion\" explicitly.","ev":"hunts/upperlower-closure/batch3/probe1.lean section C: `theorem UpperSet.erase_le_iff' {u : UpperSet α} : s.erase a ≤ u ↔ s ≤ u ∧ a ∉ u`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-a304fb","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"UpperSet.erase_eq","line":258,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"iff-name-drops-rhs","claim":"`UpperSet.erase_eq : s.erase a = s ↔ a ∉ s` (to_dual `LowerSet.erase_eq`) is the statement Mathlib names `Finset.erase_eq_self : s.erase a = s ↔ a ∉ s` (@[simp], Mathlib/Data/Finset/Erase.lean:79). The name drops the right-hand side `self`, and `erase_eq` is what Finset calls a different statement, `Finset.erase_eq (s) (a) : s.erase a = s \\ {a}` (Mathlib/Data/Finset/Basic.lean:203). The sibling `UpperSet.sdiff_eq_left` does name its RHS.","fix":"Rename to `erase_eq_self` (dual `LowerSet.erase_eq_self`) with a `@[deprecated]` alias.","ev":"git -C mathlib4 grep -n 'theorem erase_eq' origin/master -- Mathlib/Data/Finset → Erase.lean:79 `@[simp] theorem erase_eq_self : s.erase a = s ↔ a ∉ s`; Basic.lean:203 `theorem erase_eq (s : Finset α) (a : α) : s.erase a = s \\ {a}`; #check @UpperSet.erase_eq in hunts/upperlower-closure/batch4/probe1.lean prints `s.erase a = s ↔ a ∉ s`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-0d2eef","file":"Mathlib/Order/UpperLower/Closure.lean","decl":"UpperSet.erase_eq","line":258,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"rw-reverse-then-simp-erase","claim":"The proof `by rw [← sdiff_singleton]; simp [-sdiff_singleton]` is the roundabout form of `by simp [← sdiff_singleton]` (simp drops the forward lemma itself when given the reversed one). Verified in a copy of the file with `@[to_dual (attr := simp)]` intact, so the generated `LowerSet.erase_eq` also compiles.","fix":"Replace the proof by `by simp [← sdiff_singleton]`.","ev":"hunts/upperlower-closure/batch4/Closure_b4.lean:260-261: `@[to_dual (attr := simp)] lemma erase_eq : s.erase a = s ↔ a ∉ s := by simp [← sdiff_singleton]` (whole copy compiles, no errors); also hunts/upperlower-closure/batch4/probe1.lean:169 `example : s.erase a = s ↔ a ∉ s := by simp [← UpperSet.sdiff_singleton]`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261006-70e202","file":"Mathlib/Probability/Decision/BayesEstimator.lean","decl":"(module docstring)","line":41,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"stale-docstring","claim":"The module docstring lists `bayesRisk_eq_of_hasArgminEstimator`, which does not exist (the theorem is `HasArgminEstimator.bayesRisk_eq`); `IsArgminEstimator`/`HasArgminEstimator` re-bind `{𝓨 : Type*} [MeasurableSpace 𝓨]`, shadowing the section variables.","fix":"Cite `HasArgminEstimator.bayesRisk_eq`; drop the re-bound variables.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-0af205","file":"Mathlib/Probability/Decision/BayesEstimator.lean","decl":"ProbabilityTheory.avgRisk_eq_lintegral_lintegral_lintegral","line":78,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"reprovable-from-existing-api","claim":"`avgRisk_eq_lintegral_lintegral_lintegral` expands `Kernel.prod_apply` and applies measure-level `lintegral_prod_symm'` where the kernel-level `Kernel.lintegral_prod_symm` applies directly; the fixed-estimator identities only need a.e.-measurability of the loss.","fix":"Use `Kernel.lintegral_prod_symm`.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261007-44a3c2","file":"Mathlib/Probability/Distributions/Binomial.lean","decl":"binomial","line":56,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"copied-docstring","claim":"`binomial`'s docstring 'The binomial probability distribution with parameter `p`' (copied onto both notations) omits `n`; the implementation notes write `Bin(R, n p)` (missing comma); `binomial_nonneg` is a `@[simp]` lemma about the real expression `n.choose k * p ^ k * (1 - p) ^ (n - k)` whose name suggests a statement about the measure.","fix":"Mention both parameters; fix the typo; rename `binomial_nonneg` (e.g. `choose_mul_pow_mul_pow_nonneg`).","ev":"Measured: source L54-63, L27, L99.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-ca56da","file":"Mathlib/Probability/Distributions/SetBernoulli.lean","decl":"(file)","line":36,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-variable","claim":"The section variable `{i : ι}` (L36) is never used (every occurrence of `i` binds its own), and predicate binders named `p`/`P` (L55, L64) shadow the probability parameter `p : I` and the measure `P`.","fix":"Drop `{i : ι}` from the `variable` line and rename the predicate binders (e.g. `q`).","ev":"Hygiene-only finding: L36 `variable … {i : ι}`; L55 `fun p : ι → Prop ↦ {i | p i}`, L64 `fun p ↦ {i | p i}`. Raised by Astra's A1 pass (item 14).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-a2b95e","file":"Mathlib/Probability/Distributions/SetBernoulli.lean","decl":"setBernoulli","line":40,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstrings","claim":"The definition's docstring speaks of `u : Set V` and a measure on `Set V`, but the variable is `ι`; most lemmas (`setBernoulli_eq_map`, `_apply`, `_apply'`, `_ae_subset`, `_singleton`, the `map_ncard_*` binomial computations, `setBernoulli_empty`, `isSetBernoulli_congr`, `IsSetBernoulli.ae_subset`) have no docstring, and the module docstring has no main-results list (in particular it does not mention the binomial law of `ncard`). The definition's description lists only the marginals and never says the coordinates are taken *independently* (which is what distinguishes it from, e.g., `Ber(u, ∅, 1/2)`), `map_ncard_setBernoulli_apply` does not warn that for infinite `u` the pushforward uses `ncard`'s junk value `0` (e.g. `setBer(univ, 1).map ncard = dirac 0` on `ℕ`), and 'bernoulli' is lower-cased in prose (Astra A1 items 7, 8, 13).","fix":"Write `Set ι` in the definition docstring, add one-line docstrings, and list the main results in the module docstring.","ev":"Doc-only finding: L40-42 docstring `on the set `u : Set V` is the measure on `Set V``; L13-28 module docstring.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-873f2f","file":"Mathlib/Probability/Distributions/SetBernoulli.lean","decl":"setBernoulli","line":40,"sev":"NIT","status":"suspected","cat":"docs","pattern":"docstring-overstates-support","claim":"The definition's docstring says 'the elements outside of `u` are never taken'. This holds coordinatewise for every `ι`, but for uncountable `ι \\ u` the event 'the random set is not contained in `u`' is not null: by Astra's argument every measurable superset of `{s | ¬ s ⊆ u}` depends on countably many coordinates and so is everything, giving outer measure `1` (e.g. `setBer(∅, 0) = dirac ∅` on `Set ℝ` while `{s | s ≠ ∅}` has outer measure 1). This is why `setBernoulli_ae_subset` needs countability; the docstring should say 'each element outside `u` is a.s. not taken'.","fix":"Phrase the docstring coordinatewise and point to `setBernoulli_ae_subset` (countable `ι`) for the simultaneous statement.","ev":"Suspected: paper argument from Astra's A1 item 1 (via `MeasurableSet.eq_preimage_restrict_countable`); not formalised.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-d31e05","file":"Mathlib/Probability/Distributions/SetBernoulli.lean","decl":"setBernoulli","line":45,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"identity-comap","claim":"`setBernoulli` is defined as `.comap (fun s i ↦ i ∈ s) (infinitePi …)`, but `Set ι` is `ι → Prop` with the same measurable space and `fun s i ↦ i ∈ s` is definitionally the identity, so the `comap` (and the `MeasurableEquiv.setOfPred` transport in the probability instance and the `_apply` lemmas) wraps an already correctly typed product measure.","fix":"Define `setBernoulli u p := (infinitePi fun i : ι ↦ Ber(i ∈ u, False, p) : Measure (Set ι))` and simplify the transport lemmas.","ev":"hunts/set-bernoulli/probe2.lean A10: `setBer(u, p) = (infinitePi … : Measure (Set ι))` by `change Measure.comap (fun x ↦ x) _ = _; exact Measure.comap_id _` compiles. Exit 0. Raised by Astra's A1 pass (item 10).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-208162","file":"Mathlib/Probability/Distributions/SetBernoulli.lean","decl":"setBernoulli_apply_eq_apply_subsets","line":95,"sev":"NIT","status":"confirmed","cat":"api","pattern":"inconsistent-binder-explicitness","claim":"Argument explicitness is inconsistent across the section: `setBernoulli_ae_subset` takes `u p` implicitly, while `setBernoulli_singleton_of_not_subset` re-binds `(p : I)` explicitly (with `s` implicit), `setBernoulli_apply_eq_apply_subsets` and `map_ncard_setBernoulli_apply` re-bind `(u : Set ι) (p : I)` explicitly, `setBernoulli_singleton` makes `p` explicit via `variable (p) in`, and `setBernoulli_real_singleton` binds `(p : I)` explicitly after `{s u}` implicit; several of these shadow the section variables `{s u : Set ι} {p : I}`.","fix":"Pick one convention (e.g. `u p` explicit only where not inferable from other arguments) and drop the shadowing re-binders.","ev":"API-shape finding: L36 `variable … {s u : Set ι} … {p : I}`; L90 `(p : I)`, L95 `(u : Set ι) (p : I) (S …)`, L100 `(u : Set ι) (p : I) (s : Set ℕ)`, L105 `variable (p) in`, L123 `(p : I)`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-5ef7a3","file":"Mathlib/Probability/Distributions/SetBernoulli.lean","decl":"setBernoulli_apply_eq_apply_subsets","line":97,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-detour","claim":"Two proofs rebuild existing lemmas: `setBernoulli_apply_eq_apply_subsets` assembles `measure_eq_measure_of_null_sdiff` with two `grind` side goals where `measure_inter_conull` gives it in one term, and `map_ncard_setBernoulli_singleton` spells out `ENNReal.ofReal_toReal`/`measureReal_def` where `ofReal_measureReal` packages the conversion.","fix":"Use `(measure_inter_conull setBernoulli_ae_subset).symm` and `rw [← ofReal_measureReal, map_ncard_setBernoulli_real_singleton hu]`.","ev":"hunts/set-bernoulli/probe2.lean A11 and A12 (the two one-line replacements) compile. Exit 0. Raised by Astra's A1 pass (items 11, 12).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261013-e882c1","file":"Mathlib/Probability/Independence/ZeroOne.lean","decl":"Kernel.measure_eq_zero_or_one_or_top_of_indepSet_self","line":35,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"reproves-existing-lemma","claim":"The proof specializes the independence hypothesis by hand with two `measurableSet_generateFrom` witnesses and cancels with `ENNReal.mul_left_inj`; `Kernel.IndepSet.measure_inter_eq_mul` gives the product formula directly and `ENNReal.mul_eq_left` the cancellation.","fix":"`filter_upwards [Kernel.IndepSet.measure_inter_eq_mul κ μα h_indep]`, `rw [Set.inter_self]`, then `(ENNReal.mul_eq_left h0 h_top).1 ha.symm`.","ev":"hunts/zero-one/probe_astra.lean (A6): this proof of the statement compiles, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-ea1fa8","file":"Mathlib/Probability/Independence/ZeroOne.lean","decl":"Kernel.measure_eq_zero_or_one_of_indep_self","line":64,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"reproves-existing-lemma","claim":"The proof restricts both σ-algebras to `generateFrom {t}` by hand (`indep_of_indep_of_le` with two `generateFrom_singleton_le`); `Kernel.Indep.indepSet_of_measurableSet` does exactly this.","fix":"`measure_eq_zero_or_one_of_indepSet_self (hm.indepSet_of_measurableSet ht ht)`.","ev":"hunts/zero-one/probe_astra.lean (A7): this proof compiles, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-13fde7","file":"Mathlib/Probability/Independence/ZeroOne.lean","decl":"(file)","line":111,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"stale-docstring","claim":"The `Abstract` section note says '`ns : α → Set ι`' but the variable is `ns : β → Set ι` (`α` is the kernel's source type), writes '`p = bddAbove`' for `BddAbove`, and gives the `atTop` example without the order assumptions it needs (for `ι = Unit`, `BddAbove univ` holds but `∅ ∉ atTop`).","fix":"Write `ns : β → Set ι`, `p = BddAbove`, and 'for `f = atTop` on an order with no maximal element'.","ev":"Measured: src L109 (`{ns : β → Set ι}`) vs L114 and L118; L254 (`[NoMaxOrder ι]` needed for `exists_gt`).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-7efd46","file":"Mathlib/Probability/Independence/ZeroOne.lean","decl":"Kernel.indep_biSup_limsup","line":121,"sev":"NIT","status":"confirmed","cat":"api","pattern":"indirect-hypothesis","claim":"`indep_biSup_limsup` (kernel, measure, conditional) takes `p`, `hf : ∀ t, p t → tᶜ ∈ f` and `ht : p t`, but the proof only uses `hf t ht : tᶜ ∈ f`; a single hypothesis `(htf : tᶜ ∈ f)` states it.","fix":"Take `(htf : tᶜ ∈ f)` instead of `p`, `hf`, `ht`.","ev":"Measured: src L124-127 use `hf` and `ht` only as `hf t ht`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-cc5485","file":"Mathlib/Probability/Independence/ZeroOne.lean","decl":"Kernel.indep_iSup_limsup","line":181,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"reproves-existing-lemma","claim":"Two local order arguments rebuild existing lemmas: `Kernel.indep_iSup_limsup` turns the existential into an inhabited proposition to use `iSup_const` (`biSup_const (hns_univ n)` does it), and `Kernel.indep_limsup_atTop_self` unfolds `mem_atTop_sets`/`upperBounds` and builds a strict upper bound (`(eventually_gt_atTop a).mono` does it in one line).","fix":"`rw [iSup_comm]; exact iSup_congr fun n => biSup_const (hns_univ n)` and `rintro t ⟨a, ha⟩; exact (eventually_gt_atTop a).mono fun b hb hbt => (ha hbt).not_gt hb`.","ev":"hunts/zero-one/copyF.lean: the file with both replacements compiles with the Mathlib linter set, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-3624b4","file":"Mathlib/Probability/Independence/ZeroOne.lean","decl":"measure_zero_or_one_of_measurableSet_limsup","line":229,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"inconsistent-naming","claim":"The same conclusion shape is named two ways: `measure_eq_zero_or_one_of_indepSet_self`, `condExp_eq_zero_or_one_of_condIndepSet_self` (with `eq_`) but `measure_zero_or_one_of_measurableSet_limsup*`, `condExp_zero_or_one_of_measurableSet_limsup*` (without). The prime in `Kernel.measure_eq_zero_or_one_of_indepSet_self'` does not say it is the almost-everywhere-finite variant.","fix":"Use `…_eq_zero_or_one_…` throughout (with deprecated aliases) and name the primed lemma `…_of_ae_isFiniteMeasure`.","ev":"Measured: names at L48-80 vs L219-358.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-86ce98","file":"Mathlib/Probability/Independence/ZeroOne.lean","decl":"Kernel.measure_zero_or_one_of_measurableSet_limsup_atTop","line":280,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring","claim":"Docstrings are uneven: 4 of 38 declarations have one. The `atBot` kernel and conditional laws have docstrings, their `atTop` counterparts do not; the abstract laws (`measure_zero_or_one_of_measurableSet_limsup` and kernel/conditional versions) have none; the module's Main statements list only `measure_zero_or_one_of_measurableSet_limsup_atTop`. The `atBot` docstrings speak of the 'tail σ-algebra of an independent sequence' without saying the tail is at `-∞`, and the conditional `atBot` docstring omits 'almost everywhere'.","fix":"Give the `atTop` kernel/conditional laws and the abstract laws docstrings, list the kernel, conditional, `atBot` and abstract versions in Main statements, and fix the `atBot` wording.","ev":"Measured: docstrings only at L287, L335, L344, L353; module docstring L17-21.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261013-ab207d","file":"Mathlib/Probability/Independence/ZeroOne.lean","decl":"measure_zero_or_one_of_measurableSet_limsup_atTop","line":290,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"There is no bridge to `MeasureTheory.IsZeroOneMeasure`: the 0-1 law is only stated event by event, though it says exactly that `μ.trim (tail ≤ m0)` is a zero-one measure.","fix":"Add `isZeroOneMeasure_trim_limsup_atTop : IsZeroOneMeasure (μ.trim (limsup_le_iSup.trans (iSup_le h_le)))`.","ev":"hunts/zero-one/probe_astra.lean (A13): the instance is built from `trim_measurableSet_eq` and `measure_zero_or_one_of_measurableSet_limsup_atTop`, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261007-b129d3","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.hasFiniteIntegral_prodMk_left","line":64,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"inconsistent-sibling-names","claim":"The name does not mention kernels, while its only consumer and sibling, stated about the same function, is `integrable_kernel_prodMk_left` (L79). The Measure.prod analogue is `Measure.integrable_measure_prodMk_left`. In the `ProbabilityTheory` namespace, a bare `hasFiniteIntegral_prodMk_left` reads like a product-measure statement.","fix":"Rename to `hasFiniteIntegral_kernel_prodMk_left` (with a deprecated alias) to match `integrable_kernel_prodMk_left`.","ev":"src.lean L64 `theorem hasFiniteIntegral_prodMk_left` vs L79 `theorem integrable_kernel_prodMk_left`; `git grep hasFiniteIntegral_prodMk_left origin/master -- Mathlib` gives no other uses.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-ccf529","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"MeasureTheory.AEStronglyMeasurable.compProd_mk_left","line":91,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"stale-mk-naming","claim":"The name keeps the pre-rename `mk` spelling. The Measure.prod analogue is now `AEStronglyMeasurable.prodMk_left`, and the deprecated `prod_mk_left` aliases are gone from MeasureTheory. Within this file, the Measure-level wrapper of this same lemma is called `AEStronglyMeasurable.ae_of_compProd` (L453), while the kernel-level Integrable analogue is `Integrable.ae_of_compProd` (L140). So `ae_of_compProd` means the kernel version for `Integrable` but the Measure version for `AEStronglyMeasurable`.","fix":"Rename to `AEStronglyMeasurable.compProd_prodMk_left` (or a name parallel to `Integrable.ae_of_compProd`) with a deprecated alias.","ev":"src.lean L91 vs L140 and L453; Mathlib/MeasureTheory/Integral/Prod.lean `theorem MeasureTheory.AEStronglyMeasurable.prodMk_left`; `git grep prod_mk_left origin/master -- Mathlib/MeasureTheory` finds nothing.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-ea8583","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.hasFiniteIntegral_compProd_iff","line":100,"sev":"NIT","status":"confirmed","cat":"generality","pattern":"special-case-of-sibling","claim":"The `StronglyMeasurable f` version is the special case of `hasFiniteIntegral_compProd_iff'` (L118, `AEStronglyMeasurable f ((κ ⊗ₖ η) a)`) applied to `h1f.aestronglyMeasurable`. Its only consumer is the primed proof. It mirrors Prod.lean's `hasFiniteIntegral_prod_iff`/`'` pair.","fix":"Optional: make the unprimed lemma a private stepping stone, or swap the names so that the general form is unprimed (with deprecated aliases).","ev":"hunts/kernel-integral-compprod/batch0/probe.lean theorem Probe.P3: the exact statement of hasFiniteIntegral_compProd_iff := hasFiniteIntegral_compProd_iff' h1f.aestronglyMeasurable. Exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-fedc70","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.hasFiniteIntegral_compProd_iff","line":110,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"repeated-local-have","claim":"The ad hoc propositional helper `have : ∀ {p q r : Prop} (_ : r → p), (r ↔ p ∧ q) ↔ p → (r ↔ q)` is copied verbatim into three proofs in Mathlib. Prod.lean's comment calls it \"probably too specialized to be its own lemma\", but it now has three copies.","fix":"Factor it into a Logic lemma (e.g. `iff_and_iff_of_imp`) or restructure the three proofs, so that the copies go.","ev":"`git grep -n \"∀ {p q r : Prop} (_ : r → p), (r ↔ p ∧ q) ↔ p → (r ↔ q)\" origin/master -- Mathlib` gives MeasureTheory/Integral/Prod.lean:203, IntegralCompProd.lean:110 and IntegralCompProd.lean:301.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-3d607c","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.integrable_compProd_iff","line":133,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring-key-lemma","claim":"None of the batch's declarations (L60-157) has a docstring. In particular the main integrability criterion `integrable_compProd_iff` and the measurability lemma `AEStronglyMeasurable.integral_kernel_compProd` lack the docstrings their Prod.lean counterparts carry (`integrable_prod_iff`: \"A binary function is integrable if ...\"; `AEStronglyMeasurable.integral_prod_right'`: \"The Bochner integral is a.e.-measurable ...\"). The module docstring's \"Main statements\" also omits the integrability criterion.","fix":"Port the Prod.lean docstrings, adapted to `κ ⊗ₖ η`, and list `integrable_compProd_iff` under Main statements.","ev":"`awk 'NR>=60&&NR<=157&&/\\/--/' src.lean | wc -l` = 0; Prod.lean L226-227 and the docstring of `AEStronglyMeasurable.integral_prod_right'`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-17faf8","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"MeasureTheory.Integrable.integral_compProd","line":148,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"mono-instead-of-mono-prime","claim":"The 9-line term proof (L151-156) uses `Integrable.mono` and then rebuilds `‖∫ ‖f‖‖ = ∫ ‖f‖` through `norm_of_nonneg`/`integral_nonneg_of_ae`. `Integrable.mono'` takes the real-valued bound directly. The Prod.lean analogue `Integrable.integral_prod_left` has already been shortened (`grw`).","fix":"Use `hf.integral_norm_compProd.mono' hf.aestronglyMeasurable.integral_kernel_compProd (ae_of_all _ fun _ => norm_integral_le_integral_norm _)`.","ev":"hunts/kernel-integral-compprod/batch0/probe.lean theorem Probe.P2 (same statement, the 3-line `mono'` proof). Exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-252a1f","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.Kernel.integral_fn_integral_add","line":163,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-dropped-from-prod-original","claim":"No docstring. The MeasureTheory/Integral/Prod.lean original it was copied from has 'Integrals commute with addition inside another integral. `F` can be any function.'. Mathlib does not require docstrings on auxiliary lemmas, so this is cosmetic.","fix":"Copy the Prod.lean docstring, adapted to κ ⊗ₖ η.","ev":"measured: src.lean has no '/--' anywhere (grep), original docstring at Mathlib/MeasureTheory/Integral/Prod.lean:358","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-cf671c","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.Kernel.integral_fn_integral_sub","line":171,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-dropped-from-prod-original","claim":"No docstring. The MeasureTheory/Integral/Prod.lean original it was copied from has 'Integrals commute with subtraction inside another integral. `F` can be any measurable function.'. Mathlib does not require docstrings on auxiliary lemmas, so this is cosmetic.","fix":"Copy the Prod.lean docstring, adapted to κ ⊗ₖ η.","ev":"measured: src.lean has no '/--' anywhere (grep), original docstring at Mathlib/MeasureTheory/Integral/Prod.lean:367-368","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-31fc5b","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.Kernel.lintegral_fn_integral_sub","line":179,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-dropped-from-prod-original","claim":"No docstring. The MeasureTheory/Integral/Prod.lean original it was copied from has 'Integrals commute with subtraction inside a lower Lebesgue integral. `F` can be any function.'. Mathlib does not require docstrings on auxiliary lemmas, so this is cosmetic.","fix":"Copy the Prod.lean docstring, adapted to κ ⊗ₖ η.","ev":"measured: src.lean has no '/--' anywhere (grep), original docstring at Mathlib/MeasureTheory/Integral/Prod.lean:377-378","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-7f2ee5","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.Kernel.integral_integral_add","line":187,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-dropped-from-prod-original","claim":"No docstring. The MeasureTheory/Integral/Prod.lean original it was copied from has 'Double integrals commute with addition.'. Mathlib does not require docstrings on auxiliary lemmas, so this is cosmetic.","fix":"Copy the Prod.lean docstring, adapted to κ ⊗ₖ η.","ev":"measured: src.lean has no '/--' anywhere (grep), original docstring at Mathlib/MeasureTheory/Integral/Prod.lean:387","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-81fe7e","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.Kernel.integral_integral_add'","line":194,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-dropped-from-prod-original","claim":"No docstring. The MeasureTheory/Integral/Prod.lean original it was copied from has 'Double integrals commute with addition. This is the version with `(f + g) (x, y)` (instead of `f (x, y) + g (x, y)`) in the LHS.'. The prime goes unexplained: nothing says this is the '(f ± g) (x, y)' form used for rewriting. Mathlib does not require docstrings on auxiliary lemmas, so this is cosmetic.","fix":"Copy the Prod.lean docstring, adapted to κ ⊗ₖ η.","ev":"measured: src.lean has no '/--' anywhere (grep), original docstring at Mathlib/MeasureTheory/Integral/Prod.lean:394-395","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-9e76c4","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.Kernel.integral_integral_sub","line":200,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-dropped-from-prod-original","claim":"No docstring. The MeasureTheory/Integral/Prod.lean original it was copied from has 'Double integrals commute with subtraction.'. Mathlib does not require docstrings on auxiliary lemmas, so this is cosmetic.","fix":"Copy the Prod.lean docstring, adapted to κ ⊗ₖ η.","ev":"measured: src.lean has no '/--' anywhere (grep), original docstring at Mathlib/MeasureTheory/Integral/Prod.lean:401","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-3e93e2","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.Kernel.integral_integral_sub'","line":207,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-dropped-from-prod-original","claim":"No docstring. The MeasureTheory/Integral/Prod.lean original it was copied from has 'Double integrals commute with subtraction. This is the version with `(f - g) (x, y)` (instead of `f (x, y) - g (x, y)`) in the LHS.'. The prime goes unexplained: nothing says this is the '(f ± g) (x, y)' form used for rewriting. Mathlib does not require docstrings on auxiliary lemmas, so this is cosmetic.","fix":"Copy the Prod.lean docstring, adapted to κ ⊗ₖ η.","ev":"measured: src.lean has no '/--' anywhere (grep), original docstring at Mathlib/MeasureTheory/Integral/Prod.lean:408-409","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-55f943","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.Kernel.continuous_integral_integral","line":213,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"inconsistent-twin-proof","claim":"The proof is a less tidy copy of its twin continuous_integral_integral_comp in the same file. It passes the bounding function as a '_' hole of 'apply' and fills it in a separate bullet plus 'swap', and it spells the L1 type as 'Lp (α := β × γ) E 1 (((κ ⊗ₖ η) a) : Measure (β × γ))'. The twin's style (named '(h := ...)', 'β × γ →₁[(κ ⊗ₖ η) a] E', 'continuous_iff_continuousAt.2 fun g ↦ ?_') compiles in 14 lines instead of 17.","fix":"Align the proof with continuous_integral_integral_comp (named h argument, →₁ notation in the have).","ev":"hunts/kernel-integral-compprod/batch1/Copy1.lean L213-226 (compiles; Copy1.out has no messages)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-fe38e0","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.Kernel.continuous_integral_integral","line":213,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-dropped-from-prod-original","claim":"No docstring. The MeasureTheory/Integral/Prod.lean original it was copied from has 'The map that sends an L¹-function `f : α × β → E` to `∫∫f` is continuous.'. Mathlib does not require docstrings on auxiliary lemmas, so this is cosmetic.","fix":"Copy the Prod.lean docstring, adapted to κ ⊗ₖ η.","ev":"measured: src.lean has no '/--' anywhere (grep), original docstring at Mathlib/MeasureTheory/Integral/Prod.lean:415","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-e20479","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.integral_compProd","line":231,"sev":"NIT","status":"confirmed","cat":"api","pattern":"anonymous-hypothesis-binder-after-colon","claim":"The statement is written 'theorem integral_compProd : ∀ {f : β × γ → E} (_ : Integrable f ((κ ⊗ₖ η) a)), ...', a binder-after-colon form that exists only to feed 'apply Integrable.induction'. The hypothesis is anonymous, so it cannot be supplied by name ('integral_compProd (hf := h)' fails with 'Invalid argument name hf'). The form is also inconsistent with MeasureTheory.integral_prod (f) (hf : ...) and Kernel.lintegral_compProd, which name their hypotheses. Stating '{f} (hf : ...)' and doing 'revert f' (as integral_prod does) compiles unchanged.","fix":"Restate as 'theorem integral_compProd {f : β × γ → E} (hf : Integrable f ((κ ⊗ₖ η) a)) : ...' and add 'revert f' before 'apply Integrable.induction'.","ev":"hunts/kernel-integral-compprod/batch1/Probe1.lean P2: example ... := ProbabilityTheory.integral_compProd (hf := hf)  -- error: Invalid argument name `hf` (Probe1.out). Fix verified in hunts/kernel-integral-compprod/batch1/Copy1.lean (L228-249, compiles cleanly).","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-3a6d65","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.integral_compProd","line":231,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"rotate-left-side-goals","claim":"In the indicator case the side conditions of integral_toReal are handled with 'congr 1; rw [integral_toReal]; rotate_left; · exact ...; · exact ...; rw [Kernel.compProd_apply hs]' (7 lines). Passing them as arguments inside the preceding simp_rw, as MeasureTheory.integral_prod does, closes the case in the same simp_rw.","fix":"Fold 'integral_toReal (Kernel.measurable_kernel_prodMk_left' hs _).aemeasurable (ae_kernel_lt_top a h2s.ne), Kernel.compProd_apply hs' into the simp_rw and delete the congr/rotate_left block.","ev":"hunts/kernel-integral-compprod/batch1/Copy1.lean L234-239 (indicator case: one simp_rw ending in 'integral_toReal (Kernel.measurable_kernel_prodMk_left' hs _).aemeasurable (ae_kernel_lt_top a h2s.ne), Kernel.compProd_apply hs]'); whole copy compiles with no messages (Copy1.out).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-6c5770","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.setIntegral_compProd","line":257,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"stale-porting-note","claim":"'-- Porting note: `compProd_restrict` needed some explicit arguments' is a leftover. hs and ht are explicit hypotheses of compProd_restrict, and 'rw [← compProd_restrict]' cannot recover them from the proof-irrelevant 'hs.prod ht': dropping them leaves goals 'MeasurableSet s' and 'MeasurableSet t'. That is ordinary Lean 4 behaviour, not a porting artefact, so the comment carries no information.","fix":"Delete the porting-note comment (keep the explicit hs ht).","ev":"hunts/kernel-integral-compprod/batch1/Copy1_portingnote_noargs.lean: 'rw [← Kernel.restrict_apply (κ ⊗ₖ η) (hs.prod ht), ← compProd_restrict, integral_compProd]' -> error: unsolved goals case hs ⊢ MeasurableSet s, case ht ⊢ MeasurableSet t. With the args and without the comment, hunts/kernel-integral-compprod/batch1/Copy1.lean compiles.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-95aef4","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.setIntegral_compProd","line":257,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-dropped-from-prod-original","claim":"No docstring, while its model MeasureTheory.setIntegral_prod has '**Fubini's Theorem** for set integrals.'","fix":"Add a docstring ('**Fubini's theorem** for set integrals against the composition-product').","ev":"measured: no '/--' before L257 in src.lean; Prod.lean:501 '/-- **Fubini's Theorem** for set integrals. -/'","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-773a5d","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.setIntegral_compProd_univ_right","line":265,"sev":"NIT","status":"confirmed","cat":"api","pattern":"explicit-arg-determined-by-hypothesis","claim":"`f` is an explicit argument although it is determined by the explicit hypothesis `hf : IntegrableOn f (s ×ˢ univ) _`; the parent `setIntegral_compProd` and the ∫⁻ twin `Kernel.setLIntegral_compProd_univ_right` both take `{f}`, so the three sibling signatures disagree. The lemma has no uses in Mathlib (git grep origin/master), so the change is free.","fix":"Make `f` implicit (`{f : β × γ → E}`), matching `setIntegral_compProd`.","ev":"hunts/kernel-integral-compprod/batch2/Src.lean (copy of src.lean with `theorem setIntegral_compProd_univ_right {f : β × γ → E} ...`; the whole file compiles unchanged otherwise). Signatures via #check in hunts/kernel-integral-compprod/batch2/Probe1.lean: setIntegral_compProd has `{f : β × γ → E}`, Kernel.setLIntegral_compProd_univ_right has `{f : β × γ → ENNReal}`, this lemma has `(f : β × γ → E)`. `git grep -nE 'setIntegral_compProd_univ_(right|left)' origin/master -- Mathlib` hits only the two declarations.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-e95727","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.setIntegral_compProd_univ_left","line":270,"sev":"NIT","status":"confirmed","cat":"api","pattern":"explicit-arg-determined-by-hypothesis","claim":"`f` is explicit although determined by `hf : IntegrableOn f (univ ×ˢ t) _`; `setIntegral_compProd` and `Kernel.setLIntegral_compProd_univ_left` take `{f}`. No uses in Mathlib.","fix":"Make `f` implicit, matching `setIntegral_compProd`.","ev":"hunts/kernel-integral-compprod/batch2/Src.lean (copy with `theorem setIntegral_compProd_univ_left {f : β × γ → E} ...` compiles); signatures via #check in hunts/kernel-integral-compprod/batch2/Probe1.lean.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-bc606f","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"MeasureTheory.AEStronglyMeasurable.comp","line":287,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"misleading-generic-dot-name","claim":"The name `AEStronglyMeasurable.comp` follows the Mathlib convention for function composition (`Measurable.comp`, `AEStronglyMeasurable.comp_measurable`, `comp_aemeasurable`, `comp_fst`, ...), but the lemma has nothing to do with composing functions: it says `AEStronglyMeasurable f ((η ∘ₖ κ) a) → ∀ᵐ x ∂κ a, AEStronglyMeasurable f (η x)`. So `hf.comp hg` gives a confusing error, and the lemma takes the generic name. Its siblings are called `Integrable.ae_of_comp` (L335), `AEStronglyMeasurable.ae_of_compProd` (L453) and `AEStronglyMeasurable.compProd_mk_left` (L91). It has no docstring to explain the name. `MeasureTheory.AEStronglyMeasurable.ae_of_comp` is free, and the rename (with its single use at L324) compiles.","fix":"Rename it to `AEStronglyMeasurable.ae_of_comp` (deprecated alias from the old name), matching `Integrable.ae_of_comp`.","ev":"hunts/kernel-integral-compprod/batch2/Probe1.lean (P1): `example (hf : AEStronglyMeasurable f (μ.map g)) (hg : Measurable g) : AEStronglyMeasurable (f ∘ g) μ := hf.comp hg` fails: 'Function expected at AEStronglyMeasurable.comp ?m … but this term has type ∀ᵐ (x : ?m) ∂?m ?m, AEStronglyMeasurable …' (whereas `hf.comp_measurable hg` compiles); `#check @MeasureTheory.AEStronglyMeasurable.ae_of_comp` → Unknown constant. hunts/kernel-integral-compprod/batch2/Src.lean: the rename plus `hf.ae_of_comp` at L324 compiles.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-05cad1","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"MeasureTheory.Measure.integrable_comp_iff","line":327,"sev":"NIT","status":"confirmed","cat":"api","pattern":"measure-lemma-in-kernel-section","claim":"This `κ ∘ₘ μ` lemma is declared via `_root_` inside the kernel `comp` section of `namespace ProbabilityTheory`, not in the file's `MeasureTheory.Measure` section (L444–505), which holds its siblings. It has no uses in Mathlib. Its two directions are restated there as `Measure.ae_integrable_of_integrable_comp` and `Measure.integrable_integral_norm_of_integrable_comp`, and each is reproved by `rw [Measure.comp_eq_comp_const_apply, integrable_comp_iff h_int.1]` instead of using it, though each is `((Measure.integrable_comp_iff h.aestronglyMeasurable).1 h).1/.2`.","fix":"Move it into the `MeasureTheory.Measure` section, in an `Integrable` subsection, and derive the two sibling lemmas from it.","ev":"hunts/kernel-integral-compprod/batch2/Probe1.lean (P3): `example (h : Integrable f (κ ∘ₘ μ)) : ∀ᵐ x ∂μ, Integrable f (κ x) := ((Measure.integrable_comp_iff h.aestronglyMeasurable).1 h).1` and the `.2` analogue for `Integrable (fun x ↦ ∫ y, ‖f y‖ ∂κ x) μ` compile. `git grep -n 'integrable_comp_iff' origin/master -- Mathlib` shows no use of `Measure.integrable_comp_iff` besides its declaration.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-429e5a","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"MeasureTheory.Integrable.ae_of_comp","line":335,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"anonymous-projection-through-def","claim":"The proof uses the anonymous projection `hf.1`, which relies on `Integrable` unfolding to a conjunction, where the named accessor `hf.aestronglyMeasurable` exists. Its compProd twin `Integrable.ae_of_compProd` (L142) uses `hf.aestronglyMeasurable`.","fix":"Write `((integrable_comp_iff hf.aestronglyMeasurable).1 hf).1`.","ev":"hunts/kernel-integral-compprod/batch2/Probe1.lean (P4) and hunts/kernel-integral-compprod/batch2/Src.lean: `((integrable_comp_iff hf.aestronglyMeasurable).1 hf).1` compiles in place of `((integrable_comp_iff hf.1).1 hf).1`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-4630b2","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"MeasureTheory.Integrable.integral_comp","line":342,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"mono-instead-of-mono-prime","claim":"The proof uses `Integrable.mono` and then converts `‖∫ y, ‖f y‖ ∂η x‖` back to `∫ y, ‖f y‖ ∂η x` via `norm_of_nonneg`/`integral_nonneg_of_ae`/`norm_nonneg` (4 lines). `Integrable.mono'` takes a real-valued dominating function directly, so `hf.integral_norm_comp.mono' hf.1.integral_kernel_comp (ae_of_all _ fun _ ↦ norm_integral_le_integral_norm _)` proves it with no detour. The compProd twin `Integrable.integral_compProd` (L148) has the same detour.","fix":"Replace the proof by `hf.integral_norm_comp.mono' hf.1.integral_kernel_comp <| ae_of_all _ fun _ ↦ norm_integral_le_integral_norm _`.","ev":"hunts/kernel-integral-compprod/batch3/probe.lean section P2 compiles. Exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-c0807e","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.Kernel.integral_fn_integral_add_comp","line":354,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"dropped-docstrings-from-copied-api","claim":"None of the seven `Kernel.*_comp` add/sub lemmas (L354-L393) has a docstring, although the module docstring says the file is a copy of `Mathlib/MeasureTheory/Integral/Prod.lean`, whose originals (`integral_fn_integral_add` ... `integral_integral_sub'`, Prod.lean L358-L413) document that `F` can be any function and that the primed versions are the `(f + g) (x, y)` forms. The primed lemmas in particular differ from the unprimed ones only by `Pi.add_apply`/`Pi.sub_apply`, which nothing in this file explains.","fix":"Copy the Prod.lean docstrings (adapted to `η ∘ₖ κ`) onto the seven lemmas, at least the primed ones.","ev":"src.lean L353, L360, L367, L374, L379, L384, L389 (the lines before each declaration) are blank; Prod.lean at origin/master has `/-- ... -/` before each of its seven originals.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-817a3e","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"ProbabilityTheory.Kernel.integral_integral_add'_comp","line":380,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"mid-name-variant-prime","claim":"`integral_integral_add'_comp` and `integral_integral_sub'_comp` (L390) put the variant prime in the middle of the name (as a variant of `integral_integral_add_comp` it would be `integral_integral_add_comp'`). Mid-name primes in Mathlib almost always come from a primed constant (`map'_comp`, `toMatrix'_comp`, `shiftIso_add'_hom_app`); only 12 Mathlib theorem names match `_(add|sub|mul|integral)'_` at all, and these two are among the few where the prime marks a lemma variant.","fix":"Rename to `integral_integral_add_comp'`/`integral_integral_sub_comp'` with `@[deprecated]` aliases.","ev":"git -C mathlib4 grep -hoP \"^(theorem|lemma) [A-Za-z0-9_.]*_(add|sub|mul|integral)'_[A-Za-z0-9_.']+\" origin/master -- Mathlib  -> 12 hits, listed in the claim.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-e25783","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"MeasureTheory.AEStronglyMeasurable.ae_of_compProd","line":453,"sev":"NIT","status":"confirmed","cat":"api","pattern":"uncurried-hypothesis-unusable","claim":"The hypothesis is stated for `f.uncurry` with `f : α → β → E`, unlike every sibling (`Measure.integrable_compProd_iff`, `AEStronglyMeasurable.compProd_mk_left`, `AEStronglyMeasurable.prodMk_left`), which take `f : α × β → _`. For `hg : AEStronglyMeasurable g (μ ⊗ₘ κ)` with `g : α × β → E`, `hg.ae_of_compProd` does not elaborate, even with the expected type `∀ᵐ x ∂μ, AEStronglyMeasurable (fun y => g (x, y)) (κ x)` supplied. The lemma has no consumer in Mathlib (git grep). The `X.ae_of_compProd` suffix also means kernel `⊗ₖ` for `Integrable.ae_of_compProd` (L140) but measure `⊗ₘ` here.","fix":"State it for `f : α × β → X` with conclusion `∀ᵐ x ∂μ, AEStronglyMeasurable (fun y ↦ f (x, y)) (κ x)`, mirroring `AEStronglyMeasurable.prodMk_left`.","ev":"example {μ : Measure α} {κ : Kernel α β} [SFinite μ] [IsSFiniteKernel κ] {g : α × β → E}\n    (hg : AEStronglyMeasurable g (μ ⊗ₘ κ)) :\n    ∀ᵐ x ∂μ, AEStronglyMeasurable (fun y => g (x, y)) (κ x) := hg.ae_of_compProd\n-- error: Application type mismatch: hg ... expected to have type AEStronglyMeasurable (Function.uncurry ?m) (?m ⊗ₘ ?m) (hunts/kernel-integral-compprod/batch4/probe1.lean P5)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-e4b99e","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"MeasureTheory.AEStronglyMeasurable.ae_of_compProd","line":453,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"shadowed-section-variable","claim":"L454 re-binds `{E : Type*} [NormedAddCommGroup E]` although the section `variable` line (L448-449) already declares `{E : Type*} ... [NormedAddCommGroup E]`; the local binder shadows the section variable (leftover). Also the section variable `{a : α}` (L449) is used by no declaration in the `MeasureTheory.Measure` section (`a` only occurs as a bound variable in `∫ a, ...`).","fix":"Delete the local `{E : Type*} [NormedAddCommGroup E]` binders (or generalise to `X`) and drop `{a : α}` from the section `variable` line.","ev":"measured: src.lean L448-449 `variable {α β E : Type*} ... [NormedAddCommGroup E] {a : α} ...`; L454 `{E : Type*} [NormedAddCommGroup E]`; `a` is not a free variable of any statement at L453-501","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-e88e0b","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"MeasureTheory.Measure.integrable_compProd_iff","line":459,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"shadowed-section-variable","claim":"L459 re-binds `{E : Type*} [NormedAddCommGroup E]` although the section `variable` line (L448-449) already declares `{E : Type*} ... [NormedAddCommGroup E]`; the local binder shadows the section variable (leftover).","fix":"Delete the local `{E : Type*} [NormedAddCommGroup E]` binders.","ev":"measured: src.lean L448-449 vs L459 `lemma integrable_compProd_iff [SFinite μ] [IsSFiniteKernel κ] {E : Type*} [NormedAddCommGroup E]`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-ef6d44","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"MeasureTheory.Measure.integral_compProd","line":467,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"shadowed-section-variable","claim":"L467-468 re-binds `{E : Type*} [NormedAddCommGroup E]` although the section `variable` line (L448-449) already declares `{E : Type*} ... [NormedAddCommGroup E]`; the local binder shadows the section variable (leftover).","fix":"Delete the local `{E : Type*} [NormedAddCommGroup E]` binders, keeping `[NormedSpace ℝ E]`.","ev":"measured: src.lean L448-449 vs L467-468 `{E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E]`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-bb6a9f","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"MeasureTheory.Measure.setIntegral_compProd","line":474,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"shadowed-section-variable","claim":"L474-475 re-binds `{E : Type*} [NormedAddCommGroup E]` although the section `variable` line (L448-449) already declares `{E : Type*} ... [NormedAddCommGroup E]`; the local binder shadows the section variable (leftover).","fix":"Delete the local `{E : Type*} [NormedAddCommGroup E]` binders, keeping `[NormedSpace ℝ E]`.","ev":"measured: src.lean L448-449 vs L474-475 `{E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E]`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-387818","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"MeasureTheory.Measure.ae_integrable_of_integrable_comp","line":493,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"reproves-sibling-iff","claim":"The proof unfolds `Measure.comp_eq_comp_const_apply` and goes through the kernel `integrable_comp_iff` instead of using `Measure.integrable_comp_iff` (L327, same file). That gives a one-term proof, and the same 2-line block is copied into `integrable_integral_norm_of_integrable_comp`.","fix":"Use `((Measure.integrable_comp_iff h_int.1).1 h_int).1`.","ev":"example {μ : Measure α} {κ : Kernel α β} {f : β → E} (h_int : Integrable f (κ ∘ₘ μ)) :\n    ∀ᵐ x ∂μ, Integrable f (κ x) :=\n  ((Measure.integrable_comp_iff h_int.1).1 h_int).1","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-3b1351","file":"Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean","decl":"MeasureTheory.Measure.integrable_integral_norm_of_integrable_comp","line":498,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"reproves-sibling-iff","claim":"The proof repeats the `rw [Measure.comp_eq_comp_const_apply, integrable_comp_iff h_int.1] at h_int` block of the previous lemma instead of using `Measure.integrable_comp_iff` (L327, same file), which gives a one-term proof.","fix":"Use `((Measure.integrable_comp_iff h_int.1).1 h_int).2`.","ev":"example {μ : Measure α} {κ : Kernel α β} {f : β → E} (h_int : Integrable f (κ ∘ₘ μ)) :\n    Integrable (fun x ↦ ∫ y, ‖f y‖ ∂κ x) μ :=\n  ((Measure.integrable_comp_iff h_int.1).1 h_int).2","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261006-2c5fb6","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.IsRatCondKernelCDF","line":70,"sev":"NIT","status":"confirmed","cat":"correctness","pattern":"junk-toreal-infinite-measure","claim":"Outside finite kernels the predicate is satisfied through the junk value `ENNReal.toReal ∞ = 0` in its `setIntegral` field `(κ a).real (s ×ˢ Iic q)`. With `ν = 0` and `κ = Kernel.const Unit (∞ • dirac ((), 0))`, `IsRatCondKernelCDF (fun _ _ ↦ 0) κ 0` holds, yet `κ ≠ 0 ⊗ₖ η` for every `η`. At that witness `setLIntegral_stieltjesOfMeasurableRat_rat` would read `0 = ∞`. No statement in the library is affected, because every consumer that concludes anything (`setLIntegral_*`, `setIntegral_stieltjesOfMeasurableRat`, `isCondKernelCDF_stieltjesOfMeasurableRat`) assumes `[IsFiniteKernel κ]`. The module docstring says the kernels are finite, but the structure's docstring does not.","fix":"Say in the structure docstring that `κ` is meant to be a finite kernel and that, because of `.real`, the predicate is degenerate for infinite `κ`.","ev":"hunts/cdf-kernel/batch0/probe1.lean, sections (B) and (C): `theorem junk_isRatCondKernelCDF : IsRatCondKernelCDF (fun _ _ ↦ (0 : ℝ)) κjunk (0 : Kernel Unit Unit)` (fields by `simp [κjunk, measureReal_def, ENNReal.toReal_mul]`), `theorem junk_ne_compProd (η) : κjunk ≠ (0 : Kernel Unit Unit) ⊗ₖ η`, and the `≠` example showing setLIntegral_..._rat's equation fails there; `#print axioms` shows no sorryAx","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4d3ebc","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.stieltjesOfMeasurableRat_ae_eq","line":94,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"shadowed-binder-name","claim":"`filter_upwards [hf.isRatStieltjesPoint_ae a] with a ha` rebinds `a`, which is already the point of `α`, to a point of `β`. The proof is correct, but the shadowing makes it misleading to read.","fix":"Write `with b hb` and use `hb` in the following `rw`.","ev":"src.lean L96: `filter_upwards [hf.isRatStieltjesPoint_ae a] with a ha` inside a lemma binding `(a : α)`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-90cbba","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.lintegral_stieltjesOfMeasurableRat","line":173,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"special-case-of-later-general-lemma","claim":"The statement is the instance `(isCondKernelCDF_stieltjesOfMeasurableRat hf).lintegral a x` of the general `IsCondKernelCDF.lintegral` later in the file. Its only consumer anywhere is the proof of `integrable_stieltjesOfMeasurableRat` (L191), and the alternative proof in the generality finding on that lemma does not need it. After that change this lemma is a one-line corollary of later API.","fix":"After reproving `integrable_stieltjesOfMeasurableRat` by domination, prove this lemma as `(isCondKernelCDF_stieltjesOfMeasurableRat hf).lintegral a x`, or deprecate it.","ev":"hunts/cdf-kernel/batch0/probe3.lean (D): `example [IsFiniteKernel κ] (hf : IsRatCondKernelCDF f κ ν) (a : α) (x : ℝ) : ∫⁻ b, ENNReal.ofReal (stieltjesOfMeasurableRat f hf.measurable (a, b) x) ∂(ν a) = κ a (univ ×ˢ Iic x) := (isCondKernelCDF_stieltjesOfMeasurableRat hf).lintegral a x`; `git grep lintegral_stieltjesOfMeasurableRat origin/master` -> only L173 (decl) and L191 (integrable proof)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c1e91c","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.IsRatCondKernelCDFAux.measurable_right","line":243,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"let-rw-at-instead-of-term","claim":"The 3-line tactic proof binds a proof with `let h := hf.measurable` (it should be `have`), then does `rw [measurable_pi_iff] at h`. The whole statement is the term `hf.measurable.eval.comp measurable_prodMk_left` (Measurable.eval, Constructions.lean:591).","fix":"Replace the proof with `hf.measurable.eval.comp measurable_prodMk_left`.","ev":"hunts/cdf-kernel/batch1/probe1.lean P8 and hunts/cdf-kernel/batch1/copy.lean:\n    Measurable (fun t ↦ f (a, t) q) :=\n  hf.measurable.eval.comp measurable_prodMk_left","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-edd8b8","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.IsRatCondKernelCDFAux.tendsto_atTop_one","line":283,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"noop-filter-upwards","claim":"The final `filter_upwards [hf.tendsto_one_of_monotone a Nat.cast Nat.mono_cast tendsto_natCast_atTop_atTop] with x hx using hx` is a no-op wrapper around `exact hf.tendsto_one_of_monotone …`. The preceding `rw …; exact ht` is `rwa`.","fix":"Replace the last two lines with `exact hf.tendsto_one_of_monotone a Nat.cast Nat.mono_cast tendsto_natCast_atTop_atTop` and use `rwa`.","ev":"hunts/cdf-kernel/batch1/probe1.lean P9 and hunts/cdf-kernel/batch1/copy.lean:\n  suffices … by\n    filter_upwards [this, hf.mono a] with t ht h_mono\n    rwa [tendsto_iff_tendsto_subseq_of_monotone h_mono tendsto_natCast_atTop_atTop]\n  exact hf.tendsto_one_of_monotone a Nat.cast Nat.mono_cast tendsto_natCast_atTop_atTop","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-5c169b","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.IsRatCondKernelCDFAux.integrable_iInf_rat_gt","line":312,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"memlp-detour-instead-of-integrable-mono","claim":"The 13-line proof detours through `memLp_one_iff_integrable`, `memLp_iff` (as two consecutive `rw`s) and `eLpNorm_le_of_ae_bound`, with three bullet levels. Domination by the integrable `f (a, ·) (q + 1)` via `Integrable.mono'` takes 5 lines and needs neither `le_one` nor finiteness of ν.","fix":"Use the 5-line `Integrable.mono'` proof shown in the evidence.","ev":"measured: original proof L315-L327 = 13 lines; replacement (5 lines) compiles in hunts/cdf-kernel/batch1/probe1.lean P7 and hunts/cdf-kernel/batch1/copy.lean","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c6ae9b","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"MeasureTheory.Measure.iInf_rat_gt_prod_Iic","line":341,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"fun-arrow-style","claim":"`exact fun _ => (hs.prod measurableSet_Iic).nullMeasurableSet` (L341) is the only `fun … =>` in the file; everywhere else the file uses `↦`, as Mathlib style does.","fix":"Write `fun _ ↦ (hs.prod measurableSet_Iic).nullMeasurableSet`.","ev":"measured: `grep -n '=>' src.lean` -> L341 is the only `fun _ =>`; all other hits are `| ctor … =>` alternatives of `induction … with`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-1d513b","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.IsRatCondKernelCDFAux.setIntegral_iInf_rat_gt","line":344,"sev":"NIT","status":"confirmed","cat":"generality","pattern":"redundant-finite-kernel-hypothesis","claim":"`[IsFiniteKernel κ]` is redundant. If `ν a = 0`, the conclusion is trivial. If `ν a ≠ 0`, the fields `tendsto_integral_of_monotone`, `setIntegral` and `le_one'` together with `[IsFiniteKernel ν]` force `κ a` to be finite (`κ a (univ ×ˢ Iic q) ≤ ofReal ((ν a).real univ)` for every `q`). The statement then follows by restricting everything to the single point `a` (`Kernel.const Unit (κ a)`, `Kernel.const Unit (ν a)`). This has little payoff: every `IsRatCondKernelCDF` built in Mathlib is fed to `isCondKernelCDF_stieltjesOfMeasurableRat`, which genuinely needs `[IsFiniteKernel κ]` (see probe3.lean), and both callers (CondCDF, StandardBorel) have κ finite.","fix":"Optional: drop `[IsFiniteKernel κ]` by adding the lemma `ν a ≠ 0 → IsFiniteMeasure (κ a)`. Otherwise leave it; it is harmless because the only consumer needs κ finite anyway.","ev":"hunts/cdf-kernel/batch2/probe1.lean section (B) (compiles, exit 0; only deprecation warnings for `Kernel.zero_apply`): `isFiniteMeasure_of_ne_zero (hf : IsRatCondKernelCDFAux f κ ν) [IsFiniteKernel ν] (a) (hν : ν a ≠ 0) : IsFiniteMeasure (κ a)`, `aux_const` (restriction to `Unit`), then, with no `[IsFiniteKernel κ]` anywhere: `setIntegral_iInf_rat_gt'`, `iInf_rat_gt_eq'`, `isRatStieltjesPoint_ae'`, `isRatCondKernelCDF'`, each `by_cases hν : ν a = 0; · simp [hν]` (or `rw [← hf.setIntegral a hA q]; simp [hν]`), else `have := isFiniteMeasure_of_ne_zero hf a hν; exact (aux_const hf a).<original lemma> ()`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d32437","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.IsRatCondKernelCDFAux.iInf_rat_gt_eq","line":367,"sev":"NIT","status":"confirmed","cat":"generality","pattern":"redundant-finite-kernel-hypothesis","claim":"`[IsFiniteKernel κ]` is redundant. If `ν a = 0`, the conclusion is trivial. If `ν a ≠ 0`, the fields `tendsto_integral_of_monotone`, `setIntegral` and `le_one'` together with `[IsFiniteKernel ν]` force `κ a` to be finite (`κ a (univ ×ˢ Iic q) ≤ ofReal ((ν a).real univ)` for every `q`). The statement then follows by restricting everything to the single point `a` (`Kernel.const Unit (κ a)`, `Kernel.const Unit (ν a)`). This has little payoff: every `IsRatCondKernelCDF` built in Mathlib is fed to `isCondKernelCDF_stieltjesOfMeasurableRat`, which genuinely needs `[IsFiniteKernel κ]` (see probe3.lean), and both callers (CondCDF, StandardBorel) have κ finite.","fix":"Optional: drop `[IsFiniteKernel κ]` by adding the lemma `ν a ≠ 0 → IsFiniteMeasure (κ a)`. Otherwise leave it; it is harmless because the only consumer needs κ finite anyway.","ev":"hunts/cdf-kernel/batch2/probe1.lean section (B) (compiles, exit 0; only deprecation warnings for `Kernel.zero_apply`): `isFiniteMeasure_of_ne_zero (hf : IsRatCondKernelCDFAux f κ ν) [IsFiniteKernel ν] (a) (hν : ν a ≠ 0) : IsFiniteMeasure (κ a)`, `aux_const` (restriction to `Unit`), then, with no `[IsFiniteKernel κ]` anywhere: `setIntegral_iInf_rat_gt'`, `iInf_rat_gt_eq'`, `isRatStieltjesPoint_ae'`, `isRatCondKernelCDF'`, each `by_cases hν : ν a = 0; · simp [hν]` (or `rw [← hf.setIntegral a hA q]; simp [hν]`), else `have := isFiniteMeasure_of_ne_zero hf a hν; exact (aux_const hf a).<original lemma> ()`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-70abe3","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.IsRatCondKernelCDFAux.isRatStieltjesPoint_ae","line":377,"sev":"NIT","status":"confirmed","cat":"generality","pattern":"redundant-finite-kernel-hypothesis","claim":"`[IsFiniteKernel κ]` is redundant. If `ν a = 0`, the conclusion is trivial. If `ν a ≠ 0`, the fields `tendsto_integral_of_monotone`, `setIntegral` and `le_one'` together with `[IsFiniteKernel ν]` force `κ a` to be finite (`κ a (univ ×ˢ Iic q) ≤ ofReal ((ν a).real univ)` for every `q`). The statement then follows by restricting everything to the single point `a` (`Kernel.const Unit (κ a)`, `Kernel.const Unit (ν a)`). This has little payoff: every `IsRatCondKernelCDF` built in Mathlib is fed to `isCondKernelCDF_stieltjesOfMeasurableRat`, which genuinely needs `[IsFiniteKernel κ]` (see probe3.lean), and both callers (CondCDF, StandardBorel) have κ finite. (`[IsFiniteKernel ν]`, by contrast, is needed here: probe2.lean shows `IsRatCondKernelCDFAux 0 0 (Kernel.const Unit Measure.count)` holds through the junk value `(ν a).real univ = 0`, while `IsRatCondKernelCDF` fails for it.)","fix":"Optional: drop `[IsFiniteKernel κ]` by adding the lemma `ν a ≠ 0 → IsFiniteMeasure (κ a)`. Otherwise leave it; it is harmless because the only consumer needs κ finite anyway.","ev":"hunts/cdf-kernel/batch2/probe1.lean section (B) (compiles, exit 0; only deprecation warnings for `Kernel.zero_apply`): `isFiniteMeasure_of_ne_zero (hf : IsRatCondKernelCDFAux f κ ν) [IsFiniteKernel ν] (a) (hν : ν a ≠ 0) : IsFiniteMeasure (κ a)`, `aux_const` (restriction to `Unit`), then, with no `[IsFiniteKernel κ]` anywhere: `setIntegral_iInf_rat_gt'`, `iInf_rat_gt_eq'`, `isRatStieltjesPoint_ae'`, `isRatCondKernelCDF'`, each `by_cases hν : ν a = 0; · simp [hν]` (or `rw [← hf.setIntegral a hA q]; simp [hν]`), else `have := isFiniteMeasure_of_ne_zero hf a hν; exact (aux_const hf a).<original lemma> ()`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-fab747","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.IsRatCondKernelCDFAux.isRatCondKernelCDF","line":384,"sev":"NIT","status":"confirmed","cat":"generality","pattern":"redundant-finite-kernel-hypothesis","claim":"`[IsFiniteKernel κ]` is redundant. If `ν a = 0`, the conclusion is trivial. If `ν a ≠ 0`, the fields `tendsto_integral_of_monotone`, `setIntegral` and `le_one'` together with `[IsFiniteKernel ν]` force `κ a` to be finite (`κ a (univ ×ˢ Iic q) ≤ ofReal ((ν a).real univ)` for every `q`). The statement then follows by restricting everything to the single point `a` (`Kernel.const Unit (κ a)`, `Kernel.const Unit (ν a)`). This has little payoff: every `IsRatCondKernelCDF` built in Mathlib is fed to `isCondKernelCDF_stieltjesOfMeasurableRat`, which genuinely needs `[IsFiniteKernel κ]` (see probe3.lean), and both callers (CondCDF, StandardBorel) have κ finite. (`[IsFiniteKernel ν]`, by contrast, is needed here: probe2.lean shows `IsRatCondKernelCDFAux 0 0 (Kernel.const Unit Measure.count)` holds through the junk value `(ν a).real univ = 0`, while `IsRatCondKernelCDF` fails for it.)","fix":"Optional: drop `[IsFiniteKernel κ]` by adding the lemma `ν a ≠ 0 → IsFiniteMeasure (κ a)`. Otherwise leave it; it is harmless because the only consumer needs κ finite anyway.","ev":"hunts/cdf-kernel/batch2/probe1.lean section (B) (compiles, exit 0; only deprecation warnings for `Kernel.zero_apply`): `isFiniteMeasure_of_ne_zero (hf : IsRatCondKernelCDFAux f κ ν) [IsFiniteKernel ν] (a) (hν : ν a ≠ 0) : IsFiniteMeasure (κ a)`, `aux_const` (restriction to `Unit`), then, with no `[IsFiniteKernel κ]` anywhere: `setIntegral_iInf_rat_gt'`, `iInf_rat_gt_eq'`, `isRatStieltjesPoint_ae'`, `isRatCondKernelCDF'`, each `by_cases hν : ν a = 0; · simp [hν]` (or `rw [← hf.setIntegral a hA q]; simp [hν]`), else `have := isFiniteMeasure_of_ne_zero hf a hν; exact (aux_const hf a).<original lemma> ()`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ae043e","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.IsCondKernelCDF.integral","line":418,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-binder-shadowing-section-variable","claim":"Re-binds `{f : α × β → StieltjesFunction ℝ}` (L418), which duplicates the section variable declared at L396 with the same type. The neighbouring `nonneg` and `le_one` use the section variable.","fix":"Delete the explicit `{f : α × β → StieltjesFunction ℝ}` binder.","ev":"hunts/cdf-kernel/batch2/src_mod.lean removes the three binders (L418, L423, L430 of src.lean); the copy compiles with exit 0 and no warnings.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7bc8bb","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.IsCondKernelCDF.setLIntegral","line":423,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-binder-shadowing-section-variable","claim":"Re-binds `{f : α × β → StieltjesFunction ℝ}` (L423), which duplicates the section variable declared at L396 with the same type. The neighbouring `nonneg` and `le_one` use the section variable.","fix":"Delete the explicit `{f : α × β → StieltjesFunction ℝ}` binder.","ev":"hunts/cdf-kernel/batch2/src_mod.lean removes the three binders (L418, L423, L430 of src.lean); the copy compiles with exit 0 and no warnings.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-97709c","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.IsCondKernelCDF.lintegral","line":430,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-binder-shadowing-section-variable","claim":"Re-binds `{f : α × β → StieltjesFunction ℝ}` (L430), which duplicates the section variable declared at L396 with the same type. The neighbouring `nonneg` and `le_one` use the section variable.","fix":"Delete the explicit `{f : α × β → StieltjesFunction ℝ}` binder.","ev":"hunts/cdf-kernel/batch2/src_mod.lean removes the three binders (L418, L423, L430 of src.lean); the copy compiles with exit 0 and no warnings.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c8cdd5","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.IsCondKernelCDF.toKernel","line":447,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-variable-redeclaration","claim":"Section `ToKernel` re-declares `variable {_ : MeasurableSpace β} {f …} {κ : Kernel α (β × ℝ)} {ν : Kernel α β}` (L447-448) although `mβ`, `κ`, `ν` are already file-level variables (L58-59). The redeclaration is a leftover: the only effect is that `toKernel`, `toKernel_apply`, `instIsMarkovKernel_toKernel` and `toKernel_Iic` get an anonymous measurable-space binder (printed `{x : MeasurableSpace β}`, so `toKernel_Iic`'s own `x : ℝ` prints as `x_1`) instead of `mβ` like every other declaration of the file. Replacing the two lines by `variable {f : α × β → StieltjesFunction ℝ}` leaves the whole file compiling and gives `{mβ : MeasurableSpace β}`.","fix":"Replace L447-448 by `variable {f : α × β → StieltjesFunction ℝ}`.","ev":"hunts/cdf-kernel/batch3/probeB.lean (copy of src.lean with L447-448 -> `variable {f : α × β → StieltjesFunction ℝ}`; whole file compiles, exit 0; `#check @IsCondKernelCDF.toKernel` now shows `{mβ : MeasurableSpace β}`). Original, from probeA.lean P1: `@IsCondKernelCDF.toKernel : {α β} → {mα : MeasurableSpace α} → {x : MeasurableSpace β} → …`, `@IsCondKernelCDF.toKernel_Iic : … {x : MeasurableSpace β} … (p : α × β) (x_1 : ℝ), …`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-256050","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.IsCondKernelCDF.toKernel","line":453,"sev":"NIT","status":"confirmed","cat":"api","pattern":"redundant-explicit-argument","claim":"`IsCondKernelCDF.toKernel (f) (hf : IsCondKernelCDF f κ ν)` takes `f` explicitly although it is determined by `hf`. Generalized field notation already fills it: `hf.toKernel` elaborates to a `Kernel (α × β) ℝ` and is `rfl`-equal to `hf.toKernel f`. The only external consumers (StandardBorel.lean:137 `(isCondKernelCDF_condKernelCDF κ).toKernel`, :153 `(isCondKernelCDF_condCDF (κ ())).toKernel`) already omit `f`, while every in-file use writes the redundant `hf.toKernel f`.","fix":"Make `f` implicit in `IsCondKernelCDF.toKernel` and write `hf.toKernel` throughout the file.","ev":"hunts/cdf-kernel/batch3/probeA.lean, P2:\nnoncomputable example (hf : IsCondKernelCDF f κ ν) : Kernel (α × β) ℝ := hf.toKernel\nexample (hf : IsCondKernelCDF f κ ν) : hf.toKernel = hf.toKernel f := rfl\n-- file compiles, exit 0","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b7ecc2","file":"Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean","decl":"ProbabilityTheory.instIsMarkovKernel_toKernel","line":462,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"nonstandard-instance-name","claim":"The instance is explicitly named `instIsMarkovKernel_toKernel`, mixing snake_case into an `instFooBar` name (77 such underscore instance names in Mathlib vs 2535 `instFooBar` ones), and it lives in `ProbabilityTheory` rather than with `IsCondKernelCDF.toKernel`. The name is never referenced (0 uses in Mathlib besides the declaration), and the file compiles with the instance made anonymous.","fix":"Drop the explicit name (anonymous instance), or rename to `IsCondKernelCDF.instIsMarkovKernelToKernel`.","ev":"hunts/cdf-kernel/batch3/probeB.lean: `instance {hf : IsCondKernelCDF f κ ν} : IsMarkovKernel (hf.toKernel f) := …` (anonymous) — whole file compiles, exit 0. Measured: `git grep -nE '^(noncomputable )?instance inst[A-Za-z]*_' origin/master -- Mathlib | wc -l` = 77 vs `instance inst[A-Za-z0-9]+ ` = 2535; `git grep instIsMarkovKernel_toKernel origin/master` outside the file = 0 hits.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-62f7cc","file":"Mathlib/Probability/Kernel/Posterior.lean","decl":"(file)","line":1,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring","claim":"Public lemmas without docstrings: `compProd_posterior_eq_swap_comp`, `swap_compProd_posterior`, `posterior_prod_id_comp`, `posterior_comp_self`, `absolutelyContinuous_posterior`, `absolutelyContinuous_of_posterior`, `absolutelyContinuous_posterior_iff`, `Kernel.absolutelyContinuous_comp_of_absolutelyContinuous`, `rnDeriv_posterior_ae_prod`, `rnDeriv_posterior`, `rnDeriv_posterior_symm`, `posterior_eq_withDensity_of_countable`, the two `posterior_boolKernel_apply_*`.","fix":"Add one-line docstrings.","ev":"Measured: source.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-9e8b0c","file":"Mathlib/Probability/Kernel/Posterior.lean","decl":"parallelProd_posterior_comp_copy_comp","line":96,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-mismatch-operation","claim":"`parallelProd_posterior_comp_copy_comp` is about `∥ₖ` (`Kernel.parallelComp`), not a product, so the name should say `parallelComp`; and `ae_eq_posterior_of_compProd_eq_swap_comp` takes `η` explicitly while its sibling `ae_eq_posterior_of_compProd_eq` takes it implicitly.","fix":"Rename to `parallelComp_posterior_comp_copy_comp`; make `η` implicit in both.","ev":"Measured: source L96-99, L113-121.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-674ece","file":"Mathlib/Probability/Kernel/Posterior.lean","decl":"rnDeriv_posterior","line":268,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"leftover-comment","claim":"`rnDeriv_posterior`'s proof has the comment `-- much faster than \\`exact\\`` twice (L273-274, a leftover duplicate line), and `rnDeriv_posterior_symm` closes a measurability side goal with the slow `measurability` tactic (L281) where `by fun_prop` is the current idiom.","fix":"Delete the duplicated comment line; use `fun_prop`.","ev":"Measured: source L268-281.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-b773d1","file":"Mathlib/Probability/Moments/Variance.lean","decl":"(file)","line":15,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"module-doc-overstates","claim":"The module introduction states `Var[X] = 𝔼[(X - 𝔼[X])^2]` unconditionally, but `variance` is defined with the lower Lebesgue integral and agrees with the Bochner formula only for a.e.-measurable `X` (`variance_eq_integral` carries that hypothesis); for a non-measurable `X` on an indiscrete space the two differ.","fix":"Qualify the displayed equation ('for measurable `X`') or point to `variance_eq_integral`.","ev":"Doc-only finding: L15-17 module docstring vs `variance_eq_integral (hX : AEMeasurable X μ)`. Raised by Astra's A1 pass (item 4).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-8c7286","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.evariance","line":54,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"stale-todo-pointer","claim":"The TODO comment above `evariance` (lines 54-55) is an unresolved naming leftover, and its pointer is stale: it says to consider `eVariationOn` in `Mathlib.Analysis.BoundedVariation`, but `eVariationOn` is defined in `Mathlib/Topology/EMetricSpace/BoundedVariation.lean:61`. `Mathlib/Analysis/BoundedVariation.lean` is now the a.e.-differentiability file and only imports it.","fix":"Either settle the `evariance`/`eVariance` question and delete the TODO, or at least point it at `Mathlib.Topology.EMetricSpace.BoundedVariation`.","ev":"git grep -n 'def eVariationOn' origin/master -- Mathlib  =>  Mathlib/Topology/EMetricSpace/BoundedVariation.lean:61:noncomputable def eVariationOn ...; Mathlib/Analysis/BoundedVariation.lean module doc: '# Almost everywhere differentiability of functions with locally bounded variation' (public import Mathlib.Topology.EMetricSpace.VariationOnFromTo)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-292834","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.evariance_lt_top","line":98,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"manual-elpnorm-unfolding","claim":"The 8-line proof unfolds `eLpNorm` and does the `rpow` arithmetic by hand (`rpow_mul`, `inv_mul_cancel₀`, `rpow_two`). `lintegral_rpow_enorm_lt_top_of_eLpNorm_lt_top` already does this, so the proof fits in 2 lines.","fix":"Replace with `simpa [evariance] using lintegral_rpow_enorm_lt_top_of_eLpNorm_lt_top two_ne_zero ENNReal.ofNat_ne_top (hX.sub (memLp_const μ[X])).eLpNorm_lt_top`.","ev":"hunts/variance/batch0/probe1.lean lines 62-64; also used in place in hunts/variance/batch0/Variance_gen.lean, where the whole file compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-c80bb7","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.evariance_eq_top","line":111,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"manual-elpnorm-unfolding","claim":"The proof contains a no-op `(hXm.sub aestronglyMeasurable_const).congr <| by filter_upwards with x using rfl` (`fun_prop` gives the measurability directly) and redoes the `eLpNorm`/`rpow` arithmetic by hand. With `eLpNorm_lt_top_iff_lintegral_rpow_enorm_lt_top`, the step from `evariance X μ ≠ ∞` to `MemLp (X - μ[X]) 2 μ` is 3 lines, and the theorem is then 4 lines.","fix":"Factor out `MemLp (fun ω ↦ X ω - μ[X]) 2 μ` from `evariance X μ ≠ ∞` via `eLpNorm_lt_top_iff_lintegral_rpow_enorm_lt_top`, and prove the theorem by `by_contra h; refine hX ?_; convert hc.add (memLp_const μ[X]); ext; simp`.","ev":"hunts/variance/batch0/probe1.lean lines 13-17 (helper `memLp_sub_integral_of_evariance_ne_top`) and lines 66-71 (the finite-measure statement in 4 lines)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-f1eb85","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.ofReal_variance","line":143,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"alias-name-mismatch","claim":"The dot-notation alias of `ofReal_variance` is named `MemLp.ofReal_variance_eq` (line 150, used at line 400), while the sibling aliases on lines 148-149 keep the original names (`MemLp.evariance_lt_top`, `MemLp.evariance_ne_top`); the two names for one lemma disagree.","fix":"Name the alias `MemLp.ofReal_variance` (keeping `MemLp.ofReal_variance_eq` as a deprecated alias).","ev":"measured: src.lean line 143 `theorem ofReal_variance`, line 150 `protected alias _root_.MeasureTheory.MemLp.ofReal_variance_eq := ofReal_variance`, lines 148-149 alias `MemLp.evariance_lt_top := evariance_lt_top`, `MemLp.evariance_ne_top := evariance_ne_top`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-7ad7a8","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.evariance_mul","line":186,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"const-mul-named-mul","claim":"By Mathlib's convention `evariance_mul` names `evariance (X * Y)`, but the statement is about `fun ω ↦ c * X ω`. Its real-valued sibling is `variance_const_mul` (and covariance has `covariance_const_mul_left`).","fix":"Rename to `evariance_const_mul`, keeping a deprecated alias.","ev":"measured: Variance.lean:186 `theorem evariance_mul (c : ℝ) (X : Ω → ℝ) (μ : Measure Ω) : evariance (fun ω => c * X ω) μ = ENNReal.ofReal (c ^ 2) * evariance X μ` vs :207 `variance_const_mul` with the same LHS shape.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-ee7c71","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.evariance_mul","line":186,"sev":"NIT","status":"confirmed","cat":"api","pattern":"sparse-evariance-api","claim":"`evariance` has only this scaling lemma: there is no `evariance_smul`, `evariance_mul_const`, `evariance_neg` or `evariance_add_const`, although `variance` has all of them. The `ℝ≥0∞` Chebyshev `meas_ge_le_evariance_div_sq` therefore has no shift or negation API.","fix":"Add the `evariance` analogues (`smul`, `mul_const`, `neg`, `add_const`) and derive the `variance` versions from them.","ev":"hunts/variance/batch2/Probe1.lean P6 lines 102-105: `#check @evariance_const_mul`, `#check @evariance_smul`, `#check @evariance_add_const`, `#check @evariance_neg` all fail with `Unknown identifier`.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-581d92","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.covariance_self","line":197,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-shadowing-binder","claim":"`covariance_self` re-declares `{X : Ω → ℝ}`, shadowing the section variable `{X Y : Ω → ℝ}` and moving `X` after `μ` in the implicit argument order, which is inconsistent with neighbouring lemmas.","fix":"Drop the `{X : Ω → ℝ}` binder and use the section variable.","ev":"hunts/variance/batch2/Probe2.lean: `#check @covariance_self` prints `∀ {Ω} {mΩ} {μ : Measure Ω} {X : Ω → ℝ}, ...`, whereas `#check @variance_add_const` prints `∀ {Ω} {mΩ} {X} {μ} ...`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-884a95","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_eq_sub","line":226,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-shadowing-binder","claim":"`variance_eq_sub` re-declares `{X : Ω → ℝ}`, shadowing the section variable and placing `X` after `[IsProbabilityMeasure μ]` in the argument order.","fix":"Drop the `{X : Ω → ℝ}` binder.","ev":"hunts/variance/batch2/Probe2.lean: `#check @variance_eq_sub` prints `∀ {Ω} {mΩ} {μ} [IsProbabilityMeasure μ] {X : Ω → ℝ}, MemLp X 2 μ → ...`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-65ecc9","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_sub","line":276,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"misindented-proof","claim":"The indentation is off. The statement continuation (line 277) is indented 5 spaces instead of 4, and the proof (lines 278-279) 3 spaces instead of 2. The same slip appears in Covariance.lean (`covariance_eq_sub`, `IndepFun.covariance_eq_zero`).","fix":"Reindent line 277 to 4 spaces and lines 278-279 to 2 spaces.","ev":"sed -n 276,279p src.lean | cat -A: line 277 starts with 5 spaces ('     Var[X - Y; μ] = ...'), lines 278-279 with 3 spaces ('   rw [sub_eq_add_neg, ...', '   ring')","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-6fc6cb","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_sum'","line":287,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-reimplements-existing-lemma","claim":"The 5-line proof re-derives `covariance_sum_sum'` (Covariance.lean) inline from `covariance_sum_left'`/`covariance_sum_right'`, passing `(by simpa)` where `hX` itself fits. Two rewrites prove it.","fix":"Replace the proof with `rw [← covariance_self (memLp_finsetSum' _ hX).aemeasurable, covariance_sum_sum' hX hX]`.","ev":"hunts/variance/batch3/Probe1.lean (P3): `example {ι : Type*} {s : Finset ι} {X : ι → Ω → ℝ} [IsFiniteMeasure μ] (hX : ∀ i ∈ s, MemLp (X i) 2 μ) : Var[∑ i ∈ s, X i; μ] = ∑ i ∈ s, ∑ j ∈ s, cov[X i, X j; μ] := by rw [← covariance_self (memLp_finsetSum' _ hX).aemeasurable, covariance_sum_sum' hX hX]` compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-4b11a0","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_sum'","line":287,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"inconsistent-prime-finset-fintype","claim":"The prime convention is inconsistent within the file. The `Finset` version is primed (`variance_sum'`) and the `Fintype` version unprimed (`variance_sum`), following `covariance_sum_left'`. Yet `IndepFun.variance_sum` in the same file is the unprimed `Finset` version, so `variance_sum` and `IndepFun.variance_sum` sum over different index forms.","fix":"Document the convention or align it: rename `IndepFun.variance_sum` to `IndepFun.variance_sum'` and add a `Fintype` `IndepFun.variance_sum`, with a deprecated alias.","ev":"hunts/variance/batch3/Probe2.lean (Q3) #check output: `variance_sum' : ... {s : Finset ι} ... Var[∑ i ∈ s, X i; μ] = ...`; `variance_sum : ... [Fintype ι] ... Var[∑ i, X i; μ] = ...`; `IndepFun.variance_sum : ... {s : Finset ι}, ... Var[∑ i ∈ s, X i; μ] = ∑ i ∈ s, Var[X i; μ]`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-cd863d","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_map","line":305,"sev":"NIT","status":"suspected","cat":"proof","pattern":"proof-detour","claim":"Proof/API refinements suggested by Astra and not tested here: `variance_map` re-proves the transport that `covariance_map` gives (via `covariance_self`); `variance_le_sub_mul_sub` converts boundedness to `MemLp` twice and rebuilds integrability of `(a + b) * X` by hand; `covariance_self` and `variance_fun_neg` have shorter proofs; `nonrec` on `IndepFun.variance_add`/`IndepFun.variance_sum` is unnecessary; there is no `evariance_map` (transport of the extended variance, which keeps the information `toReal` discards).","fix":"Reuse `covariance_map`/`covariance_self`, factor the `MemLp` conversion, drop `nonrec`, and add `evariance_map`.","ev":"Suspected: Astra's A1 items 11, 16, 20, 24, 25; replacements not compiled here.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-b6921e","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_map","line":317,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-fun-form-companion","claim":"There is no lambda-form companion: `covariance_map_fun` exists (Covariance.lean:317), but there is no `variance_map_fun`. As a result, `HasGaussianLaw.charFun_map_eq` and `hasGaussianLaw_iff_charFun_map_eq` (HasGaussianLaw/Basic.lean:96, 105) follow `variance_map` with `Function.comp_def`. Also, `variance_map` takes `AEMeasurable X (μ.map Y)` where `covariance_map` takes `AEStronglyMeasurable`.","fix":"Add `variance_map_fun : Var[X; μ.map Y] = Var[fun ω ↦ X (Y ω); μ]` with the same hypotheses, mirroring `covariance_map_fun`.","ev":"git grep -n 'variance_map_fun' origin/master -- Mathlib → no hits; Covariance.lean:317 `lemma covariance_map_fun`; HasGaussianLaw/Basic.lean:96,105 `variance_map ..., integral_complex_ofReal, Function.comp_def]`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-51529a","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_le_expectation_sq","line":341,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-shadowing-binder","claim":"`variance_le_expectation_sq` (L341), `evariance_def'` (L362) and `meas_ge_le_evariance_div_sq` (L380) each re-bind `{X : Ω → ℝ}`, which only shadows the section variable `variable {X : Ω → ℝ}` from L309. The same leftover appears outside this batch at L398, L408, L418 (`{X Y : Ω → ℝ}`) and L424 (`{ι} {X} {s}`, shadowing L285).","fix":"Delete the redundant `{X : Ω → ℝ}` binders. The implicit argument order is unchanged, so `@meas_ge_le_evariance_div_sq _ _ _ _ …` at L401 still works.","ev":"hunts/variance/batch4/VarianceEdit.lean has these binders removed and compiles unchanged, including the `@meas_ge_le_evariance_div_sq _ _ _ _ hX.aestronglyMeasurable …` call at L401","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-23f51f","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.evariance_def'","line":362,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"primed-def-not-definition","claim":"The name is primed `_def'`, but there is no unprimed `evariance_def` anywhere in Mathlib (git grep). The statement is not the defining equation either: `evariance` is `∫⁻ ‖X - μ[X]‖ₑ²`. It is the `ℝ≥0∞` form of the computational formula `𝔼[X²] − 𝔼[X]²`, the analogue of `variance_eq_sub`.","fix":"Rename to `evariance_eq_sub` (or `evariance_eq_lintegral_sub`), keeping a deprecated alias.","ev":"git -C mathlib4 grep -nE 'variance_def|evariance_def' origin/master -- Mathlib  →  only Variance.lean:362 (this declaration)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-a9ea0d","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.evariance_def'","line":362,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"brittle-long-simp-only","claim":"The non-L² branch (L371–L377) runs a 13-lemma `simp only [..., MemLp] at hℒ` that unfolds `MemLp` and `eLpNorm` into `rpow` facts, then finishes with `mod_cast`, which is brittle. Going through `memLp_two_iff_integrable_sq` takes 4 lines and needs no unfolding.","fix":"Replace the branch with `rw [evariance_eq_top hX hℒ, eq_comm, ENNReal.sub_eq_top_iff]; refine ⟨?_, ENNReal.ofReal_ne_top⟩; contrapose! hℒ; exact (memLp_two_iff_integrable_sq hX).2 ⟨hX.pow 2, by simpa [HasFiniteIntegral, enorm_pow, lt_top_iff_ne_top] using hℒ⟩`.","ev":"hunts/variance/batch4/probe1.lean theorem P6 (full statement, new non-L² branch); also in hunts/variance/batch4/VarianceEdit.lean, which compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-bfb704","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.meas_ge_le_evariance_div_sq","line":380,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"detour-through-elpnorm","claim":"The 13-line proof (L382–L394) goes through `meas_ge_le_mul_pow_eLpNorm_enorm`, then unfolds `eLpNorm` and juggles `rpow`s (`rpow_mul`, `inv_mul_cancel₀`, `rpow_two`, `rpow_one`) to get back to `evariance`. Applying Markov's `meas_ge_le_lintegral_div` to `‖X - μ[X]‖ₑ ^ 2` after one set rewrite takes 8 lines and avoids `eLpNorm`.","fix":"Rewrite `{ω | ↑c ≤ |X ω - μ[X]|}` as `{ω | ↑c ^ 2 ≤ ‖X ω - μ[X]‖ₑ ^ 2}`, then `exact meas_ge_le_lintegral_div ((hX.aemeasurable.sub_const _).enorm.pow_const 2) (by simpa using hc) (by simp)`.","ev":"hunts/variance/batch4/probe1.lean theorem P7 (8-line proof); also substituted in hunts/variance/batch4/VarianceEdit.lean, which compiles, including the downstream `meas_ge_le_variance_div_sq`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-33fdf2","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.IndepFun.variance_sum","line":424,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-binder-shadows-section-variable","claim":"Six declarations in this batch re-bind variables already supplied by section `variable`s: `{ι : Type*}` and `{s : Finset ι}` in IndepFun.variance_sum (from line 285); `{X : Ω → ℝ}` in meas_ge_le_variance_div_sq, variance_le_sub_mul_sub and variance_le_sq_of_bounded (from line 309); `{X Y : Ω → ℝ}` in IndepFun.variance_add and IndepFun.variance_fun_add (from lines 51/309). A copy of the file with all these binders deleted compiles unchanged.","fix":"Delete the redundant binders and rely on the section variables.","ev":"hunts/variance/batch5/probe2.lean (diff vs src.lean at lines 398, 408, 418, 424, 468, 501: binders removed; whole file compiles with no errors or linter warnings)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-cdee14","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_sum_pi","line":449,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"reprove-with-file-api","claim":"The 13-line proof uses an uncommented `change` and rewrites `(measurePreserving_eval _ i).map_eq` twice, which re-derives `MeasurePreserving.variance_fun_comp` (line 327 of this file). A 4-line proof using that lemma compiles.","fix":"Replace the `congr`/`change`/`variance_map` block with `exact sum_congr rfl fun i _ ↦ (measurePreserving_eval _ i).variance_fun_comp (h i).aemeasurable`.","ev":"  rw [IndepFun.variance_sum]\n  · exact sum_congr rfl fun i _ ↦ (measurePreserving_eval _ i).variance_fun_comp (h i).aemeasurable\n  · exact fun i _ ↦ (h i).comp_measurePreserving (measurePreserving_eval _ i)\n  · exact fun i _ j _ hij ↦ (iIndepFun_pi fun i ↦ (h i).aemeasurable).indepFun hij\n(hunts/variance/batch5/probe2.lean, lemma variance_sum_pi_golf2)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-2d888f","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_sum_pi","line":449,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-fun-variant","claim":"The left-hand side is the sum of lambdas `∑ i, fun ω ↦ X i (ω i)`, not the `fun ω ↦ ∑ i, X i (ω i)` form that the file's `variance_fun_sum` convention provides. `rw [variance_sum_pi h]` fails on the `fun` form, and there is no `variance_fun_sum_pi`.","fix":"Add `variance_fun_sum_pi` stated with `fun ω ↦ ∑ i, X i (ω i)` (proof: `convert! variance_sum_pi h; simp`).","ev":"example … (h : ∀ i, MemLp (X i) 2 (μ i)) :\n    Var[fun ω ↦ ∑ i, X i (ω i); Measure.pi μ] = ∑ i, Var[X i; μ i] := by\n  rw [variance_sum_pi h]  -- error: did not find pattern Var[∑ i, fun ω ↦ X i (ω i); Measure.pi μ]\n(hunts/variance/batch5/probe1.lean lines 38-50; the `convert! …; simp` variant compiles)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-70fb79","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_sum_pi","line":449,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring","claim":"variance_sum_pi (L449), variance_add_prod (L515), variance_dual_prod' (L530) and variance_dual_prod (L537) have no docstrings and are not in the module docstring's main results. Nothing explains how the primed and unprimed `variance_dual_prod` differ (L² of `L ∘ inl`/`L ∘ inr` versus `MemLp id 2`).","fix":"Add one-line docstrings, saying for the primed/unprimed pair which hypotheses each takes.","ev":"src.lean lines 448, 514, 529, 536 (the lines before each declaration) are blank or `variable`/section lines; there is no `/--`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-d3f7cc","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_add_prod","line":515,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"stale-hypothesis-names","claim":"Stale hypothesis names. In variance_add_prod the hypotheses are `hfμ`, `hgν`, but the variables are `X`, `Y` (leftover f/g names; Covariance.lean's covariance_fst_snd_prod has the same). In variance_dual_prod the hypotheses `hLμ hLν : MemLp id 2 _` are named after `L`, which they do not mention.","fix":"Rename to `hX`/`hY` in variance_add_prod and `hμ`/`hν` in variance_dual_prod.","ev":"src.lean L515 `(hfμ : MemLp X 2 μ) (hgν : MemLp Y 2 ν)`; L537 `(hLμ : MemLp id 2 μ) (hLν : MemLp id 2 ν)`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-7eb7a0","file":"Mathlib/Probability/Moments/Variance.lean","decl":"ProbabilityTheory.variance_dual_prod","line":537,"sev":"NIT","status":"confirmed","cat":"api","pattern":"implicit-arg-not-inferable","claim":"`{L}` is implicit but appears in no hypothesis (both are `MemLp id 2 _`), so the lemma cannot be used forwards: `have := variance_dual_prod hμ hν` fails with 'don't know how to synthesize implicit argument L'. Only `rw`/`exact` against a goal works. The lemma has no consumer in Mathlib; the Gaussian/Basic.lean consumer uses the primed version.","fix":"Make `L` explicit: `(L : StrongDual ℝ (E × F))`.","ev":"example (hμ : MemLp id 2 μ) (hν : MemLp id 2 ν) : True := by\n  have := variance_dual_prod hμ hν  -- error: don't know how to synthesize implicit argument `L`\n  trivial\n(hunts/variance/batch5/probe1.lean lines 52-64; `git grep -n variance_dual_prod origin/master -- Mathlib` outside Variance.lean finds only `variance_dual_prod'`)","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261006-352b6b","file":"Mathlib/Probability/Process/LimitProcess.lean","decl":"MeasureTheory.Filtration.stronglyMeasurable_limit_process'","line":176,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-casing","claim":"`stronglyMeasurable_limit_process'` uses `limit_process` (snake case of the def name) while its sibling is `stronglyMeasurable_limitProcess`; Mathlib names lemmas after the def's lowerCamelCase name. The module docstring also has 'familes'.","fix":"Rename to `stronglyMeasurable_limitProcess'` (it has no uses); 'families'.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-10e2d0","file":"Mathlib/Probability/Process/LimitProcess.lean","decl":"MeasureTheory.Filtration.limitProcess_ae_eq","line":191,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"API/proof gaps: no `limitProcess_of_not_hasLimitProcess` (= 0) or `hasLimitProcess_iff_ae_tendsto_limitProcess`; no quantitative `eLpNorm (limitProcess X 𝓕 P) p P ≤ R` although the proof establishes it; measurability lemmas not `@[fun_prop]`; `limitProcess_ae_eq`'s final step rebuilds `AEEqFun.tendsto_ae_unique`; `limitProcess_neg`/`smul` reopen the definition with `nth_rw 2`; no `IsUnit` version of `hasLimitProcess_smul_iff`.","fix":"Add the boundary lemmas and the quantitative bound; reuse `tendsto_ae_unique`; prove neg/smul via `limitProcess_comp`.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"1adb2afba87"},{"id":"RT-20261006-e9290c","file":"Mathlib/RepresentationTheory/Homological/GroupCohomology/Shapiro.lean","decl":"(file)","line":29,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-variable","claim":"The module docstring closes with `!-/`, leaving a stray `!` in the rendered docs, and the section variable `(A : Rep k S)` is unused (both definitions bind their own `A`); a copy without both compiles.","fix":"Use `-/` and drop `(A : Rep k S)` from the `variable` line.","ev":"-- hunts/shapiro/ProbeCopy.lean compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-e4b8a1","file":"Mathlib/RingTheory/AdicCompletion/RingHom.lean","decl":"IsAdicComplete.eq_liftRingHom","line":79,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-wrong-name","claim":"Declaration docstrings refer to names that do not exist or to the wrong kind of map: `liftRingHom` and `mk_liftRingHom` call it \"`lift I f hf`\" and a \"lift linear map\"; `eq_liftRingHom` speaks of \"a compatible family of linear maps `f n : R →ₗ[R] S ⧸ (I ^ n)`\" and concludes \"it is the map `IsAdicComplete.lift`\" (the maps are ring homs and the result is `liftRingHom`); `liftAlgHom` says \"`AlgHom` version of `IsAdicCompletion.liftRingHom`\" (no `IsAdicCompletion` namespace).","fix":"Refer to `liftRingHom`/`IsAdicComplete.liftRingHom` and to ring homomorphisms `R →+* S ⧸ I ^ n`.","ev":"Source L43–47, L63–66, L79–92, L106.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-680a0b","file":"Mathlib/RingTheory/AdicCompletion/RingHom.lean","decl":"IsAdicComplete.mk_liftAlgHom","line":119,"sev":"NIT","status":"confirmed","cat":"api","pattern":"implicit-coercion-in-statement","claim":"`mk_liftAlgHom` states `liftAlgHom I f hf x = f n x`, an equation in `S ⧸ I ^ n` whose left side carries an invisible coercion (`Ideal.Quotient.mk (I ^ n)`), unlike its ring-hom sibling which writes `Ideal.Quotient.mk (I ^ n) (liftRingHom I f hf x)`; there is also no `eq_liftAlgHom` uniqueness lemma to match `eq_liftRingHom`.","fix":"Write the projection explicitly; add `eq_liftAlgHom` via `algHom_ext` and `mkₐ_comp_liftAlgHom`.","ev":"probe1.lean: `set_option pp.coercions true` shows `(Ideal.Quotient.mk (I ^ n)) ((liftAlgHom I f ⋯) x) = (f n) x`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-20c0e8","file":"Mathlib/RingTheory/Bialgebra/GroupLike.lean","decl":"IsGroupLikeElem.pow","line":45,"sev":"NIT","status":"confirmed","cat":"api","pattern":"implicit-exponent","claim":"`IsGroupLikeElem.pow` takes the exponent implicitly (`{n : ℕ}`), unlike `IsUnit.pow (n : ℕ)` and `Submonoid.pow_mem _ (n : ℕ)`. `ha.pow 3` fails with \"Function expected\"; callers must write a type ascription.","fix":"Make `n` explicit: `lemma IsGroupLikeElem.pow (ha : IsGroupLikeElem R a) (n : ℕ) : IsGroupLikeElem R (a ^ n)`, and update the `Pow` instance to `a.2.pow n`.","ev":"probe1.lean L19 `ha.pow 3` → error: Function expected at `IsGroupLikeElem.pow ha`, type `IsGroupLikeElem R (a ^ ?m)`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-38ffb2","file":"Mathlib/RingTheory/Bialgebra/GroupLike.lean","decl":"val_mul","line":73,"sev":"NIT","status":"confirmed","cat":"api","pattern":"coe-lemma-missing-norm-cast","claim":"`val_one`, `val_mul` and `val_pow` are `@[simp]` but not `@[norm_cast]`, although `GroupLike.val` is tagged `[coe]` and `val_inj` is `norm_cast`. `push_cast` therefore leaves `↑(x * y)` alone: after `push_cast`, `rw [h]` with `h : ↑x * ↑y = 1` fails to find `↑x * ↑y`.","fix":"Tag the three lemmas `@[simp, norm_cast]`.","ev":"probe1.lean L12–14: `push_cast; rw [h]` → rewrite failed, target still `↑(x * y) = 1`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-cc600a","file":"Mathlib/RingTheory/Bialgebra/GroupLike.lean","decl":"GroupLike.instCommMonoid","line":88,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-variable-binder","claim":"L88 declares `{a b : A}` for the final section, but its only declaration, `GroupLike.instCommMonoid`, uses neither.","fix":"Drop `{a b : A}` from the L88 `variable` line.","ev":"Source: L88–91, the only use site after L88 is `instCommMonoid`, which mentions no `a`/`b`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-61fe38","file":"Mathlib/RingTheory/DedekindDomain/Ideal/Basic.lean","decl":"(file)","line":59,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-modifier","claim":"The two `variable {R} in` directives (before `adjoinIntegral_eq_one_of_isUnit` and `isDedekindDomainInv_iff`) do nothing since R does not occur, and `Ideal.isCancelMulZero` (a Prop-valued instance) is marked `noncomputable` unnecessarily; a copy without them compiles.","fix":"Delete them.","ev":"-- hunts/dedekind-ideal/ProbeCopy.lean (no `variable {R} in`, no `noncomputable` on isCancelMulZero) compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4e4311","file":"Mathlib/RingTheory/Etale/Finite.lean","decl":"CommAlgCat.instIsArtinianRingFiniteEtale","line":94,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-detour","claim":"The `IsArtinianRing` instance re-derives module finiteness with `Algebra.FormallyUnramified.finite_of_free`, although `Module.Finite k R` is already an instance (from `R.property.left`); `isArtinian_of_tower k inferInstance` alone suffices.","fix":"Drop the `have` (or use `IsArtinianRing.of_finite k R`).","ev":"example (k : Type u) [Field k] (A : FiniteEtale.{v} k) : IsArtinianRing A := isArtinian_of_tower k inferInstance","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-3d0e99","file":"Mathlib/RingTheory/Etale/Finite.lean","decl":"CommAlgCat.FiniteEtale.fiber","line":118,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-claims-more","claim":"The module and `fiber` docstrings speak of 'a geometric point Ω' and 'the fiber functor', but `fiber` accepts any field Ω (for R = Ω = ℝ, A = ℂ the 'fiber' is empty), and over a disconnected base it is not a fiber functor in the sense of `PreGaloisCategory.FiberFunctor` (it does not reflect isomorphisms).","fix":"Call it the functor of Ω-points and say when it is a fiber functor.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261006-9e529b","file":"Mathlib/RingTheory/Etale/Finite.lean","decl":"CommAlgCat.FiniteEtale.fiberIsoComp","line":151,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"confusing-binder-names","claim":"Binder names shadow the base ring: the `CoeSort` instance (`fun R ↦ R.obj`), the `IsArtinianRing` instance (`(R : FiniteEtale k)`) and `fiberIsoFiniteSpec`/`equivOfIsSepClosed` (`fun R ↦ …`) name an algebra `R` in a file where `R` is the base ring; `fiberIsoComp` does not say what it composes (base change then finite Spec).","fix":"Use `S`/`A` for algebras; rename `fiberIsoComp` to `fiberIsoBaseChangeFiniteSpec`.","ev":"","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"f0d58cda75d"},{"id":"RT-20261007-d0996b","file":"Mathlib/RingTheory/GradedAlgebra/HomogeneousLocalization.lean","decl":"HomogeneousLocalization.val_injective_iff","line":556,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `HomogeneousLocalization.ext_iff_val` (RingTheory.GradedAlgebra.HomogeneousLocalization), `HomogeneousLocalization.val_injective_iff` (RingTheory.GradedAlgebra.HomogeneousLocalization) state exactly the same thing (Lean-checked). Reviewer: val_injective_iff is generated by `@[ext]` on `val_injective` (l.310-311), and the manual ext_iff_val (l.556, about 10 uses) restates it with no comment. The low-value fix is to put @[ext] on a proper `ext` lemma (generating `ext_iff`) and deprecate ext_iff_val, or accept the generated twin.","fix":"Deprecate `HomogeneousLocalization.val_injective_iff` in favour of `HomogeneousLocalization.ext_iff_val`.","ev":"dupscan/Check.lean: `example := (@HomogeneousLocalization.val_injective_iff : type_of% @HomogeneousLocalization.ext_iff_val)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"unsure","astraS":"A2 (dup3 item 19, rating NIT): The automatic `[ext]` companion and established public `ext_iff_val` make this largely cosmetic. The proposal also names `ext_iff_val` as the keeper but subsequently suggests deprecating it.","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-8bcc94","file":"Mathlib/RingTheory/Ideal/MinimalPrime/Colon.lean","decl":"exists_eq_colon_of_mem_minimalPrimes","line":39,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"comment-wrong","claim":"Proof comments misdescribe the construction: two comments state the key property as `¬ J ≠ I` (i.e. `J = I`), but the code uses `¬ J ≤ I` (L40 `∃ J : Ideal R, I ^ n * J ≤ ann ∧ ¬ J ≤ I`); L44 calls `J` 'the product of the other minimal primes raised to the `n`th power' although the term (L49) is the `n`th power of their *intersection* (`(h.toFinset.erase I).inf id ^ n`); L56 says `x'` is picked 'from the ideal `K`' although a scalar `y ∈ K` is picked and `x' = y • x`; and the docstring speaks of a Noetherian ring while the theorem is for commutative semirings and arbitrary semimodules (Astra A1 items 3, 4, 9).","fix":"Write `¬ J ≤ I` at L39 and L54, 'intersection' at L44, and 'a scalar `y ∈ K`, with `x' = y • x`' at L56.","ev":"Doc-only finding: L39 and L54 comments `… and ¬ J ≠ I` vs L40 `¬ J ≤ I`.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261007-62648e","file":"Mathlib/RingTheory/Ideal/MinimalPrime/Colon.lean","decl":"exists_eq_colon_of_mem_minimalPrimes","line":96,"sev":"NIT","status":"suspected","cat":"proof","pattern":"proof-detour","claim":"Smaller proof/API refinements suggested by Astra, not tested here: the arithmetic tail (L64, L96-99) clears `hn0` and re-derives `n = 1` with `grind` instead of using `n - 1 = 0` and `Nat.find_min` directly; `import Mathlib.RingTheory.Noetherian.Basic` is only needed for the `Module.Finite R K` instance at L74 and could be avoided via `Submodule.fg_top`/`Ideal.fg_of_isNoetherianRing`; and `AssociatedPrime/Basic.lean` has no named corollary `I ∈ (N.colon {x}).minimalPrimes → N.IsAssociatedPrime I`. (Replacing L50-51 by `Minimal.eq_of_le` does not typecheck as is: `hI` is a `minimalPrimes` membership, not a `Minimal` term.)","fix":"Simplify the tail with `Nat.find_min`, obtain finite generation from `Ideal.fg_of_isNoetherianRing`, and add the associated-prime corollary downstream.","ev":"Suspected: Astra's A1 items 5-8; only the `Minimal.eq_of_le` variant was compiled (it fails: type mismatch on `hI`).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261006-671bcc","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.span_range_eq_ideal","line":128,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"uncommented-change","claim":"The proof uses an uncommented `change` (line 135) to restrict scalars to `S`, then a `conv_rhs => rw [← Submodule.span_span_of_tower S]`. A 4-line proof through `Submodule.span_le_restrictScalars` compiles and needs neither.","fix":"Use `le_antisymm (Ideal.span_le.2 <| Set.range_subset_iff.2 <| one_smul_sub_smul_one_mem_ideal R) fun x hx ↦ by rw [← Submodule.restrictScalars_mem S, ← submodule_span_range_eq_ideal] at hx; exact Submodule.span_le_restrictScalars S _ _ hx`.","ev":"batch0/probe6_golf.lean (G2):\n  refine le_antisymm (Ideal.span_le.2 <| Set.range_subset_iff.2 <|\n    one_smul_sub_smul_one_mem_ideal R) fun x hx ↦ ?_\n  rw [← Submodule.restrictScalars_mem S, ← submodule_span_range_eq_ideal] at hx\n  exact Submodule.span_le_restrictScalars S _ _ hx","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-42e13f","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.D","line":222,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"removable-backward-compat-option","claim":"The adaptation note's 'potential fix' works in this file: with `@[implicit_reducible]` on `def KaehlerDifferential`, the two `backward.isDefEq.respectTransparency*` options on `D` (and the dead `have`) can be dropped and the whole file compiles; `backward.defeqAttrib.useBackward` is still needed. In the current file each of the three options is needed (removing any one breaks `D`), and the note's 'only together' claim also checks out. Downstream modules were not rebuilt.","fix":"Mark `KaehlerDifferential` `@[implicit_reducible]` and drop both `respectTransparency` options on `D`, after a downstream build confirms nothing else regresses.","ev":"hunts/kaehler/batch1/v5a_implred.lean (full src.lean + `@[implicit_reducible]` on `def KaehlerDifferential`, both respectTransparency options removed): EXIT=0; hunts/kaehler/batch1/v5c_implred_nohave.lean (same, also without the `have`): EXIT=0; v5b (also without useBackward): fails at map_one_eq_zero'; v7 (implicit_reducible + only instanceSearchTypes removed): fails with the CompatibleSMul synthesis error, as the note predicts; v2/v3/v4 (current file minus one option each): all fail.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4b5182","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.D","line":226,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"dead-have","claim":"The `have : LinearMap.CompatibleSMul { x // x ∈ ideal R S } Ω[S⁄R] S (S ⊗[R] S) := inferInstance` at L233 in the `leibniz'` proof is dead code: the file compiles unchanged without it (the adaptation note itself says it does not rescue the instance search, and `this` escapes the unused-variable linter).","fix":"Delete the `have` line at L233.","ev":"hunts/kaehler/batch1/v1_nohave.lean = src.lean L1-361 (+ `end KaehlerDifferential`) with L233 deleted; `lake env lean` gives EXIT=0, no messages (baseline hunts/kaehler/batch1/base.lean also EXIT=0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-e6b1d6","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.span_range_derivation","line":260,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"todo-comment","claim":"The proof carries a TODO comment (L260-261: '-- TODO: this proof looks like we're reinventing `Submodule.span_le`. -- I'm not sure what's the RHS here though.').","fix":"Resolve the TODO (rework the `∃ hx` span induction) or delete the comment.","ev":"grep -n TODO src.lean -> 260:  -- TODO: this proof looks like we're reinventing `Submodule.span_le`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-3c9836","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.subsingleton_of_surjective","line":275,"sev":"NIT","status":"confirmed","cat":"api","pattern":"explicit-args-inferable","claim":"`R` and `S` are explicit although the explicit hypothesis `h : Function.Surjective (algebraMap R S)` determines them, so every caller restates them (`subsingleton_of_surjective A B h` at L872, `subsingleton_of_surjective R P.Ring h` in Extension/ExtendScalars.lean:114).","fix":"Make `R` and `S` implicit in `subsingleton_of_surjective`.","ev":"#check @KaehlerDifferential.subsingleton_of_surjective\n-- : ∀ (R : Type u_1) (S : Type u_2) [CommRing R] [CommRing S] [Algebra R S], Function.Surjective ⇑(algebraMap R S) → Subsingleton Ω[S⁄R]   (hunts/kaehler/batch1/probeG.lean)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-7affb7","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"Derivation.liftKaehlerDifferential_unique","line":317,"sev":"NIT","status":"confirmed","cat":"api","pattern":"explicit-args-inferable","claim":"This `@[ext]` lemma takes `f f'` explicitly although `hf` determines them; Mathlib's ext lemmas take the maps implicitly (`LinearMap.ext {f g}`, `Finsupp.lhom_ext ⦃φ ψ⦄`, `TensorProduct.ext' {g h}`), so every term-mode caller writes `liftKaehlerDifferential_unique _ _ h` (L334, L359, Etale/Kaehler.lean:117).","fix":"Make `f f'` implicit (or strict-implicit) when renaming the lemma.","ev":"-- hunts/kaehler/batch1/probeG.lean\n#check @Derivation.liftKaehlerDifferential_unique  -- (f f' : Ω[S⁄R] →ₗ[S] M) explicit\n#check @LinearMap.ext       -- {f g : M →ₛₗ[σ] M₃}\n#check @Finsupp.lhom_ext    -- ⦃φ ψ : (α →₀ M) →ₛₗ[σ₁₂] N⦄\n#check @TensorProduct.ext'  -- {g h : TensorProduct R M N →ₛₗ[σ₁₂] P₂}","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-5c4235","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.quotientCotangentIdealRingEquiv","line":362,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-undefined-symbol","claim":"Docstring 'The quotient ring of `S ⊗ S ⧸ J ^ 2` by `Ω[S⁄R]` is isomorphic to `S`' never defines `J`, and the Lean quotients by the ideal `(ideal R S).cotangentIdeal` (the image of J in S ⊗ S ⧸ J²), which is only module-isomorphic to Ω[S⁄R], not by Ω itself.","fix":"Say 'by the ideal `J / J ^ 2` (`Ideal.cotangentIdeal`), with `J` the kernel of the multiplication map `S ⊗[R] S → S`'.","ev":"#check @KaehlerDifferential.quotientCotangentIdealRingEquiv  -- ((S ⊗[R] S ⧸ ideal R S ^ 2) ⧸ (ideal R S).cotangentIdeal) ≃+* S; docstring line 362 read verbatim","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-67649e","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.quotientCotangentIdeal","line":374,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-undefined-symbol","claim":"Same docstring defect as the RingEquiv: `J` undefined and 'by `Ω[S⁄R]`' where the Lean quotients by the ideal `(ideal R S).cotangentIdeal`.","fix":"Define `J` and say the quotient is by the ideal `J / J ^ 2` (`Ideal.cotangentIdeal`).","ev":"docstring line 374 read verbatim against `#check @KaehlerDifferential.quotientCotangentIdeal` (probe1.lean)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4ca11d","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.endEquivDerivation'","line":406,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-grammar","claim":"Docstring grammar: 'Derivations into `Ω[S⁄R]` is equivalent to derivations into …' (should be 'are').","fix":"Change 'is equivalent' to 'are equivalent' (or 'The equivalence between …').","ev":"docstring lines 406-407 read verbatim","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-627633","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.endEquivDerivation'","line":408,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-noncomputable","claim":"Redundant `noncomputable` modifier: the declaration sits inside `noncomputable section KaehlerDifferential` under `suppress_compilation`; the file compiles with the modifier removed.","fix":"Drop the `noncomputable` keyword.","ev":"hunts/kaehler/batch2/copy_edits.lean (modifier removed on lines 408, 425, 504, plus the other proposed edits) compiles with no errors or warnings","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-6e8afb","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.endEquiv","line":422,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-grammar","claim":"Docstring grammar ('The endomorphisms of `Ω[S⁄R]` corresponds to …'), and `endEquiv` is not listed in the module docstring's 'Main results' although it is one of the file's main constructions.","fix":"Write 'correspond' and add `KaehlerDifferential.endEquiv` to the module docstring.","ev":"docstring lines 421-424 and module docstring lines 14-46 read verbatim","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-f557fe","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.endEquiv","line":425,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-noncomputable","claim":"Redundant `noncomputable` modifier inside `noncomputable section` with `suppress_compilation`; the file compiles with it removed.","fix":"Drop the `noncomputable` keyword.","ev":"hunts/kaehler/batch2/copy_edits.lean compiles with no errors or warnings","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4becbc","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.kerTotal","line":504,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-noncomputable","claim":"Redundant `noncomputable` modifier inside `noncomputable section` with `suppress_compilation`; the file compiles with it removed.","fix":"Drop the `noncomputable` keyword.","ev":"hunts/kaehler/batch2/copy_edits.lean compiles with no errors or warnings","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b5462f","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.kerTotal_mkQ_single_smul","line":534,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"dead-let-in-proof","claim":"The first proof line `let : SMulZeroClass R S := inferInstance` is dead: the proof compiles unchanged without it (in the original file context and standalone).","fix":"Delete the `let : SMulZeroClass R S := inferInstance` line.","ev":"batch3/ModA.lean (src.lean with the `let` removed; whole file compiles, exit 0) and batch3/probe1.lean P4:\nexample (r : R) (x y : S) :\n    (KaehlerDifferential.kerTotal R S).mkQ (single (r • x) y) =\n      r • (KaehlerDifferential.kerTotal R S).mkQ (single x y) := by\n  rw [Algebra.smul_def, KaehlerDifferential.kerTotal_mkQ_single_mul,\n    KaehlerDifferential.kerTotal_mkQ_single_algebraMap, add_zero, ← LinearMap.map_smul_of_tower,\n    Finsupp.smul_single, mul_comm, Algebra.smul_def]","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-830c89","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.derivationQuotKerTotal","line":542,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"avoidable-backward-compat-option","claim":"`set_option backward.isDefEq.respectTransparency.types false in` is needed only because the `leibniz'` proof ends in a `simp` that cannot see through the coercion of the structure-literal linear map. Removing the option alone fails (ModB: unsolved goal `a • mk (single b 1) + … = a • { toFun := … } b + …`), but a direct proof works without it, so the backward-compatibility flag can go.","fix":"Drop the set_option and prove `leibniz' a b := by dsimp only [LinearMap.coe_mk, AddHom.coe_mk]; rw [kerTotal_mkQ_single_mul, one_mul, one_mul, ← Finsupp.smul_single_one _ a, ← Finsupp.smul_single_one _ b, map_smul, map_smul]` (or append `; rfl` to the current proof).","ev":"batch3/ModB.lean (option removed only: error at 549:7, fails-as-expected); batch3/ModB2.lean (option removed + proof\n  leibniz' a b := by\n    dsimp only [LinearMap.coe_mk, AddHom.coe_mk]\n    rw [KaehlerDifferential.kerTotal_mkQ_single_mul, one_mul, one_mul,\n      ← Finsupp.smul_single_one _ a, ← Finsupp.smul_single_one _ b, map_smul, map_smul]\n: whole file compiles); batch3/ModB1.lean (option removed, old proof + `; rfl`: compiles). All compiled with -D maxSynthPendingDepth=3 -D autoImplicit=false.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-12f515","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.kerTotal_eq","line":565,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"eq-name-reversed","claim":"The name `kerTotal_eq` reads as `kerTotal R S = …`, but the statement is `LinearMap.ker (Finsupp.linearCombination S (D R S)) = kerTotal R S`: the named constant is on the right-hand side, against the convention that the name describes the conclusion left to right.","fix":"Rename to `ker_linearCombination_eq_kerTotal` (with a deprecated alias), or flip the equation.","ev":"src.lean:565-567: theorem KaehlerDifferential.kerTotal_eq : LinearMap.ker (Finsupp.linearCombination S (KaehlerDifferential.D R S)) = KaehlerDifferential.kerTotal R S","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-d2bcca","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.quotKerTotalEquiv","line":581,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"hand-rolled-quotient-equiv","claim":"The 17-line hand-built equivalence can be assembled from existing API: `(Submodule.quotEquivOfEq _ _ (kerTotal_eq R S).symm).trans (LinearMap.quotKerEquivOfSurjective _ (linearCombination_surjective R S))`. It is provably equal to `quotKerTotalEquiv`. Trade-off: the hand-written `invFun` makes `symm` definitionally `liftKaehlerDifferential`, which the combinator version would only give propositionally.","fix":"Either build it from `quotEquivOfEq`/`quotKerEquivOfSurjective` and prove `symm_apply` as a lemma, or keep the explicit inverse but derive `left_inv`/`right_inv` more briefly. A judgement call.","ev":"batch3/probe4.lean:\nnoncomputable def alt : ((S →₀ S) ⧸ kerTotal R S) ≃ₗ[S] Ω[S⁄R] :=\n  (Submodule.quotEquivOfEq _ _ (kerTotal_eq R S).symm).trans\n    (LinearMap.quotKerEquivOfSurjective _ (linearCombination_surjective R S))\nexample : alt R S = quotKerTotalEquiv R S := by\n  ext x\n  obtain ⟨x, rfl⟩ := Submodule.mkQ_surjective _ x\n  rfl","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-582f87","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.quotKerTotalEquiv_symm_comp_D","line":600,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"unneeded-convert","claim":"`convert!` is unnecessary: the statement is closed by the term `(derivationQuotKerTotal R S).liftKaehlerDifferential_comp` directly.","fix":"Replace `by convert! …` with the term `(KaehlerDifferential.derivationQuotKerTotal R S).liftKaehlerDifferential_comp`.","ev":"batch3/probe1.lean P2:\nexample : (KaehlerDifferential.quotKerTotalEquiv R S).symm.toLinearMap.compDer\n      (KaehlerDifferential.D R S) = KaehlerDifferential.derivationQuotKerTotal R S :=\n  (KaehlerDifferential.derivationQuotKerTotal R S).liftKaehlerDifferential_comp\n(also in batch3/ModA.lean, whole file compiles)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-156253","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.ker_map","line":699,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"repeated-bullets-collapse","claim":"The four side-goal bullets after `rw [Finsupp.sum_mapRange_index, Finsupp.sum_mapDomain_index]` (`· simp`, `· simp`, `· simp [add_smul]`, `· simp`) collapse to `<;> simp [add_smul]`.","fix":"Replace the five lines with `rw [Finsupp.sum_mapRange_index, Finsupp.sum_mapDomain_index] <;> simp [add_smul]`.","ev":"batch3/ModA.lean (tail of `ker_map` replaced by `rw [Finsupp.sum_mapRange_index, Finsupp.sum_mapDomain_index] <;> simp [add_smul]`): whole file compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-f6ad21","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.map_surjective_of_surjective","line":726,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-open","claim":"`open IsScalarTower (toAlgHom)` (L726, just above `map_surjective_of_surjective`) is unused: `toAlgHom` occurs nowhere in L727-785, the rest of the enclosing `section`. It dates from the 2024 split of RingTheory/Kaehler (#13978). The file compiles unchanged without it.","fix":"Delete the line `open IsScalarTower (toAlgHom)`.","ev":"-- hunts/kaehler/batch4/cC_noopen.lean = src.lean with the line `open IsScalarTower (toAlgHom)` removed; `lake env lean` gives no errors and no warnings.\n-- awk 'NR>=727 && NR<=785 && /toAlgHom/' src.lean  ->  (no output)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-692d54","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.mapBaseChange","line":745,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-noncomputable","claim":"The `noncomputable` modifiers on `mapBaseChange` (L745), `kerToTensor` (L789) and `kerCotangentToTensor` (L800) do nothing: the whole file is inside `noncomputable section KaehlerDifferential` (L52) and under `suppress_compilation` (L50). The file compiles with all three removed. The same leftover is on L408, L425, L504, L542 and L581, outside this batch.","fix":"Drop the `noncomputable` keyword from these defs, or drop it file-wide.","ev":"-- hunts/kaehler/batch4/cF_no_noncomputable.lean = src.lean with `noncomputable` removed at L745, L789, L800; compiles with no errors or warnings","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b668e4","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.mapBaseChange_tmul","line":749,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-artifact-of-definition","claim":"The proof is a 3-line `conv_lhs => rw [← mul_one x, ← smul_eq_mul, ← TensorProduct.smul_tmul', map_smul]; congr 1; exact IsBaseChange.lift_eq _ _ _`. It exists only because of the hand-rolled `IsBaseChange.lift` definition. With `mapBaseChange := (map R R A B).liftBaseChange B` the lemma is `rfl`, an instance of `LinearMap.liftBaseChange_tmul`.","fix":"After redefining `mapBaseChange` via `LinearMap.liftBaseChange`, replace the proof by `rfl`.","ev":"-- hunts/kaehler/batch4/cA_liftBaseChange.lean (compiles):\n@[simp]\ntheorem KaehlerDifferential.mapBaseChange_tmul (x : B) (y : Ω[A⁄R]) :\n    KaehlerDifferential.mapBaseChange R A B (x ⊗ₜ y) = x • KaehlerDifferential.map R R A B y :=\n  rfl","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c5effb","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.exact_mapBaseChange_map","line":779,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-states-whole-sequence","claim":"The docstring says \"The sequence `B ⊗[A] Ω[A⁄R] → Ω[B⁄R] → Ω[B⁄A] → 0` is exact\", but the statement is only `Function.Exact (mapBaseChange R A B) (map R A B B)`, which is exactness at Ω[B⁄R]. Exactness at Ω[B⁄A] (the `→ 0`) is `map_surjective`, which the docstring mentions only as \"Also see\". The module docstring (L35-36) states it correctly, without `→ 0`.","fix":"Say \"The sequence `B ⊗[A] Ω[A⁄R] → Ω[B⁄R] → Ω[B⁄A]` is exact; together with `KaehlerDifferential.map_surjective` this gives right exactness.\"","ev":"-- src.lean L779-782 vs L35-36 (measured: docstring text against the statement)","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-694e50","file":"Mathlib/RingTheory/Kaehler/Basic.lean","decl":"KaehlerDifferential.range_kerCotangentToTensor","line":852,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"misplaced-stale-perf-comment","claim":"The comment `-- TODO: was simp [kerCotangentToTensor_toCotangent, RingHom.mem_ker.mp x.2] and very slow (#19751)` at L852-853 is misplaced and stale. Commit 37305b9e5ef (#19743) squeezed the first-direction `simp` (now L827-828) but put the comment in front of the second-direction block. That block was already a `simp only` before the commit, and `x.2` would not even typecheck there, because `x` is a `Finsupp`. The workaround is also no longer needed: restoring the original `simp [kerCotangentToTensor_toCotangent, RingHom.mem_ker.mp x.2]` at L827 costs about 6-14 ms more simp time (120/131 ms against 114/117 ms over two runs).","fix":"Delete the comment and restore `simp [RingHom.mem_ker.mp x.2]` at L827-828; tick this file off tracking issue #19751.","ev":"-- git show 37305b9e5ef -- Mathlib/RingTheory/Kaehler/Basic.lean: hunk 1 replaces `simp [kerCotangentToTensor_toCotangent, RingHom.mem_ker.mp x.2]` in the first direction; hunk 2 only inserts the comment before the pre-existing `simp only [smul_sub, ...]`.\n-- hunts/kaehler/batch4/cE2_original_simp.lean (original simp restored at L827) compiles; profiler simp 120ms / 131ms vs hunts/kaehler/batch4/cE0_baseline.lean 114ms / 117ms","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-9b2ecf","file":"Mathlib/RingTheory/Localization/Away/AdjoinRoot.lean","decl":"(file)","line":10,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-omission","claim":"The module docstring has no `# Title` heading and describes only `awayEquivAdjoin`. The file also proves that `Localization.Away` is finitely presented or of finite type over a finitely presented or finite-type algebra (`Algebra.FinitePresentation.of_isLocalizationAway` and two instances).","fix":"Add a title and list the finite-presentation results.","ev":"src L10-13.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-ec3025","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"(file)","line":12,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-import","claim":"`public import Mathlib.Tactic.ContinuousFunctionalCalculus` (L12) is unused: the file compiles without it. Being public, it re-exports the continuous-functional-calculus tactic layer to every importer of `MvPowerSeries.Equiv`.","fix":"Delete L12.","ev":"NoCFC.lean (src.lean minus L12) compiles with no messages.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-a10c5e","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.isEmptyEquiv","line":54,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-differs-from-mvpolynomial-analogue","claim":"The MvPolynomial analogue of this AlgEquiv is named `MvPolynomial.isEmptyAlgEquiv` (with a separate `isEmptyRingEquiv`); the power series version is `isEmptyEquiv`, so the parallel API does not line up by name.","fix":"Rename to `MvPowerSeries.isEmptyAlgEquiv` (with a deprecated alias) to match MvPolynomial.","ev":"hunts/mvpowerseries-equiv/batch0/Probe1.lean: `#check @MvPolynomial.isEmptyAlgEquiv` resolves; `git grep -n isEmptyAlgEquiv origin/master -- Mathlib/Algebra/MvPolynomial/Equiv.lean` -> line 261 `def isEmptyAlgEquiv : MvPolynomial σ R ≃ₐ[R] R`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-74aebf","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.optionFunLeft","line":66,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"defeq-abuse-forces-backward-option","claim":"The body `.mk fun n ↦ fun x ↦ p.coeff (x.optionElim n)` passes a `ℕ → (σ →₀ ℕ) → R` where `ℕ → MvPowerSeries σ R` is expected; it is type-correct only after unfolding the `MvPowerSeries` definition. That is why `coeff_coeff_optionFunLeft` carries `set_option backward.isDefEq.respectTransparency false`: without it `rw [optionFunLeft, PowerSeries.coeff_mk]` fails with 'target expression is not type-correct under the implicit transparency level'. Ascribing the inner lambda (`show MvPowerSeries σ R from fun x ↦ ...`) makes the same proof go through without the option.","fix":"Write the body as `.mk fun n ↦ (show MvPowerSeries σ R from fun x ↦ p.coeff (x.optionElim n))` and drop the `set_option backward.isDefEq.respectTransparency false in` on `coeff_coeff_optionFunLeft` (proof becomes `rw [optionFunLeft, PowerSeries.coeff_mk]; rfl`).","ev":"hunts/mvpowerseries-equiv/batch0/Golf.lean (G1: original proof of coeff_coeff_optionFunLeft without the set_option -> error 'Application type mismatch: fun n x ↦ (coeff (optionElim n x)) p has type ℕ → (σ →₀ ℕ) → R but is expected to have type ℕ → MvPowerSeries σ R'); hunts/mvpowerseries-equiv/batch0/Defn.lean (D2: `noncomputable def f2 p : PowerSeries (MvPowerSeries σ R) := .mk fun n ↦ (show MvPowerSeries σ R from fun x ↦ p.coeff (x.optionElim n))` then `example ... : coeff x (PowerSeries.coeff n (f2 p)) = coeff (x.optionElim n) p := by rw [f2, PowerSeries.coeff_mk]; rfl` compiles with no option, while the same for the original body f1 fails)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-16109d","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.optionFunLeft_monomial","line":75,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"golfable-case-split-proof","claim":"The 12-line four-branch `split_ifs` proof (with an `absurd`/`replace`/`ext u; cases u` detour) can be replaced by a 6-line proof: the key fact `y.optionElim n = x ↔ n = x none ∧ y = x.some` is `(optionEquiv.symm_apply_eq (x := (n, y))).trans Prod.ext_iff`, after which one `simp` closes the goal.","fix":"Use `classical; ext n y; have key : y.optionElim n = x ↔ n = x none ∧ y = x.some := (optionEquiv.symm_apply_eq (x := (n, y))).trans Prod.ext_iff; simp [coeff_coeff_optionFunLeft, coeff_monomial, PowerSeries.coeff_monomial, key, ite_and, apply_ite (coeff y)]`.","ev":"hunts/mvpowerseries-equiv/batch0/Golf.lean, `optionFunLeft_monomial_v2` (same statement, proof: classical / ext n y / have key ... := (optionEquiv.symm_apply_eq (x := (n, y))).trans Prod.ext_iff / simp [coeff_coeff_optionFunLeft, coeff_monomial, PowerSeries.coeff_monomial, key, ite_and, apply_ite (coeff y)]) compiles with no warnings","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-27912f","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.optionEquivLeft_X_some","line":139,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"golfable-auxiliary-have","claim":"The 6-line proof (a `classical` auxiliary `have` about `optionElim 0 (single i 1)` then a `simpa` with `PowerSeries.monomial_eq_C_mul_X_pow`) is a one-liner: `simp [X_def, optionEquivLeft_monomial]`.","fix":"Replace the proof by `simp [X_def, optionEquivLeft_monomial]`.","ev":"hunts/mvpowerseries-equiv/batch0/Golf.lean, `lemma optionEquivLeft_X_some_v1 (i : σ) : optionEquivLeft σ R (X (Option.some i)) = PowerSeries.C (X i) := by simp [X_def, optionEquivLeft_monomial, single_apply]` compiles (linter: `single_apply` unused, so `simp [X_def, optionEquivLeft_monomial]` suffices)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-056503","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.optionEquivLeft_X_some","line":139,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-parentheses","claim":"The right-hand side is wrapped in redundant parentheses: `= (PowerSeries.C (X i))`.","fix":"Write `= PowerSeries.C (X i)`.","ev":"src.lean line 140: `    optionEquivLeft σ R (X (Option.some i)) = (PowerSeries.C (X i)) := by`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-8951c4","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.embDomain_finSuccEquiv_cons","line":162,"sev":"NIT","status":"confirmed","cat":"generality","pattern":"typeclass-stronger-than-needed","claim":"`[AddCommMonoid M]` is stronger than needed: the statement holds for `[Zero M]` (casing on `Option` and using `Finsupp.embDomain_apply_self` instead of `embDomain_eq_mapDomain`). It is NIT, not MINOR, because the helper is private and used once, at `M = ℕ`.","fix":"Weaken to `[Zero M]` and prove by `cases a` with `embDomain_apply_self` (or leave it, since the helper is private and used once).","ev":"hunts/mvpowerseries-equiv/batch1/Probe1.lean (P6: `theorem embDomain_finSuccEquiv_cons' {M : Type*} [Zero M] (i : M) (x : Fin n →₀ M) : embDomain (_root_.finSuccEquiv n).toEmbedding (cons i x) = optionElim i x := by ext a; cases a with | none => simpa using embDomain_apply_self (_root_.finSuccEquiv n).toEmbedding (cons i x) 0 | some j => simpa using embDomain_apply_self (_root_.finSuccEquiv n).toEmbedding (cons i x) j.succ`). The same replacement in place in hunts/mvpowerseries-equiv/batch1/EquivCopy.lean compiles, including its use in `coeff_coeff_finSuccEquiv`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-c3570a","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.embDomain_finSuccEquiv_cons","line":162,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-binder-shadows-section-variable","claim":"The lemma re-binds `{n : ℕ}` even though `variable {n : ℕ}` (line 160) is already in scope, so the section variable is shadowed by a redundant local binder.","fix":"Drop the local `{n : ℕ}` binder and use the section variable.","ev":"src.lean L160 `variable {n : ℕ}`; L162 `private lemma embDomain_finSuccEquiv_cons {M : Type*} [AddCommMonoid M] {n : ℕ} (i : M)`. hunts/mvpowerseries-equiv/batch1/EquivCopy.lean drops the binder and compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-00e890","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.coeff_coeff_finSuccEquiv","line":172,"sev":"NIT","status":"confirmed","cat":"api","pattern":"inconsistent-binder-explicitness","claim":"The binders are inconsistent with the sibling lemmas. Here `{k : ℕ} {x : Fin n →₀ ℕ}` are implicit after an explicit `p`, while the sibling `coeff_coeff_optionEquivLeft (p) (n : ℕ) (x)` and the analogue `MvPolynomial.finSuccEquiv_coeff_coeff (m) (f) (i)` take them explicitly.","fix":"Make `k` and `x` explicit, matching `coeff_coeff_optionEquivLeft`.","ev":"#check in hunts/mvpowerseries-equiv/batch1/Probe1.lean: `coeff_coeff_finSuccEquiv : ∀ {R} [CommSemiring R] {n} (p) {k : ℕ} {x : Fin n →₀ ℕ}, ...` vs `coeff_coeff_optionEquivLeft : ∀ {σ R} [CommSemiring R] (p) (n : ℕ) (x : σ →₀ ℕ), ...`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-77abc1","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.finSuccEquiv_comp_C","line":210,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-omits-symm","claim":"The name `finSuccEquiv_comp_C` leaves out that the statement concerns `(finSuccEquiv R n).symm`, composed with `PowerSeries.C.comp C`, and that it equals `C`. It also differs from the analogue `MvPolynomial.finSuccEquiv_comp_C_eq_C`.","fix":"Rename to `finSuccEquiv_symm_comp_C_comp_C` (or at least to `finSuccEquiv_comp_C_eq_C`, matching MvPolynomial) and add a deprecated alias.","ev":"src.lean L210: `theorem finSuccEquiv_comp_C : (MvPowerSeries.finSuccEquiv R n).symm.toRingHom.comp (PowerSeries.C.comp MvPowerSeries.C) = MvPowerSeries.C`; Mathlib/Algebra/MvPolynomial/Equiv.lean:664 `theorem finSuccEquiv_comp_C_eq_C`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-e0af06","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.truncTotal_sub_truncTotal_mem_pow_idealOfVars","line":240,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-binder-shadows-section-variable","claim":"The lemma binds `{l m n : ℕ}`, which shadows the section `variable {n : ℕ}` declared two lines above (line 238).","fix":"Rename the local binders (e.g. `{l m k : ℕ}`), or drop the local `n` and use the section variable.","ev":"src.lean L238 `variable {σ R : Type*} {n : ℕ} [CommRing R] [Finite σ]`; L240 `lemma truncTotal_sub_truncTotal_mem_pow_idealOfVars {l m n : ℕ} (h : l ≤ m) (h' : l ≤ n)`; #check in Probe1.lean shows only the local `{l m n}` binders.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-70a819","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.truncTotalAlgHom","line":258,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redeclared-section-variables","claim":"The `toAdicCompletion` section redeclares variables already in scope. `truncTotalAlgHom` (258), `toAdicCompletion` (283) and `toAdicCompletionAlgEquiv` (343) re-bind `(σ R : Type*) [Finite σ] [CommRing R]`, shadowing the section's `{σ R} [CommRing R] [Finite σ]` instead of using `variable (σ R) in`, the idiom the rest of the file uses. The lemmas at 291, 294 and 323 re-bind the section variable `{n : ℕ}`. `open Finsupp` (236) repeats line 41.","fix":"Use `variable (σ R) in` for the three defs, drop the duplicate `{n : ℕ}` binders and the second `open Finsupp`.","ev":"hunts/mvpowerseries-equiv/batch2/src_mod.lean (`variable (σ R) in` for `truncTotalAlgHom`, same explicit signature `(σ R) ... (n : ℕ)`) and hunts/mvpowerseries-equiv/batch2/src_mod3.lean (the `{n : ℕ}` binders and `open Finsupp` removed) compile with no errors or warnings.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-ccee73","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.truncTotalAlgHom","line":274,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"uncommented-change","claim":"`commutes'` opens with an uncommented `change` that restates the goal, relying on `algebraMap (MvPolynomial σ R) (_ ⧸ _) p` being defeq to `Ideal.Quotient.mk _ p`. A term proof avoids restating the goal.","fix":"Use `commutes' p := Ideal.Quotient.eq.mpr <| (MvPolynomial.mem_pow_idealOfVars_iff' ..).mpr fun x h ↦ by rw [MvPolynomial.coeff_sub, sub_eq_zero, coeff_truncTotal _ h]; rfl`, or comment the `change`.","ev":"hunts/mvpowerseries-equiv/batch2/src_mod.lean (line ~277): the replacement above compiles in place.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-a9dabc","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.toAdicCompletionInv","line":300,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-omits-hypothesis","claim":"`toAdicCompletionInv`'s docstring \"An inverse function of `toAdicCompletion`\" omits that it is defined for arbitrary `σ` while `toAdicCompletion` needs `[Finite σ]` (`toAdicCompletionInv ℕ ℤ` exists, `toAdicCompletion ℕ ℤ` does not); it is coefficient extraction, an inverse only for finite `σ`. The TODO in `PowerSeries/Ideal.lean` asking for Noetherianity of finite-variable power series is now done by this file's `isNoetherianRing` instance.","fix":"Document it as coefficient extraction, inverse when `σ` is finite; remove the stale TODO.","ev":"Source (toAdicCompletion requires `[Finite σ]`, toAdicCompletionInv does not).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-962793","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"PowerSeries.toMvPowerSeries","line":375,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-noncomputable","claim":"The `noncomputable` modifier on line 375 is redundant: the anonymous `noncomputable section` opened at line 39 is still open (it runs to EOF).","fix":"Delete the `noncomputable` line before `def toMvPowerSeries`.","ev":"Removed in hunts/mvpowerseries-equiv/batch2/src_mod.lean; the file compiles unchanged.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-edf089","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"PowerSeries.toMvPowerSeries_injective","line":389,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-binder-shadows-variable","claim":"`toMvPowerSeries_injective (i : σ)` and `toMvPowerSeries_inj (i : σ)` re-bind `i`, which is already the explicit section variable `(i : σ)` of line 368; dropping the binders leaves both signatures unchanged.","fix":"Delete the `(i : σ)` binders and use the section variable.","ev":"batch3/modified.lean: `theorem toMvPowerSeries_injective : Function.Injective (toMvPowerSeries (R := R) i)` and `theorem toMvPowerSeries_inj {p q : R⟦X⟧} : ...` compile with the same signatures (`#check @PowerSeries.toMvPowerSeries_injective : ∀ {R σ} [CommSemiring R] (i : σ), Injective ⇑(toMvPowerSeries i)`).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-52d12b","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"PowerSeries.toMvPowerSeries_eq_subst","line":400,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"shadowed-section-variables","claim":"The section's variables are shadowed twice: `section CommRing` (line 398) re-declares `{R : Type*} [CommRing R] {f : R⟦X⟧} {i : σ}` over the outer `{R} [CommSemiring R] {f : PowerSeries R} (i : σ)` of line 368 (turning the explicit `i` implicit), and line 429 re-declares `f` as the renaming map `σ → τ`, so `f` means a power series in one half of the section and a function in the other.","fix":"Scope the `CommSemiring` variables in their own section, declare the `CommRing` ones only once, and call the renaming map `g`.","ev":"src.lean:368 `variable {R σ τ : Type*} [CommSemiring R] {f : PowerSeries R} (i : σ) (r : R)`; :398 `variable {R : Type*} [CommRing R] {f : R⟦X⟧} {i : σ}`; :429 `variable (f : σ → τ) [TendstoCofinite f] (a : σ) (p : R⟦X⟧)`. batch3/modified.lean renames the map to `g` and compiles.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-d33eac","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"PowerSeries.toMvPowerSeries_coeff_eq_zero","line":408,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-order-not-head-symbol","claim":"The conclusion is `coeff d (toMvPowerSeries i f) = 0`, so Mathlib's convention (head symbol first) gives `coeff_toMvPowerSeries_eq_zero`, as for the sibling `MvPowerSeries.coeff_rename_eq_zero : (rename f p).coeff x = 0` (Rename.lean:133).","fix":"Rename to `coeff_toMvPowerSeries_eq_zero` (with a deprecated alias).","ev":"Equiv.lean:408 `lemma toMvPowerSeries_coeff_eq_zero ... : (f.toMvPowerSeries i).coeff d = 0`; Rename.lean:133 `theorem coeff_rename_eq_zero (p : MvPowerSeries σ R) {x : τ →₀ ℕ} (h' : ...) : (rename f p).coeff x = 0`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-9add02","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"PowerSeries.toMvPowerSeries_coeff_eq_zero","line":408,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"roundabout-proof-via-subst","claim":"The 8-line proof detours through `rename_eq_subst`, `coeff_subst`, a finsum and a 7-lemma `simp only` (which is what forces `CommRing` and `classical`; without `classical` the `simp only` stalls), and it is laid out as `:= by classical` with the block continuing on later lines (17 such occurrences in Mathlib against 2380 with `classical` on its own line). Via a coefficient formula it is a two-line `rw`.","fix":"Prove it as `classical; rw [coeff_toMvPowerSeries, hd, single_zero, coeff_zero_eq_constantCoeff_apply, hf, ite_self]` (or from `coeff_rename_eq_zero`), with `classical` on its own line.","ev":"batch3/modified.lean (compiles, no linter warnings):\nlemma coeff_toMvPowerSeries_eq_zero {d : σ →₀ ℕ} (hd : d i = 0) (hf : f.constantCoeff = 0) :\n    (f.toMvPowerSeries i).coeff d = 0 := by\n  classical\n  rw [coeff_toMvPowerSeries, hd, single_zero, coeff_zero_eq_constantCoeff_apply, hf, ite_self]\n-- batch3/probe1.lean P4: original proof without `classical` fails (`intro _ a` finds no binder: `coeff_monomial` cannot fire). Layout counts: `git grep -E 'by classical\\s*$'` = 17, `git grep -E '^\\s+classical\\s*$'` = 2380 (origin/master, Mathlib).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-29eecf","file":"Mathlib/RingTheory/MvPowerSeries/Equiv.lean","decl":"MvPowerSeries.HasSubst.toMvPowerSeries","line":418,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"simp-unfolds-definition","claim":"`const_coeff := by simp_all [constantCoeff, toMvPowerSeries_apply]` works only by having simp unfold the definition `PowerSeries.constantCoeff` (there is no `constantCoeff_toMvPowerSeries` simp lemma), and `Finite.of_fintype d.support` is a detour for `d.support.finite_toSet`.","fix":"Once `constantCoeff_toMvPowerSeries` is a simp lemma, write `const_coeff _ := by simp [hf]` and `coeff_zero d := d.support.finite_toSet.subset ...`.","ev":"batch3/modified.lean and batch3/probe1.lean (P5):\n  const_coeff := by simp [hf]\n  coeff_zero d := d.support.finite_toSet.subset fun s => by\n    contrapose\n    simpa using fun hd ↦ coeff_toMvPowerSeries_eq_zero hd hf","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-45d995","file":"Mathlib/RingTheory/NonUnitalSubring/Defs.lean","decl":"NonUnitalSubring.mem_carrier","line":168,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"exact-duplicate-declaration","claim":"Duplicate declarations: `NonUnitalSubring.mem_toNonUnitalSubsemiring` (RingTheory.NonUnitalSubring.Defs), `NonUnitalSubring.mem_carrier` (RingTheory.NonUnitalSubring.Defs) state exactly the same thing (Lean-checked). Reviewer: This is a misstatement. `NonUnitalSubring.mem_carrier` states `x ∈ s.toNonUnitalSubsemiring ↔ x ∈ s`, exactly mem_toNonUnitalSubsemiring, whereas every sibling (Subring, Subsemiring, NonUnitalSubsemiring) states `x ∈ s.carrier ↔ x ∈ s`. Restate mem_carrier rather than deprecating it.","fix":"Deprecate `NonUnitalSubring.mem_carrier` in favour of `NonUnitalSubring.mem_toNonUnitalSubsemiring`.","ev":"dupscan/Check.lean: `example := (@NonUnitalSubring.mem_carrier : type_of% @NonUnitalSubring.mem_toNonUnitalSubsemiring)` compiles with `import Mathlib` (all 273 duplicate checks pass, exit 0; a deliberately false pairing fails). Found by dupscan/DupScan.lean.","evr":"compiles","astraV":"disagrees","astraS":"A2 (mis item 30, rating NIT): Membership in `s.toNonUnitalSubsemiring` is definitionally membership in the inherited `s.carrier`. Thus the name has an accurate reading and the alleged missing proposition is already represented. The conventional, clearer spelling is `x ∈ s.carrier ↔ x ∈ s`; changing to it is sensible cosmetic cleanup. [Structure and instances](https://github.com/leanprover-community/mathlib4/blob/e6bbacd0e1/Mathlib/RingTheory/NonUnitalSubring/Defs.lean#L116-L169)","pr":null,"res":"","at":"2026-10-07","commit":""},{"id":"RT-20261007-9fbcbd","file":"Mathlib/RingTheory/Polynomial/Selmer.lean","decl":"(file)","line":29,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-open","claim":"`open scoped Polynomial` (L29) is redundant directly inside `namespace Polynomial`, which already activates the namespace's scoped notation `R[X]`.","fix":"Delete L29.","ev":"hunts/selmer/probe.lean uses `ℤ[X]`/`ℚ[X]` inside `namespace Polynomial` with no `open scoped Polynomial` and compiles, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-28407a","file":"Mathlib/RingTheory/Polynomial/Selmer.lean","decl":"X_pow_sub_X_sub_one_irreducible_aux","line":33,"sev":"NIT","status":"confirmed","cat":"api","pattern":"public-aux-lemma","claim":"`X_pow_sub_X_sub_one_irreducible_aux` (a statement about complex `z` with `z ^ n = z + 1 ∧ z ^ n + z ^ 2 = 0`, used only by `X_pow_sub_X_sub_one_irreducible`) is a public declaration with an `_aux` name and no docstring; it should be `private`, or kept public under a descriptive name for the scalar fact it proves (e.g. `pow_add_sq_ne_zero_of_pow_eq_add_one`) with a docstring.","fix":"Make it `private`, or rename and document it as a standalone lemma (see the generality finding).","ev":"Measured: source L33; `git grep -n X_pow_sub_X_sub_one_irreducible_aux origin/master -- Mathlib` finds only this file.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-56a39a","file":"Mathlib/RingTheory/Polynomial/Selmer.lean","decl":"X_pow_sub_X_sub_one_irreducible_aux","line":35,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"opaque-proof-step","claim":"In `X_pow_sub_X_sub_one_irreducible_aux`: the `linear_combination` certificate `(1 - z - z ^ 2 - z ^ n) * h1 + (z ^ n - 2) * h2` hides the two-step argument (h2 - h1 gives z² + z + 1 = 0, times z - 1 gives z³ = 1), for which `(1 - z) * h1 + (z - 1) * h2` suffices; `replace h3` introduces a name that does not exist yet (`have`); and `z_ne_zero` is proved by `zero_ne_one ((zero_pow three_ne_zero).symm.trans (show … from h ▸ h3))` where `intro hz; simp [hz] at h3` does.","fix":"Use `have h3 : z ^ 3 = 1 := by linear_combination (1 - z) * h1 + (z - 1) * h2` and `have z_ne_zero : z ≠ 0 := by intro hz; simp [hz] at h3`.","ev":"hunts/selmer/probe.lean (C): both replacements compile, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261007-51ea70","file":"Mathlib/RingTheory/Polynomial/Selmer.lean","decl":"X_pow_sub_X_sub_one_irreducible","line":65,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"rebuilds-existing-lemma","claim":"`X_pow_sub_X_sub_one_irreducible` rebuilds `pow_sub_one_mul` with `mul_assoc (-1 : ℂ), ← pow_succ, Nat.sub_add_cancel hn.le` (L65); `pow_sub_one_mul hn0 z : z ^ (n - 1) * z = z ^ n` takes the `hn0` already in scope.","fix":"Rewrite with `pow_sub_one_mul hn0 z` instead of `← pow_succ, Nat.sub_add_cancel hn.le`.","ev":"hunts/selmer/probe.lean (D): `example (hn0 : n ≠ 0) (z : ℂ) : z ^ (n - 1) * z = z ^ n := pow_sub_one_mul hn0 z` compiles, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4a7d04df926"},{"id":"RT-20261006-78dbf3","file":"Mathlib/RingTheory/Valuation/RankOne.lean","decl":"(file)","line":9,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-import","claim":"The public imports `Mathlib.Combinatorics.Matroid.Init`, `Mathlib.Data.Sym.Sym2`, `Mathlib.Tactic.NormNum.GCD` and `Mathlib.Tactic.Positivity` are unused here: each copy of the file with one of them removed compiles. Matroid and Sym2 have nothing to do with valuations, so they are presumably leftovers of an import-minimization pass. Downstream files may rely on them transitively.","fix":"Drop them (repairing any downstream file that relied on them transitively).","ev":"hunts/valuation-rankone/drop_*.lean: src minus each of the four `public import`s, each `lake env lean` exit 0, no errors.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c7bfb1","file":"Mathlib/RingTheory/Valuation/RankOne.lean","decl":"(file)","line":38,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-open","claim":"`open Function` (L38) and the second `open WithZero` (L241) are unused.","fix":"Drop them.","ev":"hunts/valuation-rankone/noopen.lean (src without both) compiles, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ad3c9a","file":"Mathlib/RingTheory/Valuation/RankOne.lean","decl":"Valuation.RankOne.instIsNontrivial","line":125,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-instance","claim":"`instance : IsNontrivial v` (L125) re-declares what the parent projection `RankOne.toIsNontrivial` already provides, since `RankOne` `extends ... Valuation.IsNontrivial v`. The lemma `RankOne.nontrivial` it uses is a restatement of `IsNontrivial.exists_val_nontrivial`.","fix":"Delete the instance (and consider deprecating `RankOne.nontrivial` in favour of `IsNontrivial.exists_val_nontrivial`).","ev":"hunts/valuation-rankone/noinst.lean: src without L125-126 plus `example (v : Valuation R Γ₀) [RankOne v] : v.IsNontrivial := inferInstance` compiles (exit 0).","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-f871ff","file":"Mathlib/RingTheory/Valuation/RankOne.lean","decl":"Valuation.RankOne.restrict_RankOne","line":137,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-breaks-convention","claim":"`restrict_RankOne` and `restrict_RankOne_hom_eq` put an UpperCamelCase segment in snake_case names (`rankOne`). The instance would normally be anonymous, or named like `instRankOneRestrict`, and the lemma `rankOne_restrict_hom`/`hom_restrict`.","fix":"Rename to `rankOne_restrict`/`hom_restrict` (deprecated aliases).","ev":"src L137 `instance restrict_RankOne : RankOne (v.restrict)`, L142 `lemma restrict_RankOne_hom_eq`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-9fcb96","file":"Mathlib/RingTheory/Valuation/RankOne.lean","decl":"Valuation.RankLeOne.exists_val_lt","line":200,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"leftover-hygiene","claim":"`RankLeOne.exists_val_lt` re-binds `{K : Type*} [DivisionRing K] (v : Valuation K Γ₀) [RankLeOne v]`, all already declared by the section `variable` at L166. `restrict_RankOne_hom_eq`'s statement (L143) is indented 2 instead of 4. The `rankOne_of_*` docstrings say 'non trivial'.","fix":"Drop the re-bound binders, indent the statement by 4, and write 'nontrivial'.","ev":"src L166 `variable {K : Type*} [DivisionRing K] (v : Valuation K Γ₀) [RankLeOne v]`; L200 `theorem exists_val_lt {K : Type*} [DivisionRing K] (v : Valuation K Γ₀) [RankLeOne v] :`; L143.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2f8c31","file":"Mathlib/RingTheory/Valuation/RankOne.lean","decl":"Valuation.RankLeOne.exists_val_lt","line":200,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-overstates-statement","claim":"`RankLeOne.exists_val_lt` concludes a dichotomy, `Subsingleton v.ValueGroup₀ˣ ∨ ∀ γ ≠ 0, ∃ x ≠ 0, ...`, not an existence statement (the trivial valuation satisfies only the left disjunct), and it has no docstring.","fix":"Rename (e.g. `subsingleton_units_or_exists_val_lt`) and add a docstring.","ev":"src L200-202.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-559054","file":"Mathlib/RingTheory/ZMod/Torsion.lean","decl":"(file)","line":15,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"module-doc-imprecise","claim":"The module docstring \"This file shows that the `ZMod p` has `p - 1` roots-of-unity\" is ungrammatical and imprecise (the file shows every unit is a `(p-1)`-st root of unity and registers `HasEnoughRootsOfUnity`); `rootsOfUnity_eq_top` has no docstring.","fix":"\"…shows that every unit of `ZMod p` is a `(p - 1)`-st root of unity, so `ZMod p` has enough `(p - 1)`-st roots of unity.\"","ev":"Source L15, L23.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-f81eb6","file":"Mathlib/RingTheory/ZMod/Torsion.lean","decl":"ZMod.rootsOfUnity_eq_top","line":23,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"proof-detour","claim":"Both proofs take detours, and the file's private import `Mathlib.FieldTheory.Finite.Basic` is only needed for them: `rootsOfUnity_eq_top` follows from `pow_card_eq_one` on the unit group (with `Fintype.card_units`, `ZMod.card`), and the instance's cardinality step from `Subgroup.card_top`, `Nat.card_units`, `Nat.card_zmod` by `simp only`, without building a `MulEquiv.subgroupCongr`; the `NeZero (p - 1)` fact is `Nat.sub_ne_zero_of_lt (Nat.Prime.one_lt _)` rather than `grind`. With these, `Mathlib.Algebra.Field.ZMod` replaces the `FieldTheory.Finite.Basic` import.","fix":"Use the shorter proofs from probe2.lean and import `Mathlib.Algebra.Field.ZMod` instead of `Mathlib.FieldTheory.Finite.Basic`.","ev":"probe2.lean (importing only `RootsOfUnity.EnoughRootsOfUnity` and `Algebra.Field.ZMod`): both statements with the shorter proofs compile with no messages.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-5ff2a3","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"(file)","line":26,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"module-doc-stale","claim":"The module docstring is partly stale. It says the monoidal horizontal composition is `tensorHom` \"denoted by `⊗`\" (L27), but `⊗` is now `tensorObj` and the tensor of morphisms is `⊗ₘ`. Its \"Main definitions\" entry names `Tactic.BicategoryLike.eval` and describes it as taking \"a Lean expression `e` that represents a morphism in a monoidal category\". The declaration is in fact `Mathlib.Tactic.BicategoryLike.eval (nm : Name) (e : Mor₂)`, is also used for bicategories, and returns an `Eval.Result`. The entry lists none of the normal-form datatypes. There are two grammar slips: \"The function also used to normalize\" (L16) and \"the string diagrams widget only do drawing\" (L46).","fix":"Change the notation to `⊗ₘ`, give `eval`'s real signature, list `NormalExpr` and `Eval.Result`, and fix the two grammar slips.","ev":"Source L16, L26-27, L46, L57-60, L524 (`def eval (nm : Name) (e : Mor₂) : CoherenceM ρ Eval.Result`); Monoidal/Category.lean:116,125.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-8ef00a","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.HorizontalComp","line":85,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"stale-notation-in-docstring","claim":"The docstring writes the horizontal composite as `η₁ ⊗ ... ⊗ ηₙ`, but `⊗` is now only `tensorObj` notation. The tensor of morphisms is `⊗ₘ` (`Mathlib/CategoryTheory/Monoidal/Category.lean:116,125`), and the rest of the file writes this operation as `◫` (module doc L23, `MonadHorizontalComp.hConsM` L146). The docstrings of `evalHorizontalCompAux`, `evalHorizontalCompAux'` and `evalHorizontalComp` (L453/467/483) have the same stale `η ⊗ θ`. Unlike the constructors of `WhiskerRight`, `WhiskerLeft` and `NormalExpr`, the constructors `HorizontalComp.of` and `HorizontalComp.cons` have no docstrings.","fix":"Write `η₁ ◫ ... ◫ ηₙ` (noting that this is `⊗ₘ` in a monoidal category), and add docstrings to `of` and `cons`.","ev":"Source L85-89; `git grep -n '\" ⊗ \"\\|\" ⊗ₘ \"' origin/master -- Mathlib/CategoryTheory/Monoidal/Category.lean`: L116 `scoped infixr:70 \" ⊗ \" => MonoidalCategoryStruct.tensorObj`, L125 `scoped infixr:70 \" ⊗ₘ \" => MonoidalCategoryStruct.tensorHom`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-aaab5e","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.Mor₂Iso.isStructural","line":111,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"dead-code","claim":"`Mor₂Iso.isStructural` is correct but has no use anywhere in Mathlib: the only hits are its own recursive calls and a mention in the `Structural` docstring. The place that would need it, `eval`'s `isoHom`/`isoInv` branches, throws \"not implemented. try dsimp first.\" on every non-atomic structural isomorphism instead. As a result, `monoidal` fails on `(whiskerLeftIso U (α_ X Y Z)).hom = U ◁ (α_ X Y Z).hom` and on `(α_ X Y Z ≪≫ (α_ X Y Z).symm).hom = 𝟙 _`.","fix":"Use it in `eval`: when `α.isStructural` holds, return `⟨← nilM α, ← mkEqRefl e.e⟩` (with `symmM α` for `isoInv`) instead of throwing. With this guard both goals above close (probe2 Q2). Otherwise delete it.","ev":"`git grep -n isStructural origin/master -- Mathlib MathlibTest`: only Normalize.lean L111-122. hunts/coherence-normalize/batch0/probe1.lean P1 value test prints `[true, false, true, false, true, false, false, true, false]` as expected. In P4, `by monoidal` gives `error: not implemented. try dsimp first.` on both goals. hunts/coherence-normalize/batch0/probe2.lean Q2: `monoidal_top` (= `BicategoryLike.main` with that guard in front of `eval`) closes both goals. Outputs are in probe1.out and probe2.out.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-824ba3","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.MonadWhiskerRight","line":140,"sev":"NIT","status":"confirmed","cat":"api","pattern":"unused-class-layer","claim":"`MonadWhiskerRight` and `MonadHorizontalComp` (like `MonadWhiskerLeft`) are never used as constraints. Every consumer asks for `MonadNormalExpr` (Coherence/Basic.lean:42,98; Normalize.lean:207,355,514), and the only instances are `MonadNormalExpr MonoidalM` and `MonadNormalExpr BicategoryM` (Monoidal/Normalize.lean:777, Bicategory/Normalize.lean:538). Their methods are reached only through `MonadNormalExpr` (`MonadWhiskerRight.whiskerRightM` L406, `MonadHorizontalComp.hConsM` L456), so the four-level `extends` chain is layering that no client uses. Their method names also coincide with `MonadMor₂Iso.whiskerRightM`/`whiskerLeftM` (opened at L357), so the call sites have to qualify them.","fix":"Fold the four classes into the single class `MonadNormalExpr` (or document why the layers are kept).","ev":"`git grep -n '\\[MonadNormalExpr\\|\\[MonadWhiskerRight\\|\\[MonadHorizontalComp\\|\\[MonadWhiskerLeft\\|instance : Monad' origin/master -- Mathlib` finds only the `[MonadNormalExpr …]` binders listed above and the two `MonadNormalExpr` instances. `git grep -n 'MonadWhiskerRight\\|MonadHorizontalComp' origin/master -- Mathlib MathlibTest` finds only the definitions, `extends` clauses and the qualified calls at L406/L456.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-7fb72c","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.MonadNormalExpr","line":159,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-binder-mismatch","claim":"The field `MonadNormalExpr.consM` names its first argument `headStructural`, but its docstring (\"the normalized 2-morphism `α ≫ η ≫ ηs`\") and every instance (`consM α η ηs`) call it `α`.","fix":"Rename the binder to `α` (or mention `headStructural` in the docstring).","ev":"src.lean L158-159: `/-- The expression for the normalized 2-morphism `α ≫ η ≫ ηs`. -/ consM (headStructural : Structural) (η : WhiskerLeft) (ηs : NormalExpr) : m NormalExpr`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-54738f","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.NormalExpr.idM","line":209,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-wrong-identifier","claim":"The docstrings of `NormalExpr.idM` and `NormalExpr.associatorM` (and the other builders in this block) say \"as a term of `normalExpr`\"; there is no `normalExpr`, the type is `NormalExpr`.","fix":"Write `NormalExpr` in these docstrings.","ev":"src.lean L209: `/-- The identity 2-morphism as a term of `normalExpr`. -/`, L213: `/-- The associator as a term of `normalExpr`. -/`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-2370d1","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.NormalExpr.idM","line":210,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"inlines-existing-helper","claim":"`NormalExpr.idM` and `NormalExpr.associatorM` inline `.structuralAtom <| ← MonadMor₂Iso.id₂M f` / `... associatorM f g h`, which is exactly the existing `MonadMor₂Iso.id₂M'` / `MonadMor₂Iso.associatorM'` (Coherence/Datatypes.lean L297, L309); evalWhiskerRight (L428) even uses `id₂M'` and `NormalExpr.idM` side by side.","fix":"Write `idM f := do nilM (← id₂M' f)` and `associatorM f g h := do nilM (← associatorM' f g h)` (same for the other unitor/associator builders).","ev":"hunts/coherence-normalize/batch1/Probe1.lean section D: `example {m} [Monad m] [LawfulMonad m] [MonadMor₂Iso m] [MonadNormalExpr m] (f : Mor₁) : (NormalExpr.idM f : m NormalExpr) = (do MonadNormalExpr.nilM (← MonadMor₂Iso.id₂M' f)) := by simp [NormalExpr.idM, MonadMor₂Iso.id₂M']` and the analogous `associatorM`/`associatorM'` example","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-73afdb","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.NormalExpr.associatorInvM","line":218,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-wrong-identifier-case","claim":"Docstring \"The inverse of the associator as a term of `normalExpr`.\" names a nonexistent identifier `normalExpr`; the result type is `NormalExpr` (same typo in the batch-1 siblings `idM`, `associatorM`). The definition itself is correct: the probe shows its `.e.e` type-checks, has type `srcM ⟶ tgtM`, and is `rfl`-equal to the expected structural morphism (e.g. `(α_ X Y Z).inv`, `(λ_ X).hom`, `(ρ_ X).inv`).","fix":"Write `NormalExpr` (the type) instead of `normalExpr` in the docstring.","ev":"src.lean:217 reads `/-- The inverse of the associator as a term of `normalExpr`. -/`; no declaration `normalExpr` exists (git grep -nw normalExpr: only these docstrings). Corrected copy compiles: hunts/coherence-normalize/batch2/normalize_copy.lean. Correctness check of the def itself: hunts/coherence-normalize/batch2/probe_behaviour.lean (`example : assocInv% X Y Z = (α_ X Y Z).inv := rfl` etc., all compile).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-6c5638","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.NormalExpr.leftUnitorM","line":223,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-wrong-identifier-case","claim":"Docstring \"The left unitor as a term of `normalExpr`.\" names a nonexistent identifier `normalExpr`; the result type is `NormalExpr` (same typo in the batch-1 siblings `idM`, `associatorM`). The definition itself is correct: the probe shows its `.e.e` type-checks, has type `srcM ⟶ tgtM`, and is `rfl`-equal to the expected structural morphism (e.g. `(α_ X Y Z).inv`, `(λ_ X).hom`, `(ρ_ X).inv`).","fix":"Write `NormalExpr` (the type) instead of `normalExpr` in the docstring.","ev":"src.lean:222 reads `/-- The left unitor as a term of `normalExpr`. -/`; no declaration `normalExpr` exists (git grep -nw normalExpr: only these docstrings). Corrected copy compiles: hunts/coherence-normalize/batch2/normalize_copy.lean. Correctness check of the def itself: hunts/coherence-normalize/batch2/probe_behaviour.lean (`example : assocInv% X Y Z = (α_ X Y Z).inv := rfl` etc., all compile).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-8fd137","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.NormalExpr.leftUnitorInvM","line":227,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-wrong-identifier-case","claim":"Docstring \"The inverse of the left unitor as a term of `normalExpr`.\" names a nonexistent identifier `normalExpr`; the result type is `NormalExpr` (same typo in the batch-1 siblings `idM`, `associatorM`). The definition itself is correct: the probe shows its `.e.e` type-checks, has type `srcM ⟶ tgtM`, and is `rfl`-equal to the expected structural morphism (e.g. `(α_ X Y Z).inv`, `(λ_ X).hom`, `(ρ_ X).inv`).","fix":"Write `NormalExpr` (the type) instead of `normalExpr` in the docstring.","ev":"src.lean:226 reads `/-- The inverse of the left unitor as a term of `normalExpr`. -/`; no declaration `normalExpr` exists (git grep -nw normalExpr: only these docstrings). Corrected copy compiles: hunts/coherence-normalize/batch2/normalize_copy.lean. Correctness check of the def itself: hunts/coherence-normalize/batch2/probe_behaviour.lean (`example : assocInv% X Y Z = (α_ X Y Z).inv := rfl` etc., all compile).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-aef896","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.NormalExpr.rightUnitorM","line":231,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-wrong-identifier-case","claim":"Docstring \"The right unitor as a term of `normalExpr`.\" names a nonexistent identifier `normalExpr`; the result type is `NormalExpr` (same typo in the batch-1 siblings `idM`, `associatorM`). The definition itself is correct: the probe shows its `.e.e` type-checks, has type `srcM ⟶ tgtM`, and is `rfl`-equal to the expected structural morphism (e.g. `(α_ X Y Z).inv`, `(λ_ X).hom`, `(ρ_ X).inv`).","fix":"Write `NormalExpr` (the type) instead of `normalExpr` in the docstring.","ev":"src.lean:230 reads `/-- The right unitor as a term of `normalExpr`. -/`; no declaration `normalExpr` exists (git grep -nw normalExpr: only these docstrings). Corrected copy compiles: hunts/coherence-normalize/batch2/normalize_copy.lean. Correctness check of the def itself: hunts/coherence-normalize/batch2/probe_behaviour.lean (`example : assocInv% X Y Z = (α_ X Y Z).inv := rfl` etc., all compile).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-694c6f","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.NormalExpr.rightUnitorInvM","line":235,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-wrong-identifier-case","claim":"Docstring \"The inverse of the right unitor as a term of `normalExpr`.\" names a nonexistent identifier `normalExpr`; the result type is `NormalExpr` (same typo in the batch-1 siblings `idM`, `associatorM`). The definition itself is correct: the probe shows its `.e.e` type-checks, has type `srcM ⟶ tgtM`, and is `rfl`-equal to the expected structural morphism (e.g. `(α_ X Y Z).inv`, `(λ_ X).hom`, `(ρ_ X).inv`).","fix":"Write `NormalExpr` (the type) instead of `normalExpr` in the docstring.","ev":"src.lean:234 reads `/-- The inverse of the right unitor as a term of `normalExpr`. -/`; no declaration `normalExpr` exists (git grep -nw normalExpr: only these docstrings). Corrected copy compiles: hunts/coherence-normalize/batch2/normalize_copy.lean. Correctness check of the def itself: hunts/coherence-normalize/batch2/probe_behaviour.lean (`example : assocInv% X Y Z = (α_ X Y Z).inv := rfl` etc., all compile).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-2a5387","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.NormalExpr.ofM","line":239,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"reinlined-existing-helper","claim":"The body re-inlines `NormalExpr.idM` (defined 30 lines above, line 210) for its last argument and `MonadMor₂Iso.id₂M'` (Coherence/Datatypes.lean:309) for its first, with doubled parentheses `((.structuralAtom <| …))`; it is one line with the existing API.","fix":"Replace the body by `MonadNormalExpr.consM (← MonadMor₂Iso.id₂M' (← η.srcM)) η (← idM (← η.tgtM))`.","ev":"hunts/coherence-normalize/batch2/normalize_copy.lean (copy of src.lean with this body; compiles with no warnings under the prompt's flags). Behaviour of `ofM`/`ofAtomM` checked in hunts/coherence-normalize/batch2/probe_behaviour.lean: `ofWhisker% W f = (Iso.refl (W ⊗ X)).hom ≫ W ◁ f ≫ (Iso.refl (W ⊗ Y)).hom := rfl`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-c3a680","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.NormalExpr.toList","line":250,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-declaration","claim":"Dead code: `NormalExpr.toList` has no use anywhere in Mathlib or MathlibTest. The string diagram widget walks `NormalExpr` with its own recursion (`NormalExpr.nodesAux`), and every other `.toList` in the coherence/widget files is `Mor₁.toList` or `Array.toList`. Its behaviour matches its docstring (probe: `[W ◁ f]` and `[X ◁ g, f ▷ W]`).","fix":"Delete it, or use it in `Mathlib/Tactic/Widget/StringDiagram.lean` in place of the hand-written recursion.","ev":"git -C mathlib4 grep -n 'NormalExpr.toList\\|\\.toList' origin/master -- Mathlib/Tactic/CategoryTheory Mathlib/Tactic/Widget/StringDiagram.lean MathlibTest/CategoryTheory → only the definition (Normalize.lean:250,252), Mor₁.toList (Datatypes.lean:108; StringDiagram.lean:117,123,197,202 on `Atom.src`, `WhiskerLeft.srcM`, `Structural.srcM`) and `Array.toList` (Map.lean:149, ToApp.lean:146). Behaviour: hunts/coherence-normalize/batch2/probe_behaviour.lean `evalCheck%` output `toList: [X ◁ g, f ▷ W]`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-619f5d","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.Eval.Result","line":259,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-reversed-equation","claim":"The `proof` field docstring says \"The proof that the normalized expression is equal to the original expression\" (i.e. `e' = e`), but every producer and consumer uses the orientation `e = e'` (original on the left): `eval` returns `mkEqRefl`/`eval_comp … : η ≫ θ = ι`, and `normalForm` (Coherence/Basic.lean:57) feeds it to `mk_eq (ha : a = a')`. The module docstring (line 59) states the correct `e = e'`.","fix":"Say \"The proof that the original expression is equal to the normalized one (`e = e'`).\"","ev":"hunts/coherence-normalize/batch2/probe_behaviour.lean, `#check evalCheck% (X ◁ g ≫ f ▷ W)` logs `proof : X ◁ g ≫ f ▷ W = (X ◁ᵢ Iso.refl Z).hom ≫ X ◁ g ≫ … ≫ f ▷ W ≫ …`, `lhs is the original: true`, `rhs is the normal form: true`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-3134c0","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.MkEvalComp","line":266,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-variable-command","claim":"`variable {m : Type → Type}` at line 266 is unused: every class below rebinds `(m : Type → Type)` explicitly and the defs in the section are stated over `CoherenceM ρ`.","fix":"Delete line 266.","ev":"hunts/coherence-normalize/batch2/normalize_copy.lean (line deleted) compiles with no warnings.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-737c20","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.MkEvalComp","line":275,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"misnamed-binder","claim":"The last binder of `mkEvalCompCons` is named `e_η`, but it is the proof of `ηs ≫ θ = ι`: the caller `evalComp` (line 369) passes `e_ι`, both instances name it `e_ι`, and the lemma `evalComp_cons` names it `e_ι`. With named-argument or positional reading this misleads.","fix":"Rename the binder to `e_ι`.","ev":"hunts/coherence-normalize/batch2/normalize_copy.lean renames it to `e_ι` and compiles; Monoidal/Normalize.lean:268 and Bicategory/Normalize.lean:198 `mkEvalCompCons α η ηs θ ι e_ι`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-8c07f0","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.MkEval","line":338,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"monoidal-name-in-generic-api","claim":"The field `mkEvalMonoidalComp` of this bicategory-generic class handles `Mor₂.coherenceComp` (`η ⊗≫ θ`). The Bicategory instance implements it with `eval_bicategoricalComp` (Bicategory/Normalize.lean:536), so the 'Monoidal' in the name describes only one of the two instances.","fix":"Rename to `mkEvalCoherenceComp` to match `Mor₂.coherenceComp`, with a deprecated alias.","ev":"measured: Normalize.lean:351; Bicategory/Normalize.lean:512,536; Coherence/Datatypes.lean:358.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-a572c3","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.evalWhiskerRightAux","line":404,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"duplicated-docstring-aux","claim":"The docstring copies `evalWhiskerRight`'s docstring ('Evaluate the expression `η ▷ f` into a normalized form') without saying that it handles only a `HorizontalComp` whiskered by an atomic `f : Atom₁`, so the three (or two) evaluators of the same operation cannot be told apart from their docs.","fix":"State the restricted input shape in the docstring (e.g. '`η ▷ f` for `η` a horizontal composite and `f` atomic') and use `◫`.","ev":"measured: Normalize.lean lines 403/415, 453/467/483 (identical docstring text).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-9edd1f","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.evalHorizontalCompAux","line":454,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"duplicated-docstring-aux","claim":"The docstring copies `evalHorizontalComp`'s docstring ('Evaluate the expression `η ⊗ θ` …') without saying that both inputs are `HorizontalComp`s; it also writes `⊗` where the module doc uses `◫` for horizontal composition, so the three (or two) evaluators of the same operation cannot be told apart from their docs.","fix":"State the restricted input shape in the docstring (e.g. '`η ▷ f` for `η` a horizontal composite and `f` atomic') and use `◫`.","ev":"measured: Normalize.lean lines 403/415, 453/467/483 (identical docstring text).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-973836","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.evalHorizontalCompAux'","line":468,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"duplicated-docstring-aux","claim":"The docstring copies `evalHorizontalComp`'s docstring ('Evaluate the expression `η ⊗ θ` …') without saying that both inputs are `WhiskerLeft`s; it also writes `⊗` where the module doc uses `◫`, so the three (or two) evaluators of the same operation cannot be told apart from their docs.","fix":"State the restricted input shape in the docstring (e.g. '`η ▷ f` for `η` a horizontal composite and `f` atomic') and use `◫`.","ev":"measured: Normalize.lean lines 403/415, 453/467/483 (identical docstring text).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-519617","file":"Mathlib/Tactic/CategoryTheory/Coherence/Normalize.lean","decl":"Mathlib.Tactic.BicategoryLike.eval","line":524,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"stale-todo-and-leftovers","claim":"Leftovers around `eval`. (1) The comment `-- TODO: It takes a while to compile. Find out why.` (line 522) is stale: with `set_option profiler true` on a copy, all of `eval`'s phases come to about 0.43 s (LCNF base 258 ms, do-elaboration 61 ms, typeclass inference 22 ms), and the whole file compiles in about 1.9 s. (2) There are double spaces in `| .id _ _ f  =>`, `return  ⟨` and `| .of η  =>` (lines 543, 545, 585). (3) The second `variable {ρ : Type} …` block (line 511) re-declares `ρ`, shadowing line 354's, and repeats the `MonadMor₁`/`MonadMor₂Iso`/`MonadNormalExpr`/`MkEval` binders already in scope.","fix":"Delete the TODO, fix the spacing, and add only `[MonadMor₂ (CoherenceM ρ)]` instead of re-declaring the section variables.","ev":"hunts/coherence-normalize/batch3/P3a_prof.lean (copy of src.lean with `set_option profiler true in set_option profiler.threshold 20 in` before `def eval`): output 'compilation (LCNF base) took 258ms', 'compilation (LCNF mono) took 32ms'; cumulative do-elab 61.3ms, typeclass inference 21.9ms.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-a679fc","file":"Mathlib/Tactic/ClickSuggestions/FindPremises.lean","decl":"Mathlib.Tactic.ClickSuggestions.Entries.addFVar","line":173,"sev":"NIT","status":"confirmed","cat":"api","pattern":"inconsistent-indexing-paths","claim":"`Entries.addFVar` indexes local hypotheses differently from `Entries.addConst` indexes library lemmas: for `rw` it matches the relation after `whnf e` (so it also unfolds e.g. `≠`/`↔`-valued definitions), for `grw` after `e.cleanupAnnotations`, and it adds `grw` entries for `Eq`/`Iff` hypotheses too, whereas `addConst` puts `Eq`/`Iff` lemmas only in the `rw` tree and never runs `whnf`; `addFVar` also skips the `isBadMatch` filter. The asymmetry is undocumented.","fix":"Document why local hypotheses are indexed more liberally, or share one classification function between the two.","ev":"Source L136–170 vs. L173–197.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-650ccb","file":"Mathlib/Tactic/Inclusion/Extension/IntervalDyadicReal/BinarySplit.lean","decl":"(file)","line":60,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-overstates","claim":"The docstrings of `binarySplitParam` (\"A depth of `n` produces `2 ^ n` pieces\") and `mkBinarySplitCover` (\"with `2 ^ n` pieces\") overstate. `binarySplitMap` leaves every interval with an infinite endpoint unsplit (`| _ => F I`), and `mkBinarySplitCover` takes no `n`: it reads the `binSplit` parameter and returns `none` when it is absent. The docstrings of `binarySplitMap`/`binarySplit` also omit the bounded-only behaviour.","fix":"Say 'splits a bounded interval into `2 ^ n` pieces; unbounded intervals are left whole', and describe `mkBinarySplitCover` as reading `binSplit`.","ev":"src L34-40: `| n + 1, I, F => match I with | ⟨some l, some u⟩ => ... | _ => F I`; L67-70: `meta def mkBinarySplitCover : InclusionM (Option Expr)` (no `n`), `let some depth ← InclusionM.getParam? `binSplit | return none`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-9f5d9f","file":"Mathlib/Tactic/NormNum/Abs.lean","decl":"(file)","line":10,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"leftover-hygiene","claim":"There is a double blank line after the imports (L10-11). `isNNRat_abs_nonneg` and `isNNRat_abs_neg` end with the same four-line `mul_nonneg`/`Nat.cast_nonneg'`/`inv_nonneg` tail, which the `neg` lemma could get by rewriting to the `nonneg` one.","fix":"Remove the extra blank line and derive `isNNRat_abs_neg` from `isNNRat_abs_nonneg` after `simp only [Int.cast_negOfNat, neg_mul, abs_neg]`.","ev":"src L10-11, L39-43 vs L47-52.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-2849b0","file":"Mathlib/Tactic/NormNum/Abs.lean","decl":"Mathlib.Meta.NormNum.isNat_abs_nonneg","line":24,"sev":"NIT","status":"suspected","cat":"generality","pattern":"too-strong-typeclass","claim":"The helper lemmas assume more than they use: `isNat_abs_nonneg` needs only `[AddGroupWithOne α] [Lattice α] [AddLeftMono α] [ZeroLEOneClass α]` (no multiplication), `isNat_abs_neg` needs no `IsOrderedRing`, and the `isNNRat_*` lemmas need only a strict ordered semiring via `invOf_nonneg`. Not compiled here; the extension's coverage is still limited by `Result.isNNRat`.","fix":"Weaken the helper lemmas' classes (and the extension's synthesized instances accordingly).","ev":"Astra A1 sketches with `abs_of_nonneg (Nat.cast_nonneg' n)` and `invOf_nonneg`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-731925","file":"Mathlib/Tactic/NormNum/Abs.lean","decl":"Mathlib.Meta.NormNum.evalAbs","line":65,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"leftover-hygiene","claim":"In the `.isNegNat sα na pa` branch, `sα` is already a `Q(Ring $α)`, yet the branch synthesizes another `Ring α` (`rα`), one more instance that must agree. The `evalAbs` docstring ('identifies expressions `|a|` such that `norm_num` recognises `a`') omits the ring/order instance requirements (e.g. it fails for numerals in a bare `AddGroupWithOne`).","fix":"Reuse `sα`; state the instance requirements in the docstring.","ev":"src L65-69 (`| .isNegNat sα na pa => let rα : Q(Ring $α) ← synthInstanceQ q(Ring $α)`), L54-55.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-f307e1","file":"Mathlib/Tactic/Widget/SelectPanelUtils.lean","decl":"String.renameMetaVar","line":41,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"helper-in-core-namespace","claim":"`String.renameMetaVar`, a widget helper that rewrites pretty-printed `?m.N` metavariable names to `?_`, is declared in the core `String` namespace from a Mathlib tactic file, so `s.renameMetaVar` appears on every string for anything importing it; its docstring says it replaces \"all meta-variable names\", but it only handles the `?m.N` form (not named `?x` metavariables). Behaviour on `?m.N` is correct.","fix":"Move it to a `Mathlib.Tactic.Widget` namespace and state the `?m.N` scope in the docstring.","ev":"probe1.lean: `\"f ?m.12 + ?m.3 = ?m.45\".renameMetaVar` = `\"f ?_ + ?_ = ?_\"`; source L40–46.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-8d94fe","file":"Mathlib/Tactic/Widget/SelectPanelUtils.lean","decl":"mkSelectionPanelRPC","line":63,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-grammar","claim":"Docstring slips in `mkSelectionPanelRPC` and `SelectInsertParams`: \"whether the selected has to be in the goal\", \"In every cases\", \"The last arguments `params`\", \"Structures providing parameters\" (one structure); the docstring says the `pos` argument of `mkCmdStr` could be extracted from `Params`, but that argument is the array of selected `GoalsLocation`s, not a position, and is named `pos` in the binder.","fix":"Fix the grammar; rename the `mkCmdStr` binder to `locations`.","ev":"Source L50, L63–80, L82.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-de472c","file":"Mathlib/Topology/Algebra/Nonarchimedean/AdicTopology.lean","decl":"(file)","line":13,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"test-only-import","claim":"`import Mathlib.Topology.Algebra.UniformRing -- shake: keep (used in example only)`: a library import kept only for the regression `example`s at the end of the file (L291-306); such tests belong in `MathlibTest/`.","fix":"Move the `example`s to `MathlibTest/` and drop the import.","ev":"Measured: source L13, L291-306.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-1427f7","file":"Mathlib/Topology/Algebra/Nonarchimedean/AdicTopology.lean","decl":"(file)","line":15,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring","claim":"Missing docstrings on public `adic_basis`, `nonarchimedean`, `hasBasis_nhds_adic`, `isLinearTopology`, `adic_module_basis`, `is_ideal_adic_pow`, `is_bot_adic_iff`, `IsAdic.hasBasis_nhds_zero`/`_nhds`, `uniformContinuous_of_map_le`, `isTopologicallyNilpotent_of_mem` and the five `WithIdeal` instances; the module docstring's list omits `IsAdic`, `adicModuleTopology`, `uniformEquiv` and `WithIdeal.topologicalSpaceModule`.","fix":"Add one-line docstrings and complete the list.","ev":"Measured: source.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-f401f1","file":"Mathlib/Topology/Algebra/Nonarchimedean/AdicTopology.lean","decl":"is_ideal_adic_pow","line":193,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"brittle-case-split","claim":"`is_ideal_adic_pow` ends with `cases n; exfalso; exact Nat.not_succ_le_zero 0 hn; rw [← pow_mul, Nat.succ_mul]; …` where `Ideal.pow_le_pow_right (Nat.le_mul_of_pos_left m hn)` closes the step directly.","fix":"Use the `Nat.le_mul_of_pos_left` step (probe1 (C)).","ev":"hunts/adic-topology/probe1.lean (C): compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-4f2f71","file":"Mathlib/Topology/Algebra/Nonarchimedean/AdicTopology.lean","decl":"is_ideal_adic_pow","line":193,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"lean3-style-name","claim":"Lean 3 style names: `is_ideal_adic_pow` (should be `IsAdic.pow`, enabling `h.pow hn`) and `is_bot_adic_iff` (should be `isAdic_bot_iff`); the class field `WithIdeal.i` is a single lowercase letter for an ideal; `adic_basis`/`adic_module_basis` do not name their statement.","fix":"Rename with deprecated aliases.","ev":"Measured: source L193, L210, L238.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-f75b43","file":"Mathlib/Topology/Algebra/Order/Floor.lean","decl":"(file)","line":23,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"module-doc-paraphrase-differs","claim":"The module docstring says `continuousOn_ceil`: 'continuous on `Ioc n (n + 1)`', but the statement (L89-90) is about `Ioc (n - 1) n` (an equivalent family, but not what the docstring says); and none of the twelve `tendsto_*_pure`/`tendsto_*_left`/`right` lemmas or the `FloorSemiring.tendsto_*factorial*` lemmas, nor `continuousAt_fract`, has a docstring.","fix":"Write `Ioc (n - 1) n` in the module docstring and add one-line docstrings.","ev":"Doc-only finding: L23 vs L89-90.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"e6bbacd0e1b"},{"id":"RT-20261013-3340a2","file":"Mathlib/Topology/Algebra/SeparationQuotient/FiniteDimensional.lean","decl":"(file)","line":1,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"file-name-understates-scope","claim":"The file is named `SeparationQuotient/FiniteDimensional.lean`, but its only declaration is a `Module.Finite R` instance for an arbitrary semiring `R` and additive commutative monoid `M` (no division ring, so not a finite-dimensionality statement); the module title 'Separation quotient is a finite module' also drops 'of a finite module'.","fix":"Rename the file to `SeparationQuotient/Finite.lean` (or `ModuleFinite.lean`) and title it 'The separation quotient of a finite module is finite'.","ev":"Measured: src L20-23 (`[Semiring R] [AddCommMonoid M] … Module.Finite R (SeparationQuotient M)`) vs the file name and L12; hunts/sepquot-findim/probe_ok.lean (B): the instance is found by `inferInstance` for these semiring hypotheses, exit 0.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-13","commit":"f69ff8554f5"},{"id":"RT-20261007-608380","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightProfinite","line":43,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-reference","claim":"Neither the module docstring nor the `LightProfinite` docstring cites a source for the notion of light profinite set (Clausen-Scholze), or says that 'light' means a sequential limit of finite sets / metrizable profinite, which motivates the name; `Mathlib/Condensed/Light/Basic.lean:14` does cite Clausen-Scholze.","fix":"Add a `## References` section (Clausen-Scholze, light condensed sets lectures) and a sentence that 'light' means second countable, equivalently metrizable or a sequential limit of finite sets.","ev":"git -C mathlib4 grep -n -i 'clausen\\|scholze\\|reference\\|metriz' origin/master -- Mathlib/Topology/Category/LightProfinite/Basic.lean  -> no matches (exit 1); Mathlib/Condensed/Light/Basic.lean:14 cites 'Clausen-Scholze'.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-0a17f2","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"FintypeCat.toLightProfinite","line":99,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-names-wrong-object","claim":"Docstring says \"The natural functor from `Fintype` to `LightProfinite`\"; `Fintype` is a typeclass, the source category is `FintypeCat` (text copied from `FintypeCat.toProfinite`).","fix":"Write \"from `FintypeCat`\" (and the same in `FintypeCat.toProfinite`).","ev":"src.lean L99-100: `/-- The natural functor from `Fintype` to `LightProfinite`, endowing a finite type with the discrete topology. -/`; signature `FintypeCat ⥤ LightProfinite` (P2.lean #check).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-8b4b76","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"instFiniteCarrierToTopAndTotallyDisconnectedSpaceSecondCountableTopologyOfObj","line":121,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"redundant-instance","claim":"The instance `Finite (LightProfinite.of X)` is redundant: with it deleted, `inferInstance` still proves `Finite (LightProfinite.of X)` in the same context, via Profinite/Basic.lean's `instFiniteCarrierToTopTotallyDisconnectedSpaceOfObj : Finite (Profinite.of X)`, which unifies after reducible unfolding of `CompHausLike.of`. (The sibling instance at L118 on `toLightProfinite.obj X` IS needed: without it synthesis fails.)","fix":"Delete the instance at L121 (keep L118).","ev":"hunts/lightprofinite/batch1/C4.lean / C4b.lean (copy of src.lean with L118-122 replaced by `example ... := inferInstance`): L120 `example (X : FintypeCat.{u}) : Finite (LightProfinite.of X) := inferInstance` compiles and `#synth` reports `instFiniteCarrierToTopTotallyDisconnectedSpaceOfObj`; the L118 analogue fails with `failed to synthesize Finite ↑(toLightProfinite.obj X).toTop`.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-9f3a40","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightProfinite.limitCone","line":134,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-run-on","claim":"Docstring is a run-on sentence: \"... for a countable category `J` defined in terms of `CompHaus.limitCone`, ...\" reads as if `J` were defined via `CompHaus.limitCone` (missing comma), and the continuation line is indented.","fix":"Write \"..., for a countable category `J`. It is defined in terms of `CompHaus.limitCone`, ...\" with an unindented continuation line.","ev":"src.lean L134-135.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-2d7e68","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightProfinite.epi_iff_surjective","line":207,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"binders-shadow-section-variables","claim":"Re-binds `{X Y : LightProfinite.{u}} (f : X ⟶ Y)`, shadowing the section `variable {X Y : LightProfinite.{u}} (f : X ⟶ Y)` at L184. This is a copy-paste leftover from Profinite, where no such variable exists. Dropping the binders gives the identical signature.","fix":"State it as `theorem epi_iff_surjective : Epi f ↔ Function.Surjective f`, using the section variables.","ev":"hunts/lightprofinite/batch2/src_fix.lean (binders dropped) compiles; `#check @LightProfinite.epi_iff_surjective` gives `∀ {X Y : LightProfinite} (f : X ⟶ Y), Epi f ↔ Function.Surjective ⇑(ConcreteCategory.hom f)` in both src_fix.lean and sig_orig.lean","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-63ed89","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightDiagram","line":249,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-grammar","claim":"The docstring `A structure containing the data of sequential limit in `Profinite` of finite sets.` is missing an article (\"of a sequential limit\"). It also does not say that `LightDiagram` is made a category whose morphisms are the continuous maps between the cone points (the category induced along `toProfinite`), which is the main point of the definition.","fix":"Reword to \"The data of a sequential limit in `Profinite` of finite sets; morphisms are the morphisms of the limits.\"","ev":"Line 248: `/-- A structure containing the data of sequential limit in `Profinite` of finite sets. -/`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-8642ac","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightDiagram.hasForget","line":266,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"stale-instance-name-hasforget","claim":"The `ConcreteCategory LightDiagram` instance is named `hasForget`, after the class `HasForget`, which no longer exists in Mathlib (`#check @HasForget` gives an unknown identifier). Mathlib's current name for such instances is `concreteCategory` (11 of them, including the direct counterpart `CompHausLike.concreteCategory`); only `Pointed.hasForget` and `Bipointed.hasForget` share the stale name. Nothing in Mathlib refers to `LightDiagram.hasForget`.","fix":"Rename to `LightDiagram.concreteCategory`.","ev":"#check @HasForget  -- error: Unknown identifier `HasForget` (hunts/lightprofinite/batch3/Probe4.lean); git grep 'instance concreteCategory' origin/master -- Mathlib: 11 hits, incl. CompHausLike/Basic.lean:95; git grep 'LightDiagram.hasForget' origin/master -- Mathlib: no hits.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-3015d5","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"lightDiagramToProfinite","line":273,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-missing-full-stop","claim":"The docstring `The fully faithful embedding `LightDiagram ⥤ Profinite`` has no closing full stop, unlike the file's other docstrings.","fix":"End the docstring with a full stop.","ev":"Line 271: `/-- The fully faithful embedding `LightDiagram ⥤ Profinite` -/`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-41be8d","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"LightProfinite.instCountableDiscreteQuotient","line":285,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-parentheses","claim":"Doubled parentheses in the statement: `Countable (DiscreteQuotient ((lightToProfinite.obj S)))`.","fix":"Write `Countable (DiscreteQuotient (lightToProfinite.obj S))`.","ev":"Line 286: `    Countable (DiscreteQuotient ((lightToProfinite.obj S))) :=`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-ea8e5c","file":"Mathlib/Topology/Category/LightProfinite/Basic.lean","decl":"instEssSurjLightDiagram'LightDiagramToLightFunctor","line":388,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-open","claim":"`open LightDiagram` (L355, opening the EssentiallySmall section) is unused; its only effect is that the bare `toProfinite` in this instance (L392) is overloaded between `LightDiagram.toProfinite` and `FintypeCat.toProfinite` and is resolved by elaboration (it is `FintypeCat.toProfinite`).","fix":"Delete `open LightDiagram` and write `FintypeCat.toProfinite` explicitly at L392.","ev":"hunts/lightprofinite/batch5/no_open.lean (src.lean with line 355 `open LightDiagram` deleted) compiles with no errors or warnings","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4e77f237dc2"},{"id":"RT-20261007-dea795","file":"Mathlib/Topology/Category/Stonean/Basic.lean","decl":"(file)","line":12,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"module-doc-title-mismatch","claim":"The module docstring is titled \"Extremally disconnected sets\" although the file defines the category `Stonean` of extremally disconnected compact Hausdorff spaces, and says \"a pair, considering of a term\" (for \"consisting of\"). `CompHaus.Gleason`, the file's main theorem, has no docstring.","fix":"Retitle \"Stonean spaces\", fix the typo, add a docstring to `Gleason`.","ev":"Source L12, L22, L242.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-0059a8","file":"Mathlib/Topology/Category/Stonean/Basic.lean","decl":"Stonean.mkFinite","line":114,"sev":"NIT","status":"confirmed","cat":"api","pattern":"def-hides-instances","claim":"`Stonean.mkFinite X` is a `def`, so its carrier loses `X`'s instances: `Finite (Stonean.mkFinite X)` is not found by `infer_instance` (and likewise `DiscreteTopology`), unlike `Stonean.of`, which is an `abbrev`.","fix":"Make it an `abbrev` (after adding the discrete ⇒ extremally disconnected instance, `Stonean.of X`).","ev":"probe2.lean L11 `Finite (Stonean.mkFinite X) := by infer_instance` → failed to synthesize.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-2d788c","file":"Mathlib/Topology/Category/Stonean/Basic.lean","decl":"Stonean.epi_iff_surjective","line":145,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"leftover-question-comments","claim":"`Stonean.epi_iff_surjective` keeps four question comments in its proof (\"why is `ext` not doing this automatically?\", \"why is `dsimp` not getting me here?\" twice, \"what would be an idiomatic tactic for this step?\"), with `change` used as the workaround.","fix":"Resolve or turn into `-- Note:` comments explaining the `change`.","ev":"Source L145, L146, L148, L152.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-bf5bf5","file":"Mathlib/Topology/Category/Stonean/Basic.lean","decl":"CompHaus.Gleason","line":242,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"nonstandard-theorem-name","claim":"Naming: `CompHaus.Gleason` is a capitalised theorem name (convention: `projective_iff_extremallyDisconnected`); `Profinite.projective_of_extrDisc` abbreviates `extremallyDisconnected` and takes the class `ExtremallyDisconnected X` as an explicit hypothesis `(hX : …)`; `Stonean.instProjectiveCompHausCompHaus` doubles `CompHaus`.","fix":"Rename with deprecated aliases; make `hX` an instance argument.","ev":"Source L157, L242, L298.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-a2c189","file":"Mathlib/Topology/Category/Stonean/Basic.lean","decl":"Profinite.presentation","line":260,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"rebuilds-existing-object","claim":"`Profinite.presentation X` rebuilds `(profiniteToCompHaus.obj X).presentation` field by field; the two are equal by `rfl`.","fix":"`def presentation (X : Profinite) : Stonean := (profiniteToCompHaus.obj X).presentation`.","ev":"probe2.lean L14 `X.presentation = (profiniteToCompHaus.obj X).presentation := rfl` compiles.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-8990d9","file":"Mathlib/Topology/Category/TopCat/EffectiveEpi.lean","decl":"TopCat.effectiveEpiStructOfQuotientMap","line":33,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"repeated-proof-term","claim":"`effectiveEpiStructOfQuotientMap` writes out the same 3-line argument three times (in `desc`, `fac` and `uniq`): `fun a b hab ↦ congr($(h (ofHom ⟨fun _ ↦ a, continuous_const⟩) (ofHom ⟨fun _ ↦ b, continuous_const⟩) (by ext; exact hab)) a)`, i.e. that `e` is constant on fibres of `π`.","fix":"Factor it into a local `have` (or a private lemma) and reuse it.","ev":"measured: L36–39, L41–44, L48–51 of src.lean.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-98488a","file":"Mathlib/Topology/Category/TopCat/EffectiveEpi.lean","decl":"TopCat.effectiveEpi_iff_isQuotientMap","line":63,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"stale-proof-comment","claim":"The `fac` and `uniq` fields of `effectiveEpiStructOfQuotientMap` can drop the repeated fibre-constancy argument entirely: `fac e h := hom_ext (hπ.lift_comp _ _)` and `uniq` by `cancel_epi π` (with `Epi π` from surjectivity) compile, as in the `CompHausLike` analogue. Separately, the forward-direction comment in `effectiveEpi_iff_isQuotientMap` speaks of composing `π` with an isomorphism to an arbitrary coequalizer, but the proof applies `isQuotientMap_of_isColimit_cofork` directly to the cofork of `π`.","fix":"Use the two short proofs; reword the comment.","ev":"Copy.lean (with `fac := hom_ext (hπ.lift_comp _ _)` and the `cancel_epi` `uniq`) compiles (one `letI`→`let` style hint).","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-490e77","file":"Mathlib/Topology/ContinuousMap/LocallyConstant.lean","decl":"(file)","line":11,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-omission","claim":"The module docstring is only a title, ending in a period, with an empty body: it does not list the three bundled inclusions (monoid/additive, linear, algebra hom) or `separatesPoints_range_toContinuousMapAlgHom`. There is also a double blank line after `public section`.","fix":"Drop the period and add a 'Main definitions' list.","ev":"src L11-18.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-c3e8b5","file":"Mathlib/Topology/ContinuousMap/LocallyConstant.lean","decl":"LocallyConstant.toContinuousMapAlgHom","line":53,"sev":"NIT","status":"confirmed","cat":"api","pattern":"missing-characteristic-api","claim":"There is no `toContinuousMapRingHom` between the monoid/linear and algebra inclusions. The ring-hom version needs no scalars and no associativity (`[NonAssocSemiring Y] [IsTopologicalSemiring Y]`, all fields `rfl`).","fix":"Add `toContinuousMapRingHom` and derive the algebra hom's ring-hom part from it.","ev":"-- hunts/cm-locconst/P2.lean: `example [NonAssocSemiring Y] [IsTopologicalSemiring Y] : LocallyConstant X Y →+* C(X, Y) where toFun := (↑); map_zero' := rfl; ...` compiles; `#check @LocallyConstant.toContinuousMapRingHom` is an unknown constant.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-348a56","file":"Mathlib/Topology/ContinuousMap/LocallyConstant.lean","decl":"LocallyConstant.toContinuousMapAlgHom","line":58,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"overlong-proof","claim":"All the preservation fields of the four inclusions hold by `rfl`: `map_one'`, `map_mul'`, `map_smul'` and `commutes'`. They are instead proved by `ext; simp`, including `simp [Algebra.smul_def]` for `commutes'`.","fix":"Use `rfl` for these fields.","ev":"hunts/cm-locconst/rflcopy.lean (src with `map_one' := rfl`, `map_mul' _ _ := rfl`, `map_smul' _ _ := rfl`, `commutes' _ := rfl`) compiles, exit 0.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-9dc1c0","file":"Mathlib/Topology/LocallyFinsupp/Pushforward.lean","decl":"(file)","line":32,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-import","claim":"`open … TopologicalSpace` is unused, and `map_id` unfolds `map` (`simp [map, hw]`) though `map_apply` is simp; a copy with `open Set` and `simp [hw]` compiles. `hf.2` depends on the field order of `IsSpectralMap` instead of the named `hf.isCompact_preimage_of_isOpen`.","fix":"`open Set`; `simp [hw]`; use the named field.","ev":"-- hunts/lfs-pushforward/ProbeHyg.lean compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261007-74aef5","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.externalCoveringNumber","line":61,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-variable-and-scoped-open","claim":"File header leftovers before the definitions: the section variable `{x : X}` (line 61) is never used (every `x` in the file is locally bound), and `open scoped ENNReal` (line 56) is unused (no `ℝ≥0∞`/`∞` notation; `ENNReal.coe_mul` is referenced by full name). A copy of the file with both removed compiles unchanged.","fix":"Delete `{x : X}` from the `variable` line and change `open scoped ENNReal NNReal` to `open scoped NNReal`.","ev":"hunts/covering-numbers/batch0/Hygiene.lean (= src.lean with line 56 `open scoped NNReal` and line 61 without `{x : X}`) compiles with no errors or warnings","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-bef34a","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.externalCoveringNumber_le_coveringNumber","line":125,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"main-statement-without-docstring","claim":"`externalCoveringNumber_le_coveringNumber` is listed under 'Main statements' in the module docstring but has no docstring, while the comparison theorem listed next to it, `packingNumber_two_mul_le_externalCoveringNumber` (L327), has one.","fix":"Add a one-line docstring (\"The external covering number is at most the internal covering number.\").","ev":"measured: src.lean L124 is blank and L125 starts `lemma externalCoveringNumber_le_coveringNumber`, with no `/-- -/` before it; L325-326 give the docstring of `packingNumber_two_mul_le_externalCoveringNumber`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-7d60c5","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.coveringNumber_le_encard_self","line":142,"sev":"NIT","status":"confirmed","cat":"api","pattern":"inconsistent-binder-explicitness","claim":"In all three `_le_encard_self` lemmas (`externalCoveringNumber_le_encard_self` L139, `coveringNumber_le_encard_self` L142, `packingNumber_le_encard_self` L145), `A` is explicit but `ε` is implicit. Here `ε` occurs only in the conclusion and is not determined by `A`, so `have := coveringNumber_le_encard_self A` does not elaborate. The siblings `externalCoveringNumber_le_coveringNumber (ε) (A)` and `packingNumber_two_mul_le_externalCoveringNumber (ε) (A)` take both arguments explicitly.","fix":"Make `ε` explicit, `(ε : ℝ≥0) (A : Set X)`, in the three `_le_encard_self` lemmas to match the rest of the file.","ev":"-- batch1/Probe1.lean (compiles: the bare `have` fails to elaborate, ε is an unassigned implicit)\nexample (A : Set X) : True := by\n  fail_if_success have := coveringNumber_le_encard_self A\n  trivial\n-- the sibling takes both explicitly and works\nexample (A : Set X) : True := by\n  have := externalCoveringNumber_le_coveringNumber ε A\n  trivial","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-9a28a6","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.externalCoveringNumber_le_one_of_ediam_le","line":203,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"roundabout-empty-case-split","claim":"The 4-line proof splits on `A = ∅` and, in the empty case, rewrites `A = ∅` backwards into `externalCoveringNumber ε A = 0` (`rw [← externalCoveringNumber_eq_zero (ε := ε)] at h_eq_empty; simp [h_eq_empty]`). A one-line term from existing lemmas does the job.","fix":"Replace the proof by `(externalCoveringNumber_le_coveringNumber ε A).trans (coveringNumber_le_one_of_ediam_le hA)`.","ev":"hunts/covering-numbers/batch2/probe1.lean section P4: `example (hA : ediam A ≤ ε) : externalCoveringNumber ε A ≤ 1 := (externalCoveringNumber_le_coveringNumber ε A).trans (coveringNumber_le_one_of_ediam_le hA)` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-751016","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.coveringNumber_le_one_of_ediam_le","line":210,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"roundabout-empty-case-split","claim":"The empty case rewrites `A = ∅` backwards into `coveringNumber ε A = 0` (`rw [← coveringNumber_eq_zero (ε := ε)] at h_eq_empty; simp [h_eq_empty]`) instead of substituting. The dependency order is also inverted: the `≤ 1` lemmas are derived from the `= 1` lemmas through a case split, when the natural order is `≤ 1` first and `= 1` from it plus `*_pos_iff`.","fix":"Use `obtain rfl | h := A.eq_empty_or_nonempty; · simp; · exact (coveringNumber_eq_one_of_ediam_le h hA).le`, or prove `≤ 1` directly and get `= 1` as `le_antisymm (… ) (by simpa [Order.one_le_iff_pos])`.","ev":"hunts/covering-numbers/batch2/probe1.lean section P4: `example (hA : ediam A ≤ ε) : coveringNumber ε A ≤ 1 := by obtain rfl | h := A.eq_empty_or_nonempty; · simp; · exact (coveringNumber_eq_one_of_ediam_le h hA).le` and `example (h_nonempty : A.Nonempty) (hA : ediam A ≤ ε) : externalCoveringNumber ε A = 1 := le_antisymm (externalCoveringNumber_le_one_of_ediam_le hA) (by simpa [Order.one_le_iff_pos])` compile.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-c6c399","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.maximalSeparatedSet","line":248,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-suggests-different-notion","claim":"`maximalSeparatedSet` suggests a maximal-under-inclusion separated set, but it is a *maximum-cardinality finite* separated subset, with `∅` as fallback when `packingNumber = ⊤` (Astra A1 item 3); the docstrings also never state the boundary conventions (covers use `edist ≤ ε`, separation `ε < edist`), which differ across the literature (item 4).","fix":"Rename or document the maximum-cardinality meaning and state the ≤/< conventions in the module docstring.","ev":"Measured: definition via choice of a finite separated set with encard = packingNumber (src.lean L248ff); IsSeparated uses strict `<` (Topology/MetricSpace/MetricSeparated.lean:39).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-f95739","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.exists_set_encard_eq_packingNumber","line":267,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"unneeded-case-split","claim":"The case split rcases Set.eq_empty_or_nonempty A (L269-273) is unnecessary. ∅ is an ε-separated subset of every A, so it supplies the Nonempty instance needed by ENat.exists_eq_iSup_of_lt_top directly. Without the split, the 16-line proof shrinks to 8 lines.","fix":"Get the Nonempty instance from ⟨⟨∅, empty_subset _, .empty⟩⟩ and drop the A = ∅ branch.","ev":"hunts/covering-numbers/batch3/Probe1.lean section P6:\nexample (h : packingNumber ε A ≠ ⊤) :\n    ∃ C, C ⊆ A ∧ C.Finite ∧ IsSeparated ε C ∧ C.encard = packingNumber ε A := by\n  have : Nonempty {s : Set X // s ⊆ A ∧ IsSeparated ε s} := ⟨⟨∅, empty_subset _, .empty⟩⟩\n  have e : packingNumber ε A =\n      ⨆ C : {s : Set X // s ⊆ A ∧ IsSeparated ε s}, (C : Set X).encard := by\n    simp_rw [packingNumber, iSup_subtype, iSup_and]\n  obtain ⟨C, hC⟩ := ENat.exists_eq_iSup_of_lt_top (e ▸ h.lt_top)\n  exact ⟨C, C.2.1, Set.encard_ne_top_iff.mp (hC ▸ e ▸ h), C.2.2, hC.trans e.symm⟩","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-e1039a","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.isSeparated_maximalSeparatedSet","line":294,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-type-ascription","claim":"Redundant type ascription `(maximalSeparatedSet ε A : Set X)` — the term already has type `Set X`.","fix":"Write `IsSeparated ε (maximalSeparatedSet ε A)`.","ev":"hunts/covering-numbers/batch4/SrcCopy.lean L294 without the ascription compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-3e0411","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.encard_le_of_isSeparated","line":302,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"inlined-existing-lemma","claim":"The proof re-derives `IsSeparated.encard_le_packingNumber` inline (`rw` + three nested `le_iSup_of_le`) instead of composing the two existing lemmas.","fix":"Replace the proof by `(h_sep.encard_le_packingNumber h_subset).trans (encard_maximalSeparatedSet h).ge`.","ev":"hunts/covering-numbers/batch4/Probe1.lean §P2: example (h_subset : C ⊆ A) (h_sep : IsSeparated ε C) (h : packingNumber ε A ≠ ⊤) : C.encard ≤ (maximalSeparatedSet ε A).encard := (h_sep.encard_le_packingNumber h_subset).trans (encard_maximalSeparatedSet h).ge","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-df0c4c","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.isCover_maximalSeparatedSet","line":305,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"vague-docstring","claim":"Docstring \"The maximal separated set is a cover.\" omits the radius `ε`, the covered set `A`, the hypothesis `packingNumber ε A ≠ ⊤`, and the Vershynin 4.2.6 reference.","fix":"Say \"If `packingNumber ε A ≠ ⊤`, the maximal `ε`-separated set `maximalSeparatedSet ε A` is an `ε`-cover of `A` (Vershynin 4.2.6).\"","ev":"src.lean L305: `/-- The maximal separated set is a cover. -/`","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-2799bd","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.packingNumber_two_mul_le_externalCoveringNumber","line":329,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"cardinal-detour-for-encard","claim":"The 21-line proof detours through `Set.toENat_cardinalMk`, `gcongr` on cardinals, `Cardinal.mk_le_of_injective` and `Exists.choose`; `choose!` plus `Set.encard_le_encard_of_injOn` gives a 9-line proof with no cardinal arithmetic.","fix":"Use `refine iSup₂_le fun D hD ↦ iSup_le fun hD_sep ↦ le_iInf₂ fun C hC ↦ ?_; choose! f hfC hf using ...; refine encard_le_encard_of_injOn ... fun x hx y hy hxy ↦ hD_sep.eq hx hy (not_lt.2 ?_)` and the triangle inequality.","ev":"hunts/covering-numbers/batch4/Probe1.lean §P5 (also in place in hunts/covering-numbers/batch4/SrcCopy.lean L318-328; compiles)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-7ede19","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.coveringNumber_le_packingNumber","line":351,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-theorem-docstring","claim":"A main statement listed in the module docstring has no docstring, unlike its sibling `packingNumber_two_mul_le_externalCoveringNumber`.","fix":"Add \"The covering number of `A` for radius `ε` is at most its packing number for radius `ε` (Vershynin 4.2.8).\"","ev":"src.lean L351: `theorem coveringNumber_le_packingNumber` has no `/-- -/` above it.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-3adb20","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.coveringNumber_two_mul_le_externalCoveringNumber","line":358,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-theorem-docstring","claim":"A main statement listed in the module docstring has no docstring.","fix":"Add \"The covering number for radius `2 * ε` is at most the external covering number for radius `ε` (Vershynin Ex. 4.2.9).\"","ev":"src.lean L358: no docstring.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-8ae38d","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.coveringNumber_two_mul_le_externalCoveringNumber","line":360,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"dead-case-split","claim":"The proof does a dead case split `rcases Set.eq_empty_or_nonempty A with rfl | h_nonempty`: `h_nonempty` is never used and the empty case needs no separate treatment.","fix":"Replace the proof by the term `(coveringNumber_le_packingNumber _ A).trans (packingNumber_two_mul_le_externalCoveringNumber ε A)`.","ev":"hunts/covering-numbers/batch4/Probe1.lean §P3: example (ε : ℝ≥0) (A : Set X) : coveringNumber (2 * ε) A ≤ externalCoveringNumber ε A := (coveringNumber_le_packingNumber _ A).trans (packingNumber_two_mul_le_externalCoveringNumber ε A)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-1a0219","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.coveringNumber_subset_le","line":365,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-hides-radius-change","claim":"The name hides the halving of the radius (`coveringNumber ε A ≤ coveringNumber (ε / 2) B`) and reads like the monotonicity in the set that the module docstring says fails.","fix":"Rename to e.g. `coveringNumber_le_coveringNumber_half_of_subset` (deprecated alias; one consumer in CoveringExponent.lean:70).","ev":"src.lean L365-366; module docstring L43-45: \"The covering number is not monotone for set inclusion\".","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-29fc8d","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.coveringNumber_subset_le","line":365,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-theorem-docstring","claim":"A main statement listed in the module docstring has no docstring.","fix":"Add \"If `A ⊆ B`, then the covering number of `A` for radius `ε` is at most that of `B` for radius `ε / 2` (Vershynin Ex. 4.2.10).\"","ev":"src.lean L365: no docstring.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-e83832","file":"Mathlib/Topology/MetricSpace/CoveringNumbers.lean","decl":"Metric.coveringNumber_subset_le","line":368,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"inlined-existing-lemma","claim":"Calc steps L368-371 re-derive `coveringNumber_two_mul_le_externalCoveringNumber (ε / 2) A` (proved four lines earlier) instead of citing it.","fix":"Use `coveringNumber_two_mul_le_externalCoveringNumber _ A` after rewriting `ε = 2 * (ε / 2)`; the chain also shows the stronger `coveringNumber ε A ≤ externalCoveringNumber (ε / 2) B`.","ev":"hunts/covering-numbers/batch4/Probe1.lean §P4 (compiles)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"ade5dcd9754"},{"id":"RT-20261007-5899e5","file":"Mathlib/Topology/Order/Basic.lean","decl":"(file)","line":60,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"unused-variable-binder","claim":"`universe u v w` / `variable {α : Type u} {β : Type v} {γ : Type w}` (L58, L60): `γ` and `w` are never used.","fix":"Drop `γ` and `w`.","ev":"`grep -nw 'γ\\|w'` on the file: only L58 and L60.","evr":"","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-c88d6f","file":"Mathlib/Topology/Order/Basic.lean","decl":"instance@L85","line":85,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"needless-let-in-proof","claim":"The proof introduces two `let`s (`f1`, `f2`) only to call `countable_range`. It takes 6 lines where a 3-line anonymous-constructor term suffices.","fix":"Use `⟨_, ((countable_range Ioi).union (countable_range Iio)).mono (by grind), OrderTopology.topology_eq_generate_intervals⟩`.","ev":"hunts/topology-order-basic/batch0/Probe1.lean §P5: `example [TopologicalSpace α] [Preorder α] [OrderTopology α] [Countable α] : SecondCountableTopology α := ⟨_, ((countable_range Ioi).union (countable_range Iio)).mono (by grind), OrderTopology.topology_eq_generate_intervals⟩`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-a5332c","file":"Mathlib/Topology/Order/Basic.lean","decl":"OrderTopology.continuous_iff","line":100,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring-characterisation","claim":"This public characterisation of continuity into an order topology (preimages of all open rays are open) has no docstring. (Graded NIT: Mathlib does not require docstrings on theorems.)","fix":"Add a one-line docstring stating the criterion.","ev":"measured: src.lean L99-100 has `@[to_dual none]` and then the declaration, with no `/-- -/` before it","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-72c7a2","file":"Mathlib/Topology/Order/Basic.lean","decl":"isOpen_iff_generate_intervals","line":106,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring-characterisation","claim":"This public characterisation of open sets in an order topology (as `GenerateOpen` of the open rays) has no docstring. (Graded NIT: Mathlib does not require docstrings on theorems.)","fix":"Add a one-line docstring.","ev":"measured: src.lean L105-106 has no docstring","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-a7c511","file":"Mathlib/Topology/Order/Basic.lean","decl":"lt_mem_nhds","line":124,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"lt-gt-swapped-name","claim":"`lt_mem_nhds : a < b → ∀ᶠ x in 𝓝 b, a < x` (Preorder + OrderTopology) has exactly the conclusion of `eventually_gt_nhds : b < a → ∀ᶠ x in 𝓝 a, b < x` (OrderClosed.lean:230, LinearOrder + ClosedIicTopology). The latter is named by the current convention (`eventually_` for `∀ᶠ`; `gt` because the bound variable is the larger side). `lt_mem_nhds` has lt/gt swapped and says `mem_nhds` for an `∀ᶠ` statement. Its dual `gt_mem_nhds` (`x < a`) likewise clashes with `eventually_lt_nhds`. It has 67 uses.","fix":"Rename the Preorder/OrderTopology pair to e.g. `eventually_gt_nhds'`/`eventually_lt_nhds'` (or put them in the `OrderTopology` namespace), with deprecated aliases.","ev":"hunts/topology-order-basic/batch0/Probe1.lean §P7: `#check @lt_mem_nhds` gives `a < b → ∀ᶠ x in 𝓝 b, a < x`, and `#check @eventually_gt_nhds` gives `b < a → ∀ᶠ x in 𝓝 a, b < x`. On a LinearOrder with OrderTopology, `⟨eventually_gt_nhds h, eventually_ge_nhds h⟩` proves both conclusions.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-4f0a02","file":"Mathlib/Topology/Order/Basic.lean","decl":"le_mem_nhds","line":128,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"lt-gt-swapped-name","claim":"`le_mem_nhds : a < b → ∀ᶠ x in 𝓝 b, a ≤ x` has the conclusion of `eventually_ge_nhds` (OrderClosed.lean:237, LinearOrder + ClosedIicTopology). Its name has le/ge swapped against the current `eventually_ge_nhds` convention and says `mem_nhds` for an `∀ᶠ` statement. Its dual `ge_mem_nhds` clashes with `eventually_le_nhds` in the same way.","fix":"Rename the pair in step with `lt_mem_nhds`, e.g. to `eventually_ge_nhds'`/`eventually_le_nhds'`, with deprecated aliases.","ev":"hunts/topology-order-basic/batch0/Probe1.lean §P7 (`eventually_ge_nhds h : ∀ᶠ x in 𝓝 b, a ≤ x` on a LinearOrder with OrderTopology)","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-9350ba","file":"Mathlib/Topology/Order/Basic.lean","decl":"nhds_eq_order","line":132,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring-characterisation","claim":"The basic neighbourhood-filter formula of the order topology (`𝓝 a` is the infimum of the principal filters of open rays containing `a`) has no docstring, although 9 other places use it. (Graded NIT: Mathlib does not require docstrings on theorems.)","fix":"Add a docstring describing the formula.","ev":"measured: src.lean L131-132 has no docstring; `git grep -w nhds_eq_order origin/master -- Mathlib` gives 9 uses outside its definition","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-6764b5","file":"Mathlib/Topology/Order/Basic.lean","decl":"tendsto_order","line":139,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring-characterisation","claim":"`tendsto_order`, the standard ε-free characterisation of `Tendsto f x (𝓝 a)` in an order topology, is used 95 times in Mathlib but has no docstring. (Graded NIT: Mathlib does not require docstrings on theorems.)","fix":"Add a docstring stating the criterion.","ev":"measured: src.lean L138-139 has no docstring; `git grep -w tendsto_order origin/master -- Mathlib` gives 95 uses outside its definition","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-a24cbd","file":"Mathlib/Topology/Order/Basic.lean","decl":"tendstoIccClassNhds","line":142,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"missing-blank-line-between-decls","claim":"There is no blank line between the end of `tendsto_order`'s proof (L141) and `instance tendstoIccClassNhds` (L142). Everywhere else in the file, declarations are separated by a blank line.","fix":"Insert a blank line before `instance tendstoIccClassNhds`.","ev":"measured: `sed -n 140,143p src.lean | cat -A`, where L141 '  simp only [nhds_eq_order a, ...]; rfl' is directly followed by L142 'instance tendstoIccClassNhds ...'","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-5e3e86","file":"Mathlib/Topology/Order/Basic.lean","decl":"tendsto_of_tendsto_of_tendsto_of_le_of_le'","line":221,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"binder-shadows-filter-name","claim":"The eventual hypotheses bind `b` while the filter is also named `b`: `(hgf : ∀ᶠ b in b, g b ≤ f b)`, so the statement displays as `(∀ᶠ (b : β) in b, g b ≤ f b) → (∀ᶠ (b : β) in b, f b ≤ h b)`; the two `b`s are different objects.","fix":"Write `∀ᶠ x in b, g x ≤ f x` (or rename the filter to `l`).","ev":"hunts/topology-order-basic/batch1/ProbeA.lean section A5, `#check @tendsto_of_tendsto_of_tendsto_of_le_of_le'` prints `(∀ᶠ (b : β) in b, g b ≤ f b) → (∀ᶠ (b : β) in b, f b ≤ h b) → Tendsto f b (𝓝 a)`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-2c9d18","file":"Mathlib/Topology/Order/Basic.lean","decl":"nhds_order_unbounded","line":240,"sev":"NIT","status":"confirmed","cat":"api","pattern":"inconsistent-argument-order","claim":"Takes `(hu : ∃ u, a < u) (hl : ∃ l, l < a)` (upper bound first), the reverse of its siblings `nhds_basis_Ioo'` and `mem_nhds_iff_exists_Ioo_subset'`, which take `(hl : ∃ l, l < a) (hu : ∃ u, a < u)`.","fix":"Swap to `(hl) (hu)` to match the sibling lemmas.","ev":"hunts/topology-order-basic/batch1/ProbeA.lean section A5: `#check @nhds_order_unbounded` gives `(∃ u, a < u) → (∃ l, l < a) → ...`; `#check @nhds_basis_Ioo'` gives `(∃ l, l < a) → (∃ u, a < u) → ...`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-2d5085","file":"Mathlib/Topology/Order/Basic.lean","decl":"tendsto_order_unbounded","line":244,"sev":"NIT","status":"confirmed","cat":"api","pattern":"inconsistent-argument-order","claim":"Same `(hu) (hl)` argument order, reversed relative to `nhds_basis_Ioo'` / `mem_nhds_iff_exists_Ioo_subset'` (`(hl) (hu)`).","fix":"Swap to `(hl) (hu)`.","ev":"hunts/topology-order-basic/batch1/ProbeA.lean section A5: `#check @tendsto_order_unbounded` gives `(∃ u, a < u) → (∃ l, l < a) → ...`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-8e1a6c","file":"Mathlib/Topology/Order/Basic.lean","decl":"tendstoIxxNhdsWithin","line":252,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"inconsistent-instance-names","claim":"Its sibling instances are named `tendstoIccClassNhds`, `tendstoIcoClassNhds`, `tendstoIocClassNhds`, `tendstoIooClassNhds`, `tendstoIccClassNhdsPi`; this one drops `Class` (`tendstoIxxNhdsWithin`).","fix":"Rename to `tendstoIxxClassNhdsWithin` with a deprecated alias.","ev":"src.lean lines 142-157, 252, 257 (instance names).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-14796b","file":"Mathlib/Topology/Order/Basic.lean","decl":"induced_topology_eq_preorder","line":278,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring-opaque-hypotheses","claim":"No docstring, and the hypotheses are opaque: `H₁ : ∀ {a b x}, b < f a → ¬(b < f x) → ∃ y, y < a ∧ b ≤ f y` (and its dual) encode 'every `b` below `f a` that is not a strict lower bound of the range is bounded by some `f y` with `y < a`'; nothing explains this or how it relates to `induced_orderTopology'` / `StrictMono.induced_topology_eq_preorder` (which do have docstrings). (Graded NIT: Mathlib does not require docstrings on theorems.)","fix":"Add a docstring stating the result and explaining `H₁`, `H₂` in words.","ev":"src.lean lines 277-282: the declaration is preceded only by `@[to_dual self (reorder := hf (x y), H₁ H₂)]`, no `/-- -/`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-0e3177","file":"Mathlib/Topology/Order/Basic.lean","decl":"induced_orderTopology","line":308,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"missing-docstring-nontrivial-hypothesis","claim":"No docstring. The lemma is the constructor behind `instance : OrderTopology ℚ` and the irrationals' instance, and its key hypothesis `H : ∀ {x y}, x < y → ∃ a, f a ∈ Ioo x y` (range of `f` meets every nonempty open interval of `β`) is unnamed and undocumented, as is how it differs from the primed version. (Graded NIT: Mathlib does not require docstrings on theorems.)","fix":"Add a docstring: if `f` reflects and preserves `<` and its range meets every interval `(x, y)` with `x < y`, the topology induced by `f` is the order topology (cf. `induced_orderTopology'`).","ev":"src.lean lines 306-310: `@[to_dual self]` directly precedes `theorem induced_orderTopology`, no `/--` block","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-6b8521","file":"Mathlib/Topology/Order/Basic.lean","decl":"induced_orderTopology","line":311,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-parentheses","claim":"Proof term has redundant parentheses `induced_orderTopology' f (hf)`.","fix":"Write `induced_orderTopology' f hf`.","ev":"hunts/topology-order-basic/batch2/copy_nits.lean (copy of src.lean with `(hf)` -> `hf`) compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-6233d3","file":"Mathlib/Topology/Order/Basic.lean","decl":"OrderEmbedding.isEmbedding_of_ordConnected","line":335,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-missing-period","claim":"Docstring ends `... the range of `f` is\\norder-connected -/` without a final full stop (every other docstring in the block has one).","fix":"End the docstring with `order-connected. -/`.","ev":"src.lean lines 333-334; hunts/topology-order-basic/batch2/copy_nits.lean (fixed copy) compiles","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-b85c05","file":"Mathlib/Topology/Order/Basic.lean","decl":"OrderEmbedding.isEmbedding_of_ordConnected","line":337,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"redundant-namespace-qualification","claim":"The conclusion is written `Topology.IsEmbedding f` although `Topology` is opened at line 54 and the sibling lemma at line 330 writes `IsEmbedding f`.","fix":"Write `IsEmbedding f`.","ev":"hunts/topology-order-basic/batch2/copy_nits.lean (copy of src.lean with `Topology.IsEmbedding f` -> `IsEmbedding f`) compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-2d3529","file":"Mathlib/Topology/Order/Basic.lean","decl":"IsOpen.exists_Ioo_subset","line":455,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"dead-trichotomy-branch","claim":"The proof uses `lt_trichotomy x y` with an impossible middle branch `(hy rfl).elim`, plus redundant type ascriptions on `obtain`. `hy.lt_or_gt` gives a 7-line proof instead of 10.","fix":"Replace `lt_trichotomy` with `hy.lt_or_gt` and drop the dead `rfl` branch and the type ascriptions.","ev":"hunts/topology-order-basic/batch3/p1_basic.lean P2: `obtain ⟨x, hx⟩ := h; obtain ⟨y, hy⟩ := exists_ne x; rcases hy.lt_or_gt with H | H; · obtain ⟨l, lx, hl⟩ := exists_Ioc_subset_of_mem_nhds (hs.mem_nhds hx) ⟨y, H⟩; exact ⟨l, x, lx, Ioo_subset_Ioc_self.trans hl⟩; · obtain ⟨u, xu, hu⟩ := exists_Ico_subset_of_mem_nhds (hs.mem_nhds hx) ⟨y, H⟩; exact ⟨x, u, xu, Ioo_subset_Ico_self.trans hu⟩`","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-ec3981","file":"Mathlib/Topology/Order/Basic.lean","decl":"dense_iff_exists_between","line":489,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-grammar","claim":"Docstring grammar (L485–487): 'densely linear ordered type' should read 'densely linearly ordered type', and 'requires less typeclass assumptions' should read 'fewer'. It says each implication needs fewer assumptions without naming the one-directional lemmas (`Dense.exists_between`, `dense_of_exists_between`).","fix":"Fix the grammar and name `Dense.exists_between` (→, needs only `OrderClosedTopology`) and `dense_of_exists_between` (←, needs no `DenselyOrdered`).","ev":"measured: src.lean L485–487 read 'A set in a nontrivial densely linear ordered type ... Each implication requires less typeclass assumptions.'","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-a8bed5","file":"Mathlib/Topology/Order/Basic.lean","decl":"mem_nhds_iff_exists_Ioo_subset'","line":496,"sev":"NIT","status":"confirmed","cat":"proof","pattern":"apply-closing-term","claim":"The `←` branch closes with `apply mem_of_superset (Ioo_mem_nhds ha.1 ha.2) h` (L504), a fully applied term, so it should be `exact`. The whole branch is the term `fun ⟨l, u, ha, h⟩ => mem_of_superset (Ioo_mem_nhds ha.1 ha.2) h`.","fix":"Use `exact`, or a term-mode `fun ⟨l, u, ha, h⟩ => mem_of_superset (Ioo_mem_nhds ha.1 ha.2) h`.","ev":"hunts/topology-order-basic/batch3/p1_basic.lean P4: `rintro ⟨l, u, ha, h⟩; exact mem_of_superset (Ioo_mem_nhds ha.1 ha.2) h` compiles","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-c34a25","file":"Mathlib/Topology/Order/Basic.lean","decl":"countable_of_isolated_left'","line":615,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-describes-sibling-statement","claim":"The docstring 'points which are isolated on the left' describes `{x | 𝓝[<] x = ⊥}`, the set of `countable_setOfPred_isolated_left`, which has the same docstring. This lemma's set `{x | ∃ y, y < x ∧ Ioo y x = ∅}` leaves out a bottom element.","fix":"Moot if the lemma is deprecated; otherwise say 'points `x` with some `y < x` and `Ioo y x = ∅`'.","ev":"hunts/topology-order-basic/batch4/probe3.lean P5 third example: `(⊥ : α) ∈ {x : α | 𝓝[<] x = ⊥} ∧ (⊥ : α) ∉ {x : α | ∃ y, y < x ∧ Ioo y x = ∅}` compiles.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-e7f534","file":"Mathlib/Topology/Order/Basic.lean","decl":"countable_of_isolated_left'","line":617,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"primed-name-without-unprimed","claim":"It is a primed name with no unprimed `countable_of_isolated_left`. The `_of_` reads as a hypothesis, but the lemma has none: the conclusion is countability of the set of left-isolated points. It also clashes in spirit with `countable_setOfPred_isolated_left`, which is about `𝓝[<] x = ⊥`.","fix":"Deprecate it (see the reuse finding), or rename it to `countable_setOfPred_exists_lt_Ioo_eq_empty`.","ev":"Measured: `git grep -n 'countable_of_isolated_left\\b' origin/master -- .` returns nothing apart from the primed declaration.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-24b603","file":"Mathlib/Topology/Order/Basic.lean","decl":"countable_image_lt_image_Ioi_within","line":637,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"to-dual-autoname-contradicts-statement","claim":"The plain `@[to_dual]` auto-names the dual by translating only `Ioi`→`Iio`, not the `lt`/`gt` token. The generated name therefore contradicts its own statement under the file's naming scheme. In the scheme, `_lt_image_Ioi` means `f x < z ≤ f '' Ioi x` and `_gt_image_Ioi` means `f '' Ioi x ≤ z < f x`. The generated `countable_image_lt_image_Iio_within` states `{x ∈ t | ∃ z < f x, ∀ y ∈ t, y < x → f y ≤ z}`, that is f x is ABOVE `f '' Iio x`, so it should be `…_gt_image_Iio_within`. Its docstring also says 'separated below', whereas the `_lt_` Ioi version says 'separated above'. Together with the next finding, the two Iio names are swapped. No Mathlib file uses the Iio names, so a fix costs nothing downstream. (NIT per the calibration for naming on a correct statement, but the name states the opposite inequality.)","fix":"Write `@[to_dual countable_image_gt_image_Iio_within …]` explicitly, as the file already does for `isOpen_lt'`/`isOpen_gt'` and `lt_mem_nhds`/`gt_mem_nhds`.","ev":"hunts/topology-order-basic/batch4/probe3.out (#check): `countable_image_lt_image_Iio_within : … {x | x ∈ t ∧ ∃ z < f x, ∀ y ∈ t, y < x → f y ≤ z}.Countable`; findDocString? gives '…image under `f` of `(-∞, x)` is separated below from `f x`…'.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-05265c","file":"Mathlib/Topology/Order/Basic.lean","decl":"countable_image_lt_image_Ioi","line":678,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"to-dual-autoname-contradicts-statement","claim":"The plain `@[to_dual]` auto-names the dual by translating only `Ioi`→`Iio`, not the `lt`/`gt` token. The generated name therefore contradicts its own statement under the file's naming scheme. In the scheme, `_lt_image_Ioi` means `f x < z ≤ f '' Ioi x` and `_gt_image_Ioi` means `f '' Ioi x ≤ z < f x`. The generated `countable_image_lt_image_Iio` states `{x | ∃ z < f x, ∀ y < x, f y ≤ z}` (f x above `f '' Iio x`), so its name should say `gt`. It is swapped with `countable_image_gt_image_Iio`, and nothing in Mathlib uses either name.","fix":"Write `@[to_dual countable_image_gt_image_Iio …]` explicitly.","ev":"hunts/topology-order-basic/batch4/probe3.out (#check): `countable_image_lt_image_Iio : … {x | ∃ z < f x, ∀ y < x, f y ≤ z}.Countable`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-701317","file":"Mathlib/Topology/Order/Basic.lean","decl":"countable_image_gt_image_Ioi_within","line":688,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"to-dual-autoname-contradicts-statement","claim":"The plain `@[to_dual]` auto-names the dual by translating only `Ioi`→`Iio`, not the `lt`/`gt` token. The generated name therefore contradicts its own statement under the file's naming scheme. In the scheme, `_lt_image_Ioi` means `f x < z ≤ f '' Ioi x` and `_gt_image_Ioi` means `f '' Ioi x ≤ z < f x`. The generated `countable_image_gt_image_Iio_within` states `{x ∈ t | ∃ z, f x < z ∧ ∀ y ∈ t, y < x → z ≤ f y}`, so f x is BELOW `f '' Iio x`, and its docstring says 'separated above'. It should be `…_lt_image_Iio_within`.","fix":"Write `@[to_dual countable_image_lt_image_Iio_within …]` explicitly.","ev":"hunts/topology-order-basic/batch4/probe3.out (#check): `countable_image_gt_image_Iio_within : … {x | x ∈ t ∧ ∃ z, f x < z ∧ ∀ y ∈ t, y < x → z ≤ f y}.Countable`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-a48069","file":"Mathlib/Topology/Order/Basic.lean","decl":"countable_image_gt_image_Ioi","line":699,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"to-dual-autoname-contradicts-statement","claim":"The plain `@[to_dual]` auto-names the dual by translating only `Ioi`→`Iio`, not the `lt`/`gt` token. The generated name therefore contradicts its own statement under the file's naming scheme. In the scheme, `_lt_image_Ioi` means `f x < z ≤ f '' Ioi x` and `_gt_image_Ioi` means `f '' Ioi x ≤ z < f x`. The generated `countable_image_gt_image_Iio` states `{x | ∃ z, f x < z ∧ ∀ y < x, z ≤ f y}` (f x below `f '' Iio x`), so it should be `countable_image_lt_image_Iio`. It is swapped with its sibling.","fix":"Write `@[to_dual countable_image_lt_image_Iio …]` explicitly.","ev":"hunts/topology-order-basic/batch4/probe3.out (#check): `countable_image_gt_image_Iio : … {x | ∃ z, f x < z ∧ ∀ y < x, z ≤ f y}.Countable`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261007-c4317a","file":"Mathlib/Topology/Order/Basic.lean","decl":"instIsCountablyGenerated_atTop","line":707,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"instance-name-style-inconsistent","claim":"The instance name mixes conventions (`instIsCountablyGenerated_atTop`, dual `instIsCountablyGenerated_atBot`). The neighbouring instances for the same class use camel case: `instIsCountablyGeneratedAtTopProd` and `OrderDual.instIsCountablyGeneratedAtTop` in Order/Filter/AtTopBot/CountablyGenerated.lean. Across Mathlib, 2507 named `inst…` instances are camel case and 76 use an underscore.","fix":"Rename to `instIsCountablyGeneratedAtTop` (to_dual `…AtBot`) with deprecated aliases.","ev":"Measured: `git grep -E '^(@\\[[^]]*\\] )?instance (\\(priority := [0-9]+\\) )?inst[A-Za-z0-9]*_' origin/master -- Mathlib | wc -l` = 76 vs camel-case pattern = 2507; CountablyGenerated.lean:38 and :45.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-07","commit":"4beb549110a"},{"id":"RT-20261006-ff9c1d","file":"Mathlib/Topology/SeparatedMap.lean","decl":"(file)","line":30,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-overstates","claim":"The module docstring says the diagonal is closed (open) 'iff the equal locus of any two continuous maps coequalized by `f` is closed (open)', but the file proves only the forward directions (`IsSeparatedMap.isClosed_eqLocus`, `IsLocallyInjective.isOpen_eqLocus`). Grammar: 'The analogue of separated maps and locally injective maps ... are' should read 'analogues'.","fix":"Add the converses (instantiate with `Pullback.fst`/`Pullback.snd`) or say 'implies'; fix 'analogues'.","ev":"src L22-31 (module doc) vs L180-188: only `IsSeparatedMap f → ... → IsClosed {a | g₁ a = g₂ a}` and the open analogue are stated.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b0f0e3","file":"Mathlib/Topology/SeparatedMap.lean","decl":"Topology.IsEmbedding.toPullbackDiag","line":44,"sev":"NIT","status":"confirmed","cat":"reuse","pattern":"reprovable-from-existing-api","claim":"`IsEmbedding.toPullbackDiag` recomputes induced neighbourhood filters, but it is `(isEmbedding_graph continuous_id).codRestrict _ (fun _ ↦ rfl)`. Likewise `Function.Injective.IsLocallyInjective` rebuilds `Function.Injective.injOn` as `fun _ _ _ _ ↦ @inj _ _`.","fix":"Use `(isEmbedding_graph continuous_id).codRestrict {q | f q.1 = f q.2} fun _ ↦ rfl` and `inj.injOn`.","ev":"-- hunts/separated-map/P2.lean: `example (f : X → Y) : IsEmbedding (toPullbackDiag f) := (isEmbedding_graph (continuous_id : Continuous (id : X → X))).codRestrict {q : X × X | f q.1 = f q.2} (fun _ => rfl)` and `fun _ ↦ ⟨_, isOpen_univ, trivial, inj.injOn⟩` compile.","evr":"compiles","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-4786bb","file":"Mathlib/Topology/SeparatedMap.lean","decl":"t2space_iff_isSeparatedMap","line":64,"sev":"NIT","status":"confirmed","cat":"naming","pattern":"name-breaks-convention","claim":"`t2space_iff_isSeparatedMap` should be `t2Space_iff_isSeparatedMap` (`T2Space` ↦ `t2Space`, as in `t2Space_iff_disjoint_nhds`), and `discreteTopology_iff_locallyInjective` (L158) names its conclusion `IsLocallyInjective` without the `is`.","fix":"Rename to `t2Space_iff_isSeparatedMap` and `discreteTopology_iff_isLocallyInjective`, with deprecated aliases.","ev":"-- hunts/separated-map/P.lean: `t2Space_iff_isSeparatedMap` is an unknown identifier; Mathlib uses `t2Space_iff_*` (e.g. `t2Space_iff_disjoint_nhds`).","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-b85cac","file":"Mathlib/Topology/SeparatedMap.lean","decl":"(file)","line":192,"sev":"NIT","status":"confirmed","cat":"hygiene","pattern":"leftover-hygiene","claim":"L192 `variable {X E A : Type*}` re-declares `X` and `A` in the same scope, and `X` changes role from the source of `f : X → Y` to the base of `p : E → X`. Also, `;`-chained tactics appear on one line at L130 and L162–163.","fix":"Use fresh names (or a `section`) for the lifting part, and put one tactic per line.","ev":"src L42 `variable {X Y A} [TopologicalSpace X] [TopologicalSpace A]`, L192 `variable {X E A : Type*} [TopologicalSpace E] [TopologicalSpace A] {p : E → X}`; L130 `obtain ...; exact ...`; L162 `convert hU; ext x'; refine ...`.","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-76222e","file":"Mathlib/Util/ElabWithoutMVars.lean","decl":"elabTermWithoutNewMVars","line":20,"sev":"NIT","status":"confirmed","cat":"docs","pattern":"docstring-overstates","claim":"The module docstring is only a title with an empty body. `elabTermWithoutNewMVars` is declared in the root namespace (not `Mathlib`/`Mathlib.Tactic`), and its docstring says it ensures the term 'has no metavariables', but it only rejects new holes created by `elabTermWithHoles`. Pre-existing metavariables in the term are not checked, which is what the name says.","fix":"Say 'creates no new metavariables', add a sentence to the module doc, and consider moving it into the `Mathlib` namespace.","ev":"src L10-13, L19-24 (`let (e, mvars) ← elabTermWithHoles t none tactic; unless mvars.isEmpty do throwErrorAt ...`).","evr":"measured","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"},{"id":"RT-20261006-ca992f","file":"Mathlib/Util/ElabWithoutMVars.lean","decl":"elabTermWithoutNewMVars","line":20,"sev":"NIT","status":"confirmed","cat":"api","pattern":"hidden-precondition","claim":"The function calls `elabTermWithHoles t none tactic` with no parent tag, so it needs an active main goal even for a complete term: inside `closeMainGoalUsing` it fails with 'No goals to be solved'. The expected type is also fixed to `none`, and the requirement that callers install the goal's local context (`withMainContext`) is undocumented.","fix":"Take `(expectedType? : Option Expr := none)` and an explicit parent tag (or avoid `getMainTag`), and document the context requirement.","ev":"-- hunts/elab-without-mvars/P.lean: `elab \"audit_close \" t:term : tactic => closeMainGoalUsing `audit_close fun _ _ => elabTermWithoutNewMVars `audit_close t`; `example : True := by audit_close True.intro` fails: 'No goals to be solved'.","evr":"fails-as-expected","astraV":"","astraS":"","pr":null,"res":"","at":"2026-10-06","commit":"4beb549110a"}]}