Skip to content

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

Merged
ajtmccarty merged 8 commits into
developfrom
ajtm-07012026-allow-order-ignore
Jul 9, 2026
Merged

feat(core): add ordered flag to attribute schema to ignore list eleme…#9782
ajtmccarty merged 8 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, and built-in schema flips this for enum, dropdown choices, generic used_by, and restricted_namespaces.

  • New Features

    • Added ordered: boolean to attribute schemas (default true).
    • Diff conflict logic treats List/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.
    • ConflictsEnricher now requires db via DI; internals use ujson for canonicalization.
    • Field exposed in generated schema and openapi.json; regenerated frontend REST types and refreshed .betterer.results. Docs updated; tests cover JSON arrays and both recompute paths.
  • Dependencies

    • Bumped python_sdk.

Written for commit 7491608. 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 (7491608) with develop (4c2e557)

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 Outdated
@@ -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>

@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 1 file (changes from recent commits).

Shadow auto-approve: would not auto-approve. Auto-approval blocked by 1 unresolved issue from previous reviews.

Re-trigger cubic

@ajtmccarty ajtmccarty merged commit a64b804 into develop Jul 9, 2026
98 of 100 checks passed
@ajtmccarty ajtmccarty deleted the ajtm-07012026-allow-order-ignore branch July 9, 2026 22:22
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