Skip to content

Add AGENTS.md and CLAUDE.md#495

Open
pbrubeck wants to merge 4 commits into
FEniCS:mainfrom
firedrakeproject:pbrubeck/agents-md
Open

Add AGENTS.md and CLAUDE.md#495
pbrubeck wants to merge 4 commits into
FEniCS:mainfrom
firedrakeproject:pbrubeck/agents-md

Conversation

@pbrubeck

@pbrubeck pbrubeck commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds AGENTS.md, documenting UFL's architecture (the Expr/BaseForm primal-dual split, the singledispatchmethod-based DAGTraverser dispatch pattern in apply_derivatives.py, map_integrands's recursive form transform), coding conventions (Google-style docstrings, the # type: ignore convention on AD rule registrations, ruff's 100-char line length), testing conventions, and the fork-push/origin-PR + three-stage-lint workflow this repo uses.
  • The Anti-Patterns section is written directly from real bugs: using a bare 0/Form([]) instead of ZeroBaseForm for a form that turned out to be zero (losing argument shape) and a documented dead end from that same investigation (Fix ZeroBaseForm holes in derivative expansion and action #494 — naively generalizing map_integrands's Form branch the way its FormSum branch already works), plus a third worked example from fixing pbrubeck/fix/replace-coefficient-derivative's CoefficientDerivativeRuleDispatcher: narrowing a dispatcher's node-type coverage (to protect foreign Derivative subtypes) without narrowing where that narrowing applies, which silently also left spatial Grad un-normalized inside a CoefficientDerivative's own content.
  • Adds a Pattern Matching For Planning And Debugging section (moved to just before Anti-Patterns) drawing on Fix ZeroBaseForm holes in derivative expansion and action #494, Cancel contractions of the Jacobian with its inverse #496 (Jacobian cancellation), and the CoefficientDerivativeRuleDispatcher fix: search sibling/downstream packages for prior art before designing a new algorithm (Cancel contractions of the Jacobian with its inverse #496's JacobianCanceller/IdentityEliminator deliberately ports GEM's own Delta-cancellation passes), match a new dispatch rule to the nearest structurally similar existing one, classify which structural category a fix belongs to before generalizing it to a sibling code path, isolate cross-package regressions with a one-delta reproduction, and — new — treat a fix that trades one failing test for another as a context signal (type-keyed dispatch can't distinguish "inside a region" from "outside it") rather than a cue to add more special cases.
  • The Debugging section gained two entries from the same fix: DAGTraverser tracebacks are mostly KeyError cache-miss noise (skip to the last exception, read self's class at each frame to see which dispatcher/ruleset was active), and diffing a narrow code path against the full pipeline on the same input localizes exactly which node differs.
  • Adds CLAUDE.md importing AGENTS.md so Claude Code picks it up automatically, mirroring the pattern already in use downstream in Firedrake.

Test plan

  • N/A (documentation only)

🤖 Generated with Claude Code

pbrubeck added 4 commits July 11, 2026 12:13
AGENTS.md documents UFL's Expr/BaseForm primal-dual split, the
singledispatchmethod-based DAGTraverser dispatch pattern used
throughout apply_derivatives.py, map_integrands' recursive form
transform, and the PR/lint workflow (fork push + origin-targeted PR,
the three separate lint.yml stages). The Anti-Patterns section is
built directly from the ZeroBaseForm/argument-preservation bugs fixed
in the companion PR, including a documented dead end (naively
generalizing map_integrands' Form branch the way its FormSum branch
already works) so a future agent does not have to rediscover it via a
test regression.

CLAUDE.md imports AGENTS.md so Claude Code picks it up automatically,
mirroring the pattern already in use downstream in Firedrake.
Generalizes lessons from today's two PRs: JacobianCanceller's design
was adapted from GEM's own Delta-cancellation passes rather than
derived from scratch, and the map_integrands Form/FormSum asymmetry
cost a real regression before being scoped correctly. Encourages
borrowing proven designs from sibling/downstream packages, matching
new dispatch rules to the nearest *structurally* similar existing one
(boilerplate included), classifying which structural category a fix
belongs to before generalizing it to a sibling code path, and
isolating cross-package regressions with a one-delta reproduction.
Tightened every section for scannability (shorter bullets, less
repeated prose, dedup the "how to add a rule" guidance that was split
across Project Architecture and Pattern Matching). Moved Pattern
Matching For Planning And Debugging to just before Anti-Patterns.

Added lessons from the CoefficientDerivativeRuleDispatcher fix:
- Debugging: DAGTraverser tracebacks are mostly KeyError cache-miss
  noise (skip to the last exception, read `self`'s class at each
  frame); diff a narrow code path against the full pipeline on the
  same input to localize where they structurally diverge.
- Pattern Matching: a fix that trades one failing test for another is
  a context signal (type-keyed dispatch can't distinguish "inside a
  region" from "outside it"), not a cue to add more special cases.
- Anti-Patterns: a new worked example (narrowing a dispatcher's
  node-type coverage without narrowing its point of use) built
  directly from the Grad-inside-CoefficientDerivative bug.
Structural/.signature() agreement between two independently-built
expressions, or the absence of an exception, does not prove a
derivative or simplification is correct -- both paths can share the
same wrong rule. Require verifying the actual mathematical claim
(numeric evaluation, assemble-and-compare, or a Taylor test for
derivatives), and reserve structural comparisons for checking that two
constructions agree with each other, not that either is right.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant