Skip to content

Resolve authoritativeDefinitions that reference another contract file - #1453

Open
simonharrer wants to merge 1 commit into
mainfrom
feature/local-business-definition-references
Open

Resolve authoritativeDefinitions that reference another contract file#1453
simonharrer wants to merge 1 commit into
mainfrom
feature/local-business-definition-references

Conversation

@simonharrer

Copy link
Copy Markdown
Contributor

A property can now link to a property in another contract file, and the CLI resolves that link relative to the referencing contract before linting, testing, or exporting:

# top-artists-by-year-view.odcs.yaml
properties:
  - name: artist_name
    logicalType: string
    physicalType: character
    primaryKey: true
    authoritativeDefinitions:
      - type: businessDefinition
        url: top-artists-by-year.odcs.yaml#schema/top_artists_by_year_ba/properties/artist_name

The technical contract keeps its own physical shape and inherits businessName, description, examples, and everything else the business attribute defines. This covers the common layering of a business-level contract plus one technical contract per materialization, where both live in the same repository and no server is involved.

How it works

  • The route is chosen by the url's shape, not by the link's type. A # fragment on a non-HTTP url is read from disk; anything else keeps going through the existing lookup. So every resolvable type accepts either form.
  • businessDefinition is now a resolvable type, alongside semantics, semantic, and definition — the type says what a reference means, not whether it is a file or a URL. Precedence becomes semanticssemanticdefinitionbusinessDefinition.
  • Fragments walk schema/<schema>/properties/<property>, matching on id first and falling back to name, and descend into nested properties and array items. A fragment must end at a property.
  • Chains resolve transitively (technical → business → glossary), each file parsed once per run. A cycle between files is reported as an error rather than followed.
  • Merge semantics are unchanged: inline values always win, and id / name / authoritativeDefinitions / properties / items are never merged.

Behaviour change

businessDefinition links pointing at an HTTP URL were previously informational and triggered no request; they are now fetched like definition links. A contract whose businessDefinition points at something that is not an ODCS property document (a Confluence page, say) will now fail to resolve, and --no-inline-references is the escape hatch. Flagging it explicitly since it affects existing contracts.

Also

  • examples/business-definitions/ — an anonymized two-contract example, linted by lint_examples.py in CI.
  • docs/docs/semantics.md — a "Reference another contract file" section.
  • tests/test_resolve_local_definitions.py — 20 tests covering resolution by id and name, nested properties and array items, relative paths, merge precedence, one-read-per-file, transitive chains, cycle detection, every failure mode, and --no-inline-references.

Full suite passes; the s3/schema-evolution failures seen under -n 8 are testcontainer port contention and pass serially. test_duckdb_json.py::test_nested_json and the test_test_mysql.py import error both fail on main too.

@github-actions

This comment was marked as outdated.

A property can now link to a business definition kept in a file next to
the contract, resolved relative to the referencing contract. This lets a
technical contract own its physical shape while inheriting the business
meaning from the same repository, with no server involved.

Two shapes, both resolvable by every type:

  url: business.odcs.yaml#schema/orders/properties/order_id
  url: definitions/order_id.odcs.yaml

With a fragment, the reference addresses one property inside another
contract. Without one, the file *is* the definition and holds the
property's elements directly -- a glossary as one file per term.

The route is chosen by the url's shape, not by the link's type: a `#`
fragment reads from disk, as does a fragment-less url naming a .yaml,
.yml, or .json file; anything else keeps going through the existing
lookup, so `url: /definitions/order_id` stays a path on the configured
host. `businessDefinition` becomes a resolvable type alongside
`semantics`, `semantic`, and `definition`, since the type says what a
reference means and not whether it is a file or a URL.

Fragments walk `schema/<schema>/properties/<property>`, matching on `id`
first and falling back to `name`, and descend into nested properties and
array items. Chains resolve transitively; a cycle between files is
reported rather than followed.
@simonharrer
simonharrer force-pushed the feature/local-business-definition-references branch from 31d5059 to 0290d8f Compare July 29, 2026 12:30
@jschoedl jschoedl added the waiting-for-decision Waiting for a decision of the maintainers. label Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

waiting-for-decision Waiting for a decision of the maintainers.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants