FAQ¶
Common questions from CS01 / CS02 dogfooding and from external adopters trying physics-lint for the first time.
What is an “adapter”?¶
An adapter is a small Python file (physics_lint_adapter.py by
convention) that exposes your model function plus a domain spec to
physics-lint. Rules that need to query the model at multiple points
(e.g., symmetry checks, BC queries) operate via the adapter. See
Loading models for the full contract.
Can I lint a model without writing an adapter?¶
Yes — if you can produce a .npz dump of model predictions, you can
lint that directly:
physics-lint check pred.npz --format text
The dump-mode rule set is narrower (no symmetry, no BC re-query), but covers conservation, positivity, and maximum-principle checks. Adapters are required for the full rule set.
What does APPROXIMATE vs FAIL mean?¶
Each rule has a calibrated noise-floor band. A model whose emitted
quantity is below the band passes (PASS); above the band but within
a tolerable factor is APPROXIMATE (warning); above the tolerable
factor is FAIL (error). Exact thresholds are per-rule and documented
on each rule’s page.
Why does PH-SYM-001 report SKIP on my model?¶
SKIP with a reason means a rule’s preconditions aren’t met for the
input. PH-SYM-001 checks rotational equivariance; it SKIPs if the
domain isn’t rotationally symmetric or if the model doesn’t expose an
operator the rule can query. See the
PH-SYM-001 rule page for the exact
preconditions.
What does a SARIF result in the Security tab mean?¶
A non-PASS rule firing emits one SARIF result. GitHub code scanning
surfaces it in the repository’s Security tab with the rule ID, the
location of the model artifact, and the properties block including
raw value, violation ratio, and a one-line reason. See
SARIF schema for the field-by-field contract.
How do I suppress a rule on a known-acceptable case?¶
Pass --disable RULE_ID on the CLI to skip the rule entirely on a run.
The flag is repeatable:
physics-lint check my_model.py --disable PH-NUM-001 --disable PH-SYM-004
Disabled rules are not iterated, so they emit no result and no SARIF
notification. There is no per-rule “downgrade to note” surface in
v1.0; the public knobs are run-with or skip-entirely. A future v1.x
release may add a config-file equivalent under [tool.physics-lint]
for shared suppression policy.
How do I add a new rule?¶
Three steps:
Implement the rule in
src/physics_lint/rules/ph_xxx_nnn.py, following the registry pattern (see existing rules for examples).Add the rule’s user-facing description as a
## Rule referencesection inexternal_validation/PH-XXX-NNN/README.md. This is mandatory — the docs build fails loudly if the canonical section is missing.Write validation tests under
external_validation/PH-XXX-NNN/and a harness fixture underexternal_validation/_harness/if needed.
See Contributing for the full development workflow.
What’s the difference between physics-lint and physics-lint[mesh]?¶
physics-lint[mesh] adds the scikit-fem dependency for unstructured-
mesh field support (used by PhysicsNeMo MGN-style adapters and FE
adapters). Most grid adapters work without it.
Why “physics-lint” and not “physics-check” or “physics-test”?¶
Lint means “structural / mechanical static-ish check that catches
problems the test suite doesn’t.” physics-lint runs on a trained model
artifact in CI; it doesn’t validate physics in a research sense (that
requires comparing to held-out data or analytical solutions). It checks
properties the model should obey — conservation, symmetry,
positivity, boundary behavior — against calibrated floors. The framing
is the same as ruff or mypy: cheap mechanical checks that catch
real bugs.