The plasticity-solvers skill shipped in .claude/skills/ presents cm.enable_yield_homotopy() as "the recommended default for any hard-Min solve" (SKILL.md:17, :21). That method does not exist:
$ git grep -c "enable_yield_homotopy" development -- src/
(no match)
$ git grep -c "enable_yield_homotopy" feature/regime-diagram -- src/
(no match)
Its headline code example raises AttributeError. The skill references it in six places (:17, :21, :42, :82, :102, :112, :123), including solver-option advice (snes_linesearch_type="basic", an snes_max_it floor of 100) that describes machinery no longer present.
Why this bites
The two skills disagree and the stale one is the one you land on. nonlinear-solver is correct and explicitly says so:
(This supersedes the enable_yield_homotopy() in-SNES ramp still described in plasticity-solvers; that path is retained only as a dead-experiment record — use the multi-solve continuation above.)
But plasticity-solvers carries no such warning at its own top, and its description ("Reach for THIS first when a Drucker-Prager / yield-stress Stokes solve stalls...") is what routes you there. So a session that follows the descriptions gets the dead API and the retired in-SNES ramp strategy — which is not merely absent but proven harmful: nonlinear-solver records that ramping δ inside a single SNES solve diverges after ~2 iterations and grinds for ~2 hours even on the correct config.
The live entry point is:
report = stokes.solve(homotopy=True) # smooth mode + tangent + march
report["settled_delta"]
Also stale in the same file
- It teaches only the sqrt soft-min law. The homotopy path now hardcodes the power-mean (
_yield_homotopy_control() sets yield_smoother="powermean"), so the δ semantics the skill describes are not the ones the driver uses — δ≤1 for the power mean, where δ=1 is the harmonic mean, versus the sqrt family's δ up to 64. Following the skill's δ intuition on the live path gives silently wrong schedules.
- No mention of
powermean anywhere in the file.
Suggested fix
Either fold plasticity-solvers into nonlinear-solver, or reduce it to the yield-law maths and the tangent-per-model table (which are still correct and are what nonlinear-solver defers to it for), and delete the enable_yield_homotopy recipe entirely rather than leaving it as a "dead-experiment record" in the file a reader is routed to first.
Related: while auditing this I also noticed constitutive_models.py:1044 (the yield_smoother property docstring) still states the power-mean sharpness is s = 1/δ, where the code at :1014 uses s = 1/(δ + 0.001). Minor, but it is the number a reader would use to pick δ0.
The
plasticity-solversskill shipped in.claude/skills/presentscm.enable_yield_homotopy()as "the recommended default for any hard-Min solve" (SKILL.md:17, :21). That method does not exist:Its headline code example raises
AttributeError. The skill references it in six places (:17, :21, :42, :82, :102, :112, :123), including solver-option advice (snes_linesearch_type="basic", ansnes_max_itfloor of 100) that describes machinery no longer present.Why this bites
The two skills disagree and the stale one is the one you land on.
nonlinear-solveris correct and explicitly says so:But
plasticity-solverscarries no such warning at its own top, and its description ("Reach for THIS first when a Drucker-Prager / yield-stress Stokes solve stalls...") is what routes you there. So a session that follows the descriptions gets the dead API and the retired in-SNES ramp strategy — which is not merely absent but proven harmful:nonlinear-solverrecords that ramping δ inside a single SNES solve diverges after ~2 iterations and grinds for ~2 hours even on the correct config.The live entry point is:
Also stale in the same file
_yield_homotopy_control()setsyield_smoother="powermean"), so the δ semantics the skill describes are not the ones the driver uses — δ≤1 for the power mean, where δ=1 is the harmonic mean, versus the sqrt family's δ up to 64. Following the skill's δ intuition on the live path gives silently wrong schedules.powermeananywhere in the file.Suggested fix
Either fold
plasticity-solversintononlinear-solver, or reduce it to the yield-law maths and the tangent-per-model table (which are still correct and are whatnonlinear-solverdefers to it for), and delete theenable_yield_homotopyrecipe entirely rather than leaving it as a "dead-experiment record" in the file a reader is routed to first.Related: while auditing this I also noticed
constitutive_models.py:1044(theyield_smootherproperty docstring) still states the power-mean sharpness iss = 1/δ, where the code at :1014 usess = 1/(δ + 0.001). Minor, but it is the number a reader would use to pick δ0.