§1 — Verdict

This review examined the full standard-names system across its three repositories: imas-standard-names (ISN — the grammar library and read-only catalog server), imas-codex (the LLM-augmented name-minting pipelines), and imas-standard-names-catalog (ISNC — the published data repository). The architecture is sound and the separation of concerns (ISN defines what a valid name is; codex decides what names to create; ISNC carries the data) is respected in practice. The system's weaknesses are concentrated at well-defined seams, and most of what this review found was fixed in-session (§9). The headline numbers:

AxisStateEvidence
Grammar ↔ catalog consistencyPerfect2124/2124 published names parse strictly and round-trip; only 1 name carries a multi-token qualifier segment
Grammar engineStrong, 2 high-severity defects found & fixedLLM contract taught the retired long form; parser silently dropped operators over binary expressions
Vocabulary structureExcellent113/113 qualifiers categorized exactly once; zero irreducibility violations; all 13 cross-set overlaps intentional and ratcheted
Vocabulary curationDecayed in LLM-fed setsphysical_bases at 154 tokens with ~16 ungated catch-alls; processes.yml at 89 tokens with synonym accretion
Codex grammar integrationClean core, drifted edges (fixed)Single integration point (build_compose_context) correct; 37 unparseable prompt examples, stale counts, and a dead kind-derivation path found at the edges
Catalog documentation qualityHigh63/68 stratified sample entries clean; no boilerplate, no missing sign conventions or ranges
Catalog referential integrityWeakest axis388 dangling structured links touching 314/2124 entries (14.8%), plus 74 dangling inline references
Lifecycle governanceVestigialAll 2124 entries status=draft; zero deprecates/superseded_by anywhere; renames leave no trail for consumers

§2 — Scope, method, and the system under review

Method: parallel specialist reviews (grammar design, vocabulary audit, codex prompt audit, codex pipeline debug scan, export/import deep-dive, stratified catalog sampling), with every load-bearing claim re-verified by direct execution against the live code and data before any fix was applied. Confirmed defects were fixed in-session and pushed; design-level faults that require physics or governance judgment are ranked as recommendations in §10 rather than changed unilaterally.

imas-standard-names grammar spec + vocabularies parser / composer / context validators · MCP (read-only) imas-codex 7-pool LLM pipeline (sn run) generate → review → refine Neo4j graph · sn edit imas-standard-names-catalog 18 domain YAML files catalog.yml manifest validate → tag → release Consumers catalog.db · wheel docs site (SPA) MCP tools grammar context pinned dep sn export build sn import (curator edits, origin=catalog_edit) 1 2 3 4 5 6 Fault sites — amber: found and fixed this session; red: open recommendation. 1 LLM contract taught retired form · 2 parser dropped operators over binary · 3 prompt hard-coding + enum-drift pin · 4 export gates (unit loss, dangling links, accounting) · 5 import round-trip (curator deletion, stage clobber) · 6 governance lifecycle vestigial (no deprecation trail)
The three-repository pipeline and where this review found its faults. Grammar knowledge flows left to right; curator edits flow back through sn import.

§3 — Grammar design review (ISN)

The grammar is a two-layer system: a structural intermediate representation (operator stack, projection, ordered qualifiers, base, locus, mechanism) with a strict pure renderer and a liberal staged parser, bridged to a flat Pydantic StandardName model. parse_standard_name recomposes every parse and requires byte-equality, so the grammar admits exactly one spelling per name — a strong and well-enforced invariant. Dual-role tokens are governed by an explicitly ratcheting allowlist rather than convention, which is the right mechanism. The design earns a positive verdict overall; the defects found were in the details, not the architecture.

