Skip to content

Expand reused nested types per-path in direct resources generator - #6618

Merged
janniklasrose merged 3 commits into
mainfrom
janniklasrose/generator-nested-field-behaviors
Sep 11, 2026
Merged

janniklasrose merged 3 commits into
mainfrom
janniklasrose/generator-nested-field-behaviors

Conversation

@janniklasrose

@janniklasrose janniklasrose commented Sep 10, 2026

Copy link
Copy Markdown
Member

What

Allow get_field_behaviors to exhaustively extract from specs.

This discovers OUTPUT_ONLY / INPUT_ONLY field behaviours.

Why

Follow-up to the discussion on #6525
(#6525 (comment)): the
model_services resource can't rely on the generator to suppress its
output-only config fields, because the destination-config type reused under
config.routing.fallback.destinations[*] is deduped away. That is a general
generator bug, not model_services-specific — it already drops correct
suppressions on the three resources above. Fixing it here lets a later
apitypes.yml pin (model_services: catalog.ModelService, riding with #6525)
generate the full set instead of hand-classifying it.

Explanation

(There's also inline comments on resources.generated.yml)

get_field_behaviors in bundle/direct/tools/generate_resources.py threaded a
single global visited set through the whole schema walk, deduping by type name
across the entire tree. A type reached at two sibling paths was therefore
expanded only at the first one, and its nested OUTPUT_ONLY / INPUT_ONLY
annotations were dropped at every later path — surfacing later as phantom drift
on those server-populated fields.

This scopes visited to the current root→node path (each branch gets its own
copy via visited | {ref}) so a self-referential type still terminates the
recursion, but a type reused at sibling paths is expanded at each occurrence.
max_depth stays as the runaway guard.

Tests

  • go test ./bundle/direct/dresources/ passes, including
    TestResourcesYMLNoRedundantRules (the recovered entries don't collide with
    hand-written resources.yml rules).
  • Regeneration is idempotent; the script is ruff-clean and formatted with the
    pinned ruff@0.15.17.
  • No acceptance test references the recovered fields, so there is no
    golden-output churn.
  • Simulated Add direct-mode bundle support for AI Gateway model_service #6525 and the model_services annotations are picked up

This pull request and its description were written by Isaac.

janniklasrose and others added 2 commits September 10, 2026 19:38
get_field_behaviors threaded a single global `visited` set through the
whole schema walk, so a type reached at two sibling paths was expanded
only at the first. A reused element type — e.g. the destination config
under both config.routing.destinations[*] and
config.routing.fallback.destinations[*] — lost its nested OUTPUT_ONLY /
INPUT_ONLY annotations at the second path, which then surfaced as phantom
drift on those server-populated fields.

Scope `visited` to the current root->node path (pass `visited | {ref}`
per branch) so a self-referential type still terminates the recursion,
but a type reused at sibling paths is expanded at each occurrence.
Regenerating resources.generated.yml recovers the dropped suppressions on
apps, database_instances, and external_locations.

Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 2f07b5e

Run: 34613352469

Env 🔄​flaky 💚​RECOVERED ✅​pass 🙈​skip Time
💚​ aws linux 1 275 15 10:34
🔄​ aws windows 3 1 274 13 8:10
💚​ azure linux 1 274 15 7:06
💚​ azure windows 1 276 13 7:04
💚​ gcp linux 1 275 15 10:27
💚​ gcp windows 1 277 13 6:55
Test Name aws linux aws windows azure linux azure windows gcp linux gcp windows
💚​ TestAccept 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
🔄​ TestSyncNestedSpacePlusAndHashAreEscapedSync ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p
🔄​ TestFilerRecursiveDelete ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p
🔄​ TestFilerRecursiveDelete/files ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p
Top 3 slowest tests (at least 2 minutes):
duration env testname
3:26 gcp windows TestAccept
3:24 aws windows TestAccept
3:21 azure windows TestAccept

@janniklasrose janniklasrose left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Self-review notes: for each newly-generated suppression, the spec type of the field and where that type was already visited (so the diff is easier to follow). These are all fields whose OUTPUT_ONLY/INPUT_ONLY the global per-type visited set was dropping at a second path; scoping it per-path restores them.

apps:

ignore_remote_changes:
- field: git_repository.caller_credential_id

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Type: apps.GitRepository.caller_credential_id — INPUT_ONLY (a write-only PAT credential id the server never returns).

New because the fix stopped the global visited set from swallowing it. apps.GitRepository is reached and marked visited earlier, under the OUTPUT_ONLY parents active_deployment (→ AppDeployment.git_sourceGitSource.git_repository) and default_git_source. Those parents collapse to a single entry (filter_prefixes), so that first occurrence is invisible in this file — which is why there's no sibling line to compare against. Per-path visited now lets the top-level git_repository branch expand on its own; on this path there's no parent to propagate, so it keeps its intrinsic INPUT_ONLY.

reason: spec:input_only
- field: node_count
reason: spec:input_only
- field: parent_instance_ref.lsn

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Type: database.DatabaseInstanceRef.lsn — INPUT_ONLY. parent_instance_ref is the same type as each child_instance_refs[] element (already emitted above).

Previously dropped because child_instance_refs[*] visited DatabaseInstanceRef first. Behavior is path-dependent: under child_instance_refs (OUTPUT_ONLY parent) lsn shows as output_only; here under parent_instance_ref (IMMUTABLE, no propagation) it keeps its intrinsic input_only. Both correct — that path-dependence is exactly what per-path expansion restores.

reason: spec:output_only
- field: effective_custom_tags
reason: spec:output_only
- field: effective_custom_tags[*].key

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Type: database.CustomTag.key / .value — these have no intrinsic behavior; they inherit from the parent field. Both custom_tags[] and effective_custom_tags[] are database.CustomTag.

custom_tags[*] (INPUT_ONLY) visited CustomTag first, so these were dropped. They are the OUTPUT_ONLY mirror of the already-present custom_tags[*].key / .value (input_only) — same type, opposite behavior, because the parent differs.

reason: spec:output_only
- field: effective_usage_policy_id
reason: spec:output_only
- field: parent_instance_ref.effective_lsn

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Type: database.DatabaseInstanceRef.effective_lsn / .uid — both intrinsically OUTPUT_ONLY. Same DatabaseInstanceRef as child_instance_refs[].

Dropped before because child_instance_refs[*] visited the type first; recovered per-path. Compare the already-present child_instance_refs[*].effective_lsn / .uid above.

reason: spec:output_only
- field: effective_file_event_queue
reason: spec:output_only
- field: file_event_queue.managed_aqs.managed_resource_id

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Types: file_event_queue and effective_file_event_queue are both catalog.FileEventQueue; inside it managed_aqs/provided_aqscatalog.AzureQueueStorage, managed_pubsub/provided_pubsubcatalog.GcpPubsub, managed_sqs/provided_sqscatalog.AwsSqsQueue. Each queue type's managed_resource_id is OUTPUT_ONLY (server-computed).

Two layers of reuse hid all six before: (1) effective_file_event_queue (OUTPUT_ONLY, earlier field) visited FileEventQueue first and collapses to a single entry, so these were never visible; (2) within one FileEventQueue, the managed_/provided_ pairs share the same cloud type, so even a single expansion dropped the second of each pair. Per-path visited expands file_event_queue and each of the six sub-configs independently.

@janniklasrose
janniklasrose added this pull request to the merge queue Sep 11, 2026
Merged via the queue into main with commit 95206fb Sep 11, 2026
33 checks passed
@janniklasrose
janniklasrose deleted the janniklasrose/generator-nested-field-behaviors branch September 11, 2026 19:39
denik added a commit that referenced this pull request Sep 11, 2026
…the generator change

#6618 expands reused nested types per-path in the direct resources generator, which changes the field
paths the catalog enumerates for these two types. Both are local_only, so this is their local truth --
verdict counts shift (database_instances' COLLATERAL_DRIFT findings actually decrease, external_locations
stays finding-free), no new problems, deterministic. Regenerated to match the new structure.

Co-authored-by: Isaac
@eng-dev-ecosystem-bot

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 95206fb

Run: 34640022738

Env ❌​FAIL 🟨​KNOWN 🙈​SKIP ✅​pass 🙈​skip Time
❌​ aws linux 361 7 1 1232 1042 210:43
❌​ aws windows 170 7 1 1327 1066 245:29
❌​ azure linux 28 3 3 1382 1089 172:14
❌​ azure windows 46 3 3 1268 1113 173:03
❌​ gcp linux 254 3 3 1142 1093 187:33
❌​ gcp windows 237 3 3 1063 1117 189:46
461 interesting tests: 453 FAIL, 7 KNOWN, 1 SKIP
Test Name aws linux aws windows azure linux azure windows gcp linux gcp windows
🟨​ TestAccept 🟨​K 🟨​K 🟨​K 🟨​K 🟨​K 🟨​K
❌​ TestAccept/bundle/apps/job_permissions ❌​F ❌​F ❌​F ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/apps/job_permissions/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ❌​F ❌​F ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/config-remote-sync/cli_defaults ❌​F 🙈​s ❌​F 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/cli_defaults/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/config-remote-sync/config_edits ❌​F 🙈​s ❌​F 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/config_edits/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/config-remote-sync/dashboard_etag ❌​F 🙈​s ❌​F 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/dashboard_etag/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/config-remote-sync/flushed_cache ❌​F 🙈​s ❌​F 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/flushed_cache/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/config-remote-sync/formatting_preserved ❌​F 🙈​s ❌​F 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/formatting_preserved/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/config-remote-sync/job_fields ❌​F 🙈​s ❌​F 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/job_fields/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/config-remote-sync/job_multiple_tasks ❌​F 🙈​s ❌​F 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/job_multiple_tasks/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/config-remote-sync/job_params_variables ❌​F 🙈​s ❌​F 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/job_params_variables/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/config-remote-sync/job_pipeline_task ❌​F 🙈​s ❌​F 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/job_pipeline_task/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/config-remote-sync/json_status_selectors ❌​F 🙈​s ✅​p 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/json_status_selectors/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ❌​F
❌​ TestAccept/bundle/config-remote-sync/multiple_files ❌​F 🙈​s ✅​p 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/multiple_files/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ❌​F
❌​ TestAccept/bundle/config-remote-sync/multiple_resources ❌​F 🙈​s ✅​p 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/multiple_resources/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ❌​F
❌​ TestAccept/bundle/config-remote-sync/output_json ❌​F 🙈​s ✅​p 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/output_json/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ❌​F
❌​ TestAccept/bundle/config-remote-sync/output_no_changes ❌​F 🙈​s ✅​p 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/output_no_changes/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ❌​F
❌​ TestAccept/bundle/config-remote-sync/pipeline_fields ❌​F 🙈​s ✅​p 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/pipeline_fields/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ❌​F
❌​ TestAccept/bundle/config-remote-sync/policy_injected_cluster_fields ❌​F 🙈​s ✅​p 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/policy_injected_cluster_fields/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ❌​F
❌​ TestAccept/bundle/config-remote-sync/resolve_variables ❌​F 🙈​s ❌​F 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/resolve_variables/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/config-remote-sync/select_basic ❌​F 🙈​s ❌​F 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/select_basic/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/config-remote-sync/select_multiple ❌​F 🙈​s ❌​F 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/select_multiple/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/config-remote-sync/skip_deployment ❌​F 🙈​s ❌​F 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/skip_deployment/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/config-remote-sync/skip_permissions ❌​F 🙈​s ✅​p 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/skip_permissions/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ❌​F
❌​ TestAccept/bundle/config-remote-sync/target_override ❌​F 🙈​s ✅​p 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/target_override/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ❌​F
❌​ TestAccept/bundle/config-remote-sync/task_rename_revert ❌​F 🙈​s ✅​p 🙈​s ❌​F 🙈​s
❌​ TestAccept/bundle/config-remote-sync/task_rename_revert/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ❌​F
❌​ TestAccept/bundle/deploy/empty-bundle ❌​F ❌​F ✅​p ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/deploy/empty-bundle/DATABRICKS_BUNDLE_ENABLE_EXPERIMENTAL_YAML_SYNC=/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ❌​F ✅​p ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/deploy/empty-bundle/DATABRICKS_BUNDLE_ENABLE_EXPERIMENTAL_YAML_SYNC=true/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ❌​F ✅​p ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/deploy/files/no-snapshot-sync ❌​F ❌​F ✅​p ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/deploy/files/no-snapshot-sync/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ❌​F ✅​p ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/deploy/mlops-stacks ❌​F ❌​F ✅​p ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/deploy/mlops-stacks/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ❌​F ✅​p ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/deploy/spark-jar-task ❌​F ❌​F ✅​p ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/deploy/spark-jar-task/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ❌​F ✅​p ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/destroy/jobs-and-pipeline ❌​F ✅​p ✅​p ✅​p ❌​F ❌​F
❌​ TestAccept/bundle/destroy/jobs-and-pipeline/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ✅​p ✅​p ❌​F ❌​F
❌​ TestAccept/bundle/destroy/root-path-name-target ❌​F ✅​p ✅​p ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/destroy/root-path-name-target/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ✅​p ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/destroy/root-path-not-scoped ❌​F ✅​p ✅​p ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/destroy/root-path-not-scoped/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ✅​p ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/destroy/sibling-target ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/destroy/sibling-target/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/declined-deploy ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/declined-deploy/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/depends-on ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/depends-on/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/deployment-metadata-change ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/deployment-metadata-change/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/existing-state ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/existing-state/DATABRICKS_BUNDLE_ENGINE=direct/DMS= ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/multiple-resources ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/multiple-resources/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/no-drift ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/no-drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/no-resources ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/no-resources/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/provenance ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/provenance/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/record-failure ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/record-failure/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/stale-plan ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/stale-plan/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/READPLAN= ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/stale-plan/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/READPLAN=1 ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/successful-recreate ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/dms/successful-recreate/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/generate/pipeline_and_deploy ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/generate/pipeline_and_deploy/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ✅​p ✅​p ❌​F ❌​F ✅​p
❌​ TestAccept/bundle/generate/python_job_and_deploy ✅​p ✅​p ✅​p ✅​p ❌​F ✅​p
❌​ TestAccept/bundle/generate/python_job_and_deploy/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ✅​p ✅​p ✅​p ✅​p ❌​F ✅​p
❌​ TestAccept/bundle/invariant/no_drift ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster.yml.tmpl/READPLAN= ✅​p ❌​F ✅​p ✅​p ✅​p ✅​p
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN= ✅​p ❌​F ✅​p ✅​p ✅​p ✅​p
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=app.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=app.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=catalog.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=catalog.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=cluster.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=cluster.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=cluster_policy.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=cluster_policy.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=dashboard.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=dashboard.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=experiment.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=experiment.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=genie_space.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=genie_space.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=instance_pool.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=instance_pool.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_apply_policy_default_values_for_each_task.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_apply_policy_default_values_for_each_task.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_apply_policy_default_values_job_cluster.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_apply_policy_default_values_job_cluster.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_apply_policy_default_values_task_cluster.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_apply_policy_default_values_task_cluster.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_cross_resource_ref.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_cross_resource_ref.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_escaped_refs.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_escaped_refs.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_permission_ref.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_permission_ref.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_pydabs_10_tasks.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_pydabs_10_tasks.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_run.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_run.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_table_update_trigger.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_table_update_trigger.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_with_depends_on.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_with_depends_on.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_with_task.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=job_with_task.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=model.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=model.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=model_serving_endpoint.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=model_serving_endpoint.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=model_with_permissions.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=model_with_permissions.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=pipeline.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=pipeline.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=pipeline_allow_duplicate_names.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=pipeline_allow_duplicate_names.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=pipeline_apply_policy_default_values.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=pipeline_apply_policy_default_values.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=pipeline_config_dots.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=pipeline_config_dots.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=registered_model.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=registered_model.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=schema.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=schema.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=schema_grant_ref.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=schema_grant_ref.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=schema_uppercase_name.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=schema_uppercase_name.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=secret.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=secret_scope.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=secret_scope.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=secret_scope_default_backend_type.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=secret_scope_default_backend_type.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=sql_warehouse.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=sql_warehouse.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=vector_search_endpoint.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=vector_search_endpoint.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=vector_search_index.yml.tmpl/READPLAN= ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=vector_search_index.yml.tmpl/READPLAN=1 ❌​F ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=volume.yml.tmpl/READPLAN= ✅​p ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=volume.yml.tmpl/READPLAN=1 ✅​p ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=volume_path_job_ref.yml.tmpl/READPLAN= ✅​p ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=volume_path_job_ref.yml.tmpl/READPLAN=1 ✅​p ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=volume_uppercase_name.yml.tmpl/READPLAN= ✅​p ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=volume_uppercase_name.yml.tmpl/READPLAN=1 ✅​p ❌​F ✅​p ✅​p ✅​p ❌​F
❌​ TestAccept/bundle/local_state_staleness ✅​p ❌​F ✅​p ✅​p ✅​p ✅​p
Top 50 slowest tests (at least 2 minutes):
duration env testname
25:14 aws windows TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster.yml.tmpl/READPLAN=1
23:18 aws windows TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN=1
19:49 aws linux TestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
16:26 gcp linux TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
16:00 aws linux TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
14:17 gcp windows TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
14:17 gcp linux TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
14:15 aws linux TestAccept/bundle/resources/clusters/resize-terminated-fallback/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
14:00 aws windows TestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
13:59 gcp windows TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
12:56 aws windows TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
11:02 aws linux TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
10:59 aws windows TestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
10:38 aws linux TestAccept/bundle/resources/clusters/resize-terminated-fallback/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
9:22 aws windows TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
9:04 aws linux TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
8:53 aws linux TestAccept/bundle/deploy/spark-jar-task/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
8:42 gcp windows TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
8:38 aws linux TestAccept/bundle/deploy/spark-jar-task/DATABRICKS_BUNDLE_ENGINE=terraform/DMS=
8:35 azure linux TestAccept/bundle/invariant/delete_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster.yml.tmpl/READPLAN=
8:22 aws windows TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
8:16 aws linux TestAccept/bundle/invariant/destroy_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN=1
8:10 gcp windows TestAccept/bundle/resources/clusters/deploy/local_ssd_count/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
8:01 aws linux TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
7:51 aws windows TestAccept/bundle/invariant/destroy_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN=
7:42 gcp windows TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
7:41 aws windows TestAccept/bundle/invariant/destroy_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster.yml.tmpl/READPLAN=1
7:34 aws windows TestAccept/bundle/invariant/destroy_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster.yml.tmpl/READPLAN=
7:30 aws linux TestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
7:27 aws windows TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
7:25 aws linux TestAccept/bundle/invariant/destroy_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster.yml.tmpl/READPLAN=
7:25 azure linux TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
7:24 gcp windows TestAccept/bundle/resources/clusters/deploy/local_ssd_count/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
7:24 aws windows TestAccept/bundle/resources/clusters/resize-terminated-fallback/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
7:18 aws linux TestAccept/bundle/invariant/destroy_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster.yml.tmpl/READPLAN=1
7:15 aws windows TestAccept/bundle/resources/clusters/resize-terminated-fallback/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
7:10 aws linux TestAccept/bundle/resources/clusters/deploy/simple/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
7:10 azure windows TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
7:07 azure windows TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
7:07 gcp linux TestAccept/bundle/resources/apps/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
7:06 gcp windows TestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
7:06 aws linux TestAccept/bundle/invariant/destroy_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN=
6:59 azure linux TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
6:53 gcp linux TestAccept/bundle/resources/clusters/deploy/local_ssd_count/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
6:47 azure linux TestAccept/bundle/config-remote-sync/multiple_resources/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
6:42 gcp linux TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
6:42 gcp windows TestAccept/bundle/resources/apps/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
6:34 aws linux TestAccept/bundle/config-remote-sync/multiple_resources/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
6:27 gcp linux TestAccept/bundle/resources/apps/lifecycle-started-omitted/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
6:26 gcp windows TestAccept/bundle/resources/apps/lifecycle-started-omitted/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
(283 table rows omitted to keep the report under 60000 bytes)

alex-khakhlyuk added a commit that referenced this pull request Sep 14, 2026
Follow-up to the mcp_service support, mirroring #6654 for model_services now
that #6618 enabled it. Added catalog.McpService to apitypes.yml so the
generator reads field behaviors from the response type (config.* paths),
removed the hand-written config.source_connection.is_deleted override from
resources.yml, and regenerated resources.generated.yml. The suppression is
unchanged, just auto-derived from the OpenAPI schema instead of hand-listed.

Co-authored-by: Isaac <no-reply@databricks.com>
alex-khakhlyuk added a commit that referenced this pull request Sep 14, 2026
Follow-up mirroring #6654 (model_services) and the mcp_services cleanup, now
that #6618 enabled generating field behaviors from the response type. Added
catalog.ModelProviderService to apitypes.yml, removed the hand-written
recreate_on_changes (config.provider_type) and ignore_remote_changes
(inference_table + write-only provider credentials) from resources.yml, and
regenerated resources.generated.yml. The generator now derives all of these
from the OpenAPI schema (and additionally picks up config.anthropic.relayed.
plan_type as immutable); no suppression is lost.

Co-authored-by: Isaac <no-reply@databricks.com>
alex-khakhlyuk added a commit that referenced this pull request Sep 14, 2026
Follow-up to the mcp_service support, mirroring #6654 for model_services now
that #6618 enabled it. Added catalog.McpService to apitypes.yml so the
generator reads field behaviors from the response type (config.* paths),
removed the hand-written config.source_connection.is_deleted override from
resources.yml, and regenerated resources.generated.yml. The suppression is
unchanged, just auto-derived from the OpenAPI schema instead of hand-listed.

Co-authored-by: Isaac <no-reply@databricks.com>
alex-khakhlyuk added a commit that referenced this pull request Sep 14, 2026
Follow-up mirroring #6654 (model_services) and the mcp_services cleanup, now
that #6618 enabled generating field behaviors from the response type. Added
catalog.ModelProviderService to apitypes.yml, removed the hand-written
recreate_on_changes (config.provider_type) and ignore_remote_changes
(inference_table + write-only provider credentials) from resources.yml, and
regenerated resources.generated.yml. The generator now derives all of these
from the OpenAPI schema (and additionally picks up config.anthropic.relayed.
plan_type as immutable); no suppression is lost.

Co-authored-by: Isaac <no-reply@databricks.com>
alex-khakhlyuk added a commit that referenced this pull request Sep 14, 2026
Follow-up mirroring #6654 (model_services) and the mcp_services cleanup, now
that #6618 enabled generating field behaviors from the response type. Added
catalog.ModelProviderService to apitypes.yml, removed the hand-written
recreate_on_changes (config.provider_type) and ignore_remote_changes
(inference_table + write-only provider credentials) from resources.yml, and
regenerated resources.generated.yml. The generator now derives all of these
from the OpenAPI schema (and additionally picks up config.anthropic.relayed.
plan_type as immutable); no suppression is lost.

Co-authored-by: Isaac <no-reply@databricks.com>
alex-khakhlyuk added a commit that referenced this pull request Sep 14, 2026
Follow-up mirroring #6654 (model_services) and the mcp_services cleanup, now
that #6618 enabled generating field behaviors from the response type. Added
catalog.ModelProviderService to apitypes.yml, removed the hand-written
recreate_on_changes (config.provider_type) and ignore_remote_changes
(inference_table + write-only provider credentials) from resources.yml, and
regenerated resources.generated.yml. The generator now derives all of these
from the OpenAPI schema (and additionally picks up config.anthropic.relayed.
plan_type as immutable); no suppression is lost.

Co-authored-by: Isaac <no-reply@databricks.com>
alex-khakhlyuk added a commit that referenced this pull request Sep 15, 2026
Follow-up to the mcp_service support, mirroring #6654 for model_services now
that #6618 enabled it. Added catalog.McpService to apitypes.yml so the
generator reads field behaviors from the response type (config.* paths),
removed the hand-written config.source_connection.is_deleted override from
resources.yml, and regenerated resources.generated.yml. The suppression is
unchanged, just auto-derived from the OpenAPI schema instead of hand-listed.

Co-authored-by: Isaac <no-reply@databricks.com>
alex-khakhlyuk added a commit that referenced this pull request Sep 15, 2026
Follow-up mirroring #6654 (model_services) and the mcp_services cleanup, now
that #6618 enabled generating field behaviors from the response type. Added
catalog.ModelProviderService to apitypes.yml, removed the hand-written
recreate_on_changes (config.provider_type) and ignore_remote_changes
(inference_table + write-only provider credentials) from resources.yml, and
regenerated resources.generated.yml. The generator now derives all of these
from the OpenAPI schema (and additionally picks up config.anthropic.relayed.
plan_type as immutable); no suppression is lost.

Co-authored-by: Isaac <no-reply@databricks.com>
alex-khakhlyuk added a commit that referenced this pull request Sep 15, 2026
Follow-up mirroring #6654 (model_services) and the mcp_services cleanup, now
that #6618 enabled generating field behaviors from the response type. Added
catalog.ModelProviderService to apitypes.yml, removed the hand-written
recreate_on_changes (config.provider_type) and ignore_remote_changes
(inference_table + write-only provider credentials) from resources.yml, and
regenerated resources.generated.yml. The generator now derives all of these
from the OpenAPI schema (and additionally picks up config.anthropic.relayed.
plan_type as immutable); no suppression is lost.

Co-authored-by: Isaac <no-reply@databricks.com>
denik added a commit that referenced this pull request Sep 15, 2026
…the generator change

#6618 expands reused nested types per-path in the direct resources generator, which changes the field
paths the catalog enumerates for these two types. Both are local_only, so this is their local truth --
verdict counts shift (database_instances' COLLATERAL_DRIFT findings actually decrease, external_locations
stays finding-free), no new problems, deterministic. Regenerated to match the new structure.

Co-authored-by: Isaac
sunishsheth2009 pushed a commit to sunishsheth2009/cli that referenced this pull request Sep 15, 2026
…cks#6654)

Follow-up to databricks#6525 after databricks#6618 enabled this.

Added `catalog.ModelService` to apitypes.yml, removed the override from
resources.yml, and generated the rest
janniklasrose added a commit that referenced this pull request Sep 15, 2026
)

## What

Allow `get_field_behaviors` to exhaustively extract from specs.

This discovers `OUTPUT_ONLY` / `INPUT_ONLY` field behaviours.

## Why

Follow-up to the discussion on #6525
(#6525 (comment)):
the
`model_services` resource can't rely on the generator to suppress its
output-only config fields, because the destination-config type reused
under
`config.routing.fallback.destinations[*]` is deduped away. That is a
general
generator bug, not model_services-specific — it already drops correct
suppressions on the three resources above. Fixing it here lets a later
`apitypes.yml` pin (`model_services: catalog.ModelService`, riding with
#6525)
generate the full set instead of hand-classifying it.

## Explanation

(There's also inline comments on `resources.generated.yml`)

`get_field_behaviors` in `bundle/direct/tools/generate_resources.py`
threaded a
single global `visited` set through the whole schema walk, deduping by
type name
across the entire tree. A type reached at two sibling paths was
therefore
expanded only at the first one, and its nested `OUTPUT_ONLY` /
`INPUT_ONLY`
annotations were dropped at every later path — surfacing later as
phantom drift
on those server-populated fields.

This scopes `visited` to the current root→node path (each branch gets
its own
copy via `visited | {ref}`) so a self-referential type still terminates
the
recursion, but a type reused at sibling paths is expanded at each
occurrence.
`max_depth` stays as the runaway guard.

## Tests

- `go test ./bundle/direct/dresources/` passes, including
`TestResourcesYMLNoRedundantRules` (the recovered entries don't collide
with
  hand-written `resources.yml` rules).
- Regeneration is idempotent; the script is ruff-clean and formatted
with the
  pinned `ruff@0.15.17`.
- No acceptance test references the recovered fields, so there is no
  golden-output churn.
- Simulated #6525 and the `model_services` annotations are picked up

This pull request and its description were written by Isaac.

---------

Co-authored-by: Isaac <no-reply@databricks.com>
janniklasrose added a commit that referenced this pull request Sep 15, 2026
Follow-up to #6525 after #6618 enabled this.

Added `catalog.ModelService` to apitypes.yml, removed the override from
resources.yml, and generated the rest
deco-sdk-tagging Bot added a commit that referenced this pull request Sep 16, 2026
## Release v1.17.0

### Notable Changes

 * Bump the direct deployment state version to 3. Clients older than v1.8.0 will reject bundles deployed with this release. ([#6713](#6713))

### CLI

 * Add an `INVALID_REFRESH_TOKEN` error code to `databricks auth token --output json` failures. ([#6684](#6684))
 * Add experimental `databricks auth docker configure` to configure Docker credential helper access for Databricks Artifact Registry. ([#6700](#6700))
 * Add experimental `databricks auth docker token` to generate Docker credentials for Databricks Artifact Registry. ([#6699](#6699))
 * `databricks environments setup-local` now reports the `E_PROVISION_CONFLICT` error code instead of the generic `E_PROVISION` when `uv sync` fails to resolve a dependency conflict. ([#6666](#6666))
 * Preserve SSH sessions across temporary tunnel disconnects, with bounded replay and backpressure for large transfers. ([#6650](#6650))
 * Allow OAuth U2M logins to override the CLI client ID with `--client-id`, profile `client_id`, or `DATABRICKS_CLIENT_ID`. ([#6594](#6594))

### Bundles

 * direct: Store a dashboard's `serialized_dashboard` in state as a content hash instead of its full contents. ([#6105](#6105))
 * direct: Fix pipelines recreation when the whole `ingestion_definition` block is added or removed. ([#6589](#6589))
 * `bundle plan`, `deploy`, and `destroy` no longer report removing `permissions`, `grants`, or secret scope ACLs from a bundle as a deletion, since it leaves the resource untouched. ([#6647](#6647))
 * `bundle plan` and `deploy` no longer list or count a resource that was already deleted remotely as a deletion, matching `bundle destroy`; applying still cleans up its stale state entry. ([#6675](#6675))
 * Fix `bundle run` failing with `expected an int, found a string` when an unrelated resource references another resource that is not deployed. `bundle run` now resolves `${resources.*}` references only within the resource being run. ([#6690](#6690))
 * Add grants support for the AI Gateway `model_service`, `mcp_service`, and `model_provider_service` resources (direct engine). ([#6635](#6635))
 * Add bundle support for the AI Gateway `mcp_service` resource (direct engine). ([#6633](#6633))
 * Add bundle support for the AI Gateway `model_provider_service` resource (direct engine). ([#6634](#6634))
 * Add bundle support for the AI Gateway `model_service` resource (direct engine). ([#6525](#6525))
 * Prevent resource drift on catalogs if `storage_root` contained a trailing slash in the URL. ([#6622](#6622))
 * Fixed a "lineage mismatch in state files" error that could occur after destroying a bundle and redeploying it from another machine. `bundle destroy` now removes the local state file so no stale lineage is left behind, and prunes the state directories it leaves empty (such as `.internal/` and `sync-snapshots/`). ([#6210](#6210), [#6685](#6685))
 * direct: `bundle plan` no longer reports a permanent update on a cluster that uses a cluster policy: when the cluster spec sets `policy_id`, a field present in the remote but absent from the bundle config is not treated as drift. ([#6531](#6531))
 * `bundle deploy` on the direct engine now reports each resource as soon as it is deployed, instead of listing them all after the deployment finishes. A deploy that fails part way through now reports the resources it did apply. ([#6361](#6361))
 * Direct-engine bundles no longer flag phantom drift on server-populated nested fields under reused config types (e.g. `external_locations` file-event-queue resource IDs, `database_instances` parent-instance refs, `apps` git credential ID). ([#6618](#6618))
 * `databricks bundle generate app` now reproduces a git-backed app's `git_repository` and `git_source` configuration instead of emitting a workspace `source_code_path`, so generating from a Git-deployed app no longer silently converts it to workspace source. ([#6656](#6656))
 * Improved configuration load time for bundles with many included files. ([#6195](#6195))
 * `bundle destroy` no longer deletes triggered job runs, leaving them untouched on the backend. ([#6672](#6672))
 * direct: resources.job\_runs: new lifecycle.triggers.on\_file\_change setting to restart the run when monitored files change. Can be set to a series of paths or globs. ([#6309](#6309))
 * Bundle summary now shows a name for Postgres branches, endpoints, databases, and roles instead of a blank Name field. ([#6663](#6663))
 * Added PyDABs (Python) support for cluster policies, dashboards, and Genie spaces. ([#6585](#6585))
 * CLI commands no longer imply that a resource whose type has no workspace URL is merely not deployed yet. ([#6583](#6583))
 * Capture the implicit dependency a vector search index has on a catalog or schema defined in the same bundle, so the catalog and schema are deployed first. ([#6655](#6655))

### Dependency Updates

 * Bump dependencies with known vulnerabilities. ([#6695](#6695))
 * Bump `github.com/databricks/databricks-sdk-go` from v0.177.0 to v0.178.0. ([#6673](#6673))
 * Bump Terraform provider from v1.131.0 to v1.132.0. ([#6671](#6671))
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.

3 participants