AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Physics Interpreter

skill-leventilo-mobius-physics-interpreter · by leventilo

Translate paper-parser's extracted equations, claims, and surrounding text into a typed physics sub-tree of the SimSpec — governing equations, boundary conditions, initial conditions, declared constants, regime classification, and named approximations. Run after paper-parser, before simspec-author.

No reviews yet
0 installs
5 views
0.0% view→install

Install

$ agentstack add skill-leventilo-mobius-physics-interpreter

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-leventilo-mobius-physics-interpreter)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
3mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Physics Interpreter? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

physics-interpreter

Purpose and scope

This skill produces exactly one artifact: the physics sub-tree of the SimSpec, defined at $defs.physics of simspec.schema.json. That sub-tree fixes what every downstream skill is allowed to assume about the paper: which equations govern the system, on which domain they live, with which boundary and initial conditions, with which constants, in which regime, and under which named approximations. Mobius's "same paper, same simulator, ten times in a row" property begins here. If the regime is wrong, every solver heuristic in simspec-author Rule 3-6 fires the wrong way and the rest of the pipeline silently builds the wrong simulator.

What this skill does NOT do. It does not extract equations from the PDF — that is paper-parser's job, and its equations[] array is an input here, not an output. It does not extract numerical claims from figures or text — that is claim-extractor. It does not compose the full SimSpec — that is simspec-author. It does not generate Python solver code — that is primitive-generator. It does not write Three.js or Canvas templates — that is viz-mapper. It does not run units, CFL, or conservation checks — those are the five bundled scripts of science-integrity. The physics-interpreter is a typed-translate skill: paper-parser artifacts in, validated physics sub-tree out, every interpretive choice logged.

Inputs

The skill expects three artifacts on disk in the current working directory.

