Skip to content

Prevent cross-type label suffixes from breaking references - #146

Merged
samir-gandhi merged 7 commits into
mainfrom
polaris/dedupe-labels
Sep 1, 2026
Merged

samir-gandhi merged 7 commits into
mainfrom
polaris/dedupe-labels

Conversation

@samir-gandhi

Copy link
Copy Markdown
Contributor

Fixes #145

Summary

The dependency graph indexed nodes by (resource type, API ID) but allocated unique labels globally by label alone, while the orchestrator assigns ResourceData.Label per resource type. When two different resource types produced the same base label (e.g., pingone_davinci_connection.__pingcli_DVA and pingone_davinci_flow.__pingcli_DVA), the second graph insertion was internally renamed with a _2 suffix while the emitted resource block kept the original label. Graph-derived standard references, embedded references, and runtime depends_on could then point at a non-existent address — which type broke depended on processing order.

The same work item also fixes an adjacent type-scoping bug: filter exclusion bookkeeping (excludedIDs) was keyed by raw API ID only, so if two resource types shared an API ID, excluding one could incorrectly force references to the other into fallback variables.

Changes

  • internal/graph: label allocation (nameUsage) is now scoped by (resource type, label). Same-type duplicate suffixing (_2, _3) and all public graph APIs are unchanged.
  • internal/core: filter exclusion state uses a type-qualified identity (excludedResourceIdentity) at every producer (direct filtering, upstream expansion) and consumer (resolveOneReference), removing cross-type exclusion bleed.
  • Regression tests added across graph, orchestrator (standard + embedded + runtime references, both insertion orders), HCL/Terraform JSON formatters, imports, and command output matching.
  • Changelog entry in .changelog/pr-145.txt.

Tests

Validating tests (new):

  • internal/graph/graph_test.go — cross-type equal labels unsuffixed (both insertion orders), same-type suffixes intact
  • internal/core/orchestrator_test.go — TestExportOrchestrator_Export_EqualLabelsAcrossTypes, TestExportOrchestrator_Export_FilterExclusionIsTypeAware, TestExportOrchestrator_Export_IncludeUpstreamExclusionIsTypeAware, TestResolveOneReference_ExcludedResourceTypeAware, TestResolveDependsOnResources_EqualLabelsAcrossTypes
  • internal/core/embedded_references_test.go — TestResolveEmbeddedReferences_EqualLabelsAcrossTypes
  • Formatter/import/cmd boundary tests in internal/formatters/{hcl,tfjson}, internal/imports, cmd/export_outputs_test.go

Impacted tests passing:

  • go test ./... -count=1 — all packages pass
  • make vet, go build ./..., git diff --check — pass
  • go test -race ./internal/graph ./internal/core -count=1 — pass

Known unrelated failures (pre-existing, not from this change):

  • TestResolveEmbeddedReferences_DisambiguatedName_StableAcrossEnvironments (internal/core/embedded_references_test.go:1357) fails intermittently: map iteration order decides which node receives the disambiguated fallback-variable suffix (node1 vs node2). Reproducible with -count=10 on main as well.
  • make lint reports existing issues in unchanged files (cmd/export.go, cmd/list_outputs.go, internal/core/apidata.go, internal/compare/content.go).

Breaking changes

None. Labels that are unique within their type are unchanged; only the incorrect cross-type graph-side renaming is removed.

🤖 Generated with Claude Code

samir-gandhi and others added 5 commits August 27, 2026 15:28
Cover equal labels across standard references, embedded RawHCLValue references and graph edges, and runtime dependencies.
Add boundary regressions for canonical labels, raw import IDs, runtime dependency omission, and type-qualified output matching across HCL, Terraform JSON, imports, and command outputs.
Document the cross-type label and API ID identity fixes for issue #145.

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

Regression Test Results

Matrix Entry Status Breaking Acceptable
default-hcl ✅ PASS 0 0
default-tfjson ✅ PASS 0 0
hcl-include-all ✅ PASS 0 0
hcl-skip-deps ✅ PASS 0 0
tfjson-skip-deps ✅ PASS 0 0

✅ No regressions detected

All export configurations produced compatible output.


Generated by regression workflow • View run

These 4 task-summary files were force-added despite the existing
.polaris/ .gitignore rule, so they showed up in the PR diff. .polaris/
holds local Polaris SDLC workflow state and should never be committed
to a public branch, matching the existing convention for .claude/,
.github/agents/, CLAUDE.md, and AGENT.md.

Removes them from git tracking only — the files remain on disk.

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

Regression Test Results

Matrix Entry Status Breaking Acceptable
default-hcl ✅ PASS 0 0
default-tfjson ✅ PASS 0 0
hcl-include-all ✅ PASS 0 0
hcl-skip-deps ✅ PASS 0 0
tfjson-skip-deps ✅ PASS 0 0

✅ No regressions detected

All export configurations produced compatible output.


Generated by regression workflow • View run

pr-145.txt referenced the linked issue number, not the PR; repo
convention keys the filename to the PR (#146).

Co-Authored-By: Claude <noreply@anthropic.com>
@samir-gandhi
samir-gandhi merged commit a3806cc into main Sep 1, 2026
7 checks passed
@samir-gandhi
samir-gandhi deleted the polaris/dedupe-labels branch September 1, 2026 20:58
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

Regression Test Results

Matrix Entry Status Breaking Acceptable
default-hcl ✅ PASS 0 0
default-tfjson ✅ PASS 0 0
hcl-include-all ✅ PASS 0 0
hcl-skip-deps ✅ PASS 0 0
tfjson-skip-deps ✅ PASS 0 0

✅ No regressions detected

All export configurations produced compatible output.


Generated by regression workflow • View run

plambrechtsen pushed a commit to plambrechtsen/pingcli-plugin-terraformer that referenced this pull request Sep 21, 2026
Store the Terraform HCL describing the static PingOne regression
environment used by the PR regression workflow, so it can be rebuilt if
lost or audited for drift. Generated by `pingcli-terraformer export
--output-format hcl --include-values` at c14d0b5 (post PR pingidentity#146), then
reviewed and scrubbed:

- Connector clientSecret values are empty in the export (the API does
  not return secret values on read) — marked "provide manually".
- davinci_variable_testPW_value is a password held in a plain DaVinci
  variable; scrubbed from the tfvars and from three flow definitions
  that embed it in a rich-text node.
- Four flows with empty descriptions had description = "" omitted; the
  pingidentity/pingone provider enforces min-length 1 and the verbatim
  export fails `terraform validate` otherwise.

Also add the CONFIG_AS_CODE_PLAN.md written earlier this session.

Un-ignore tests/regression/environment/** in .gitignore so the snapshot
can be committed alongside the *.tf output-file rule.

Co-Authored-By: Claude Code <noreply@anthropic.com>
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.

Prevent cross-type label suffixes from breaking references

1 participant