Skip to content

feat(contract-schema): add depends_on/related_to relation fields and cross-reference validation#18

Merged
kschlt merged 7 commits into
mainfrom
feat/contract-schema
Apr 2, 2026
Merged

feat(contract-schema): add depends_on/related_to relation fields and cross-reference validation#18
kschlt merged 7 commits into
mainfrom
feat/contract-schema

Conversation

@kschlt
Copy link
Copy Markdown
Owner

@kschlt kschlt commented Apr 2, 2026

Why

ADRs often depend on or relate to other decisions, but there was no structured way to express these links in front matter. Without explicit relation fields, downstream tooling (impact analysis, relationship graphs) cannot discover these dependencies, and authors have no schema-enforced way to record them. This work adds the schema foundation and surfaces dangling references at contract-compile time before they become silent data quality issues.

Approach

Two new optional array-of-string fields (depends_on, related_to) were added to ADRFrontMatter, following the same pattern as superseded_by. The existing ensure_list_or_none validator was extended to normalise empty lists to None, keeping serialised output clean. The JSON schema received explicit property definitions (rather than relying on additionalProperties: true) so tooling gets type information.

Cross-reference validation was added to ConstraintsContractBuilder: it now collects all parsed ADRs (not just accepted ones) before calling _validate_relation_references(). Warnings are printed alongside existing malformed-ADR warnings. The strict=False philosophy is preserved — the contract file is unchanged, only advisory messages are added. References to proposed ADRs are not flagged as broken.

A regression test verifies that clause_id is not dropped during model_dump(exclude_none=True) — the serialisation path used by ConstraintsContract.to_json_file().

What Was Tested

  • clause_id serialisation under exclude_none=True (regression test)
  • depends_on / related_to round-trip through parse → model → serialise
  • Unresolved reference warnings fire for unknown ADR IDs, do not fire for proposed ADRs
  • ADRFrontMatter construction in creation workflow passes mypy with the new required fields

Risks

Additive changes only. Existing ADRs without depends_on/related_to are unaffected (fields default to None). The only new user-visible behaviour is advisory warning output during contract compilation, which does not alter the compiled contract.

kschlt and others added 7 commits April 3, 2026 00:43
Confirms the already-implemented clause_id field is not dropped when
model_dump(exclude_none=True) is called — the path used by
ConstraintsContract.to_json_file(). Closes the end-to-end serialization
gap in the existing TestClauseIdGeneration coverage.
…Matter

Establishes the schema foundation for inter-ADR relationship tracking.
These fields enable ADRs to declare explicit dependencies and non-hierarchical
relationships, which downstream tooling (relationship computation, impact
analysis) can consume. Empty lists are normalised to None by extending the
existing ensure_list_or_none validator rather than adding a new one.
…ng properties

Schema validators and documentation tooling need explicit property definitions
to understand relation fields; relying on additionalProperties: true would accept
the fields silently but provide no type information or docs. Explicit definitions
follow the same pattern as superseded_by.
During contract compilation, ConstraintsContractBuilder now collects all
parsed ADRs (not just accepted ones) and calls _validate_relation_references()
to surface depends_on/related_to entries that point to unknown ADR IDs.
Warnings are printed alongside the existing malformed-ADR warnings, keeping
the strict=False philosophy — contract output is unchanged, only advisory
messages are added. all_ids is built from the full parse set so that
references to proposed ADRs do not produce false positives.
…kflow

ADRFrontMatter gained two new required fields (depends_on, related_to) but
the construction site in creation.py was not updated, causing mypy errors.
@kschlt kschlt merged commit ced3271 into main Apr 2, 2026
1 check passed
@kschlt kschlt deleted the feat/contract-schema branch April 2, 2026 23:08
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