Repository navigation
fix(sdl): keep imported tool affordances bound to their own tool content - #1440
Merged
Merged
Conversation
doublewhy
force-pushed
the
298-tool-authoring-verification
branch
from
October 9, 2026 11:38
89b2ade to
94dc1b8
Compare
doublewhy
marked this pull request as ready for review
October 9, 2026 12:27
This was referenced Oct 9, 2026
Closed
fix(sdl): rename nested node-service and content-item references with their parent declaration
#1573
Open
doublewhy
force-pushed
the
298-tool-authoring-verification
branch
from
October 13, 2026 03:12
600080a to
76bb083
Compare
doublewhy
marked this pull request as draft
October 13, 2026 03:12
9 of 11 tasks
doublewhy
marked this pull request as ready for review
October 13, 2026 04:37
This was referenced Oct 13, 2026
Rewrite an imported tool affordance's tool_ref through the import's named symbols, so a section-qualified content ref such as content.scanner-package binds the unit's own tool instead of the importing scenario's content of the same name. Verify DSL-117 tool, affordance and interactive-access authoring through composition, compilation and runtime admission, and record clause verification, fulfillment boundary and traceability.
…us tool for issue #298 The rewrite that the fix changed is shared by module composition and rename_sdl_declaration. Renaming the tool content now rewrites a section-qualified tool_ref to content.<new-name>, where dev refused the rename with artifact-transformation.target-invalid. Add bare and qualified rename cases, check that the published authoring schema requires each affordance relation on its own, and add an importer tool_ref that names both an exported node and exported content. Record the rename effect and the boundary-classification rewrite in the DSL-117 record.
Rewriting every imported tool_ref through the named symbol map changed one composition that dev accepted: a bare tool_ref whose name the unit also gives to an unexported declaration of a later section (ambiguous in the unit alone) was rewritten to that declaration's private name and failed. Keep a bare content name on the content map, as before, and send only other spellings, such as content.<name>, through the named map.
Before an import is namespaced, composition now resolves each authored tool_ref of the unit through the unit's own declaration index, the index standalone validation uses. A ref with more than one candidate fails with the standalone "is ambiguous; use one of" diagnostic, anchored at the unit file and naming only the unit's own addresses. Composition used to bind the content silently, although the unit already failed on its own. The two-file fixture moves to examples/scenarios/participant-tools with a README mapping each DSL-117 concern to its authored field, and the test module reads the examples. New cases cover the ambiguity for a relationship clash and a content-item clash, the qualified spelling beside each clash, a cross-fragment ref to root content, an unsupported channel in the unit and in the importer, the invocation interface reached through each import's own action contract, and renames of the access account in both spellings. docs/decisions/issue-298-tool-authoring.md records the composition rule, the three settled boundaries and the migration. The DSL-117 record maps each clause to its fields and paths, and links adjacent defects #1573, #1574, #1575 and #1498. sections.md rejoins the binding-reference sentence that #1426's paragraph split.
SonarCloud python:S5778 flagged two possibly raising calls inside one pytest.raises block. The test module is outside the research-evidence digest, so the recorded captures still bind this source.
The README's Imports section stated the import binding and ambiguity rules for every reference, but composition applies them to tool_ref only. Scope both sentences to tool_ref and say that other reference families still bind an ambiguous bare name silently (#1575) and that reference-typed action argument values are not resolved or namespaced on import (#1574).
…port name The Imports section said that every reference family other than tool_ref binds an ambiguous bare name silently, but composition already rejects a bare stateful dependency name that matches both a generated artifact and a persistent volume (_rewrite_stateful_dependency_ref). Name that check and limit the silent-binding statement to references renamed through the combined name map, such as authority_scope_refs (#1575).
doublewhy
force-pushed
the
298-tool-authoring-verification
branch
from
October 13, 2026 14:58
c7f9679 to
f3d5db9
Compare
9 of 11 tasks
doublewhy
marked this pull request as draft
October 13, 2026 19:38
Collected on this branch's source (3ecaf6b, implementation digest b4e37ba26a53): every pinned specification artifact ran through the production pipeline, the 10 retained formal SDL cases were replayed with replay_case, the 4 production cases ran with their raes processor argv, and the 14 participant functions ran (18 passed).
doublewhy
force-pushed
the
298-tool-authoring-verification
branch
from
October 13, 2026 20:18
f3d5db9 to
c1ee3ee
Compare
doublewhy
marked this pull request as ready for review
October 14, 2026 03:33
…authoring-verification
…authoring-verification
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Verifies DSL-117 (tools, affordances, interfaces, channels, scope) through parsing, validation, composition and compiler output, delivering all five #298 done-when bullets, and fixes two composition gaps for an imported unit's
tool_ref:tool_ref(content.scanner-package) was never rewritten, so it bound the importer's own content and could not be renamed. It is now namespaced and renamed with its declaration.tool_refnaming two unit declarations fails in the unit alone but composition bound it silently. Composition now raises the identical diagnostic at the unit file (ADR-053; ADR-076 section 3).Requirement governance is skipped (no scope file) pending the maintainer's decision on #1510; forced for DSL-117, it reports only
requirement-ownership-mismatchfor the DSL-117 and decision records.Requirement UIDs
DSL-117Related Issues
Refs #298
Adjacent defects, filed: #1573 (nested-ref rename refused), #1574 (reference-typed action arguments not namespaced on import), #1575 (the same silent binding in other
symbols["named"]families). #1498 tracks__privaterefs in importers.Merge order: no prerequisite; drafts #1576, #1592, #1584 and #1484 share files with it and rebase onto it once it merges.
ADR Impact
Changes
_behavior.py:_rewrite_tool_affordancekeeps a bare content name onsymbols["content"]and any other spelling onsymbols["named"];_behavior.py:_reject_ambiguous_unit_tool_refs, called by_expand.py:_expand_one_importbefore namespacing, resolves eachtool_refthrough the unit's ownDeclarationIndex.examples/scenarios/participant-tools/(a unit imported twice; README maps each DSL-117 concern to its field); decision record (rule, boundaries, migration); DSL-117 clause mapping.capture-e33b51ac...andcapture-1decb5d4..., collected on clean3ecaf6bd(dev348c4903), recorded withpython -m tools.research_capture record. Specification: 6 pinned artifacts via_execute_artifact(38 stages passed, 4 preregistered non-execution, 0 failed);recompute_analysis10 of 10 load-bearing passed. Formal: 10 retained cases viareplay_case, 4 viaraes processor, 14 participant functions (18 passed); 20 of 20 outcomes as expected. Drift from dev's record templatesc9ca186a/3bad3945: thesdl-pipelinesurface digest, the replay command id andversions.python.Done-when matrix. Tests:
test_issue_298_tool_authoring.py(36 cases), CI lanecanonical / test-shard; evidence for every row: 36 passed locally, run 38461730034 green.test_reusable_tool_bindings_resolve_inside_their_own_namespace(reads the examples)_rewrite_tool_affordancetest_imported_affordance_keeps_its_own_tool_when_the_importer_declares_the_same_name[qualified]: fails_reject_ambiguous_unit_tool_refs,_expand_one_importtest_bare_tool_ref_naming_two_unit_declarations_fails_composition_as_it_fails_alone: both cases fail (composition succeeds); plustest_importing_scenario_bindings_fail_closedtest_declared_and_displayed_tool_neither_admits_nor_records_an_invocationtest_renaming_a_declaration_rewrites_either_spelling_of_its_tool_or_access_ref[tool-qualified],[tool-is-a-node]: failTest Plan
Fail before the change: with
_behavior.pyand_expand.pyrestored toorigin/dev, 7 cases fail; with the change all 36 pass (uv run --project implementations/python --frozen --all-extras python -m pytest implementations/python/tests/test_issue_298_tool_authoring.py -q).c1ee3ee4carries the code commits off3d5db90, wherenox -s contracts -- --base-rev origin/dev(both evidence steps), the module with the three evidence modules (244 passed; 18 with-m integration), 14 related modules (704 passed, 1 skipped), lint,make policyanddocs-localpassed. Atc1ee3ee4both evidence checkers pass, also on thegit merge-tree --write-tree origin/dev HEADtree, andverify-fast-feedbackpasses every stage except expected SKIPs. CI run 38461730034: all checks green, includingsonar.Ground Control Checks
Traceability
implementations/python/packages/raes/composition/{_behavior,_expand}.pyimplementations/python/tests/test_issue_298_tool_authoring.pyexamples/scenarios/participant-tools/{tool-kit,twice-imported}.sdl.yamldocs/decisions/issue-298-tool-authoring.md,examples/scenarios/participant-tools/README.md,docs/explain/sdl/sections.mdChecklist
ruff format,ruff checkclean)tool_refresolves to the rewritten form of the declaration it named, or composition fails with the unit's own diagnostic.fixcuts a patch release