Repository navigation
fix(sdl): namespace named-ACL, bare content-item, compact workflow-step and variation member references when a module is imported #1590
Description
Gap Claim
Module expansion leaves some reference spellings unnamespaced in fields that it does rewrite. The rewrite looks each value up by exact match in the named map that symbol_index() builds (raes/_module_symbols.py), and the map has no entry for the spellings below, although purpose-bearing fields accept them. ADR-053 lists "content", "relationships", "objectives" and "qualified runtime references" among the surfaces composition must update.
The spellings, labelled as ADR-076 §3 and raes/_declarations.py label them:
- Named ACLs,
infrastructure.<infra>.acls.<acl>: a canonical address (ADR-003 §2;_declarations.py:385-394, no alias). - Content items written by their bare item name
<item>: a lookup alias (aliases=(item.name,),_declarations.py:415) of the canonicalcontent.<content>.items.<item>. The named map holds only the qualified form. - Workflow steps written in the compact form
<workflow>.<step>outside objective windows (objective windows already rewrite it,raes/composition/_terminal.py:211). - Variation members and alternatives: canonical
variation_points.<point>.members.<member>andvariation_points.<point>.alternatives.<alternative>, or compact<point>.<member>and<point>.<alternative>.
Reproduced on dev cf8b430 with parse_sdl_file on a root that imports the module as first (and as first plus second), and by reading the expanded document (skip_semantic_validation=True):
- Named ACL and bare content item. Module: switch
lanwith infrastructurelanand ACLa1; computeweb; contentfixtures(dataset onweb, itemseed-file); relationshipsacl-edge: {type: connects_to, source: web, target: infrastructure.lan.acls.a1}andrel: {type: depends_on, source: web, target: seed-file}; exportsnodes: [lan, web],infrastructure: [lan]. It validates alone. Imported once, it fails withRelationship 'first.__private.acl-edge' target 'infrastructure.lan.acls.a1' does not reference any defined targetable element;relvalidates and binds the module's own item. Imported twice, it also fails withRelationship 'first.__private.rel' target 'seed-file' is ambiguous; use one of: content.first.__private.fixtures.items.seed-file, content.second.__private.fixtures.items.seed-file(and the same forsecond.__private.rel). The expanded values stayinfrastructure.lan.acls.a1andseed-file. Objectivetargetsgo through the same map (_terminal.py:222). - Compact workflow step. Module: workflow
wf(stepdone, typeend), a time domain and clock, and temporal constrainttcwithsubject_refs: [wf.done]; exportsworkflows: [wf]. It validates alone. Imported, it fails withTemporal constraint 'first.__private.tc' subject_ref 'wf.done' does not reference any defined element; the expanded value stayswf.done(subject_refsare rewritten through the named map,_terminal.py:110). - Variation members and alternatives. Module: subset point
pick(membersbase,extra), alternative pointalt(alternativesa1,a2), and temporal constrainttcwhosesubject_refsname one ofvariation_points.pick.members.base,pick.base,variation_points.alt.alternatives.a1oralt.a1. In the expanded document the points becomefirst.__private.pickandfirst.__private.alt, whilesubject_refskeep the unnamespaced spelling in all four cases. Such a module is refused on its own by the variation candidate check (Variation point 'pick' candidate is invalid for target slot,raes/validator/_variation.py), so for these spellings the gap is checked on the expanded document, not by "valid alone, fails imported".
Existing Surface Audit
symbol_index()(raes/_module_symbols.py:160) renames section keys and theirsection.keyaliases, entities, node services, registered runtime-family records, qualified content items (_nested_content_item_aliases) and forwarding agents.raes/composition/_behavior.pyadds behavior-specification entries. Nothing adds ACL, bare content-item, compact workflow-step or variation member/alternative entries; the variation point key itself is renamed.- Checked kind by kind against
build_declaration_index(_declarations.py:468), by canonical address and by everyaliases=entry: the bare content-item name is the onlyaliases=entry the map lacks; the named-ACL address and the variation member/alternative addresses are canonical addresses the map lacks; the compact workflow step is a lookup alias built by the validator (raes/validator/_time_model.py:94-96).
Alternatives
- Do nothing. Rejected: a module that names one of these spellings cannot be imported twice, or binds a same-named root declaration when imported once.
- Rewrite these fields at validation time relative to the importing namespace. Rejected: a second resolution rule beside the composition rewrite (ADR-053 ends composition before semantic validation).
- Add the missing entries to the named map that composition already uses, so that every field that rewrites through it gains them. Selected.
Chosen Architecture
symbol_index() adds a namespaced entry for each listed spelling of the module's own declarations. The fix states which spelling it writes for each (for example whether a bare content-item name becomes the qualified address). It does not change any ambiguity rule: ADR-076 lists "Changing bare-reference ambiguity semantics" as a non-goal, and #1582 decides the canonical-versus-alias precedence. #1582's interaction bullet already records that compact <point>.<member> references, and <workflow>.<step> references outside objective windows, pass through unrewritten.
Verification Plan
- For each spelling, the expanded document of a module imported as
firstcarries a namespaced spelling of the module's own declaration. - The named-ACL, bare content-item and compact workflow-step modules above validate imported once and twice, and with a same-named root declaration each copy binds its own declaration.
- A value that names no module declaration keeps today's diagnostic.
Related
- fix(sdl): rewrite ACL networks and detection source artifacts when a module is imported under a namespace #1579, feat!: make reference eligibility explicit per purpose and align the editor with validation #1446 (
specs/sdl/references.md§7 rule 5 names this spelling class), Lookup aliases can make a canonical address ambiguous and crash completion #1582, ADR-053, ADR-076, ADR-003
Activity
test(sdl): pin the same-named root mis-binding and narrow the detecti…
test(sdl): pin the same-named root mis-binding and narrow the detecti…