paper.json from paper-parser carries the full paper provenance and a list equations[]. Each equation has at minimum a latex field (LaTeX source as it appears in the PDF), a tentative sympy field (parser's best-effort sympy translation, may be empty), a free-text surrounding_context excerpt (~200 chars before and after), and an optional variables dict that paper-parser populated from the equation's typesetting context (e.g. greek-symbol heuristics, definition-by-text "where E is the electric field"). The figures[] and numerical_claims[] arrays are read for cross-references.

text_body.json from paper-parser carries the segmented paper body keyed by section anchor (abstract, I, II.A, etc.). The interpreter scans this body for boundary-condition phrases, initial-condition declarations, named approximations, and regime hints. The body is read-only.

hints.json from the orchestrator (optional) carries any pre-classification cues: domain_hint ("optics"|"mechanics"|...), paper_class_guess, and references to known canonical models the orchestrator already matched by title regex. When absent, the interpreter starts from zero priors.

Outputs

The skill writes physics.json to the working directory. Its top-level keys mirror $defs.physics exactly:

{
  "governing_equations": [...],
  "boundary_conditions":  [...],
  "initial_conditions":   [...],
  "constants":            [...],
  "regime":               "linear" | "weakly-nonlinear" | "strongly-nonlinear" | "stochastic" | "quantum-coherent",
  "approximations":       ["thin-lens", ...]
}

In addition the skill emits a sibling interpretation_log.json (NOT part of the schema) with the shape:

{
  "entries": [
    {
      "phase": "1-symbol-resolution" | "2-equation-classification" | "3-bc-extraction" | "4-constants" | "5-regime",
      "choice": "string short label of what was decided",
      "alternatives_considered": ["...", "..."],
      "reason": "why this branch was chosen",
      "confidence": 0.0
    }
  ]
}

simspec-author reads physics.json verbatim into the SimSpec's physics sub-tree. The orchestrator forwards interpretation_log.json into integrity.checks[] as one type: "ambiguity" check per low-confidence entry (confidence , \hat{H}, or a wavefunction symbol from Phase 1? YES → tag = quantum-coherent. continue Q2a (linearity refinement). NO → continue Q3.

Q2a. Are nonlinear-in-psi terms present (e.g. |psi|^2 psi for Gross-Pitaevskii)? YES → tag = quantum-coherent + nonlinear flag. STOP. NO → tag = quantum-coherent. STOP.

Q3. Does E contain a time derivative \partial_t or d/dt? YES → continue Q4. NO → continue Q5 (steady-state branch).

Q4. Are nonlinear terms in the dependent variable present (products like u u_x, |E|^2 E, sin(theta) where theta is unbounded)? NO → tag = linear-time-dependent. STOP. YES → continue Q4a.

Q4a. Does the paper text or approximations list contain "small amplitude", "perturbative", "linearization", "harmonic approximation"? YES → tag = weakly-nonlinear. STOP. NO → tag = strongly-nonlinear. STOP.

Q5. Steady-state. Are nonlinear terms present? NO → tag = linear-steady. STOP. YES → tag = strongly-nonlinear-steady. STOP.


Per-equation tags are written to a private side-table (not part of the schema output) and consumed by Phase 5.

### Phase 3 — Boundary and initial condition extraction

Scan `text_body.json` for the regex set `(boundary condition|BC|fixed at|clamped at|free at|periodic|open boundary|absorbing|PML|radiation condition|no-slip|no-flux|reflecting wall|hard wall|infinite well)`. For every hit, extract a 200-char window around the match and run the BC classifier:

- "fixed", "clamped", "= 0", "u(0)=", "psi(0)=" → `dirichlet`.
- "no-flux", "insulating", "du/dn = 0", "free end" → `neumann`.
- "Robin", "h u + k du/dn" pattern → `robin`.
- "periodic", "wraps", "torus" → `periodic`.
- "open", "outflow" → `open`.
- "absorbing", "PML", "radiation condition", "Sommerfeld" → `absorbing`.

For each extracted BC, write one entry into `boundary_conditions[]` with `region` filled from the text window (e.g. "x=0", "r=R"), `value` as a sympy-parseable string, and `variable` matching a Phase 1 dependent symbol. If the variable cannot be resolved to a Phase 1 symbol, the BC is dropped and a log entry emitted.

Initial conditions use the regex set `(initial state|initially|at t=0|t = 0|prepared in|the system starts)`. For every hit, extract `variable`, `expression`, and the `t0` value (almost always 0; non-zero only when paper explicitly says "we set the clock at t = t_0"). Wavefunctions get special handling: `psi(x, 0) = exp(-x**2 / (2*sigma**2))` and similar Gaussian-wavepacket forms are recognized verbatim.

### Phase 4 — Constants harvesting

Aggregate three sources:
1. `paper.equations[*].variables` entries with `role == "constant"` from Phase 1.
2. `paper.numerical_claims[]` entries whose `source_quote` matches a definition pattern ("we use g = 9.81 m/s^2", "the mass m = 1 kg").
3. Standard CODATA values pulled from the bundled `constants_table.json` (script-supplied; not in this prompt) when the paper uses a symbol like `\hbar`, `c`, `k_B` without redeclaring.

For each entry produce a `{symbol, value, unit, source}` tuple. `source` is `"paper"` if the value came from sources 1 or 2, `"standard"` if from CODATA, `"derived"` if computed from other constants (e.g. `omega_0 = sqrt(k/m)` when both `k` and `m` are paper constants).

Unit conflicts (paper says `\lambda = 632 nm`, claims says `\lambda = 6.328e-7 m`) are reconciled by canonicalizing both to UCUM via pint's parser, comparing magnitudes, and keeping the paper-text value if they agree to 0.1 %. Disagreement emits a log entry and keeps the paper-text value (paper is authoritative for paper-specific constants).

### Phase 5 — Regime + named approximations

The `physics.regime` enum has five values; map per-equation tags from Phase 2 to one whole-spec value via:

- Any per-equation tag is `stochastic`? → spec regime = `stochastic`.
- Else any tag is `quantum-coherent`? → spec regime = `quantum-coherent`.
- Else any tag is `strongly-nonlinear` or `strongly-nonlinear-steady`? → spec regime = `strongly-nonlinear`.
- Else any tag is `weakly-nonlinear`? → spec regime = `weakly-nonlinear`.
- Else → spec regime = `linear`.

Named approximations are extracted by dictionary lookup over `text_body.json`. The dictionary lives in the bundled `approximations_dictionary.json` (script-supplied) and contains entries like `{"thin lens": "thin-lens", "paraxial approximation": "paraxial", "Born-Oppenheimer": "Born-Oppenheimer", "Boussinesq": "Boussinesq", "small-angle": "harmonic-small-amplitude", "Stokes flow": "Stokes", "WKB": "WKB", "rotating-wave approximation": "RWA", "tight-binding": "tight-binding", "incompressible": "incompressible"}`. Multi-word matches win over single-word matches. Each match emits a log entry with the verbatim quote that triggered it (auditable provenance for `approximations[]`).

## Ambiguity handling

A choice is ambiguous when two or more branches in any of the five phases are non-trivially compatible with the inputs. Every such choice commits a value AND writes one entry into `interpretation_log.json` with the shape declared in Outputs. Confidence is a number in [0, 1] computed as follows:

- Single matching branch with clear textual evidence → confidence 0.95+.
- Multiple branches matched, paper text broke the tie → confidence 0.7 to 0.9.
- Tie broken by bundled-examples prior → confidence 0.5 to 0.7.
- Tie broken by an arbitrary default → confidence below 0.5; the orchestrator surfaces this to the user as a "hidden physics default" toggle in the UI (the SINTEF tacit-assumption gap rendered visible).

Three rules govern logging:
1. Never commit silently. Even high-confidence choices that closed a non-trivial branch are logged.
2. The `reason` field cites either the paper section anchor, the symbol, or the dictionary entry that decided the branch. Never "by convention".
3. Conflicts between sources (paper text vs claims vs equations) become a log entry with `phase: "*-conflict"` and confidence ≤ 0.6.

## The bundled examples library

The `examples/` directory holds eight worked examples, one per canonical physics class. Each file is a markdown document with frontmatter tags `domain`, `regime`, `technique`, `paper`, plus four sections: source equations (LaTeX verbatim), parsed equations (sympy), resulting `physics` sub-tree (JSON validated against `simspec.schema.json`), interpretation reasoning, and a list of ambiguities the interpreter would log on this paper.

The orchestrator loads the relevant subset of these examples by frontmatter match before invoking the skill: when the orchestrator's pre-classifier identifies the paper as e.g. "QM, time-dependent, 1D", it injects `infinite-well-1d.md` and `tunneling-1d.md` as few-shot context. When the paper class is unknown, all eight are injected (the per-skill 200K-token budget under Opus 4.7 1M comfortably absorbs them). The examples are not just human reference: Opus 4.7 reads them as in-context priors when filling Phase 1 symbol roles and Phase 5 named approximations.

The eight examples:

| File                       | Domain     | Regime                | Technique           |
|----------------------------|------------|-----------------------|---------------------|
| `young-double-slit.md`     | optics     | linear                | wave-FFT            |
| `simple-pendulum.md`       | mechanics  | linear (small-angle)  | RK4 ODE             |
| `double-pendulum.md`       | mechanics  | strongly-nonlinear    | RK4 ODE             |
| `infinite-well-1d.md`      | quantum    | quantum-coherent      | analytic            |
| `tunneling-1d.md`          | quantum    | quantum-coherent      | FFT-spectral split  |
| `2d-ising.md`              | stat-mech  | stochastic            | Monte-Carlo         |
| `stokes-sphere.md`         | fluid      | linear (low-Re)       | analytic            |
| `damped-oscillator.md`     | mechanics  | linear (dissipative)  | analytic + ODE      |

## 11. archetype hints

physics-interpreter MAY emit an advisory field `viz_hint_archetype` on each governing equation to help `simspec-author` pick the right `viz.scene_archetype`. Possible values match the eight enum members defined in `viz-mapper`'s SKILL.md §4: `ray-optics`, `glass-dispersion`, `field-2d`, `orbital-3d`, `particle-cloud`, `lattice`, `graph-time`, `schematic`.

Mapping table from per-equation tags (Phase 2) and `domain_hints[]` to advisory archetype:

- `domain_hints` includes `em` or `wave` AND regime is linear-time-dependent → advisory `field-2d` (or `glass-dispersion` if the surrounding text mentions "prism", "dispersion", "Abbe", "refraction in 3D").
- `domain_hints` includes `QM` AND any equation involves a 3D Laplacian on a wavefunction → advisory `orbital-3d`.
- `domain_hints` includes `QM` AND only 1D / 2D coordinates appear → advisory `field-2d`.
- `domain_hints` includes `mechanics` AND regime is `linear` or `weakly-nonlinear` AND only one or two dependent variables → advisory `graph-time`.
- `domain_hints` includes `fluid` → advisory `field-2d`.
- `domain_hints` includes `materials` AND regime is `stochastic` → advisory `lattice`.
- Per-equation tag is `stochastic` AND surrounding text contains "Brownian", "particle", "ensemble", "trajectory" → advisory `particle-cloud`.

The advisory is written into the side-table consumed by `simspec-author`, not into `physics.json` directly (the schema does not currently carry it, and emitting it would break the canonical form §). This field is advisory only — `simspec-author` ultimately decides per the routing rules in its SKILL.md §11. Conflicts between this advisory and `simspec-author`'s rules are logged with `phase: "5x-archetype-advisory"` and confidence 0.5.

## Hand-off

`simspec-author` copies `physics.json` verbatim into `simspec.physics`. All six sub-keys must be present even when empty (use `[]` for arrays, never omit). Schema reference: `$defs.physics` in `mobius/skills/simspec-author/schema/simspec.schema.json`.

Downstream consumers:
- `simspec-author` Rule 3 reads `regime` and `governing_equations[*].domain_hints` to choose `solver_hints.scheme`.
- `simspec-author` Rule 8 reads `approximations` to truncate slider ranges.
- `primitive-generator` reads `governing_equations[*].sympy` and the constants table to template Python solver code.
- `science-integrity` (units check) reads `constants[*].unit` and `governing_equations[*].variables[*].unit`.

## Red flags

Refuse to emit `physics.json` when any of the following holds. Write the partial output AND a `phase: "abort"` log entry; the orchestrator decides whether to re-dispatch.

Never invent equations. If `paper.equations[]` is empty, emit `governing_equations: []` and abort with a log entry. Inventing a "probably the wave equation" entry is the single most catastrophic failure mode.

Never tag a regime without paper evidence. If Phase 5 cannot find at least one per-equation tag, emit `regime: "linear"` (the most conservative default) AND a confidence-0.0 log entry. Do not tag `quantum-coherent` from a title keyword alone.

Never tag an approximation that is not literally named in the paper text or implied by a term explicitly dropped in an equation derivation. The bundled dictionary is a whitelist, not a generator. When in doubt, omit the approximation and log it.

Never resolve a Phase-1 symbol to a unit not declared in the paper or derivable from the equation's dimensional structure. The CODATA fallback is allowed only for universally-named constants (`\hbar`, `c`, `k_B`, `e`, `m_e`).

Never silently drop a boundary condition because its variable is unresolved. Drop AND log; the orchestrator will re-dispatch Phase 1 with extra hints.

Never emit `physics.json` if any of the bundled validators fail (sympy round-trip, pint unit parse, JSON schema). Write `physics.partial.json` instead and log the failure.

## Edge cases (sympy + pint)

Two library-specific traps the skill must handle.

`sympy.parsing.latex.parse_latex` has two backends. The default ANTLR backend silently drops trailing partial expressions: `parse_latex(r'x -')` returns `x` without raising. The Lark backend raises `UnexpectedEOF` on the same input. The skill MUST call `parse_latex(..., backend='lark')` an

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [leventilo](https://github.com/leventilo)
- **Source:** [leventilo/mobius](https://github.com/leventilo/mobius)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.