Population, zone and aggregation tokens now carry definitions that render.
_vocabulary_definitions reads the three vocabularies as well as
the locus registry, the physical bases and the geometry carriers, and
select_conventions emits an applied definition for a
population, zone or aggregation token that carries one.
Shape chosen for the definition-only entry: a sibling shape,
AppliedDefinition(token, segment, definition), carried on
AppliedConventions.definitions beside
concepts. AppliedConcept keeps its required
phrase, equation and
restates_equation; no phrase or equation was invented to fill
a required field. The sibling also lets the two be told apart: a concept
names a shared phrase or equation, a token definition states only what the
token means.
The three files changed from lists to token-keyed entries in which each
entry maps its token to that token's definition, so a token without a
definition still loads. This is not the root-keyed shape the locus registry
and physical bases use: the codegen token extractor recognises a root key
only for loci, carriers, bases,
operators and axes
(grammar_codegen/spec.py), and the cross-segment uniqueness
lint reads a bare mapping's keys as its token list
(tests/grammar/test_vocab_uniqueness.py). A root key
populations: is extracted as the single token
populations, which would have broken the generated enums and
the drift gate — measured by loading a scratch spec through
IncludeLoader. The token-keyed shape satisfies both readers
unchanged. Adopting the root-keyed shape is a one-line addition to that
root-key tuple, in a file outside this node's write scope; it is recorded
as a follow-on rather than made here.
Definitions moved from comments, not invented. Seven populations carry one
(fast: Non-thermal / energetic population.), two
aggregations (total: Summed over sub-populations, species
or additive contributions.), and four zones whose comment states a
position (upper, lower, inner,
outer). The nine remaining zone tokens
(core, edge, pedestal,
separatrix, divertor,
scrape_off_layer, front_surface,
back_surface, wetted) record no meaning in a
comment, so they were left undefined rather than filled in.
The level of the corpus these tokens are read from — the conventions
accessor — emits the definition for a name carrying the token. Its output
for lower_outer_squareness_of_flux_surface is:
token: lower segment: zone definition: Lower vertical position. token: outer segment: zone definition: Outer radial position.
And for total_plasma_current, whose only defined token is the
outer aggregation:
token: total segment: aggregation definition: Summed over sub-populations, species or additive contributions.
A token without a definition loads and contributes nothing:
core_electron_temperature parses, and
select_conventions returns an empty
definitions tuple for it.
Measure. tests/grammar/test_token_definitions.py asserts the
loaders against Population, Aggregation and
Zone — the enums are the token record the plain lists held —
so load_populations and load_aggregations return
the same sets and load_zones the same ordered tuple. The gate
(this file plus test_vocab_uniqueness,
test_conventions, test_codegen_drift,
test_segment_vocabulary_additions,
test_model_grammar_sync) ran 71 passed, 7 xfailed
(EXIT=0) at head against 66 passed, 7 xfailed (EXIT=0) at base — five
added tests, zero added failures. The codegen gate passing is the direct
check that the entries shape still yields the full token list.
Negative control, declared as removing the definition emission. With
definitions=definitions_applied dropped from the
AppliedConventions construction and everything else held
fixed, tests/grammar/test_token_definitions.py ran 2 failed, 3
passed (EXIT=1), failing
test_a_definition_renders_for_a_name_carrying_the_token and
test_a_zone_definition_names_the_segment_the_token_was_used_in
— both of which pass at head. The three that still pass are the loader
identity tests, the definition-presence test and the
contributes-nothing test, none of which routes through the emission. Log:
negative-control.log in the run directory.
No figure accompanies this fragment: the change is a data shape and an accessor field, and the rendered definitions above carry it. The figure directory given to this node is left empty.