Skip to content

fix(provenance): add regression tests and fix flag inheritance#1949

Merged
aknysh merged 17 commits intomainfrom
osterman/provenance-regression-fix
Jan 13, 2026
Merged

fix(provenance): add regression tests and fix flag inheritance#1949
aknysh merged 17 commits intomainfrom
osterman/provenance-regression-fix

Conversation

@osterman
Copy link
Copy Markdown
Member

@osterman osterman commented Jan 11, 2026

what

  • Add comprehensive regression tests for line-level provenance tracking
  • Fix flag inheritance regression where custom commands could not define flags that already exist on parent commands
  • Custom commands can now declare --stack, --verbose, or other existing flags when the type matches
  • Type mismatches still produce clear error messages (e.g., defining --stack as bool when parent has it as string)

why

  • Provenance output format needs regression tests to prevent accidental breakage of import chains, depth tracking, and source attribution
  • PR Fix custom command flag conflicts with global flags #1947 introduced overly strict flag conflict checking that rejected valid use cases
  • Custom commands legitimately need to use flags like --stack and --verbose that are defined elsewhere
  • The fix allows flag inheritance when types match (skip re-registration) while still catching actual conflicts (type mismatch)

references

  • Fixes flag regression introduced in Fix custom command flag conflicts with global flags #1947
  • Adds test fixtures: tests/fixtures/scenarios/provenance-advanced/ and tests/fixtures/scenarios/flag-inheritance/
  • Test cases: tests/test-cases/provenance-snapshots.yaml and tests/test-cases/flag-inheritance.yaml

Summary by CodeRabbit

  • New Features

    • Custom commands now support flag inheritance with type-safety validation and conflict detection
    • Custom commands can define their own --version flags independent of the global version flag
    • Configuration provenance tracking now displays where each setting originates in the stack hierarchy
    • Enhanced atmos list components command shows unique components with stack counts
  • Configuration

    • Updated list command configuration structure in atmos.yaml under new list.components, list.instances, and list.stacks paths

✏️ Tip: You can customize this high-level summary in your review settings.

Add comprehensive test fixtures and snapshot tests for provenance output:
- Create provenance-advanced fixture based on quickstart-advanced example
- Add snapshot test for complex multi-level import provenance
- Verify provenance symbols, depth indicators, and line numbers are correct

This regression test captures the expected provenance output format including
imports, settings, and vars sections with proper source attribution and depth
tracking through import chains.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@osterman osterman requested review from a team as code owners January 11, 2026 21:45
@github-actions github-actions bot added the size/xl Extra large size PR label Jan 11, 2026
@mergify
Copy link
Copy Markdown

mergify bot commented Jan 11, 2026

Warning

This PR exceeds the recommended limit of 1,000 lines.

Large PRs are difficult to review and may be rejected due to their size.

Please verify that this PR does not address multiple issues.
Consider refactoring it into smaller, more focused PRs to facilitate a smoother review process.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Jan 11, 2026

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

None

…hing types

PR #1947 introduced a regression where custom commands couldn't define flags
that matched existing flags (like --stack), even when the types matched.
This broke the quickstart-advanced example's custom commands.

Changes:
- Custom commands can now "declare" they need a flag that already exists
- If the flag exists with the same type, it's inherited (not re-registered)
- If the flag exists with a different type, an error is returned
- Shorthand collisions for different flag names still error
- Duplicates within the same command still error

Updated tests to verify type-matching behavior rather than blocking all
redefinitions. Removed duplicated provenance-advanced fixture in favor of
using examples/quick-start-advanced directly.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions github-actions bot added size/l Large size PR and removed size/xl Extra large size PR labels Jan 11, 2026
osterman and others added 2 commits January 11, 2026 16:37
Comprehensive smoke test that verifies:
- Global flags work (--help, --version, --verbose)
- Terraform commands with --stack work
- Custom commands inherit --stack from parent (quickstart-advanced)
- List and describe commands work

