Skip to content

Validate in/out relationship pairing at schema save #3026

Closed

Description

@malibio

Overview

Split out of the review of PR #2951 (#2941). Writes through an in-direction declaration's name are now stored as the forward edge. The forward name is the declaration's reverseName, looked up on the declaration's targetType. That only works when the far type really declares that name as out. Schema save doesn't check this.

Problem Statement

Today create_relationship catches an unpaired or wrongly paired in declaration only when someone writes through it, and rejects the write with a clear error. Until then the schema looks valid:

  • An unpaired in declaration that is required: true can never be satisfied, so check_node_completeness reports it missing forever.
  • The in declaration's own cardinality, reverseCardinality and edgeFields are ignored for storage, because only the forward declaration's values apply. When the two sides disagree, the schema says one thing and does another.

Proposed Solution

In create_schema / update_schema, reject an in declaration unless all of these hold:

  • its targetType chain declares reverseName with direction: out;
  • that forward declaration's reverseName equals the in declaration's name;
  • the forward declaration's targetType is satisfied by this schema (itself or an extends ancestor);
  • the cardinalities agree: the in side's cardinality equals the forward side's reverseCardinality, and the reverse.

A self-referential pair declared in one payload must still validate, like the adr supersedes/superseded_by pair. Consider whether an in declaration should carry edgeFields at all.

Acceptance Criteria

  • Saving an unpaired in declaration is rejected with an error naming the missing forward declaration
  • A pair whose names or cardinalities don't match is rejected
  • A self-referential pair in one payload is still accepted
  • Code passes bun run quality:fix
  • Tests pass (bun run test:all)

Activity

  1. added a commit that references this issue on Sep 25, 2026
    874fb13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions