Skip to content

feat(core): add ordered flag to attribute schema to ignore list eleme…#9782

Open
ajtmccarty wants to merge 6 commits into
developfrom
ajtm-07012026-allow-order-ignore
Open

feat(core): add ordered flag to attribute schema to ignore list eleme…#9782
ajtmccarty wants to merge 6 commits into
developfrom
ajtm-07012026-allow-order-ignore

Conversation

@ajtmccarty

@ajtmccarty ajtmccarty commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Why

When two branches both edit the same list-valued attribute (a List/JSON attribute, or a
Dropdown's choices, an attribute's enum, etc.) so that they end up holding the same elements
in a different order
, the diff reports a value conflict and merge/rebase is refused — even though
there is no semantic divergence. This is the converged-state dead-end described in #9764 for
Dropdown.choices: once both branches hold the same set of choices, the branch still cannot rebase.

Goal: let a schema author declare that element order is not significant for an attribute, so
reordering (or converging to the same set in a different order) is not treated as a conflict.

Non-goals: this does not change the rebase guard to honor ResolveDiffConflict selections
— that is a separate change. It also does not alter merge value resolution: when there is no
conflict, the merge continues to apply the branch's value as before.

Closes #9764 (resolves the converged-choices dead-end; the rebase-guard resolution handling is
out of scope here and is captured in #9654).

What changed

Behavioral changes

  • New ordered boolean on attribute schemas (default True). When set to False on a List or
    JSON-array attribute, reordering its elements is no longer a conflict during branch merge or
    rebase. Element multiplicity still matters — adding or removing an element is still a conflict.
  • The built-in schema attributes enum, dropdown choices, generic used_by, and
    restricted_namespaces are marked ordered=False, so two branches converging to the same set of
    values in a different order no longer conflict.

Implementation notes

  • Conflict detection lives in one place: ConflictsEnricher._have_same_value. For an unordered
    attribute it now compares the two JSON values as multisets (canonicalizing each element), falling
    back to exact comparison when a value is not a JSON array.
  • The enricher resolves the attribute schema from the diff (source) branch, so a branch that
    changes an attribute's ordered flag has that change honored within its own diff. Schema lookups
    degrade gracefully (fall back to order-sensitive) when a schema/branch cannot be resolved.
  • ordered uses UpdateSupport.ALLOWED: it only affects how diffs are interpreted, never stored
    data, so no data migration is required (unlike unique/read_only).

What stayed the same

  • Default behavior is unchanged (ordered=True): order-sensitive conflict detection for every
    attribute that does not opt out.
  • No data migration; merge value resolution and the rebase guard are unchanged.
  • Conflicts are still re-evaluated against live values on every recompute (both the
    update_branch_diff and recalculate paths) — a conflict recorded during a real divergence is
    cleared once the two sides converge.