This provides confidence that the flag inheritance fix doesn't break
real-world usage patterns.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive snapshot tests for flag handling to memorialize
CLI output and prevent regressions. These tests verify:

- Custom commands inherit --stack flag from parent commands
- Help output correctly shows inherited flags
- Built-in commands continue to work with flags
- Custom commands can read inherited flag values

Tests cover:
- tf plan --help (custom command under terraform alias)
- terraform provision --help (custom command)
- show component --help (custom command with --stack)
- terraform --help (built-in parent command)
- describe component --help (built-in command)
- show component with -s flag (flag value reading)
- version command (global flags)
- --help flag (global flag)
- describe component with --stack and --provenance
- list stacks and list components

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions github-actions bot added size/xl Extra large size PR and removed size/l Large size PR labels Jan 11, 2026
@mergify
Copy link
Copy Markdown

mergify bot commented Jan 11, 2026

Warning

This PR exceeds the recommended limit of 1,000 lines.

Large PRs are difficult to review and may be rejected due to their size.

Please verify that this PR does not address multiple issues.
Consider refactoring it into smaller, more focused PRs to facilitate a smoother review process.

osterman and others added 2 commits January 11, 2026 19:56
This shell script is superseded by proper snapshot tests in
tests/test-cases/flag-inheritance.yaml which:
- Run as part of make testacc
- Have golden snapshots capturing exact output
- Are integrated with the test framework

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This is the use case that originally led to the flag inheritance fix.
Custom commands should be able to declare they need --verbose (a global
flag) and inherit it without error, as long as the type matches.

Added:
- New test fixture: tests/fixtures/scenarios/flag-inheritance/
- Custom 'echo info' command with --verbose flag
- Custom 'deploy component' command with --stack flag
- Tests verifying help shows the flag, and flag value is readable
- Snapshot tests capturing the exact output

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@osterman osterman force-pushed the osterman/provenance-regression-fix branch from e16c837 to 9194175 Compare January 12, 2026 02:19
@osterman osterman added the patch A minor, backward compatible change label Jan 12, 2026
@osterman osterman changed the title test(provenance): add regression tests for line-level provenance fix(flags): allow custom commands to inherit existing flags with matching types Jan 12, 2026
The flag inheritance fix commit inadvertently deleted the
provenance-advanced test fixture. This restores it.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@osterman osterman changed the title fix(flags): allow custom commands to inherit existing flags with matching types fix(provenance): add regression tests and fix flag inheritance Jan 12, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 12, 2026

📝 Walkthrough

Walkthrough

Refactors custom command flag validation to use type-aware inheritance checks instead of reserved flag lookups, moves --version flag to local, adds provenance-aware YAML caching logic, introduces UniqueComponents for deduplicated component listings, restructures list configuration with TopLevelListConfig, and adds comprehensive test fixtures and snapshots.

Changes

