an.semantic#
The semantic layer: one versioned vocabulary registry, methods, aspects and the matcher.
ADR 0003 (the structured ↔ semantic spectrum) and ADR 0002 (capability-based applicability). Defined once, in the core, for every genre (design principle 3):
the vocabulary — every name a document may spell, as an
Entry(id, version, kind, title, description, params as JSON Schema with defaults, examples, requires, accepted levels, expand): action and entity kinds, easings, camera moves and IR fields from the core (an.semantic.seeds); motion and expression presets, methods and aspects from the genres (an.genres.Genre’svocabularyandaspects);methods and aspects — a
Methodis an entry of kindmethodrealising anAspect, whose default chain ends in a method that requires nothing or in the recordedNOOP;the queries —
applicable(),why_not()andresolve()(with aPolicy), all calls to the one matcheran.capabilities.missing();the generated surfaces — the
an iterateprompt (an.semantic.prompt), the skill’s vocabulary section (an.semantic.docs), the MCP surface (an.mcp), and the shot’s vocabulary digest for the compile key (an.semantic.digest).
Nothing here imports an.ir at module level, and nothing below the IR ever
calls an LLM.
>>> from an.semantic import entry, vocabulary
>>> entry("action.tween").kind
'action'
>>> any(e["id"] == "easing.ease_in_out" for e in vocabulary())
True
Functions
|
The methods of |
|
The registered aspect |
|
|
|
|
|
The problems with the registered aspects and methods (empty: sound). |
|
Every entry (registered and viewed), filtered by |
|
The entry with this id; |
|
The entry of |
|
Every registered method of an aspect: its chain first, in order, then the rest. |
|
|
|
Register an aspect and its default chain. |
|
Register a vocabulary entry under |
|
Choose the method that realises |
|
Every entry as data (what the MCP surface returns), filtered by |
|
What |
Classes
|
Something every asset of a kind gets (locomotion, speech, blink, …). |
|
One method choice in a policy or a request: |
|
One vocabulary entry: a named, versioned, described, parametrised recipe. |
|
A way of realising an aspect (ADR 0002): an entry of kind |
|
One unmet requirement term and what would meet it. |
|
Per-aspect method orders set by a style (study_the_masters §4). |
|
What |
Exceptions
A name or id is not in the vocabulary; the message lists what is. |
|
A vocabulary entry, aspect or policy is malformed or collides with a registered one. |
- class an.semantic.Aspect(name, chain, applies_to=frozenset({}), description='', declared_by='', records_fallback=False)[source]#
Bases:
objectSomething every asset of a kind gets (locomotion, speech, blink, …).
chainis the default order of method ids, first applicable wins; its last link requires nothing, or isNOOP.applies_tois the entity kinds it makes sense for (empty: all); for any other kind the aspect resolves to the recorded no-op.- declared_by: str = ''#
The asset-document field an asset declares its request in (a character’s
gait,speech): a declared method choice, reported as such bydescribe_assetand honoured by the compiler.
- records_fallback: bool = False#
Record falling down the chain even when nothing was requested (reason
missing, so--strict-assetssees it). For an aspect whose fallback is a behaviour the asset never had before — speech’s pulse on a baked face — rather than today’s long-standing default (a legless walk).
- class an.semantic.Choice(method, args=<factory>, version=None)[source]#
Bases:
objectOne method choice in a policy or a request:
previz’sFormulaCallplus a pin.>>> Choice.of({"method": "speech.mouth_flap", "args": {"shapes": 3}}).args {'shapes': 3} >>> Choice.of("loco.rock").method 'loco.rock'
- class an.semantic.Entry(id, kind, version='1', name='', title='', description='', usage='', params=<factory>, examples=(), requires=(), levels=frozenset({'a', 'b-name'}), aspects=(), expand=None)[source]#
Bases:
objectOne vocabulary entry: a named, versioned, described, parametrised recipe.
idis the persisted identifier (dotted:motion.walk,loco.legged_cycle);nameis how a document spells it (walk; defaults toid), looked up perkind.versionchanges whenever the meaning changes for the same params; the versions of the entries a shot uses fold into its compile key.paramsis a JSON Schema object;properties.*.defaultare the defaults ({}when the entry takes none).aspectsnames the aspects that using this entry resolves (awalkresolveslocomotion), so the digest of a shot can include the methods it may resolve to.usageis the longer note the generated surfaces print under the one-sentencedescription(how a document spells it, what bites).
- classmethod from_json(data, *, expand=None)[source]#
An entry from its JSON form (what
to_json()writes, or another package exports — previz’s formulas): the explicit loader, amethodkind giving aMethod.- Return type:
>>> e = Entry("camera.demo", "camera_move", name="demo", description="d") >>> Entry.from_json(e.to_json()) == e True
- class an.semantic.Method(id, kind='method', version='1', name='', title='', description='', usage='', params=<factory>, examples=(), requires=(), levels=frozenset({'a', 'b-name'}), aspects=(), expand=None, aspect='', remedies=<factory>)[source]#
Bases:
EntryA way of realising an aspect (ADR 0002): an entry of kind
method.remediesoverrides a capability’s own remedy per requirement term (a method can say “split the legs into two slots with hip pivots” where the capability only says “add legs”).>>> m = Method("loco.rock", aspect="locomotion", name="rock") >>> m.kind, m.aspect, m.requirement_free ('method', 'locomotion', True)
- class an.semantic.Missing(term, remedy)[source]#
Bases:
objectOne unmet requirement term and what would meet it.
- class an.semantic.Policy(order=<factory>)[source]#
Bases:
objectPer-aspect method orders set by a style (study_the_masters §4).
The parsed form of a style document’s
policy:block; precedence when resolving is the author’s request, then the shot, then the style, then the aspect’s chain (layered()).>>> p = Policy.of({"locomotion": ["loco.bob", {"method": "loco.glide", "args": {"bob": 0}}]}) >>> [c.method for c in p.choices("locomotion")], p.choices("speech") (['loco.bob', 'loco.glide'], ())
- class an.semantic.Resolution(aspect, method, args=<factory>, source='chain', substitution=None, considered=(), skipped=(), choice=None)[source]#
Bases:
objectWhat
resolve()chose: the method, its args, where the choice came from.sourceisrequest,policy,chainornoop;substitutionis the record when the choice departs from what was asked (Nonewhen it did not);consideredis the trail of methods tried before it, each with what it was missing;skippedthe policy’s entries among them (a policy is an order: an entry that does not apply is passed over, information for whoever records the choice, never a substitution);choicethe request or policy entry that was chosen, as written (its ownargs, without the method’s defaults),Nonefor a chain link.
- exception an.semantic.UnknownEntryError[source]#
Bases:
VocabularyError,KeyErrorA name or id is not in the vocabulary; the message lists what is.
- exception an.semantic.VocabularyError[source]#
Bases:
ValueErrorA vocabulary entry, aspect or policy is malformed or collides with a registered one.
- an.semantic.applicable(aspect_name, subjects)[source]#
The methods of
aspect_namethat apply tosubjects, the default chain’s order first.
- an.semantic.aspect(name)[source]#
The registered aspect
name;UnknownEntryErrorotherwise.- Return type:
- an.semantic.check_registry(*, owner=None, capabilities=True)[source]#
The problems with the registered aspects and methods (empty: sound).
ADR 0002 decision 5 as a check: every aspect’s chain names methods of that aspect, and its last link requires nothing or is the recorded
NOOP; one spelling is one entry; and (capabilities) every requirement names a registered capability.ownerlimits it to one genre’s aspects and entries.an.genres.register_genre()runs the chain checks per genre;an.genres.load()runs the capability check once every genre is in, so a genre needing another’s capability does not depend on load order.
- an.semantic.entries(*, kind=None, owner=None)[source]#
Every entry (registered and viewed), filtered by
kind/owner, in a stable order.
- an.semantic.entry(entry_id)[source]#
The entry with this id;
UnknownEntryErrornaming the known ids otherwise.- Return type:
- an.semantic.lookup(kind, name, *, aspect=None)[source]#
The entry of
kinda document spellsname(for methods, withinaspect).
- an.semantic.methods_of(aspect_name)[source]#
Every registered method of an aspect: its chain first, in order, then the rest.
- an.semantic.register_aspect(a, *, owner='an', replace=False)[source]#
Register an aspect and its default chain. Checked as a whole by
an.semantic.check_registry()(a chain may name methods registered after it, within the same genre).- Return type:
- an.semantic.register_entry(e, *, owner='an', replace=False)[source]#
Register a vocabulary entry under
owner: ONE entry per id, and per spelling.A name means one thing everywhere (
push_inis one entry, an#257): a second entry under a taken id — registered or provided by a view — or under a taken(kind, name)(within an aspect, for methods) raises, unlessreplace=Trueis passed explicitly, and then the replacement is recorded (replacements()). Re-registering the same entry is a no-op.- Return type:
>>> from an.semantic.entries import Entry >>> register_entry(Entry("demo.push_in", "camera_move", name="push_in"), owner="demo") Traceback (most recent call last): ... an.semantic.entries.VocabularyError: camera_move 'push_in' is already defined by 'camera.push_in' (owner 'an'); ...
- an.semantic.resolve(aspect_name, subjects, requested=None, *, declared=None, policy=None, entity='', entity_kind=None)[source]#
Choose the method that realises
aspect_nameonsubjects.requestedis the author’s explicit choice (a method id, its spelling in the aspect —"hem"for locomotion —, or{method, args, version});declaredthe asset’s own declaration for the aspect (the fieldAspect.declared_bynames), placed byDECLARED_OUTRANKS_POLICY(the request when nothing was requested, or the policy’s last entry);policythe layered shot/style policy;entity_kindthe asset’s kind, checked against the aspect’sapplies_to. Never raises for a method that does not apply: it falls back and records why.- Return type:
- an.semantic.vocabulary(*, kind=None, owner=None)[source]#
Every entry as data (what the MCP surface returns), filtered by
kind/owner.
- an.semantic.why_not(method, subjects)[source]#
What
methodis missing onsubjects, each with its remedy (empty: it applies).
Modules
Describe an asset: what it affords, and per aspect what applies and what is missing. |
|
Which vocabulary entries a shot names, at which versions: the shot's vocabulary digest. |
|
The vocabulary section of the downstream |
|
The vocabulary as a published, code-free contract file: |
|
The three queries and the policy (ADR 0002 decision 4): |
|
The |
|
The one vocabulary registry (ADR 0003 decision 6): entries and aspects, by owner. |
|
The core's vocabulary: views over the kind and easing registries, camera moves, IR fields. |
|
View spaces: what a camera move moves through, defined once for every engine (an#257). |