From 2c4c3331bd021237cce1c909d2c3edb5102b6c7e Mon Sep 17 00:00:00 2001 From: Jan Rose Date: Thu, 10 Sep 2026 19:38:46 +0000 Subject: [PATCH 1/2] Expand reused nested types per-path in direct resources generator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../direct/dresources/resources.generated.yml | 24 +++++++++++++++++++ bundle/direct/tools/generate_resources.py | 20 +++++++++------- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/bundle/direct/dresources/resources.generated.yml b/bundle/direct/dresources/resources.generated.yml index 85a0466d499..01578115219 100644 --- a/bundle/direct/dresources/resources.generated.yml +++ b/bundle/direct/dresources/resources.generated.yml @@ -27,6 +27,8 @@ resources: apps: ignore_remote_changes: + - field: git_repository.caller_credential_id + reason: spec:input_only - field: git_source reason: spec:input_only - field: source_code_path @@ -129,6 +131,8 @@ resources: reason: spec:input_only - field: node_count reason: spec:input_only + - field: parent_instance_ref.lsn + reason: spec:input_only - field: retention_window_in_days reason: spec:input_only - field: stopped @@ -156,6 +160,10 @@ resources: reason: spec:output_only - field: effective_custom_tags reason: spec:output_only + - field: effective_custom_tags[*].key + reason: spec:output_only + - field: effective_custom_tags[*].value + reason: spec:output_only - field: effective_enable_pg_native_login reason: spec:output_only - field: effective_enable_readable_secondaries @@ -168,6 +176,10 @@ resources: reason: spec:output_only - field: effective_usage_policy_id reason: spec:output_only + - field: parent_instance_ref.effective_lsn + reason: spec:output_only + - field: parent_instance_ref.uid + reason: spec:output_only - field: pg_version reason: spec:output_only - field: read_only_dns @@ -196,6 +208,18 @@ resources: reason: spec:output_only - field: effective_file_event_queue reason: spec:output_only + - field: file_event_queue.managed_aqs.managed_resource_id + reason: spec:output_only + - field: file_event_queue.managed_pubsub.managed_resource_id + reason: spec:output_only + - field: file_event_queue.managed_sqs.managed_resource_id + reason: spec:output_only + - field: file_event_queue.provided_aqs.managed_resource_id + reason: spec:output_only + - field: file_event_queue.provided_pubsub.managed_resource_id + reason: spec:output_only + - field: file_event_queue.provided_sqs.managed_resource_id + reason: spec:output_only genie_spaces: diff --git a/bundle/direct/tools/generate_resources.py b/bundle/direct/tools/generate_resources.py index 45996b5fa27..edf9ce5910f 100644 --- a/bundle/direct/tools/generate_resources.py +++ b/bundle/direct/tools/generate_resources.py @@ -73,10 +73,14 @@ def get_field_behaviors(schemas, type_name, resource_name=None, array_element_ty array_element_types = {} def extract(schema, prefix, visited, depth, inherited): - # Bound recursion as a runaway guard only; `visited` already guarantees - # termination (each type is expanded at most once). Real fields reach depth 5 - # (e.g. external_model.custom_provider_config.bearer_token_auth.token_plaintext), - # so keep ample headroom above that. + # `visited` holds the ref types on the path from the root to here, so a type + # that transitively references itself terminates the recursion. It is scoped + # to the current path (each branch gets its own copy via `visited | {ref}`), + # not global, so a type reused at sibling paths is expanded at each one — e.g. + # ModelServiceConfigDestinationConfig under both config.routing.destinations[*] + # and config.routing.fallback.destinations[*]. max_depth is a runaway guard + # only; real fields reach depth 5 (e.g. + # external_model.custom_provider_config.bearer_token_auth.token_plaintext). max_depth = 10 if depth > max_depth: raise Exception(f"Nested field found at depth {depth} ({max_depth=})") @@ -92,17 +96,17 @@ def extract(schema, prefix, visited, depth, inherited): if "ref" in prop: ref = prop["ref"] if ref in schemas and ref not in visited: - visited.add(ref) propagate = [b for b in behaviors if b in ("INPUT_ONLY", "OUTPUT_ONLY")] - results.update(extract(schemas[ref], path, visited, depth + 1, propagate)) + results.update(extract(schemas[ref], path, visited | {ref}, depth + 1, propagate)) elif resource_name is not None: # For array fields with no ref in the schema, use the element type from # out.fields.txt (e.g. App.resources[] -> AppResource). elem_type = array_element_types.get((resource_name, path)) if elem_type and elem_type in schemas and elem_type not in visited: - visited.add(elem_type) propagate = [b for b in behaviors if b in ("INPUT_ONLY", "OUTPUT_ONLY")] - results.update(extract(schemas[elem_type], f"{path}[*]", visited, depth + 1, propagate)) + results.update( + extract(schemas[elem_type], f"{path}[*]", visited | {elem_type}, depth + 1, propagate) + ) return results # Find INPUT_ONLY/OUTPUT_ONLY from container types that reference this type From fdbf58b37a9e5b1684f72b8fee52b4747d4221bc Mon Sep 17 00:00:00 2001 From: Jan Rose Date: Thu, 10 Sep 2026 19:42:43 +0000 Subject: [PATCH 2/2] Add changelog fragment Co-authored-by: Isaac --- .nextchanges/bundles/direct-nested-reused-types.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 .nextchanges/bundles/direct-nested-reused-types.md diff --git a/.nextchanges/bundles/direct-nested-reused-types.md b/.nextchanges/bundles/direct-nested-reused-types.md new file mode 100644 index 00000000000..23e1fa16722 --- /dev/null +++ b/.nextchanges/bundles/direct-nested-reused-types.md @@ -0,0 +1 @@ +* 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](https://github.com/databricks/cli/pull/6618))