#Sev.FindingStatus
F1Highget_grammar_context() — the single ISN→codex LLM contract — advertised the retired {axis}_component_of_{base} long form as correct, plus three further non-parsing examples (temperature, power_due_to_ohmic, major_radius_of_plasma_boundary), actively training the composer toward invalid names. The MCP tool surface carried the same stale examples independently (hand-maintained duplication that had already half-drifted).Fixed: all advertised examples now parse; a guard test walks the context so examples and parser cannot drift again
F2HighThe IR parser silently discarded prefix operators peeled before a binary terminator: gradient_of_ratio_of_electron_pressure_to_magnetic_pressure recomposed without gradient, zero diagnostics — silent token loss in a layer whose whole contract is lossless round-tripping.Fixed: full operator stack carried over the binary; flat model raises an honest "not representable" error instead of a misleading token-loss message; regression tests added
F3MedRound-trip is a tested property, not a structural guarantee: the flat model is a lossy projection of the IR held together by fold/reject special cases. F2 was one instance; others may exist outside the tested corpus.Recommendation (§10.9)
F4MedNo canonical intra-order on multi-token qualifier segments — both incident_fluctuating_… and fluctuating_incident_… are accepted as canonical, violating the one-spelling invariant. Zone order is enforced, so the mechanism exists.Recommendation (§10.6) — verified safe: only 1 published name has a multi-token qualifier segment
F5MedThe two parse entry points disagree on unregistered loci: IR-level validate_round_trip accepts electron_temperature_at_foobar (vocab-gap diagnostic) while parse_standard_name rejects it — opposite validity oracles.Recommendation (§10.10)
F6–F7MedAGENTS.md documented disambiguation rules for a parser that no longer exists, claimed pre-commit hooks that were never configured, and the codegen drift gate ran only in CI — which is exactly how a vocabulary change landed without its regenerated enums (the incident that opened this session, breaking the reaction-channel tokens for the pinned codex consumer).Fixed: rules rewritten to match the actual peel order; check-only pre-commit config added with the drift gate wired in
F8LowReaction-channel routing is purely syntactic: deuterium_tritium_electron_temperature parses. Governance controls which tokens are dual-role but not which combinations are meaningful.Recommendation (§10.11), contained
F9–F10LowStale generated-file annotations (obsolete enum-removal notes, wrong output filename in the spec header); Transformation/Decomposition enums are byte-identical duplicates.Headers fixed; enum dedup is a recommendation

§4 — Vocabulary audit (22 sets)

Structural discipline is excellent: every qualifier maps to exactly one category (113/113, test-enforced), exhaustive decomposition finds zero real irreducibility violations in physical_bases.yml, and all 13 cross-set token overlaps are intentional, documented, and allowlisted with a shrink-toward-empty ratchet. The eponym rule is coherent (multi-base eponyms are qualifiers; single-base eponyms are atomic bases). Two stale allowlist entries were pruned and a contradictory file header corrected in-session.

The weakness is curation quality in the two LLM-fed sets. physical_bases.yml has grown to 154 tokens, including ~16 semantically empty catch-alls (coefficient, factor, parameter, index, flag, weight, …) that are not gated as generic and therefore validate almost anything — while current, power and temperature are gated: the gating policy is inconsistent. processes.yml (89 tokens) shows clear per-rotation synonym accretion: three tokens for thermalization, collisions beside coulomb_collisions, a seven-token radiation family, disruption/disruption_event, viscous/viscosity. Smaller issues: non-species tokens filed as subjects (state, gyrokinetic, hard_xray, pfirsch_schlueter, bare halo — which holds an unphysical triple role); regions.yml fully duplicated inside the locus registry with one typing conflict (halo_boundary: region vs position); 15 of 18 directional tokens duplicated between components.yml and coordinate_axes.yml; a handful of baked-in operator compounds (maximum_over_flux_surface) against the compositional style. Remedies ranked in §10.

§5 — imas-codex: prompts and LLM pipelines

The core integration is exactly right: one function (build_compose_context()) pulls ISN's get_grammar_context() plus the full closed-vocabulary token map at runtime, and every prompt receives grammar knowledge through it. Renaming logic imports ISN's real parser; the vocabulary tooling pulls token maps at call time. A prompt-hash clear-gate exists so silent prompt drift trips a barrier. The exceptions sat at the edges, and the worst three were live defects rather than future risks:

The pipeline debug scan (19 confirmed findings) rated the claim/lease machinery, LLM-response retry handling, score typing, and the fail-closed validation gate as sound. The bugs that mattered: the sn edit --rename cascade hardcodes override_edits=True, include_accepted=True, silently bypassing both human-edit and accepted-name protections with no CLI opt-in and a dry-run that previews the clobbers as ordinary renames (High); name-hint edits strand edit_status='open' forever because the recomposed successor never inherits the edit fields; --only's skip-generate flag is computed and then dropped, so scoped runs still burn compose budget; an empty {"reviews": []} LLM response persists as a canonical 0.0/"poor" review, driving good names toward exhaustion; scoped clears wipe the whole LLM-cost ledger; and an explicitly-empty path allowlist widens to the entire graph — the exact shape of the historical 1863-name reset incident, still unguarded one layer below the CLI. All eight are fixed with the protections defaulting closed: rename cascades now block on protected/accepted descendants unless the operator passes explicit --override-edits/--include-accepted flags (recorded on the edited node and honoured at acceptance time), hint edits propagate their open-edit state to the recomposed successor and reconcile the predecessor, and empty path allowlists fail closed. Findings that need operational design (claim TTL vs batch runtime, cascade atomicity with acceptance, family-scope semantics) are ranked in §10.

A full-suite integration pass after the fix wave surfaced six pre-existing test failures (unrelated to the fixes — verified against commit dates): the geometry-enumeration-collapse and shape-parameter tests still target line_of_sight as a bare geometric base, which ISN migrated to an along-relation locus (toroidal_angle_along_line_of_sight) before the previous dependency pin; and two benchmark-runner tests use fixture names whose residues (divertor) no longer parse. These document an incomplete codex-side migration to the along-locus grammar surface and are queued in §10.

§6 — Export, import, and release integrity

The export/import deep-dive found two high-severity data-integrity defects and a cluster of accounting/determinism faults. High: (1) the export query projected the unit exclusively from the HAS_UNIT edge, so any node whose unit lives only on the property exported with an empty unit into the published catalog (fixed — coalesce, matching the codebase's canonical read); (2) curator-only catalog names import without validation_status, are therefore ineligible for the next export, and a full-scope publish then deletes them from ISNC — the round-trip that is supposed to preserve human edits silently destroys them (fixed: import defaults the status with a coalesce that preserves an existing quarantine). Medium, all fixed: import force-flipped every entry to accepted — superseded nodes are now excluded from the write set entirely and genuine no-ops no longer masquerade as writes; four ordering queries treated the scalar physics_domain as a list, silently degrading the advertised topological file ordering to alphabetical; wall-clock timestamps and an embedded HEAD SHA made every export churn all 18 domain files and dead-end the no-change fast path (stamps now derive from the source commit — identical content produces identical bytes); the manifest's exclusion buckets did not close against the published count (new accounting lives in .export_report.json because the manifest schema is closed and validated by the release gate; one semantic correction: excluded_below_score_count is now purely score-based). The 388 dangling links in the published catalog (§7) are pruned by a new export gate with counted, logged accounting. The watermark CAS, import locking, and sn.id-keyed merge idempotency were verified sound.

§7 — Catalog quality (2124 published names)

The strongest single result of the review: every one of the 2124 published names parses strictly and round-trips through the ISN grammar — the grammar and the catalog are fully consistent. Documentation quality is high: in a 68-entry stratified sample, 63 scored clean, with dimensionally consistent equations, explicit sign conventions, plausible ranges, and relevant cross-links throughout; no boilerplate patterns were found. Two suspected faults dissolved on inspection as principled design: the K-vs-eV temperature split is exactly hardware-vs-plasma (0 violations in 63 entries), and the s⁻¹-vs-m⁻³·s⁻¹ source-rate split is exactly plant-injection-vs-plasma-continuity (52/52 correct).

The real faults cluster in a small number of families:

#FaultBreadthRemedy
1Dangling cross-references: structured links: to names absent from the published set, plus dangling inline references in documentation prose388/5783 link edges, 314 entries (14.8%); +74 inlineExport-side pruning gate with manifest count (in flight); ISN-side validator resolving both structured and inline references (§10.3)
2Z-axis generator gap: empty or missing documentation exclusively on the third member of x/y/z coordinate and unit-vector triples6/6 instances on zFix the batch generator; targeted docs regen for the affected names
3Bare "momentum" means momentum source density and collides dimensionally with the differently-defined *_momentum_flux family~30 entriesRename family to *_momentum_source; add validator rule for source/flux families sharing units under near-identical names
4"energy_flux" names carrying particle-flux units (m⁻²·s⁻¹) with docs that admit the mismatch ("despite the energy-flux label…")4 entries vs 24 correct siblingsFold into the particle-flux family; reserve energy_flux for W·m⁻²
5"power_density" used for both W·m⁻³ (volumetric) and W·m⁻² (surface flux); one near-duplicate concept pair (power_density_at_wallenergy_flux_at_wall) with no linking6/69 entries + 1 pairRename the six to *_power_flux_*; deprecate/alias one of the pair
6_at_plasma_boundary momentum entries are surface integrals of a density-like integrand — no standard physical referent; corroborates the already-tracked composer separatrix→plasma_boundary locus issue with a concrete examplemomentum familyRaise the priority of the tracked locus fix
7One-line self-contradictions: electron_source_rate (unit s⁻¹, text says "per unit volume"), toroidal_angle_of_active_limiter_point (unit 1, text says radians), one Hz-vs-s⁻¹ outlier; plus one self-referential broken link (height_of_optical_element)4 entriesFix in the codex graph via sn edit so the next export carries them (ISNC YAML is generated — not hand-edited)

A meta-finding on validation: the official validate_catalog run passes with 0 errors but emits ~600 advisory notes, the dominant class being a "may indicate measurement location — consider using subject (electron, ion)" nudge fired at obviously intrinsic hardware properties (width_of_poloidal_field_coil). Since the specification itself declares the of_<entity> postfix locus to be the authoring convention for instrument properties, this advisory contradicts the spec and buries the one real warning in the stream (an energy with unit 1). The advisory should be suppressed for hardware/geometry bases.

§8 — Lifecycle rules and import robustness

Two disconnected state machines govern a name's life. Operationally, codex runs a seven-stage pipeline (pending → drafted → refining → reviewed → accepted, with exhausted and superseded exits) keyed on graph properties, with claim tokens, TTL leases, and a fail-closed validation gate — this machine works and is well-tested. Governance-side, ISN's models define draft / active / deprecated / superseded with a validator requiring every deprecated entry to name its successor — and this machine is entirely vestigial: every one of the 2124 published entries is draft, no entry anywhere uses deprecates/superseded_by, and nothing in the export path can ever promote, deprecate, or supersede a published name. When a name is renamed in the codex graph, the old name simply vanishes from the next export: catalog consumers who pinned it get silent breakage with no deprecation stub, no successor pointer, and no trail. The graph knows the supersession chain (it maintains supersede edges internally) — the information is simply dropped at the boundary.

Import robustness ("what happens to a catalog after a successful review") had the two genuine holes described in §6 — curator-name deletion on round-trip and unconditional stage-flipping — both now guarded. The locking, watermark compare-and-set, and id-keyed idempotent merge were verified correct. The ISNC release chain is sound: validation gates the release workflow, and the tag carries both the data version and the resolved ISN SHA. Recommendations: (1) emit deprecated stubs with superseded_by for renamed/superseded accepted names at export, activating ISN's designed governance path and giving consumers a migration trail; (2) decide what status: active means for this catalog (e.g. survives N releases, or curator-promoted) and implement the promotion — or delete the status field rather than publish a field that never varies; (3) the ISNC validate workflow should not rely on --summary text alone (known to hide error detail).

§9 — Fixes landed during this review

All commits pushed to main on their respective repositories; both test suites green (ISN: 1648 passed; codex: targeted suites for every touched module).

RepoCommitWhat
ISNddf7fa9Regenerate model types for the reaction-channel qualifiers (closes the vocab-vs-generated-enum drift that opened the session)
ISN81c1416Unit-restatement documentation check: token-boundary matching (the draft's substring test false-positived every single-letter unit) + 7 tests
ISNdae87b8LLM grammar context: every advertised example now parses; retired long form flipped to an anti-pattern; guard test walks the whole context (F1)
ISNd9c4e80Generated-file headers no longer claim live enums face removal; spec header names the real outputs (F9)
ISN4ee656bnormalizing_qualifiers header corrected; two satisfied overlap-allowlist entries pruned (ratchet)
ISNaff701aAGENTS.md disambiguation rules rewritten to the real parser; check-only pre-commit with the codegen drift gate (F6/F7)
ISN515d83cParser keeps prefix operators over a binary terminator; flat model raises an honest error for unrepresentable nesting (F2)
ISNe83e5c0Tests and comments named by capability instead of plan/release labels (five test modules renamed)
codex09acc9fbISN pin bumped past the drift incident; reaction-channel qualifiers verified visible downstream
codexd8708d24Kind derivation reads the ISN base registry; vector kind reachable again, un-breaking MAGNITUDE_OF edges (+12 tests)
codex1c491a9bExport unit coalesce — no more empty units when the HAS_UNIT edge is missing (+ query-contract tests)
codex57808564 e3d8c72e f4d1419bImport integrity: curator-only names stay export-eligible (validation_status coalesce); superseded nodes excluded from the write set; genuine no-ops honest in the report (+ full content-field change detection including non-protected unit/physics_domain)
codex15ca50ef a7b443f8 c2fc7021 a56bb71e 31fffcd1Export integrity: scalar physics_domain equality restores topological ordering; deterministic commit-derived stamps and no per-file SHA churn; Gate B fails loudly without ISN; exclusion accounting closes (in .export_report.json); dangling internal links pruned and counted
codex5ef1efbf c9d0c07b 0021367e 4ec8ec97 4530f03fPrompt repair: all 72 naming-consistency examples round-trip under a guard that reads the real YAML; rule prose reconciled with the live parser; token counts rendered not hand-typed; qualifier-row semantics corrected; VALID_SEGMENTS derived from ISN; DT dual-role wording
codex8a3ce10f 3f4c316d ef2678fb 10d16a5d 91cb77e5 c8894436 201b5f07 24a33482Edit/pipeline protections: rename cascades default-closed with explicit operator opt-ins honoured at acceptance; hint edits propagate open state and block source-less targets; --only phases stop composing; empty LLM reviews fail the cycle instead of scoring 0.0; scoped clears spare the cost ledger; empty allowlists fail closed; prune never injects stages; last pipeline_status straggler gone

§10 — Ranked recommendations

These recommendations are now planned and decision-locked in Systematic Review Remediation — a six-phase plan (deprecation architecture for accepted names only, sn edit validation parity, referential integrity, unit-family repairs, vocabulary curation, pipeline hardening) with the governing decisions recorded there. The list below is retained as the review's original ranking by leverage per unit effort; items 1–5 close whole fault clusters.

  1. Referential-integrity validation on both sides of the boundary. Export prunes and counts dangling links (in flight); add an ISN semantic check that resolves every structured and inline name reference, failing the ISNC build on misses. Closes the 14.8%-of-entries defect surface permanently.
  2. Deprecation trail at export. Emit deprecated stubs with superseded_by for renamed/superseded accepted names, activating ISN's dormant governance model. Without it every rename is a silent breaking change for consumers.
  3. Fix the z-axis batch generator and regenerate documentation for the six affected coordinate/unit-vector names.
  4. Curate the two LLM-fed vocabularies. Dedup processes.yml (synonym families listed in §4) and gate or retire the ~16 physical_bases catch-alls; add a curation gate so rotation harvests cannot reintroduce synonyms. These sets otherwise erode the closed-vocabulary guarantee release by release.
  5. Catalog unit-family repairs via sn edit: momentum→momentum_source family rename, the four energy-flux dimension flips, the six power-density flux outliers, and the four one-line self-contradictions. Each closes a cluster, and all must go through the graph so exports carry them.
  6. Enforce canonical qualifier intra-order (F4) using the category ranks, mirroring the zone mechanism — verified to affect at most one published name, so the change is cheap now and only gets more expensive.
  7. Suppress the "measurement location" advisory for hardware/geometry bases — it contradicts the of_<entity> authoring convention and buries real warnings (600-line noise floor on a clean catalog). Periodically reconcile the naming-consistency rule prose against the live parser too: the example guard now catches drifted examples, but rule text prescribing retired forms is what produced the 37-example hole.
  8. Derive the MCP grammar-tool payloads from get_grammar_context() instead of hand-maintaining a parallel copy — the two surfaces had already half-drifted apart when found.
  9. Operational pipeline hardening (design-level): claim-TTL heartbeat vs batch runtime; cascade atomicity with acceptance (or constraint-collision handling); family-scope semantics (currently a parent-subtree, documented as siblings); docs-edit claim preconditions and protection filtering; single-transaction reset/clear; declare the new edit_override_edits/edit_include_accepted node properties in the LinkML graph schema (persisted raw today — verified safe, but the schema should own them); enrich_parents claim verify-guard (the one pool without it).
  10. Finish the codex migration to the along-locus grammar surface: six pre-existing test failures (geometry-enumeration collapse, shape-parameter surface, benchmark fixtures) still target the retired bare line_of_sight carrier and non-parsing fixture names — update the collapse feature and fixtures to the along-relation forms.
  11. Reconcile the two parse contracts (F5): decide whether unregistered _at_ loci are valid, then make validate_round_trip and parse_standard_name agree — or document the IR entry point as diagnostics-only.
  12. Semantic gating for dual-role reaction-channel tokens (F8) once a second dual-role family appears; today the exposure is contained.
  13. Vocabulary hygiene tail: resolve the halo triple-role and the regions/locus halo_boundary typing conflict; derive regions.yml from the region-typed loci; retire binary_operators.yml if truly superseded; dedupe the Transformation/Decomposition enums; sweep the remaining RC-tagged provenance banners in vocabulary YAML comments.