Cohort / File(s) Summary
Custom Command Flag Validation & Inheritance
cmd/cmd_utils.go, cmd/custom_command_flag_conflict_test.go, cmd/root.go, cmd/root_test.go
Replaced runtime reserved/global flag lookups with type-based inheritance validation; detects duplicate flags, enforces type compatibility on inherited flags, checks shorthand conflicts; added 5 new inheritance tests covering version flag allowance, matching types, and nested inheritance; moved --version flag from PersistentFlags to local Flags on root.
YAML Provenance Caching
pkg/utils/yaml_utils.go, pkg/utils/yaml_utils_test.go
Added nil-safe provenance checks in parseAndCacheYAML; forces re-parse when provenance enabled and cached positions missing; added 7 new tests covering provenance reparse, nil-config safety, cache-hit semantics, and concurrent access scenarios.
List Components Deduplication
pkg/list/extract/components.go, cmd/list/components.go, cmd/list/components_test.go
Introduced UniqueComponents() function for deduplicated component extraction with stack filtering; enhanced metadata enrichment to surface vars, settings, component_folder, terraform_component; updated list components to use UniqueComponents and adjusted default columns (Stack → Stacks count).
List Metadata & Status Rendering
pkg/list/extract/metadata.go, pkg/list/extract/metadata_test.go, cmd/list/instances.go, pkg/list/list_instances.go
Added TTY-aware status rendering (colored dots for TTY, semantic text for non-TTY); introduced new configuration path precedence for list.instances.columns over deprecated components.list.columns.
Configuration Schema
pkg/schema/schema.go, .golangci.yml
Added TopLevelListConfig type with Components, Instances, Stacks; added List field to AtmosConfiguration; added file-length-limit exception for schema.go in linter config.
Global Flags Restructure
pkg/flags/global_builder.go, pkg/flags/global_builder_test.go
Removed global registration of --version flag; flag now LOCAL on RootCmd only; updated test expectations from "version" to "use-version"; added clarifying comments.
Flag Inheritance Test Fixtures
tests/fixtures/scenarios/flag-inheritance/*, tests/test-cases/flag-inheritance.yaml
Added atmos.yaml and dev.yaml fixtures defining echo→info and deploy→component commands with inherited --verbose and --stack flags; added comprehensive test suite validating help output and flag value reading.
Custom Version Flag Fixtures
tests/fixtures/scenarios/custom-version-flag/atmos.yaml, tests/test-cases/custom-command-version-flag.yaml
Added fixture with install and check-version commands defining per-command --version flags (string/bool); added 4 test cases covering string/shorthand invocation, help output, and root --version backward compatibility.
Provenance Test Fixtures
tests/fixtures/scenarios/provenance/*, tests/test-cases/provenance-snapshots.yaml
Added multi-level stack fixtures (orgs/acme structure) with import chain (depth 3); added 2 provenance snapshot tests validating legend, import graph, and var provenance markers.
Mock Component Updates
tests/fixtures/components/terraform/mock/main.tf
Added 5 variables: enabled (bool), name/environment/region/message (string) for test scenarios.
Configuration & Documentation
examples/quick-start-advanced/atmos.yaml, website/blog/2026-01-11-list-components-fix.mdx
Migrated list config from components.helmfile.list to settings.list.{components,instances}; added documentation on list commands, deduplication, filtering, configuration precedence, and migration guidance.
Test Snapshots (Multi-Command Help/Execution)
tests/snapshots/TestCLICommands_*.golden
Updated 50+ snapshot files: removed global --version flag from help output across all commands; added telemetry notice lines to stderr snapshots; added new help/execution snapshots for flag-inheritance and custom-version-flag scenarios; updated describe-component provenance snapshots with legend and var mappings.

Sequence Diagrams

sequenceDiagram
    participant CC as Custom Command
    participant FlagReg as Flag Registry
    participant Parent as Parent Command
    participant Validator as Type Validator
    participant Result as Result

    CC->>FlagReg: Declare flag (e.g., --stack: string)
    FlagReg->>Validator: Check duplicates in command
    Validator-->>FlagReg: OK / Error

    FlagReg->>Parent: Check PersistentFlags
    Parent-->>FlagReg: Flag exists (type: bool)
    
    FlagReg->>Validator: Type mismatch? string vs bool
    Validator-->>FlagReg: Type conflict detected
    FlagReg-->>Result: Return ErrReservedFlagName with details
Loading
sequenceDiagram
    participant CLI as CLI Request
    participant Cache as YAML Cache
    participant Parser as YAML Parser
    participant Config as Config (TrackProvenance)
    participant Result as Cached Entry

    CLI->>Cache: UnmarshalYAMLFromFileWithPositions(file, provenance=true)
    Cache->>Cache: Check cache hit
    
    alt Cache hit + provenance enabled + positions missing
        Cache->>Parser: Re-parse with position tracking
        Parser->>Result: Parse + extract positions
        Cache->>Cache: Update cache entry with positions
    else Cache hit + provenance disabled or positions exist
        Cache-->>CLI: Return cached entry
    end
Loading
sequenceDiagram
    participant Stacks as Stacks Map
    participant Extract as UniqueComponents
    participant Seen as Seen Map
    participant Enrich as Metadata Enricher
    participant Output as Output List

    Stacks->>Extract: UniqueComponents(stacksMap, stackPattern)
    
    loop For each component type
        Extract->>Extract: Iterate stacks matching pattern
        Extract->>Seen: Track component by (type, name)
        
        alt First occurrence
            Extract->>Enrich: Build base component entry
            Enrich->>Enrich: Extract vars, settings, component_folder
            Enrich-->>Extract: Enriched component
        else Duplicate
            Extract->>Extract: Increment stack count
        end
    end
    
    Extract-->>Output: Return deduplicated list with stack_count
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • osterman
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes: fixing a provenance-related regression and adding/fixing flag inheritance tests and functionality.
Docstring Coverage ✅ Passed Docstring coverage is 85.45% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch osterman/provenance-regression-fix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
@tests/fixtures/scenarios/provenance-advanced/components/terraform/vpc/vpc-flow-logs.tf:
- Around line 3-11: The aws_flow_log "default" resource is using an invalid
module output accessor; replace
module.vpc_flow_logs_bucket[0].outputs.vpc_flow_logs_bucket_arn with the direct
output reference module.vpc_flow_logs_bucket[0].vpc_flow_logs_bucket_arn in the
log_destination assignment so Terraform accesses the module output correctly
(leave surrounding logic like count/local.vpc_flow_logs_enabled,
log_destination_type, traffic_type, vpc_id, and tags unchanged).
🧹 Nitpick comments (3)
tests/fixtures/scenarios/provenance-advanced/stacks/schemas/opa/vpc/validate-vpc-component.rego (2)

40-42: Consider using regex.match instead of deprecated re_match.

The re_match built-in is deprecated in newer OPA versions. If this fixture should demonstrate current best practices:

-errors[vpc_name_regex_error_message] {
-    not re_match(vpc_name_regex, input.vars.name)
+errors[vpc_name_regex_error_message] {
+    not regex.match(vpc_name_regex, input.vars.name)
 }

If intentionally kept for backward compatibility testing, a comment noting this would help.


17-19: Consider modern Rego imports.

Regal suggests using import rego.v1 for modern OPA policies. This bundles future keywords and enables stricter semantics:

 package atmos

-import future.keywords.in
+import rego.v1

Optional for test fixtures but aligns with current OPA best practices.

tests/fixtures/scenarios/provenance-advanced/components/terraform/vpc/variables.tf (1)

1-209: Comprehensive VPC variable definitions.

This fixture covers the full spectrum of VPC configuration options with clear descriptions and appropriate types. The heredoc descriptions for complex variables like availability_zones and ipv4_cidrs are helpful.

Optional: Similar to the flow logs bucket, you could add validation blocks for constrained string values like vpc_flow_logs_traffic_type and vpc_flow_logs_log_destination_type.

♻️ Optional validation blocks
 variable "vpc_flow_logs_traffic_type" {
   type        = string
   description = "The type of traffic to capture. Valid values: `ACCEPT`, `REJECT`, `ALL`"
   default     = "ALL"
+  validation {
+    condition     = contains(["ACCEPT", "REJECT", "ALL"], var.vpc_flow_logs_traffic_type)
+    error_message = "Valid values are: ACCEPT, REJECT, ALL."
+  }
 }

 variable "vpc_flow_logs_log_destination_type" {
   type        = string
   description = "The type of the logging destination. Valid values: `cloud-watch-logs`, `s3`"
   default     = "s3"
+  validation {
+    condition     = contains(["cloud-watch-logs", "s3"], var.vpc_flow_logs_log_destination_type)
+    error_message = "Valid values are: cloud-watch-logs, s3."
+  }
 }

osterman and others added 2 commits January 11, 2026 21:41
- Add status indicator (colored dot for TTY, text for piped output)
- Add component_folder field extracted from metadata.component
- Refactor test fixtures to use shared mock component library
- Delete unused provenance-advanced fixture
- Update default sort to stack:asc,component:asc for deterministic output

The status field shows:
- TTY: Colored dot (green=enabled, red=locked, gray=disabled)
- Piped: Semantic text ("enabled", "disabled", "locked")

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This PR fixes the list components command to show unique component
definitions (deduplicated across stacks) instead of component instances.

Changes:
- Add UniqueComponents() function with --stack filter support
- Introduce new config namespace: list.components and list.instances
- Maintain backward compatibility with components.list.columns
- Add explicit TTY/non-TTY tests for status indicator
- Update quick-start-advanced example with new config structure

The list components command now shows:
- Component name
- Component type (terraform, helmfile, packer)
- Number of stacks using the component

Users can filter by stack pattern: atmos list components --stack "*-dev"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…efine it

The --version flag was registered as a persistent global flag, causing it
to be inherited by all subcommands. This prevented custom commands from
defining their own --version flag (e.g., `atmos install --version 1.0.0`).

Changes:
- Remove --version from GlobalOptionsBuilder persistent flags
- Register --version as a local flag on RootCmd only
- Update flag conflict detection to only check PersistentFlags() and
  InheritedFlags(), not local Flags() on parent commands
- Add unit test TestCustomCommand_VersionFlagAllowed
- Add integration test for custom command with --version flag

The --use-version flag remains persistent as it's needed for re-exec
on any subcommand.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 13, 2026
Update test expectations after d021669 changed list components to show
unique component definitions instead of per-stack instances:
- Stack filter is no longer applied (use list instances for per-stack filtering)
- Default columns changed from 6 to 3 (Component, Type, Stacks)
- Config path changed from Components.List to List.Components
- Default sorter changed to sort by component only

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@aknysh
Copy link
Copy Markdown
Member

aknysh commented Jan 13, 2026

@coderabbitai full review please

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 13, 2026

@aknysh, I'll conduct a full review of the changes in this PR.


🧠 Learnings used
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.

Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: docs/prd/tool-dependencies-integration.md:58-64
Timestamp: 2025-12-13T06:07:37.766Z
Learning: cloudposse/atmos: For PRD docs (docs/prd/*.md), markdownlint issues like MD040/MD010/MD034 can be handled in a separate documentation cleanup commit and should not block the current PR.
✅ Actions performed

Full review triggered.

@codecov
Copy link
Copy Markdown

codecov bot commented Jan 13, 2026

Codecov Report

❌ Patch coverage is 96.40719% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.17%. Comparing base (b24edb5) to head (59c6cba).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
cmd/list/instances.go 0.00% 5 Missing ⚠️
cmd/list/components.go 75.00% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1949      +/-   ##
==========================================
+ Coverage   74.13%   74.17%   +0.03%     
==========================================
  Files         772      772              
  Lines       69744    69847     +103     
==========================================
+ Hits        51708    51806      +98     
- Misses      14611    14617       +6     
+ Partials     3425     3424       -1     
Flag Coverage Δ
unittests 74.17% <96.40%> (+0.03%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
cmd/cmd_utils.go 57.53% <100.00%> (+0.83%) ⬆️
cmd/root.go 62.75% <100.00%> (+0.04%) ⬆️
pkg/flags/global_builder.go 100.00% <ø> (ø)
pkg/list/extract/components.go 100.00% <100.00%> (+2.40%) ⬆️
pkg/list/extract/metadata.go 98.13% <100.00%> (+0.13%) ⬆️
pkg/list/list_instances.go 82.78% <100.00%> (+0.58%) ⬆️
pkg/schema/schema.go 88.98% <ø> (ø)
pkg/utils/yaml_utils.go 84.88% <100.00%> (+0.20%) ⬆️
cmd/list/components.go 59.11% <75.00%> (-0.41%) ⬇️
cmd/list/instances.go 17.28% <0.00%> (-1.14%) ⬇️

... and 5 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
cmd/cmd_utils.go (2)

115-256: Potential panic: config flag can collide with flags already added to customCommand (e.g., auto-added --identity).
Right now validation + “skip registration” only looks at parentCommand.{PersistentFlags,InheritedFlags}. If a config declares identity (or any other pre-seeded flag on customCommand), the registration loop can still hit a pflag “flag redefined” panic.

Proposed fix (check customCommand first, then parent chain).
@@
-            seen := make(map[string]bool)
+            seen := make(map[string]bool)
             for _, flag := range commandConfig.Flags {
@@
-                existingFlag := parentCommand.PersistentFlags().Lookup(flag.Name)
-                if existingFlag == nil {
-                    existingFlag = parentCommand.InheritedFlags().Lookup(flag.Name)
-                }
+                // Check the custom command itself first (it already has flags like --identity).
+                existingFlag := customCommand.PersistentFlags().Lookup(flag.Name)
+                if existingFlag == nil {
+                    existingFlag = parentCommand.PersistentFlags().Lookup(flag.Name)
+                }
+                if existingFlag == nil {
+                    existingFlag = parentCommand.InheritedFlags().Lookup(flag.Name)
+                }
@@
-                // Flag doesn't exist yet - validate shorthand for new flags only.
+                // Flag doesn't exist yet - validate shorthand for new flags only.
                 if flag.Shorthand != "" {
@@
-                    existingByShorthand := parentCommand.PersistentFlags().ShorthandLookup(flag.Shorthand)
+                    existingByShorthand := customCommand.PersistentFlags().ShorthandLookup(flag.Shorthand)
+                    if existingByShorthand == nil {
+                        existingByShorthand = parentCommand.PersistentFlags().ShorthandLookup(flag.Shorthand)
+                    }
                     if existingByShorthand == nil {
                         existingByShorthand = parentCommand.InheritedFlags().ShorthandLookup(flag.Shorthand)
                     }
@@
             // Process and add flags to the command.
             // Skip flags that are inherited from parent command chain.
             for _, flag := range commandConfig.Flags {
-                existingFlag := parentCommand.PersistentFlags().Lookup(flag.Name)
+                // Skip flags already present on the custom command (e.g., auto-added --identity)
+                // and inherited/persistent flags from the parent chain.
+                existingFlag := customCommand.PersistentFlags().Lookup(flag.Name)
                 if existingFlag == nil {
                     existingFlag = parentCommand.InheritedFlags().Lookup(flag.Name)
                 }
                 if existingFlag != nil {
                     // Flag exists and type was validated above - skip registration (inherit).
                     continue
                 }

115-137: Comment punctuation may trip godot (multi-line // blocks).
Some lines in the added comment blocks end with commas or no period. If godot is strict per-line in this repo, add trailing periods to each // ... line.

Also applies to: 181-184

cmd/list/components.go (1)

110-116: Config path inconsistency in tab completion.

columnsCompletionForComponents references atmosConfig.Components.List.Columns (old path), while getComponentColumns at lines 279-290 uses atmosConfig.List.Components.Columns (new path). Consider aligning both to the new config path.

Suggested fix
 	// Extract column names from atmos.yaml configuration.
-	if len(atmosConfig.Components.List.Columns) > 0 {
+	if len(atmosConfig.List.Components.Columns) > 0 {
 		var columnNames []string
-		for _, col := range atmosConfig.Components.List.Columns {
+		for _, col := range atmosConfig.List.Components.Columns {
 			columnNames = append(columnNames, col.Name)
 		}
 		return columnNames, cobra.ShellCompDirectiveNoFileComp
 	}
🤖 Fix all issues with AI agents
In @pkg/list/extract/components.go:
- Around line 190-237: The stackPattern matching in UniqueComponents currently
uses filepath.Match which is OS-dependent; normalize stackName to use forward
slashes and switch to path.Match to ensure consistent, slash-separated pattern
behavior across platforms: before calling filepath.Match replace backslashes in
stackName with "/" (or canonicalize both stackName and stackPattern to use "/")
and then use path.Match (or call path.Match on the normalized values) instead of
filepath.Match; update the matching logic in UniqueComponents (the block that
handles stackPattern and matched/err) to operate on the normalized strings so
Windows backslashes don't break glob matching.
🧹 Nitpick comments (4)
pkg/list/extract/metadata.go (1)

17-23: Consider caching the TTY check to avoid repeated allocations.

Creating terminal.New() on every call could be inefficient when processing many instances. Based on learnings from this codebase, caching terminal detection at package initialization is the preferred pattern.

♻️ Suggested refactor
+var isTTYCached = sync.OnceValue(func() bool {
+	term := terminal.New()
+	return term.IsTTY(terminal.Stdout)
+})
+
 func getStatusIndicator(enabled, locked bool) string {
-	// Check if stdout is a TTY.
-	term := terminal.New()
-	isTTY := term.IsTTY(terminal.Stdout)
-
-	return getStatusIndicatorWithTTY(enabled, locked, isTTY)
+	return getStatusIndicatorWithTTY(enabled, locked, isTTYCached())
 }

You'll need to add "sync" to imports.

pkg/utils/yaml_utils.go (1)

799-814: Logic is correct; minor redundancy.

The provenance-aware cache re-parse logic works well. Note: the atmosConfig != nil check on line 802 is redundant since lines 780-782 already return an error for nil config. Not a blocker—just a small cleanup opportunity.

🔧 Optional: remove redundant nil check
 	if found {
 		// Cache hit - but check if we need positions and don't have them.
 		// This can happen if the file was first parsed without provenance tracking,
 		// then later requested with provenance enabled.
-		if atmosConfig != nil && atmosConfig.TrackProvenance && len(positions) == 0 {
+		if atmosConfig.TrackProvenance && len(positions) == 0 {
 			// Need to re-parse with position tracking.
 			// Force a cache miss to re-parse and update the cache with positions.
 			found = false
pkg/utils/yaml_utils_test.go (1)

1465-1590: Global cache/stat mutations aren’t restored (possible test flakiness).
These tests reset parsedYAMLCache and parsedYAMLCacheStats but don’t restore the previous state, which can leak into other tests in the utils package.

Example pattern (capture + restore via t.Cleanup).
@@
 func TestUnmarshalYAMLFromFileWithPositions_ProvenanceReparse(t *testing.T) {
+    // Capture old state.
+    parsedYAMLCacheMu.Lock()
+    oldCache := parsedYAMLCache
+    parsedYAMLCacheMu.Unlock()
+    t.Cleanup(func() {
+        parsedYAMLCacheMu.Lock()
+        parsedYAMLCache = oldCache
+        parsedYAMLCacheMu.Unlock()
+    })
+
     // Clear cache to ensure clean state.
     parsedYAMLCacheMu.Lock()
     parsedYAMLCache = make(map[string]*parsedYAMLCacheEntry)
     parsedYAMLCacheMu.Unlock()
@@
 }
cmd/custom_command_flag_conflict_test.go (1)

1207-1508: Optional: reduce repeated fixture/TestKit setup by using newCustomCommandTestHelper.
Not blocking, but it would make the new inheritance tests shorter and more uniform.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 13, 2026
aknysh
aknysh previously approved these changes Jan 13, 2026
@aknysh aknysh merged commit 860160f into main Jan 13, 2026
92 of 93 checks passed
@aknysh aknysh deleted the osterman/provenance-regression-fix branch January 13, 2026 17:04
@github-actions
Copy link
Copy Markdown

These changes were released in v1.204.0-rc.4.

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

Labels

patch A minor, backward compatible change size/xl Extra large size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants