Skip to content

fix(trace): resolve the by feature of a satisfy, and empty collections - #11

Merged
superWorldSavior merged 4 commits into
mainfrom
fix/trace-satisfying-feature
Oct 25, 2026
Merged

superWorldSavior merged 4 commits into
mainfrom
fix/trace-satisfying-feature

Conversation

@superWorldSavior

@superWorldSavior superWorldSavior commented Oct 25, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • The by feature of a satisfy is resolved.

    • Before, satisfy massBudget by budget; came back as an unresolved link ("Unexpected relationship result: VoidExpressionResult").
    • Cause: SysON v2026.7.0's SatisfyRequirementUsageImpl derives satisfyingFeature from a subsetting or a binding connector, never from the FeatureValue that the textual import writes.
    • When the derived accessor is empty, the trace now reads the explicit binding: subjectParameter → FeatureValue → FeatureReferenceExpression.referent.
    • A satisfy without a by feature stays unresolved, with no inferred target.
  • Feature chains.

    • For by rover.pack.cell, the referent is an anonymous Feature carrying FeatureChaining.
    • The trace reports the chain's last feature, a real and navigable element, labelled with the whole path (rover.pack.cell).
    • So two cells in different packs stay distinct.
  • An empty collection is no longer an error. SysON answers an empty AQL collection with no result type (a StringsExpressionResult the GraphQL query does not select). Two cases reported errors before:

    • a root with requirements but no satisfy relationship: "Could not resolve satisfy relationships…";
    • a root with no requirements: "Unexpected result type: undefined".

    Both are now zero objects. Other unexpected result types still fail.

Test plan

  • Each new test failed before its fix with the production symptom:
    • the by fallback;
    • a satisfy without by;
    • the feature chain (it returned the anonymous Feature);
    • no satisfy relationship;
    • no requirements.
  • The test for a resolved satisfyingFeature pins the exact AQL sequence: the fallback is not queried when the derived accessor answers.
  • deno task fmt, lint, check, test (281 passed).
  • Live, on the local audit project:
    • Drone budget goes from 0/3 to 2/3 covered (massBudget and thrustMargin by budget);
    • a chain probe: cellLife by rover.pack.cell → the cell part usage, packLife by rover.pack → pack;
    • Batmobile's batmobileSpecification by batmobileDesignV23;
    • the viewpoint satisfy without by stays unresolved, with "Satisfaction relationship has no explicit satisfying feature";
    • a root without requirements returns 0, with no error.
  • Independent review (Sonnet). The feature-chain and empty-collection findings are fixed here, and its test gaps are filled.

🤖 Generated with Claude Code

superWorldSavior and others added 4 commits October 25, 2026 10:57
`satisfy massBudget by budget;` showed as an unresolved link ("Unexpected
relationship result: VoidExpressionResult"): SysON v2026.7.0 records the
`by` feature as the value of the relationship's subject parameter and
derives no satisfyingFeature from it. When the derived accessor is
empty, the trace now reads that explicit binding. A satisfy without a
`by` feature stays unresolved; no target is inferred.

Verified on a live SysON: the Drone budget trace goes from 0 to 2 of 3
requirements covered, and the Batmobile specification is satisfied by
batmobileDesignV23.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SysON answers an empty AQL collection with a result object that has no
__typename (a StringsExpressionResult the GraphQL query does not select), so
evalAql returns {}. The requirements trace reported it as "Unexpected result
type: undefined" for a root without requirements, and as "Could not resolve
satisfy relationships: Unexpected relationship result: undefined" for every
requirement when nothing satisfies them.

An undefined result type is now an empty collection in both places; other
unexpected result types (String, Int, Boolean...) still fail, and
VoidExpressionResult keeps its allowAbsent behaviour.

Tests cover both empty shapes, assert the exact AQL sequence so the `by`
fallback is not queried when satisfyingFeature is non-empty, and pin the
top-level error of a satisfy without a `by` feature.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… path

`satisfy cellLife by rover.pack.cell;` makes the subject's referent an
anonymous Feature carrying FeatureChaining, so the trace reported that
nameless node as the satisfying target. The chain's `chainingFeature`
list now gives the target: its last feature (a real, navigable element)
labelled with the whole path (`rover.pack.cell`), so two `cell`s in
different packs stay distinct.

Verified on a live SysON: `by rover.pack.cell` and `by rover.pack`
resolve to the `cell` and `pack` part usages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@superWorldSavior
superWorldSavior merged commit 2989f92 into main Oct 25, 2026
2 checks passed
@superWorldSavior superWorldSavior mentioned this pull request Oct 25, 2026
2 tasks done
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