ID |
|
|---|---|
Status |
Backlog |
Bucket |
cleanup |
Priority |
4 |
Theme |
model-cleanup |
Created |
2026-09-01 |
Updated |
2026-09-01 |
The authored presence guard re-spells the wire address instead of carrying it
Two records now hold the same three components with the same two invariants. The model’s
WireAddress carries (outerArgName, path, list) and rejects a blank argument name and an empty
path. The command layer’s PresenceGuard.FieldPresent carries (outerArgName, path, list) and
rejects a blank argument name and an empty path. ConditionCommands.presenceOf is the whole
distance between them: it reads the three components off one and passes them to the other.
WireAddress has exactly one field (FkTargetConditionFilter.field()), one construction site
(FieldBuilder’s reference-field arm) and one reader (presenceOf`), so it exists only to be
copied one step later into an identically shaped record.
Why this is worth an item rather than a shrug: an invariant spelled twice is two places a fix has to land, and a component added to the wire address later reaches the guard only if someone remembers the second record. The tree already states that principle at `WireMapChain’s javadoc, about this very descent ("the shape is one decision about generated code and not two, and two spellings of it are two places a fix has to land").
The copy is justified in javadoc by two claims that do not hold against the tree:
-
presenceOf’s javadoc calls it "the same produce-time narrowing `ReachPath#narrowperforms".ReachPath.narrownarrows a type,List<JoinStep>down toList<JoinStep.Hop>, and refuses a step the reach cannot carry; it keeps the model’s ownJoinStep.HopandOnvalues. LikewiseAuthoredMethodRefis a real projection: it drops the reflected reference’s signature facts and keeps the address.presenceOfdrops nothing and refuses nothing. -
PresenceGuard.FieldPresent’s javadoc says the address is "narrowed off the model’s `WireAddressat production", andpresenceOfsays the point is that "the renderer spells a traversal without reading the classified model".ConditionGlueRendereralready importsrewrite.model.CallParamandrewrite.model.CallSiteExtractionand reads both, and command records already carry model value types across this same seam:ColumnTermcarries aColumnRef,ArgBindingcarries aCallParam,CallWrapcarriesJoinStep,On,OrderBySpec,ParentCorrelationandTableRef. There is no boundary here for the copy to be respecting.
What to do
Have PresenceGuard.FieldPresent carry the WireAddress it is made from, so the guard’s shape is
the address’s shape by construction rather than by coincidence, and presenceOf becomes the
wrapping it actually is. That is the house shape at this seam, the one ColumnTerm and
ArgBinding already use. Delete the duplicated validation with it. Then correct the two javadoc
paragraphs above so they state what the record does, and drop the ReachPath.narrow analogy
rather than repairing it.
If the alternative is preferred, that the command layer must not name a model record here, then the justification has to be a boundary that exists: state which rule the surrounding command records break, or accept that they set the convention. What should not survive is a copy defended by a narrowing that does not narrow.
A smaller adjacent question, for the same pass
The generated arm elides its guard when the term is proven non-null (appendGuardedAnd emits the
bare statement when ColumnTerm.nonNull() holds). The authored arm has no such elision: a filter
field that is statically non-null under a statically non-null argument still gets a runtime
presence test that is always true. The fact needed to elide it is effectiveNonNull && rf.nonNull(),
computed two lines below the WireAddress construction site and already passed to the implicit body
param. Emitting the always-true test is harmless, so this is tidiness, not correctness. Note that
Predicate.Authored’s compact constructor currently forbids the honest datum for that case: a
non-empty reach must carry `FieldPresent, so a statically-present field cannot say Always.
Whoever picks this up decides whether the invariant should read "a non-empty reach carries a
presence decision" instead, or whether the elision belongs in the renderer’s spelling of a
FieldPresent guard it can prove constant. Do not weaken the invariant without replacing what it
buys, which is that an unguarded generator-minted EXISTS is unconstructable.
Provenance
Found at the In Review to Done gate on the item that introduced both records, the optional-filter
@reference join fix. Nothing here is a defect in that item’s behaviour: the emitted guard is
correct, the full reactor is green, and the fix’s own pins are load-bearing. This is the shape of
the data the fix carries, filed rather than bounced.