Suggested review order

  1. backend/infrahub/core/diff/conflicts_enricher.py — the core comparison and schema resolution.
  2. backend/infrahub/core/schema/definitions/internal.py — the new field and the four ordered=False flips.
  3. backend/infrahub/dependencies/builder/diff/conflicts_enricher.py — wiring db into the enricher.
  4. Tests: backend/tests/component/core/diff/test_ordered_attribute_conflicts.py and additions to test_conflicts_enricher.py.
  5. Generated/rendered files (mechanical): core/schema/generated/attribute_schema.py, schema/openapi.json, docs/docs/reference/schema/*.mdx.

Impact & rollout

  • Backward compatibility: fully backward compatible — ordered defaults to True, preserving
    existing order-sensitive behavior for all attributes that do not opt out.
  • Performance: negligible; the enricher does one extra JSON parse + sort only for attributes
    flagged ordered=False.
  • Config/env changes: none. New per-attribute schema field, no feature flag.
  • Deployment notes: safe to deploy; no data migration required (UpdateSupport.ALLOWED).

Checklist

  • Tests added/updated
  • Changelog entry added (changelog/9764.fixed.md)
  • External docs updated (schema reference regenerated)
  • Internal .md docs updated (internal knowledge and AI code tools knowledge)
  • I have reviewed AI generated content

Summary by cubic

Adds an ordered flag to attribute schemas so reordering elements in List/JSON arrays no longer triggers merge/rebase conflicts. Actual adds/removes or different counts still conflict.

  • New Features
    • Added ordered: boolean to attribute schemas (default true).
    • Diff conflict logic treats List and JSON-array attributes with ordered=false as order-insensitive (multiset). Schema is resolved from the diff branch so a branch’s own ordered change applies.
    • Core schema sets ordered=false for: enum, dropdown choices, generic used_by, and restricted_namespaces.
    • ConflictsEnricher now takes db; DI updated. Internals use ujson for canonicalization.
    • Field exposed in generated schema and openapi.json; regenerated frontend REST types and refreshed .betterer.results. Docs updated (reference and conflict guide). Tests added for reorder scenarios, including JSON arrays and both recompute paths.

Written for commit 8ea3f4a. Summary will update on new commits.

Review in cubic

@github-actions github-actions Bot added type/documentation Improvements or additions to documentation group/backend Issue related to the backend (API Server, Git Agent) labels Jul 1, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 10 files

Confidence score: 4/5

  • In changelog/9764.fixed.md, the documented default for ordered conflicts with the schema (false vs actual true), which can mislead users into relying on the wrong behavior and cause unexpected conflict handling after upgrade; update the changelog text (including the “default” parenthetical) to match the real default before merging.

Shadow auto-approve: would not auto-approve because issues were found.

Re-trigger cubic

Comment thread changelog/9764.fixed.md Outdated
@codspeed-hq

codspeed-hq Bot commented Jul 1, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 12 untouched benchmarks


Comparing ajtm-07012026-allow-order-ignore (8ea3f4a) with develop (e2e8744)

Open in CodSpeed

@github-actions github-actions Bot added the group/frontend Issue related to the frontend (React) label Jul 1, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 2 files (changes from recent commits).

Shadow auto-approve: would require human review. Adds new ordered flag to attribute schemas and modifies core conflict detection logic for diff/merge. This is a feature change in a critical path that requires human review to ensure correctness and no unintended side effects.

Re-trigger cubic

@ajtmccarty ajtmccarty marked this pull request as ready for review July 1, 2026 23:59
@ajtmccarty ajtmccarty requested review from a team as code owners July 1, 2026 23:59

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The List path is well covered, but the "JSON" branch of _UNORDERED_CAPABLE_KINDS never fires in any test. Could we add one JSON attribute with an array value (proves the JSON branch works) and one where the JSON value is a top-level dict (locks in the exact-comparison fallback)?

ajtmccarty and others added 4 commits July 7, 2026 17:20
…nt order in diffs

Adds an `ordered` boolean to AttributeSchema (default True). When set to False on
a List or JSON-array attribute, reordering its elements is no longer reported as a
conflict during branch merge or rebase; element counts still matter, so adding or
removing an element remains a conflict. The diff conflict enricher compares such
attributes as multisets and resolves the schema from the diff branch first, so a
branch's own `ordered` change is honored within its diff.

The built-in schema `enum`, dropdown `choices`, generic `used_by`, and
`restricted_namespaces` attributes are marked ordered=False.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Regenerate frontend/app/src/shared/api/rest/types.generated.ts after adding the
`ordered` field to schema/openapi.json, fixing the frontend-validate-openapi-types
CI check.

Drop the incorrect "(the default)" qualifier in the changelog: the `ordered`
attribute-schema field defaults to `true` (order-sensitive), not `false`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Regenerating the frontend OpenAPI REST types for the new `ordered` field changed
the type structures that TypeScript embeds in several existing tracked error
messages. The error count and locations are unchanged (212 issues); only the
message text differs. Refresh .betterer.results so `betterer ci` passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ajtmccarty ajtmccarty force-pushed the ajtm-07012026-allow-order-ignore branch from 361f3fb to 3f78c61 Compare July 8, 2026 00:42
@ajtmccarty ajtmccarty requested review from a team as code owners July 8, 2026 00:42
@ajtmccarty ajtmccarty changed the base branch from stable to develop July 8, 2026 00:56

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 3 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="python_sdk">

<violation number="1" location="python_sdk:1">
P2: The SDK submodule bump (e0c27a14) adds MERGE_FAILED to BranchStatus but does not add the new `ordered` attribute schema field that this PR introduces. AttributeSchema in the SDK is a Pydantic model that deserializes server schema responses — without `ordered`, SDK-based clients that fetch attribute schemas (e.g., infrahubctl schema dump) will silently drop the field. Consider adding `ordered: bool = True` to AttributeSchema so the SDK round-trips the new field correctly.</violation>
</file>

Shadow auto-approve: would not auto-approve because issues were found.
Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread python_sdk
@@ -1 +1 @@
Subproject commit b76594a5ce659265832cad22f4406e46af21d3cb
Subproject commit e0c27a149d8d5442805d5660c0d86869a30d3298

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The SDK submodule bump (e0c27a14) adds MERGE_FAILED to BranchStatus but does not add the new ordered attribute schema field that this PR introduces. AttributeSchema in the SDK is a Pydantic model that deserializes server schema responses — without ordered, SDK-based clients that fetch attribute schemas (e.g., infrahubctl schema dump) will silently drop the field. Consider adding ordered: bool = True to AttributeSchema so the SDK round-trips the new field correctly.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At python_sdk, line 1:

<comment>The SDK submodule bump (e0c27a14) adds MERGE_FAILED to BranchStatus but does not add the new `ordered` attribute schema field that this PR introduces. AttributeSchema in the SDK is a Pydantic model that deserializes server schema responses — without `ordered`, SDK-based clients that fetch attribute schemas (e.g., infrahubctl schema dump) will silently drop the field. Consider adding `ordered: bool = True` to AttributeSchema so the SDK round-trips the new field correctly.</comment>

<file context>
@@ -1 +1 @@
-Subproject commit b76594a5ce659265832cad22f4406e46af21d3cb
+Subproject commit e0c27a149d8d5442805d5660c0d86869a30d3298
</file context>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

group/backend Issue related to the backend (API Server, Git Agent) group/frontend Issue related to the frontend (React) type/documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: rebase refuses additive Dropdown conflicts even after resolution or converging both sides to the union

2 participants