Skip to content

The keyword registry

petroscript.eclipse.catalog.REGISTRY holds one row per keyword the render writes, the import reads, or the OPM Flow manual documents. A row says what the keyword is, how OPM Flow treats it, and where PetroScript stands with it:

FieldValuesMeaning
sectionRUNSPEC … SCHEDULEthe card’s home section
rolesection, toggle, dimension, directive, report, array, program, table, event, step, vector, recordwhat kind of card it is
flowreads, ignores, rejectsFlow’s treatment, with the manual’s words in reason for the last two
statussupported, non-goal, not-yetPetroScript’s standing, with the refusal in reason for the last two
radiala token or Nonethe card’s spelling on a radial grid (PERMX → PERMR)
recordedboolrecorded on the import result rather than read into the model
importsboolread by the importer; False with the reason in import_reason (a render-only card the importer does not invert yet)
capturedboola run-instruction card captured onto the run object rather than the model
measuredapplies, partial, ignores, rejects, unknown, other-binary or Nonehow the measurement (flow_measured.json) classed the card; flow is the registry’s word for it
record_fieldsitem namesthe record items in deck order where the record renderer writes the card; empty otherwise
capacityboolthe card sizes what Flow allocates (WELLDIMS, TABDIMS, …)
bodyrecords, lines, line, spanhow the deck reader takes the card’s body (UDQ and ACTIONX lines, the TITLE line, a SKIP span)
well_patternboolthe card’s well-name item is a pattern Flow binds at the card’s deck position
program_measuredboolthe grid program’s GRID or EDIT place on this array was measured card by card

KEYWORD_CATALOG is the derived name-to-section view of the authorable rows: supported, not recorded, not lexical (850 of 1,548). A recorded directive is restated from an import, never authored; the reader owns the lexical words; non-goal and not-yet rows have no spelling. Laws that mean “registered” read REGISTRY itself. rows(...) and names(...) query by any column: names(role="program"), names(capacity=True).

The importer’s refusal hints are rows: NON_GOALS for what is not a goal, NOT_INVERTED for what the importer does not read yet (a not-yet row when the render does not write it either), FLOW_IGNORES and FLOW_REJECTS for Flow’s own treatment, RECORDED_DIRECTIVES and CAPTURED_RUN_FIELDS for what the importer records or captures instead of modelling, LEXICAL_KEYWORDS for the reader’s own words. The coverage metric is the count of rows marked not-yet or imports=False.

The manual index. src/petroscript/eclipse/manual_keyword_index.json is the OPM Flow Reference Manual’s own keyword index, read from the PDF’s outline by tools/manual_keyword_index.py: one entry per keyword subsection in the keyword chapters, with the section the chapter names and the page the page’s footer prints, under the edition and the PDF’s sha256 (1,463 entries, 1,149 names; SUMMARY vectors are tables in the manual, not entries). It holds facts about where each keyword is documented and no text of the manual. Every name in it has a row: the ones PetroScript has no statement for and the importer does not read are not-yet rows seeded from the index (_MANUAL_ONLY, 632 names as of 2026-09-06), each citing its subsection and page. A name the manual lists in several sections is filed under its first. INCLUDE is the reader’s and is not a row. The law is tests/test_manual_keyword_index_law.py: nothing the manual documents is unlisted, every seeded row cites its source, the seeded rows change nothing authorable, and the generator reproduces the committed index from the PDF. Rows: 1,548 (864 supported, 649 not-yet, 35 non-goal).

Acknowledgement. The index’s names, sections, subsections and pages were read in the “OPM Flow Reference Manual” (OPM Flow 2025-10, Rev-0), Copyright 2025 by the Open Porous Media team, licensed under CC BY-SA 4.0. The file holds those facts only, and like the rest of PetroScript it is Apache-2.0; NOTICE at the repository root (shipped in the wheel’s metadata) acknowledges the manual as the source consulted.

The registry lives in petroscript.eclipse.catalog, a leaf module that imports nothing from PetroScript, so the reader, the model, the compiler, the importer and the comparator all read the same rows. The section lists, the program cards the render merges and the importer sites, the report cards whose record is a set of mnemonics, the RUNSPEC-only toggles, the radial spelling, the reader’s line blocks, title line and skip spans, the well-pattern cards, the capacity cards, the record renderer’s schemas and the arrays whose program section was measured are names(...) queries over it or its columns, not copies.

  • Every card literal the render writes and every key the import handles is a row, in its section (tests/test_keyword_registry_law.py).
  • Every token of the grid-array kind table is an array row.
  • Every supported card row renders in a committed example snapshot or is pinned by name with the reason it stays uncovered, and has an import handler or carries imports=False with its reason (tests/test_keyword_coverage_ratchet_law.py). A non-goal row is handled by its refusal, and the section headers and lexical words are not cards.
  • The verdict classifier’s slate, directive and report tables are registry queries; measured on the cached verdicts, the swap moved no row.

Add its row, with its section, to src/petroscript/eclipse/keyword_catalog.json, give it a role in _ROLE_NAMES if it is not a plain record, and if Flow ignores or rejects it, or PetroScript refuses it, put the manual’s words in FLOW_IGNORES, FLOW_REJECTS or NON_GOALS. The importer’s refusal hints, the target’s ignored-card reasons and the recorded directives read from those tables; the laws tell you what else the new row needs.

The registry tracks the manual; the surface tracks the corpus. A row costs nothing on the authoring surface, and a verb exists only for a supported row.

PetroScript is licensed under the Apache License 2.0. © 2026 Blauweiss EDV LLC. PetroScript by Blauweiss AI.For AI agents: llms.txt