ReferenceOperatorsfrontend.presentation.resolve

frontend.presentation.resolve

Generated by docs/scripts/generate-docs.mjs from operators/frontend-presentation-resolve/operator.md and operators/frontend-presentation-resolve/operator.json. Edit the source, not this page.

Binding

FieldValue
idfrontend.presentation.resolve
domainfrontend
resources.profileluna
resources.requires
policy.webSearch
policy.grammarBound
policy.imageGeneration

Job

Resolve every application-owned presentation property on one already-composed tree to exactly one published rule, emit its class and its verifiable contract claim, and stop at the smallest owning gap instead of inventing a value.

Structure arrives decided

Structure, element order, Grammar component selection, copy, data and behaviour arrive decided, and so does the owner ceiling: it is carried by the direction this branch resolves, never re-declared here. This operator only answers, for each node the application owns, which value each presentation property takes and which rule authorizes it. It changes nothing about what the tree renders.

No fabricated rule

A rule exists only if the bound knowledge topic publishes its identifier, and that inventory is frozen for the whole run. An emitted identifier absent from the inventory is UNKNOWN_RULE. A class that contradicts its identifier is rejected: the rule number is an ordinal on the value scale, so GAP-5 renders gap-6 and PADDING-5 renders p-6, and writing the ordinal as the step is the defect this check exists to catch. When no published case matches the observed condition the run stops with RULE_MISSING naming that node; it does not choose a nearby value, round to the closest step, or copy a neighbouring node. The operator never edits knowledge: a missing case goes back to the knowledge owner, and the same tree is resolved again once the case is published.

Grammar is read as published, and consulted first

The owned relationships come from the published package’s own data-contract claims, never from Grammar source. A property a component already owns resolves to that component, emits no application class, and names the rule the component satisfies; that ordering makes reimplementation impossible rather than merely discouraged. An application class that reimplements an owned relationship, overrides Grammar anatomy or sits off the closed scale is removed with its own row, per node and never silently.

The scope is every folder the write set touches

The tree the direction names is the surface, not the boundary. A page reaches its final appearance through the leaves and branches it composes, so a leaf that repaints a control, or a branch that rebuilds a shell band, changes the same surface the page does and is resolved in the same pass. The scope is therefore every leaf and branch folder the application owns that the declared write set touches — packages/ui/** and src/components/{leaves,branches}/** as much as src/components/{pages,blocks}/** — and not only the target surface’s own tree. A folder the write set does not touch is out of scope, because resolving it would widen a change nobody asked for; a folder the write set does touch is in scope even when the direction never named it, because the alternative is a resolved page sitting on an unresolved leaf.

A Grammar object’s className is never a resolution target

There is one thing this operator may not resolve, however the tree presents it: a className on a Grammar object. Presentation may not “add padding, typography or paint inside Card, Input, Button or another Grammar object”, so the class is not a property awaiting a value — it is a reach through an anatomy the family owns. It is removed at step 7 and recorded under ## Removed, with overrides Grammar anatomy when it repaints anatomy, or with refused by <RULE> Case <n> naming the case that answered no. When the relationship the class was reaching for is real and the component publishes no prop for it, the removal is joined by a ## Gaps row and the family owner gets the question. What never happens is a rule being selected for it: choosing a value would legitimise the reach and hand the node two owners for one property.

A forbidden class is removed, not ruled

When the only case that names an application class states a condition the node does not meet (an accent foreground that SURFACE-4 allows solely inside a raised band, written on an unraised row), the property is not missing a rule: the rule has answered, and the answer is no. The class is removed in the removal step, the property falls back to what the node inherits, and the removal is recorded with the case that refused it. RULE_MISSING is reserved for a property no published case addresses at all.

A missing public path is a gap, not a stop

When Common exposes no public path for a relationship the application legitimately needs, the node keeps its application class and the branch records a row under ## Gaps naming the node, the property and the missing path. The branch does not stop: a recorded workaround is visible to the family owner and to the next audit, while a stop here would only trade one silent value for a blocked chain.

The contract is a claim, not a verdict

Every application-owned node publishes the identifiers it claims. data-contract records which rules a node claims to satisfy and never asserts that the node passes; the claim exists so a later audit can contradict it, and one rule stays selectable as [data-contract~="GAP-4"]. With emission off the tree carries nothing and the receipt alone holds the claims.

The loop is counted

An audit that sends its findings back here starts another round, and a round that repeats itself is not progress. The number of audit receipts this session has fed back is counted at the gate, and a run beyond maxRounds stops with NO_PROGRESS rather than resolving the same tree a third time.

Boundary

Context is read-only. The operator writes only response/ of its own branch: the resolution receipt, the inventory and the resolved tree. It does not change DOM structure, element order, Grammar component selection, copy or behaviour, write a class for a property a Grammar component already owns, reach into Grammar anatomy with a selector or a passed class, edit knowledge, publish Grammar, write product source, or record a verdict, score or pass claim on any node.

Context

AliasBindRequired
@knowledge/ui/presentationthe closed rule inventory read at its fingerprint; the only source of valid identifiersyes
@grammar/corethe published package’s owned relationships, read as published and never from Grammar sourceyes
@workspaces/fethe routed checkout the composed tree belongs to, read at the frozen headyes

Inputs

KindFromRequired
frontend-direction-decisionfrontend.direction.decide, the intent and the owner ceiling this resolution works inside; never a source of presentation valuesyes
frontend-surface-auditfrontend.surface.audit, the findings that opened this round; present only when this is a loopno

Requirements

FieldTypeDefaultAsk
maxRoundsnumber2How many audit-to-resolve rounds this surface may take before the loop is called off
contractEmissionchoiceonon writes the claim token list onto the tree, off leaves the receipt as the record
resumetokennullThe blocked branch’s token when re-entering after a stop

Steps

#StepParamsReadsWritesStops with
1Validate the gate and resume, and count the audit roundsresume, maxRoundsrequest/request.json, input frontend-surface-audit when this is a loop, @workspaces/fe at the frozen headINVALID_INPUT, SOURCE_DRIFT, NO_PROGRESS
2Bind the authority@knowledge/ui/presentation (every topic with its fingerprint and rule inventory), @grammar/core (the published package’s owned relationships), @workspaces/fe (the routed head and the frozen tree), input frontend-direction-decision, @tools/git, @tools/registryKNOWLEDGE_UNBOUND, GRAMMAR_UNPUBLISHED
3Walk the tree once under the owner ceiling the direction carries@workspaces/fe (the frozen tree, in document order), input frontend-direction-decisionOWNER_CONFLICT
4Determine the owner of every present property@grammar/core (the owned relationships), @workspaces/fe (the properties the node presently carries)response/data/inventory.json
5Select one presentation rule per remaining application-owned property@knowledge/ui/presentation (the cases the bound topic publishes)RULE_MISSING
6Classify a missing public path as a Grammar gap@grammar/core (the relationship under question), @knowledge/ui/presentation (the capability-gap marking)
7Remove what the tree should not carry@workspaces/fe (the application classes on the node), @grammar/core (Grammar anatomy and the closed scale)
8Emit the contract claims onto the application-owned nodescontractEmission@knowledge/ui/presentation (the frozen rule inventory)UNKNOWN_RULE
9Emiteverything aboveresponse/artifacts/<target>.resolved.tsx, response/data/inventory.json, response/response.md, response/response.json

Step 8 claims only what a node can carry: a property the application owns on a Grammar component’s className carries no attribute, because the component forwards className and publishes no prop for the relationship, so its rule is recorded under ## Gaps instead of being emitted. Forwarding data-contract from every Common component that accepts className is a Grammar change and belongs to the family owner, not to this operator.

The walk visits every node in document order and records a stable node path; a node outside the ceiling the direction carries is observed and never mutated. Steps 4 to 8 run per node, so a single tree yields one decision per node and property. The receipt authorizes a later audit to measure the rendered result against the claims; it proves nothing about how the tree renders.

Outputs

KindFileTypeRequired
frontend-presentation-resolutionresponse/response.mdmdyes
inventoryresponse/data/inventory.jsondatayes
resolved-treeresponse/artifacts/<target>.resolved.tsxartifactyes

Stops

CodeDisposition
INVALID_INPUTterminate
SOURCE_DRIFTterminate
OWNER_CONFLICTterminate
KNOWLEDGE_UNBOUNDterminate
UNKNOWN_RULEterminate
RULE_MISSINGterminate
GRAMMAR_UNPUBLISHEDterminate
NO_PROGRESSterminate

Next

WhenOperator
the tree is resolved and its values must be written into product sourcefrontend.source.apply
a gap needs a family component before the next round, so a person publishes it and the same tree is resolved againfrontend.presentation.resolve

Source: operators/frontend-presentation-resolve/operator.md.