Skip to content

feat!: make reference eligibility explicit per purpose and align the editor with validation - #1446

Open
doublewhy wants to merge 16 commits into
devfrom
1339-explicit-target-eligibility
Open

doublewhy wants to merge 16 commits into
devfrom
1339-explicit-target-eligibility

Conversation

@doublewhy

@doublewhy doublewhy commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The participant identity audit found two defects. F4: one targetable boolean, expanded by exclusion, served every reference purpose. F5: completion ignored validation's policy; a participant relationship endpoint offered organizations, propositions and the relationship itself.

This PR delivers the whole #1339 done-when: validation, composition, instantiation, completion, navigation and diagnostics read one explicit policy.

Breaking authoring change. Four purposes narrow: objective subjects, action targets (including effect target_refs[] naming a declaration), shared state and authority scopes. Narrowing only refuses references; typed relationship endpoints refuse nothing new. An inventory of 200 YAML documents across rae, env-packs, lilrae and adapters found identical validation outcomes before and after.

Requirement UIDs

Related Issues

Closes #1339

Merge order: this merges first; #1484, #1584, #1576 and #1592 rebase onto it once it merges.

Related: #1338, #1340, #1341, #220, #1517. Follow-ups: #1503, #1511, #1577, #1578, #1579.

ADR Impact

  • No ADR required. Rests on ADR-109, ADR-076 sections 3-5.1, ADR-052, ADR-029, ADR-038, ADR-003, ADR-020, ADR-053.

Changes

Lane for every row: canonical test-shard.

Done-when (verbatim) Change Test
Define eligible declaration kinds separately for objective subjects, action/interaction/effect targets, shared state, relationship subtypes, observation subjects, authority anchors/scopes, and operating scope. _relationship_endpoint_policy.py:relationship_endpoint_purposes test_issue_1339_relationship_endpoints.py (fails at collection on dev a391904)
Enforce the rules at the existing DeclarationIndex/reference-policy boundary, including generic and special/nested registration. _declarations.py:resolve_for test_an_unclassified_kind_is_eligible_for_nothing_and_cannot_register (fails: no ReferencePurpose)
A participant can act and be targeted. Eligibility grants neither participation, authority, nor visibility to another kind. _reference_targetability.py test_a_targeted_participant_gains_no_participation_authority_or_visibility (fails: DID NOT RAISE)
Participant relationships accept and suggest only unambiguous participants. State separately whether propositions/assertions can be objective subjects; that must not make them action targets. _language_context.py test_participant_relationship_completion_offers_only_participants (fails: offers action_contracts.probe)
New referenceable kinds require an explicit eligibility decision. Preserve the narrower resource-only operating scope. _operating_scope_index.py test_every_indexed_section_and_runtime_family_has_an_explicit_decision (fails: no DECLARATION_CATEGORIES)
Qualified references, ambiguous bare names, duplicate imports, and incomplete editor documents receive consistent validation, completion, navigation, and diagnostics. language_service.py test_issue_1339_editor_imports.py (14 of 16 fail on a391904), test_issue_1339_endpoint_editor.py (fails at collection)
Test the confirmed editor mismatch and each reference purpose through composition, instantiation, and compilation. tests test_the_two_stage_matrices_cover_every_reference_purpose_in_every_stage (fails at collection)

Test Plan

  • Unit tests pass
  • Integration tests pass if applicable
  • Full completion suite required in CI before merge
  • No coverage regression

uv run --project implementations/python --frozen --all-extras python -m pytest <modules> -q: the five #1339 modules gave 322 passed; 26 regression modules 1821 passed, 1 skipped; evidence modules 226 passed. Fail-before: each matrix test fails as its row states with implementations/python/packages at dev 348c490; row 3's test now also refuses red's behavior surfaces as action targets, which dev accepts. Evidence: both families re-recorded with python -m tools.research_capture record on dev 348c490; both checkers pass. nox -s verify-fast-feedback -- --base-rev origin/dev, nox -s lint, make policy, nox -s docs-local and nox -s contracts pass.

Ground Control Checks

  • Repository policy command passes
  • Regression tests fail on the pre-change source and pass after

make policy passes at this head.

Traceability

  • IMPLEMENTS, under implementations/python/packages/raes/: _reference_targetability.py, _relationship_endpoint_policy.py, _declarations.py, _operating_scope_index.py, validator/, _language_context.py, _language_metadata.py, language_service.py, _language_references.py, composition/_expand.py, _composition_budget.py, parser.py, formatting.py, module_registry/, relationships.py; and specs/sdl/references.md
  • TESTS, under implementations/python/tests/: the five test_issue_1339_*.py modules, fixtures/issue-1339-declaration-kinds.sdl.yaml, expectation-only edits in six existing modules

Checklist

  • Code follows the project coding standards
  • FM1 (static semantic): invariants in specs/sdl/references.md section 7, tested over the all-kinds fixture.
  • Published contract schemas regenerated: five Relationship descriptions, with ledger records.
  • PR title is a Conventional Commit; feat! because authoring narrows.
  • Architectural docs updated.

Documentation

Updated: specs/sdl/references.md, docs/migration/reference-eligibility.md and nine more pages.

@doublewhy
doublewhy force-pushed the 1339-explicit-target-eligibility branch 5 times, most recently from 8e32e4d to 4b8794a Compare October 9, 2026 15:12
@doublewhy
doublewhy marked this pull request as ready for review October 9, 2026 15:47
@doublewhy
doublewhy force-pushed the 1339-explicit-target-eligibility branch 3 times, most recently from a36ae06 to 94777b1 Compare October 9, 2026 20:14
@doublewhy
doublewhy force-pushed the 1339-explicit-target-eligibility branch from 94777b1 to 3da6039 Compare October 10, 2026 14:28
@doublewhy
doublewhy force-pushed the 1339-explicit-target-eligibility branch from 3da6039 to ab22b8f Compare October 13, 2026 03:21
@doublewhy doublewhy changed the title feat!: make reference eligibility explicit per purpose and align editor suggestions feat!: make reference eligibility explicit per purpose and align the editor with validation Oct 13, 2026
@doublewhy
doublewhy marked this pull request as draft October 13, 2026 03:21
@doublewhy
doublewhy force-pushed the 1339-explicit-target-eligibility branch from ab22b8f to 4ac06f1 Compare October 13, 2026 03:54
@doublewhy
doublewhy marked this pull request as ready for review October 13, 2026 04:34
…or suggestions

Every indexed declaration kind now has one eligibility category or is
explicitly unreferenceable, and each reference purpose admits an explicit set
of categories. The declaration index refuses a kind without a decision, so a
new section gains no eligibility by default.

Objective subjects, interaction and declared effect targets, shared-state
refs, and behavior authority scopes narrow; the other purposes keep their
accepted declarations. Validation, completion, navigation, and diagnostics
share the same purposes, so participant relationship endpoints suggest only
unambiguous agents, also in documents that do not validate yet.

The reference catalog, parity expectations, and author docs name the purpose
tokens, and docs/migration/reference-eligibility.md publishes the inventory
and rewrite rules for issue #1339.
Objective subjects, action targets, shared state, and authority scopes now
resolve a bare name among every targetable declaration and then require the
single match to be eligible, as participant endpoints already did. A bare
name that a refused declaration shares therefore stays ambiguous, so
narrowing only refuses references: such a name is refused instead of
validating and then compiling to no authority-scope address. Variation
candidates and completion follow the same rule.

Unresolved-reference diagnostics for the narrowed purposes name the purpose
instead of "targetable" and list the declarations the reference does name.
Each purpose now lists its categories explicitly, and the unused
_all_targetable_elements helper is removed.

Tests drive the shared bare name through compilation, the mixed-control and
inject-delivery scopes, and every specialized purpose through composition and
instantiation.
Navigation counted a value in a purpose-bearing field by declaration kind,
so an ambiguous bare participant endpoint or a bare name shared with a
condition was reported under the eligible declaration, and operating
scopes were attributed through the general aliases. A value is now an
occurrence of a qualified symbol only when the field's resolver resolves
it to exactly that declaration: the declaration index for the field's
purpose, or the operating-scope aliases. Documents that do not validate
yet resolve among their top-level entries, which completion now shares.

Participant-relationship scope_refs complete only the operating scopes
both endpoints hold and authority_basis_refs only the source's anchors,
variation candidate references complete and navigate in their target
slot's section or purpose, and an ambiguity diagnostic lists the eligible
candidates before the declarations the purpose refuses.

The migration note lists every declaration kind that effect target_refs
now refuse and drops test bookkeeping; references.md section 7 states
which diagnostics carry the purpose and the named declarations.
An inject delivery's control_authority_scope_refs must equal its target
controller state's scope_refs, so the refusal is the state's diagnostic or
a disagreement with the state, not a named-reference diagnostic of its own.
Validation resolves a variation point's target owner in its slot's owner
section and each governed allowed ref in the slot's candidate section, but
completion and navigation still treated both as general targets. Completion
therefore offered owners and allowed refs that validation refuses,
navigation reported a refused value as an occurrence, and a valid bare owner
or allowed ref whose name a condition shares was reported nowhere. Both
fields now select their section from the authored slot, as a candidate's
reference already did.

Tests drive every owner and allowed-ref suggestion through validation and
navigation, the refused values, and the shared bare names. The owner
completion assertion of the variation-point language-service test now
expects only the slot's owner section. The shared-name ambiguity test also
checks what the compiled model keeps for each field, and the decision-table
test registers runtime-inventory records through the declaration index and
rejects a kind that is both categorized and unreferenceable.
…itory

The SDL sections guide still said objective targets may name any element
except variables, objectives and workflows. It now names the eligible
objective subjects, links the reference purposes, and says that a bare name
a refused declaration shares stays ambiguous.

The migration note's editor section covers variation owners and allowed
refs, says that operating-scope fields complete and navigate only in a
document that validates structurally, and no longer claims that scope_refs
completion applies every validator bound. The inventory is rerun with
per-repository commits and counts, covering env-packs and adapters at dev.
The reference catalog's authority-scope row names the further bound on
mixed-control state scope_refs, and rule 5 covers variation owners.
Every relationship type and typed detail field now has one explicit endpoint
decision. Ten endpoint purposes admit declaration kinds (node, identity
domain, forest, authority and facade, deployment tenant, node service,
runtime application, database and mail service endpoints), resolve among
relationship-endpoint candidates, and combine by conjunction when a type and
its details both narrow one side.

Runtime child records are tested by a family-qualified eligibility kind
inside the policy; published declaration kinds do not change. The
validator's application, database and mail resolvers read the policy's
sets, and an all-kinds fixture pins the identity, topology and tenancy
modules' accepted kinds to the policy. The Relationship schema description
states the narrowed endpoints (description only, five schemas).
…ts in the editor

Completion and navigation select each relationship endpoint's purposes from
its type and typed details, and publish a conjunction as one composite
context token. A document that does not validate yet resolves through an
index that the validator's index builder makes from the entries that
validate on their own, so navigation reports an occurrence only for a
declaration that index resolves exactly.

The language-service helpers accept an optional document path. With it,
local imports compose through the existing composition, and a registry
import is refused in editor path mode without any fetch.
References §7 rule 5 now states that composition leaves a detection
definition's source_artifact_ref unchanged, tracked by #1579.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant