-
-
Notifications
You must be signed in to change notification settings - Fork 136
feat: Add metadata inheritance and metadata.name for workspace key prefix #1812
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Introduces a design proposal for making metadata fields inheritable from base components, solving the versioned component state management problem. Key changes: - New `stacks.inherit.metadata` configuration option (default: true) - All metadata fields inherit except `metadata.inherits` - New `metadata.name` field for logical component identity - Updated workspace_key_prefix auto-generation to use metadata.name This enables DRY patterns for versioned components where the logical identity (for state keys) can be defined once in a base component and inherited by all derived components. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Introduces a design proposal for using metadata.name as the logical component identity in workspace_key_prefix auto-generation. Key points: - New metadata.name field represents logical component identity - Priority: explicit config > metadata.name > metadata.component > Atmos name - Fully backwards compatible - falls back to current behavior if not set - Solves versioned component state stability problem - Works with metadata inheritance for DRY configuration 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
…efix This implements the metadata inheritance feature and workspace_key_prefix calculation improvements: - Add `stacks.inherit.metadata` configuration option (default: true) - Make metadata inheritable from base components (except `metadata.inherits`) - Add `metadata.name` field for logical component identity - Update workspace_key_prefix auto-generation priority: 1. Explicit backend config 2. metadata.name (new) 3. metadata.component 4. Atmos component name This enables versioned component patterns where state remains stable across version upgrades (e.g., vpc/v1 -> vpc/v2) when using metadata.name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
- Add metadata to list of inherited sections in inheritance docs - Document stacks.inherit.metadata configuration option - Update folder-based versioning to use metadata.name pattern - Remove incorrect settings.workspace_key_prefix examples - Add blog posts for metadata inheritance and stable workspace keys 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
…e_key_prefix pattern - Add explicit convention that metadata.name should use top-level component folder - Document convention in blog post and version management docs - Replace manual workspace_key_prefix patterns with inherited metadata.name in: - git-flow-branches-as-channels.mdx (catalog inheritance pattern) - release-tracks-channels.mdx (both track organization approaches) - terraform-workspace.mdx (add recommended section before advanced) - version-management/index.mdx (best practices) - continuous-version-deployment.mdx (planned divergence examples) - strict-version-pinning.mdx (catalog pattern for versioned components) - folder-based-versioning.mdx (convention callout) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
|
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. |
Dependency Review✅ No vulnerabilities or license issues found.Scanned FilesNone |
📝 WalkthroughWalkthroughAdds default-on metadata inheritance (opt-out via Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant SP as StackProcessor
participant Base as BaseConfigLoader
participant Merge as MetadataMerge
participant Backend as BackendDefaults
participant Out as Output/Describe
SP->>Base: load base & component configs
SP->>SP: check stacks.inherit.metadata (default: true)
alt inheritance enabled
SP->>Merge: mergeMetadata(baseMetadata, componentMetadata)
Merge->>Merge: filter base (exclude inherits / type: abstract)
Merge->>Merge: deep-merge, overlay component (component wins)
Merge-->>SP: finalComponentMetadata
else inheritance disabled
SP-->>SP: finalComponentMetadata = componentMetadata
end
SP->>Out: write finalComponentMetadata into component map
SP->>Backend: processTerraformBackend(finalComponentMetadata)
Backend->>Backend: compute workspace key/prefix:
Backend->>Backend: 1) explicit backend value?
alt explicit present
Backend-->>Out: use explicit
else
Backend->>Backend: 2) metadata.name?
alt metadata.name present
Backend-->>Out: use metadata.name (slashes -> -)
else
Backend->>Backend: 3) metadata.component?
alt metadata.component present
Backend-->>Out: use metadata.component (slashes -> -)
else
Backend-->>Out: use Atmos component name
end
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes
Possibly related PRs
Suggested labels
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
website/docs/design-patterns/version-management/continuous-version-deployment.mdx (1)
236-244: Please drop the old workspace_key_prefix guidanceThe example still tells readers to set
settings.workspace_key_prefix, which is the manual pattern this PR is retiring. To stay consistent, show the stable identity viametadata.name(or inherit from the catalog base) and remove the explicit prefix override. That keeps the doc aligned with the new metadata.name convention.vpc: metadata: - component: vpc-experiment # Pin dev to experiment - settings: - workspace_key_prefix: "vpc" # Keep stable across experiments + name: vpc # Stable identity across experiments + component: vpc-experiment # Pin dev to experiment
🧹 Nitpick comments (3)
pkg/schema/schema.go (1)
438-445: Stacks inheritance surface and default metadata behavior are well-shapedThe
Stacks.Inheritstruct plusStacksInherit.IsMetadataInheritanceEnabled()giving a default oftruelines up cleanly with the docs (“enabled by default, opt-out via atmos.yaml”) and keeps the config surface explicit while preserving sane zero-values.If you ever want extra nil-safety, you could switch the receiver to a value to allow
var s *StacksInheritcallers without risking a panic:-func (s *StacksInherit) IsMetadataInheritanceEnabled() bool { - if s.Metadata == nil { +func (s StacksInherit) IsMetadataInheritanceEnabled() bool { + if s.Metadata == nil { return true } - return *s.Metadata + return *s.Metadata }Also applies to: 447-462
docs/prd/metadata-inheritance.md (2)
26-26: Minor wording simplification.The phrase "each component must define" is slightly redundant since ownership is implied. Consider: "each component must explicitly define its own metadata" → "metadata cannot be inherited from base components."
352-352: Add missing punctuation.Line 352 (the
Exclude metadata.inherits...bullet) is missing a period at the end of the paragraph following the code block.Apply this minor fix:
- - Exclude `metadata.inherits` from being inherited + - Exclude `metadata.inherits` from being inherited.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (20)
docs/prd/metadata-inheritance.md(1 hunks)docs/prd/workspace-key-prefixes.md(1 hunks)internal/exec/stack_processor_backend.go(4 hunks)internal/exec/stack_processor_backend_test.go(2 hunks)internal/exec/stack_processor_merge.go(3 hunks)internal/exec/stack_processor_process_stacks_helpers.go(1 hunks)internal/exec/stack_processor_process_stacks_helpers_inheritance.go(2 hunks)internal/exec/stack_processor_utils.go(1 hunks)pkg/datafetcher/schema/stacks/stack-config/1.0.json(2 hunks)pkg/schema/schema.go(2 hunks)website/blog/2025-11-21-metadata-inheritance.mdx(1 hunks)website/blog/2025-11-21-metadata-name-workspace-keys.mdx(1 hunks)website/docs/cli/commands/terraform/terraform-workspace.mdx(1 hunks)website/docs/core-concepts/stacks/inheritance/inheritance.mdx(3 hunks)website/docs/design-patterns/version-management/continuous-version-deployment.mdx(2 hunks)website/docs/design-patterns/version-management/folder-based-versioning.mdx(6 hunks)website/docs/design-patterns/version-management/git-flow-branches-as-channels.mdx(3 hunks)website/docs/design-patterns/version-management/index.mdx(1 hunks)website/docs/design-patterns/version-management/release-tracks-channels.mdx(2 hunks)website/docs/design-patterns/version-management/strict-version-pinning.mdx(1 hunks)
🧰 Additional context used
🧠 Learnings (14)
📓 Common learnings
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
📚 Learning: 2025-09-29T02:20:11.636Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1540
File: internal/exec/validate_component.go:117-118
Timestamp: 2025-09-29T02:20:11.636Z
Learning: The ValidateComponent function in internal/exec/validate_component.go had its componentSection parameter type refined from `any` to `map[string]any` without adding new parameters. This is a type safety improvement, not a signature change requiring call site updates.
Applied to files:
internal/exec/stack_processor_process_stacks_helpers.gointernal/exec/stack_processor_backend.gointernal/exec/stack_processor_process_stacks_helpers_inheritance.gointernal/exec/stack_processor_merge.go
📚 Learning: 2025-10-08T06:48:07.499Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1602
File: internal/exec/stack_processor_utils.go:968-1003
Timestamp: 2025-10-08T06:48:07.499Z
Learning: The `FindComponentDependenciesLegacy` function in `internal/exec/stack_processor_utils.go` is legacy code that is not actively used and is kept only for backward compatibility purposes.
Applied to files:
internal/exec/stack_processor_process_stacks_helpers.gointernal/exec/stack_processor_backend.gointernal/exec/stack_processor_utils.gointernal/exec/stack_processor_merge.go
📚 Learning: 2024-12-08T14:26:16.972Z
Learnt from: pkbhowmick
Repo: cloudposse/atmos PR: 828
File: pkg/schema/schema.go:98-100
Timestamp: 2024-12-08T14:26:16.972Z
Learning: The `ListConfig` columns array in the `Components` struct can be empty.
Applied to files:
internal/exec/stack_processor_process_stacks_helpers.go
📚 Learning: 2024-11-02T15:35:09.958Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 759
File: internal/exec/terraform.go:366-368
Timestamp: 2024-11-02T15:35:09.958Z
Learning: In `internal/exec/terraform.go`, the workspace cleaning code under both the general execution path and within the `case "init":` block is intentionally duplicated because the code execution paths are different. The `.terraform/environment` file should be deleted before executing `terraform init` in both scenarios to ensure a clean state.
Applied to files:
website/docs/cli/commands/terraform/terraform-workspace.mdxwebsite/docs/design-patterns/version-management/folder-based-versioning.mdx
📚 Learning: 2024-12-03T03:49:30.395Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: website/docs/core-concepts/stacks/yaml-functions/terraform.output.mdx:104-110
Timestamp: 2024-12-03T03:49:30.395Z
Learning: In the documentation for `!terraform.output`, warnings about template variable availability are already covered in other sections, so no need to suggest adding them here.
Applied to files:
website/docs/cli/commands/terraform/terraform-workspace.mdx
📚 Learning: 2025-08-29T20:57:35.423Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1433
File: cmd/theme_list.go:33-36
Timestamp: 2025-08-29T20:57:35.423Z
Learning: In the Atmos codebase, avoid using viper.SetEnvPrefix("ATMOS") with viper.AutomaticEnv() because canonical environment variable names are not exclusive to Atmos and could cause conflicts. Instead, use selective environment variable binding through the setEnv function in pkg/config/load.go with bindEnv(v, "config.key", "ENV_VAR_NAME") for specific environment variables.
Applied to files:
website/docs/cli/commands/terraform/terraform-workspace.mdx
📚 Learning: 2024-12-01T00:33:20.298Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: examples/tests/stacks/catalog/terraform/template-functions-test2/defaults.yaml:28-32
Timestamp: 2024-12-01T00:33:20.298Z
Learning: In `examples/tests/stacks/catalog/terraform/template-functions-test2/defaults.yaml`, `!exec atmos terraform output` is used in examples to demonstrate its usage, even though `!terraform.output` is the recommended approach according to the documentation.
Applied to files:
website/docs/cli/commands/terraform/terraform-workspace.mdxwebsite/docs/design-patterns/version-management/release-tracks-channels.mdx
📚 Learning: 2025-10-07T00:25:16.333Z
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.
Applied to files:
website/blog/2025-11-21-metadata-inheritance.mdxdocs/prd/metadata-inheritance.mdinternal/exec/stack_processor_utils.gowebsite/docs/core-concepts/stacks/inheritance/inheritance.mdx
📚 Learning: 2025-11-10T23:23:39.771Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: toolchain/registry/aqua/aqua_test.go:417-442
Timestamp: 2025-11-10T23:23:39.771Z
Learning: In Atmos toolchain AquaRegistry, tests should not hit real GitHub. Use the options pattern via WithGitHubBaseURL to inject an httptest server URL and make GetLatestVersion/GetAvailableVersions deterministic.
Applied to files:
internal/exec/stack_processor_backend_test.go
📚 Learning: 2025-11-08T19:56:18.660Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1697
File: internal/exec/oci_utils.go:0-0
Timestamp: 2025-11-08T19:56:18.660Z
Learning: In the Atmos codebase, when a function receives an `*schema.AtmosConfiguration` parameter, it should read configuration values from `atmosConfig.Settings` fields rather than using direct `os.Getenv()` or `viper.GetString()` calls. The Atmos pattern is: viper.BindEnv in cmd/root.go binds environment variables → Viper unmarshals into atmosConfig.Settings via mapstructure → business logic reads from the Settings struct. This provides centralized config management, respects precedence, and enables testability. Example: `atmosConfig.Settings.AtmosGithubToken` instead of `os.Getenv("ATMOS_GITHUB_TOKEN")` in functions like `getGHCRAuth` in internal/exec/oci_utils.go.
Applied to files:
internal/exec/stack_processor_backend.go
📚 Learning: 2025-10-13T18:13:54.020Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1622
File: pkg/perf/perf.go:140-184
Timestamp: 2025-10-13T18:13:54.020Z
Learning: In pkg/perf/perf.go, the `trackWithSimpleStack` function intentionally skips ownership checks at call stack depth > 1 to avoid expensive `getGoroutineID()` calls on every nested function. This is a performance optimization for the common single-goroutine execution case (most Atmos commands), accepting the rare edge case of potential metric corruption if multi-goroutine execution occurs at depth > 1. The ~19× performance improvement justifies this trade-off.
Applied to files:
internal/exec/stack_processor_utils.go
📚 Learning: 2024-11-13T21:37:07.852Z
Learnt from: Cerebrovinny
Repo: cloudposse/atmos PR: 764
File: internal/exec/describe_stacks.go:289-295
Timestamp: 2024-11-13T21:37:07.852Z
Learning: In the `internal/exec/describe_stacks.go` file of the `atmos` project written in Go, avoid extracting the stack name handling logic into a helper function within the `ExecuteDescribeStacks` method, even if the logic appears duplicated.
Applied to files:
internal/exec/stack_processor_utils.go
📚 Learning: 2024-12-07T16:16:13.038Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 825
File: internal/exec/helmfile_generate_varfile.go:28-31
Timestamp: 2024-12-07T16:16:13.038Z
Learning: In `internal/exec/helmfile_generate_varfile.go`, the `--help` command (`./atmos helmfile generate varfile --help`) works correctly without requiring stack configurations, and the only change needed was to make `ProcessCommandLineArgs` exportable by capitalizing its name.
Applied to files:
internal/exec/stack_processor_utils.go
🧬 Code graph analysis (3)
internal/exec/stack_processor_backend_test.go (1)
pkg/schema/schema.go (1)
AtmosConfiguration(53-94)
internal/exec/stack_processor_utils.go (3)
pkg/schema/schema.go (1)
Stacks(438-445)pkg/config/const.go (1)
InheritsSectionName(102-102)pkg/merge/merge.go (1)
Merge(389-427)
internal/exec/stack_processor_merge.go (3)
pkg/schema/schema.go (1)
Stacks(438-445)pkg/merge/merge.go (1)
Merge(389-427)pkg/config/const.go (1)
MetadataSectionName(75-75)
🪛 GitHub Actions: Website Preview Build
website/blog/2025-11-21-metadata-name-workspace-keys.mdx
[error] 1-1: Build failed: Docusaurus reported broken links during locale en build. Broken link: /changelog/metadata-name-workspace-keys -> /blog/metadata-inheritance. Command: 'npm run build:site' (exit code 1).
website/docs/cli/commands/terraform/terraform-workspace.mdx
[error] 1-1: Build failed: Docusaurus reported broken links during locale en build. Broken link: /changelog/metadata-name-workspace-keys -> /blog/metadata-inheritance. Command: 'npm run build:site' (exit code 1).
website/docs/design-patterns/version-management/continuous-version-deployment.mdx
[error] 1-1: Build failed: Docusaurus reported broken links during locale en build. Broken link: /changelog/metadata-name-workspace-keys -> /blog/metadata-inheritance. Command: 'npm run build:site' (exit code 1).
website/blog/2025-11-21-metadata-inheritance.mdx
[error] 1-1: Build failed: Docusaurus reported broken links during locale en build. Broken link: /changelog/metadata-name-workspace-keys -> /blog/metadata-inheritance. Command: 'npm run build:site' (exit code 1).
website/docs/design-patterns/version-management/folder-based-versioning.mdx
[error] 1-1: Build failed: Docusaurus reported broken links during locale en build. Broken link: /changelog/metadata-name-workspace-keys -> /blog/metadata-inheritance. Command: 'npm run build:site' (exit code 1).
website/docs/design-patterns/version-management/index.mdx
[error] 1-1: Build failed: Docusaurus reported broken links during locale en build. Broken link: /changelog/metadata-name-workspace-keys -> /blog/metadata-inheritance. Command: 'npm run build:site' (exit code 1).
website/docs/design-patterns/version-management/git-flow-branches-as-channels.mdx
[error] 1-1: Build failed: Docusaurus reported broken links during locale en build. Broken link: /changelog/metadata-name-workspace-keys -> /blog/metadata-inheritance. Command: 'npm run build:site' (exit code 1).
website/docs/core-concepts/stacks/inheritance/inheritance.mdx
[error] 1-1: Build failed: Docusaurus reported broken links during locale en build. Broken link: /changelog/metadata-name-workspace-keys -> /blog/metadata-inheritance. Command: 'npm run build:site' (exit code 1).
website/docs/design-patterns/version-management/strict-version-pinning.mdx
[error] 1-1: Build failed: Docusaurus reported broken links during locale en build. Broken link: /changelog/metadata-name-workspace-keys -> /blog/metadata-inheritance. Command: 'npm run build:site' (exit code 1).
website/docs/design-patterns/version-management/release-tracks-channels.mdx
[error] 1-1: Build failed: Docusaurus reported broken links during locale en build. Broken link: /changelog/metadata-name-workspace-keys -> /blog/metadata-inheritance. Command: 'npm run build:site' (exit code 1).
🪛 LanguageTool
docs/prd/workspace-key-prefixes.md
[typographical] ~66-~66: Consider using a typographic opening quote here.
Context: ...e metadata-inheritance.md) - Represents "what this component IS" vs "where its co...
(EN_QUOTES)
[typographical] ~66-~66: Consider using a typographic close quote here.
Context: ...md) - Represents "what this component IS" vs "where its code lives" ### Updated ...
(EN_QUOTES)
[typographical] ~66-~66: Consider using a typographic opening quote here.
Context: ... Represents "what this component IS" vs "where its code lives" ### Updated Calcu...
(EN_QUOTES)
[typographical] ~66-~66: Consider using a typographic close quote here.
Context: ...s component IS" vs "where its code lives" ### Updated Calculation Logic **New p...
(EN_QUOTES)
[style] ~246-~246: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...endDefaults()similarly forprefix. Update setAzureBackendKey()similarly fork...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
website/docs/design-patterns/version-management/git-flow-branches-as-channels.mdx
[typographical] ~192-~192: Consider using a typographic opening quote here.
Context: ...erits name: vpc → workspace_key_prefix: "vpc" vars: name: "dev-use1...
(EN_QUOTES)
[typographical] ~192-~192: Consider using a typographic close quote here.
Context: ...s name: vpc → workspace_key_prefix: "vpc" vars: name: "dev-use1-vpc...
(EN_QUOTES)
[typographical] ~232-~232: Consider using a typographic opening quote here.
Context: ...erits name: vpc → workspace_key_prefix: "vpc" vars: name: "prod-use...
(EN_QUOTES)
[typographical] ~232-~232: Consider using a typographic close quote here.
Context: ...s name: vpc → workspace_key_prefix: "vpc" vars: name: "prod-use1-vp...
(EN_QUOTES)
docs/prd/metadata-inheritance.md
[style] ~26-~26: Since ownership is already implied, this phrasing may be redundant.
Context: ...d entirely - each component must define its own metadata. ### Problems This Causes ##...
(PRP_OWN)
[grammar] ~352-~352: Please add a punctuation mark at the end of paragraph.
Context: ... Exclude metadata.inherits from being inherited 2. Modify `internal/exec/stack_process...
(PUNCTUATION_PARAGRAPH_END)
website/docs/design-patterns/version-management/strict-version-pinning.mdx
[typographical] ~128-~128: Consider using a typographic opening quote here.
Context: ...erits name: vpc → workspace_key_prefix: "vpc" vars: name: "prod-vpc...
(EN_QUOTES)
[typographical] ~128-~128: Consider using a typographic close quote here.
Context: ...s name: vpc → workspace_key_prefix: "vpc" vars: name: "prod-vpc" ...
(EN_QUOTES)
[typographical] ~130-~130: Consider using a typographic opening quote here.
Context: ...prefix: "vpc" vars: name: "prod-vpc" cidr_block: "10.0.0.0/...
(EN_QUOTES)
[typographical] ~130-~130: Consider using a typographic close quote here.
Context: ...vpc" vars: name: "prod-vpc" cidr_block: "10.0.0.0/16" ``` <...
(EN_QUOTES)
[typographical] ~131-~131: Consider using a typographic opening quote here.
Context: ... name: "prod-vpc" cidr_block: "10.0.0.0/16" ``` ### 2. Maintai...
(EN_QUOTES)
[typographical] ~131-~131: Consider using a typographic close quote here.
Context: ...od-vpc" cidr_block: "10.0.0.0/16" ``` ### 2. Maintain Stable Wor...
(EN_QUOTES)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Acceptance Tests (windows)
- GitHub Check: Summary
🔇 Additional comments (24)
pkg/datafetcher/schema/stacks/stack-config/1.0.json (1)
506-509:metadata.namefield and updatedcustomdocs look consistent with inheritance behaviorAdding
metadata.nameas a logical identity for workspace key generation and clarifying thatmetadata.custominherits whenstacks.inherit.metadatais enabled matches the new stacks inheritance model and is backwards compatible (optional field, no new required keys).Also applies to: 550-551
pkg/schema/schema.go (1)
836-851: BaseComponentMetadata field nicely completes the base component config shapeAdding
BaseComponentMetadataalongside vars/settings/env/auth/providers/hooks keeps the base-component surface symmetric withComponentProcessorResultand gives you a clear slot to carry inherited metadata through the pipeline.website/blog/2025-11-21-metadata-name-workspace-keys.mdx (1)
1-60: Post reads well; please re-check the/blog/metadata-inheritancelink against the preview buildThe explanation and examples around using
metadata.nameas the stable top-level folder identity are clear and match the new convention. Given the reported Docusaurus error about/blog/metadata-inheritance, once this and the companion post are in place, please re-run the website build to confirm that link is now resolved (and adjust any changelog entry if it still points at a mismatched path).website/blog/2025-11-21-metadata-inheritance.mdx (1)
1-61: Nice concise overview of metadata inheritance; verify it clears the previously broken linkThe before/after YAML makes the behavior change obvious, and the config snippet for disabling
stacks.inherit.metadataaligns with the newStacksInheritAPI. Since the build previously reported/blog/metadata-inheritanceas missing, this file should fix that; please rerun the site build to confirm the broken-link check is now clean.internal/exec/stack_processor_process_stacks_helpers.go (1)
48-86: AddingBaseComponentMetadatato ComponentProcessorResult is consistent with the new metadata flowThreading
BaseComponentMetadatathroughComponentProcessorResultmatches the schema-sideBaseComponentConfigchange and gives inheritance helpers a proper place to stash merged base metadata without affecting existing fields.internal/exec/stack_processor_process_stacks_helpers_inheritance.go (2)
18-29: Wiring BaseComponentMetadata alongside other base maps looks consistentInitializing
result.BaseComponentMetadatawith the same capacity hint as vars/settings/env/auth keeps the pattern consistent and avoids nil-map edge cases when later merging.
193-203: Propagating BaseComponentMetadata out of BaseComponentConfig is the right placeAssigning
result.BaseComponentMetadata = baseComponentConfig.BaseComponentMetadatahere mirrors how other base sections are surfaced and keeps all inheritance-derived data flowing through the same struct.website/docs/core-concepts/stacks/inheritance/inheritance.mdx (1)
49-73: Metadata inheritance docs read clearly and match the new behaviorThe “What Gets Inherited” table plus the
:::info Metadata Inheritanceblock do a nice job of spelling out that metadata is inherited while excludingmetadata.inherits, and the small wording tweaks in the Single/Multiple/Multilevel sections keep the story consistent without overloading the reader. Thestacks.inherit.metadata: falseexample is also a helpful escape hatch for older stacks.Also applies to: 81-83, 251-253, 394-395
website/docs/design-patterns/version-management/index.mdx (1)
231-256: Best-practice shift to metadata.name for stable keys is coherentUsing
metadata.nameas the stable identity and keeping version info inmetadata.componentwhile flagging versionedworkspace_key_prefixpatterns as WRONG lines up well with the new backend behavior and should make upgrades much less brittle. The example YAML and cross-link to folder-based versioning are tight and actionable.website/docs/cli/commands/terraform/terraform-workspace.mdx (1)
55-85: Nice, this puts the simple metadata.name pattern before the advanced templatingThe catalog + prod stack example makes it obvious how
metadata.namedrives a stableworkspace_key_prefixwithout extra config, and parking the Go-templateworkspace_key_prefixunder an “Advanced” heading keeps that escape hatch available without encouraging it as the default. This matches the backend semantics you’re testing around metadata.name.Also, CI is currently failing on a Docusaurus broken link:
/changelog/metadata-name-workspace-keys -> /blog/metadata-inheritance. It doesn’t appear in this file, but you’ll want to update or remove that link elsewhere before merging.Also applies to: 87-98
internal/exec/stack_processor_merge.go (1)
136-152: Metadata inheritance merge and wiring into backend look solidUsing
finalComponentMetadataas the merge of base + component metadata (with component last) matches the documented “component wins” behavior, and threading that same merged map into both the publicMetadatasection andterraformBackendConfig.componentMetadatakeeps backend defaults (e.g., metadata.name-based workspace prefixes) aligned with what users see in the processed stack. The conditional onIsMetadataInheritanceEnabled()plus a non-empty base map keeps the fast path cheap.Also applies to: 161-163, 169-180
internal/exec/stack_processor_backend_test.go (1)
14-28: Good coverage for metadata.name-driven workspace key behaviorAdding
componentMetadatato the test matrix and asserting priority/fallback rules across S3/GCS/Azure (incl. slash normalization, explicitworkspace_key_prefixprecedence, and empty/absent name cases) gives strong confidence that the new backend logic matches the documented semantics. Normalizing nil metadata to an empty map in the test harness is also a nice touch to keep the call shape predictable.Also applies to: 235-347, 354-366
website/docs/design-patterns/version-management/folder-based-versioning.mdx (4)
103-165: Catalog inheritance pattern is well-documented and clear.The introduction of the catalog-based base component with
metadata.nameeffectively demonstrates how to stabilize workspace keys across version changes. The YAML structure is correct, and the inheritance pattern usingmetadata.inheritsis properly explained.
208-216: Metadata.name convention clearly established.The tip section effectively communicates the convention that
metadata.nameshould use the top-level component folder name. The examples make the pattern predictable and easy to follow.
272-303: Rollback strategy leverages catalog inheritance well.The section correctly shows how updating the base catalog component automatically propagates to all derived components. The zero-downtime rollback explanation is valuable context.
1-400: Review comment is inaccurate—the file doesn't contain the cited broken link.The search found no
/blog/metadata-inheritancelinks in the reviewed filefolder-based-versioning.mdx. The link actually exists in the blog postwebsite/blog/2025-11-21-metadata-name-workspace-keys.mdx(line 18), and that link target is valid—the destination blog postwebsite/blog/2025-11-21-metadata-inheritance.mdxexists. No action needed on the file under review.Likely an incorrect or invalid review comment.
website/docs/design-patterns/version-management/release-tracks-channels.mdx (3)
112-127: Catalog base definitions establish clear metadata inheritance pattern across both track organizations.Both "Tracks Per Component" and "Track-First Organization" approaches properly define base catalog components with
metadata.namefor logical identity. This makes the pattern consistent regardless of folder organization choice.Also applies to: 218-233
129-153: Stack-level component inheritance correctly leverages catalog metadata.Both production stack examples show proper usage of
metadata.inheritsto pull from base defaults, with clear comments explaining thatworkspace_key_prefixis inherited frommetadata.name. This reinforces the pattern established in file 1.Also applies to: 235-259
1-300: The review comment references non-existent broken links.After comprehensive search across the codebase, the link
/changelog/metadata-name-workspace-keys→/blog/metadata-inheritancedoes not exist in eitherrelease-tracks-channels.mdxorfolder-based-versioning.mdx.The only occurrence of
/blog/metadata-inheritanceexists in a separate blog post file (website/blog/2025-11-21-metadata-name-workspace-keys.mdx), where it is a valid link. The files cited in the review contain no such broken link pattern.All verified internal links in both documentation files are properly formed and reference valid paths.
Likely an incorrect or invalid review comment.
docs/prd/metadata-inheritance.md (5)
1-120: PRD effectively articulates the problem and proposed solution.The problem statement clearly explains why metadata inheritance is needed: preventing silent state loss during component version upgrades and enabling DRY metadata patterns. The proposed solution with
stacks.inherit.metadataconfiguration and the newmetadata.namefield is well-reasoned and backward-compatible.
121-165: Workspace key priority logic is clear and well-documented.The four-level priority (explicit prefix > metadata.name > metadata.component > Atmos name) is sensible and gives users appropriate control. The convention of setting
metadata.nameto the top-level folder name makes the pattern predictable.
166-282: Use cases comprehensively cover real-world scenarios.All four use cases—versioned components, release tracks, governance patterns, and multi-instance components—demonstrate practical value of the feature. The examples are clear and properly annotated with expected outcomes.
283-324: Breaking change analysis is thorough and honest.The assessment that breakage risk is low (because metadata wasn't previously inherited) is sound. Providing both a config-level opt-out and field-level overrides gives users adequate migration paths.
325-392: Implementation plan provides clear direction for backend team.Schema changes, processing updates, and JSON schema modifications are all specified. The plan correctly identifies the three key processing areas: stack utilities, merge logic, and backend defaults.
…ession Fix regression in `atmos list instances` where all component instances were being filtered out due to inheriting `metadata.type: abstract` from base components. ## Changes **Code fixes:** - Exclude `metadata.type: abstract` from metadata inheritance in stack_processor_utils.go - Abstract is a base component designation that should not propagate to child components - Other metadata.type values (e.g., 'real', custom types) continue to be inherited - Update code comments to clarify both 'inherits' and 'type: abstract' exclusions **Documentation updates:** - Update metadata-inheritance.md PRD to document the exclusion - Update inheritance.mdx website docs with clear explanation - Clarify that child components inheriting from abstract components are concrete implementations ## Test Results - TestCLICommands/atmos_list_instances - PASS - TestCLICommands/atmos_list_instances_no_tty - PASS - All internal/exec tests - PASS - Abstract component tests - PASS ## Impact - atmos list instances now correctly returns all non-abstract component instances - Base abstract components retain metadata.type: abstract - Child components do not inherit the abstract type designation - Other metadata fields continue to be inherited as designed 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Add extensive unit tests for metadata.name inheritance and metadata.type: abstract exclusion. ## What Changed - Added `internal/exec/metadata_inheritance_test.go` with 653 lines of comprehensive tests - Fixed broken changelog link in metadata-name-workspace-keys blog post ## Test Coverage Added ### 6 Major Test Functions (24+ test cases): 1. **TestMetadataNameInheritance** - Verifies metadata.name inheritance from base components and usage in workspace_key_prefix calculation 2. **TestMetadataTypeAbstractExclusion** - Confirms metadata.type: abstract is NOT inherited (prevents child components from becoming abstract) 3. **TestMetadataInheritsNotInherited** - Validates metadata.inherits is not inherited (it's the meta-property) 4. **TestMetadataInheritanceConfiguration** - Tests stacks.inherit.metadata flag (enabled/disabled) 5. **TestMetadataDeepMerge** - Verifies deep merging of nested metadata fields 6. **TestVersionedComponentUpgrade** - Validates PRIMARY use case from PRD (stable state paths across version upgrades) ## Coverage Improvement **Before**: ~40% coverage - Backend configuration with metadata.name tested - Abstract component handling tested - Missing: inheritance behavior, configuration flags, PRD use cases **After**: ~75-85% coverage (estimated) - All critical functionality tested - Edge cases covered - Primary use case validated - Configuration flags tested ## Test Results All tests PASS: - 24 new test cases added - All existing tests still pass (no regressions) - Website builds successfully ## Why This Matters The PR implemented metadata inheritance and metadata.name features but was missing critical test coverage for: - metadata.name inheritance from base components - metadata.type: abstract exclusion (commit af24538) - stacks.inherit.metadata configuration flag - Versioned component upgrade scenario (primary PRD use case) These tests ensure the feature works as documented and prevents regressions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
internal/exec/metadata_inheritance_test.go (1)
587-617: Test helper accuracy concern: filterBaseMetadata differs from production code.The test helper
filterBaseMetadata(lines 603-617) filters metadata fields before merging, but the production code in stack_processor_merge.go (lines 136-152) comments that filtering is "already excluded during collection" - which happens in stack_processor_utils.go (lines 1724-1748).However, your test helper implements the filtering correctly and matches the production logic in stack_processor_utils.go. The test approach is valid.
Minor suggestion: Add a comment explaining that this helper replicates the filtering logic from
processBaseComponentConfigInternalin stack_processor_utils.go for testing purposes, to make the relationship explicit.Apply this diff to clarify the helper's purpose:
-// filterBaseMetadata filters base metadata to exclude 'inherits' and 'type: abstract'. +// filterBaseMetadata filters base metadata to exclude 'inherits' and 'type: abstract'. +// This replicates the filtering logic from processBaseComponentConfigInternal in stack_processor_utils.go. func filterBaseMetadata(baseMetadata map[string]any) map[string]any {
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (6)
docs/prd/metadata-inheritance.md(1 hunks)internal/exec/metadata_inheritance_test.go(1 hunks)internal/exec/stack_processor_merge.go(3 hunks)internal/exec/stack_processor_utils.go(1 hunks)website/blog/2025-11-21-metadata-name-workspace-keys.mdx(1 hunks)website/docs/core-concepts/stacks/inheritance/inheritance.mdx(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- website/blog/2025-11-21-metadata-name-workspace-keys.mdx
- website/docs/core-concepts/stacks/inheritance/inheritance.mdx
🧰 Additional context used
🧠 Learnings (12)
📓 Common learnings
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
📚 Learning: 2025-09-29T02:20:11.636Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1540
File: internal/exec/validate_component.go:117-118
Timestamp: 2025-09-29T02:20:11.636Z
Learning: The ValidateComponent function in internal/exec/validate_component.go had its componentSection parameter type refined from `any` to `map[string]any` without adding new parameters. This is a type safety improvement, not a signature change requiring call site updates.
Applied to files:
internal/exec/stack_processor_merge.gointernal/exec/stack_processor_utils.gointernal/exec/metadata_inheritance_test.go
📚 Learning: 2025-10-07T00:25:16.333Z
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.
Applied to files:
docs/prd/metadata-inheritance.md
📚 Learning: 2025-10-08T06:48:07.499Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1602
File: internal/exec/stack_processor_utils.go:968-1003
Timestamp: 2025-10-08T06:48:07.499Z
Learning: The `FindComponentDependenciesLegacy` function in `internal/exec/stack_processor_utils.go` is legacy code that is not actively used and is kept only for backward compatibility purposes.
Applied to files:
internal/exec/stack_processor_utils.go
📚 Learning: 2024-11-19T23:00:45.899Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 795
File: internal/exec/stack_processor_utils.go:378-386
Timestamp: 2024-11-19T23:00:45.899Z
Learning: In the `ProcessYAMLConfigFile` function within `internal/exec/stack_processor_utils.go`, directory traversal in stack imports is acceptable and should not be restricted.
Applied to files:
internal/exec/stack_processor_utils.go
📚 Learning: 2025-10-13T18:13:54.020Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1622
File: pkg/perf/perf.go:140-184
Timestamp: 2025-10-13T18:13:54.020Z
Learning: In pkg/perf/perf.go, the `trackWithSimpleStack` function intentionally skips ownership checks at call stack depth > 1 to avoid expensive `getGoroutineID()` calls on every nested function. This is a performance optimization for the common single-goroutine execution case (most Atmos commands), accepting the rare edge case of potential metric corruption if multi-goroutine execution occurs at depth > 1. The ~19× performance improvement justifies this trade-off.
Applied to files:
internal/exec/stack_processor_utils.go
📚 Learning: 2024-10-20T00:41:57.135Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 731
File: internal/exec/validate_stacks.go:93-98
Timestamp: 2024-10-20T00:41:57.135Z
Learning: When downloading schema files in `internal/exec/validate_stacks.go`, use a consistent temporary file name to overwrite the file each time and avoid creating multiple temporary files.
Applied to files:
internal/exec/metadata_inheritance_test.go
📚 Learning: 2024-12-07T16:19:01.683Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 825
File: internal/exec/terraform.go:30-30
Timestamp: 2024-12-07T16:19:01.683Z
Learning: In `internal/exec/terraform.go`, skipping stack validation when help flags are present is not necessary.
Applied to files:
internal/exec/metadata_inheritance_test.go
📚 Learning: 2024-11-02T15:35:09.958Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 759
File: internal/exec/terraform.go:366-368
Timestamp: 2024-11-02T15:35:09.958Z
Learning: In `internal/exec/terraform.go`, the workspace cleaning code under both the general execution path and within the `case "init":` block is intentionally duplicated because the code execution paths are different. The `.terraform/environment` file should be deleted before executing `terraform init` in both scenarios to ensure a clean state.
Applied to files:
internal/exec/metadata_inheritance_test.go
📚 Learning: 2024-12-07T16:16:13.038Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 825
File: internal/exec/helmfile_generate_varfile.go:28-31
Timestamp: 2024-12-07T16:16:13.038Z
Learning: In `internal/exec/helmfile_generate_varfile.go`, the `--help` command (`./atmos helmfile generate varfile --help`) works correctly without requiring stack configurations, and the only change needed was to make `ProcessCommandLineArgs` exportable by capitalizing its name.
Applied to files:
internal/exec/metadata_inheritance_test.go
📚 Learning: 2024-11-13T21:37:07.852Z
Learnt from: Cerebrovinny
Repo: cloudposse/atmos PR: 764
File: internal/exec/describe_stacks.go:289-295
Timestamp: 2024-11-13T21:37:07.852Z
Learning: In the `internal/exec/describe_stacks.go` file of the `atmos` project written in Go, avoid extracting the stack name handling logic into a helper function within the `ExecuteDescribeStacks` method, even if the logic appears duplicated.
Applied to files:
internal/exec/metadata_inheritance_test.go
📚 Learning: 2025-11-11T03:47:45.878Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: toolchain/add_test.go:67-77
Timestamp: 2025-11-11T03:47:45.878Z
Learning: In the cloudposse/atmos codebase, tests should prefer t.Setenv for environment variable setup/teardown instead of os.Setenv/Unsetenv to ensure test-scoped isolation.
Applied to files:
internal/exec/metadata_inheritance_test.go
🧬 Code graph analysis (3)
internal/exec/stack_processor_merge.go (3)
pkg/schema/schema.go (1)
Stacks(438-445)pkg/merge/merge.go (1)
Merge(389-427)pkg/config/const.go (1)
MetadataSectionName(75-75)
internal/exec/stack_processor_utils.go (3)
pkg/schema/schema.go (1)
Stacks(438-445)pkg/config/const.go (1)
InheritsSectionName(102-102)pkg/merge/merge.go (1)
Merge(389-427)
internal/exec/metadata_inheritance_test.go (3)
pkg/schema/schema.go (2)
Stacks(438-445)StacksInherit(448-453)internal/exec/stack_processor_process_stacks_helpers.go (1)
ComponentProcessorResult(48-86)pkg/config/const.go (1)
InheritsSectionName(102-102)
🪛 LanguageTool
docs/prd/metadata-inheritance.md
[style] ~26-~26: Since ownership is already implied, this phrasing may be redundant.
Context: ...d entirely - each component must define its own metadata. ### Problems This Causes ##...
(PRP_OWN)
[grammar] ~354-~354: Please add a punctuation mark at the end of paragraph.
Context: ... Exclude metadata.inherits from being inherited 2. Modify `internal/exec/stack_process...
(PUNCTUATION_PARAGRAPH_END)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Acceptance Tests (windows)
- GitHub Check: Acceptance Tests (macos)
- GitHub Check: Acceptance Tests (linux)
- GitHub Check: Summary
🔇 Additional comments (7)
internal/exec/stack_processor_merge.go (1)
136-152: LGTM! Metadata inheritance implementation follows established patterns.The metadata merging logic correctly:
- Gates on
IsMetadataInheritanceEnabled()for opt-out behavior- Follows the same merge order as other sections (base → component, component wins)
- Passes the final merged metadata to backend processing
One clarification: The comment states that
inheritsandtype: abstractare "already excluded during collection." Verify this happens in the base component processing path (lines 1724-1748 in stack_processor_utils.go), where the filtering actually occurs. The comment is accurate but refers to logic in a different file.docs/prd/metadata-inheritance.md (2)
103-122: LGTM! Inheritance behavior is clearly documented.The inheritance table and special exclusions section accurately reflect the implementation:
metadata.inheritsis excluded (it's the meta-property defining inheritance)metadata.type: abstractis excluded (base component designation)- Other fields are inherited and can be overridden
This matches the filtering logic in internal/exec/stack_processor_utils.go lines 1730-1741.
143-167: Documentation accurately reflects implementation—no changes needed.The priority order in the PRD matches the backend processing logic exactly. The explicit
backend.s3.workspace_key_prefixis checked first (line 87); if present and non-empty, the block is skipped entirely, preserving the user override. The fallback chain then follows:metadata.name(line 90),metadata.component(line 92), then the Atmos component name default (line 88). This same pattern is consistently applied to S3, GCS, and Azure backends.internal/exec/stack_processor_utils.go (1)
1724-1748: LGTM! Base component metadata filtering and merging is correct.The implementation properly:
- Filters out
metadata.inherits(line 1732) - the meta-property defining inheritance- Excludes
type: abstract(lines 1736-1740) - base component designation- Merges the filtered base metadata with accumulated
BaseComponentMetadata- Gates the entire block on
IsMetadataInheritanceEnabled()This filtering happens during base component processing, which is what the comment in stack_processor_merge.go refers to when it says "already excluded during collection."
One edge case to consider: If a base component has
type: "concrete"(or any non-abstract type), it will be inherited. Is this intentional? Based on the PRD (lines 109, 250-260 in metadata-inheritance.md), this appears correct - onlytype: abstractshould be excluded.internal/exec/metadata_inheritance_test.go (3)
15-204: LGTM! Comprehensive test coverage for metadata.name inheritance.The test suite covers critical scenarios:
- Basic inheritance from base components
- Component override of inherited values
- Versioned components (the primary use case)
- Inheritance disabled via configuration flag
- Slash normalization in metadata.name
- Empty/missing name handling
- Multiple component instances with different names
Each test verifies both the metadata merging and the downstream effect on workspace_key_prefix calculation by calling the actual
processTerraformBackendfunction, providing good integration coverage.
208-335: LGTM! Type exclusion logic is thoroughly tested.The tests correctly verify:
type: abstractis excluded from inheritance (lines 221-232)- Other type values like
real-componentARE inherited (lines 249-260)- Component can explicitly override inherited type (lines 262-274)
- Other metadata fields are still inherited when type is excluded (lines 322-332)
This matches the PRD specification (lines 109, 119-122 in metadata-inheritance.md) that only
type: abstractis excluded as a special case.
619-643: Simplified merge helper is adequate for tests.The
simpleMergehelper uses a recursive approach for deep merging maps (lines 631-637), which is simpler than the productionpkg/merge.Mergethat handles list merge strategies and other complexities.For unit testing metadata inheritance, this simplified version is sufficient since metadata typically contains nested maps rather than complex list structures. The comment on line 620 appropriately notes this difference.
The `atmos describe config` output now includes the `stacks.inherit` field, which was added as part of the metadata inheritance feature. This field controls whether metadata is inherited from base components. This is an expected change in the configuration schema and output format. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
…e resolution Apply metadata inheritance when processing stacks in ExecuteDescribeStacks to ensure inherited metadata fields like terraform_workspace are correctly resolved. Previously, ExecuteDescribeStacks only merged YAML imports via FindStacksMap but did not apply component inheritance, causing components with metadata.inherits to ignore inherited metadata fields. Changes: - Call ProcessBaseComponentConfig to resolve inheritance chains for each component - Merge base component metadata with component's own metadata (component overrides base) - Remove terraform_workspace_pattern/template when explicit terraform_workspace exists to ensure explicit values take precedence over inherited/imported patterns Fixes TestDescribeStacksWithFilter7 which expects test/test-component-override-3 to inherit terraform_workspace from its inheritance chain. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1812 +/- ##
==========================================
+ Coverage 71.98% 72.03% +0.04%
==========================================
Files 471 471
Lines 45222 45299 +77
==========================================
+ Hits 32555 32631 +76
+ Misses 10071 10067 -4
- Partials 2596 2601 +5
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this 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
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (5)
pkg/schema/schema.go(2 hunks)tests/snapshots/TestCLICommands_atmos_describe_config.stdout.golden(1 hunks)website/blog/2025-11-21-metadata-name-workspace-keys.mdx(1 hunks)website/docs/core-concepts/components/terraform/backends.mdx(1 hunks)website/docs/core-concepts/components/terraform/workspaces.mdx(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- pkg/schema/schema.go
🧰 Additional context used
📓 Path-based instructions (2)
website/**
📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)
website/**: Update website documentation in thewebsite/directory when adding new features, ensure consistency between CLI help text and website documentation, and follow the website's documentation structure and style
Keep website code in thewebsite/directory, follow the existing website architecture and style, and test website changes locally before committing
Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases
Files:
website/docs/core-concepts/components/terraform/backends.mdxwebsite/docs/core-concepts/components/terraform/workspaces.mdxwebsite/blog/2025-11-21-metadata-name-workspace-keys.mdx
website/blog/**/*.mdx
📄 CodeRabbit inference engine (CLAUDE.md)
PRs labeled minor/major MUST include blog post at website/blog/YYYY-MM-DD-feature-name.mdx with YAML front matter, after intro, tags (feature/enhancement/bugfix/contributors), and author (committer's GitHub username).
Files:
website/blog/2025-11-21-metadata-name-workspace-keys.mdx
🧠 Learnings (6)
📚 Learning: 2025-10-07T00:25:16.333Z
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.
Applied to files:
website/docs/core-concepts/components/terraform/backends.mdxtests/snapshots/TestCLICommands_atmos_describe_config.stdout.golden
📚 Learning: 2025-08-29T20:57:35.423Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1433
File: cmd/theme_list.go:33-36
Timestamp: 2025-08-29T20:57:35.423Z
Learning: In the Atmos codebase, avoid using viper.SetEnvPrefix("ATMOS") with viper.AutomaticEnv() because canonical environment variable names are not exclusive to Atmos and could cause conflicts. Instead, use selective environment variable binding through the setEnv function in pkg/config/load.go with bindEnv(v, "config.key", "ENV_VAR_NAME") for specific environment variables.
Applied to files:
website/docs/core-concepts/components/terraform/backends.mdx
📚 Learning: 2025-01-19T15:49:15.593Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 955
File: tests/snapshots/TestCLICommands_atmos_validate_editorconfig_--help.stdout.golden:0-0
Timestamp: 2025-01-19T15:49:15.593Z
Learning: In future commits, the help text for Atmos CLI commands should be limited to only show component and stack parameters for commands that actually use them. This applies to the example usage section in command help text.
Applied to files:
website/docs/core-concepts/components/terraform/backends.mdx
📚 Learning: 2024-12-01T00:33:20.298Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: examples/tests/stacks/catalog/terraform/template-functions-test2/defaults.yaml:28-32
Timestamp: 2024-12-01T00:33:20.298Z
Learning: In `examples/tests/stacks/catalog/terraform/template-functions-test2/defaults.yaml`, `!exec atmos terraform output` is used in examples to demonstrate its usage, even though `!terraform.output` is the recommended approach according to the documentation.
Applied to files:
website/docs/core-concepts/components/terraform/backends.mdx
📚 Learning: 2025-03-18T12:26:25.329Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1149
File: tests/snapshots/TestCLICommands_atmos_vendor_pull_ssh.stderr.golden:7-7
Timestamp: 2025-03-18T12:26:25.329Z
Learning: In the Atmos project, typos or inconsistencies in test snapshot files (such as "terrafrom" instead of "terraform") may be intentional as they capture the exact output of commands and should not be flagged as issues requiring correction.
Applied to files:
website/docs/core-concepts/components/terraform/backends.mdxtests/snapshots/TestCLICommands_atmos_describe_config.stdout.golden
📚 Learning: 2024-11-02T15:35:09.958Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 759
File: internal/exec/terraform.go:366-368
Timestamp: 2024-11-02T15:35:09.958Z
Learning: In `internal/exec/terraform.go`, the workspace cleaning code under both the general execution path and within the `case "init":` block is intentionally duplicated because the code execution paths are different. The `.terraform/environment` file should be deleted before executing `terraform init` in both scenarios to ensure a clean state.
Applied to files:
website/docs/core-concepts/components/terraform/workspaces.mdx
🪛 LanguageTool
website/blog/2025-11-21-metadata-name-workspace-keys.mdx
[grammar] ~30-~30: Please add a punctuation mark at the end of paragraph.
Context: ...name - Easy to forget when creating new components ## The Solution metadata.name provi...
(PUNCTUATION_PARAGRAPH_END)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Acceptance Tests (windows)
- GitHub Check: Acceptance Tests (linux)
- GitHub Check: Acceptance Tests (macos)
- GitHub Check: Summary
🔇 Additional comments (5)
tests/snapshots/TestCLICommands_atmos_describe_config.stdout.golden (1)
46-46: Snapshot correctly reflects the new inherit field.The addition of the
inheritfield to the stacks config output is spot-on. The empty object representation is appropriate here—default inheritance behavior is computed at runtime rather than serialized in the config output, consistent with other fields in this snapshot.website/blog/2025-11-21-metadata-name-workspace-keys.mdx (1)
1-76: Blog post meets all content guidelines.YAML frontmatter is complete (slug, title, authors, tags),
<!--truncate-->is correctly placed, and the post clearly explains the problem, solution, and convention formetadata.name. The progression from motivation through concrete examples to a convention table is well-structured.website/docs/core-concepts/components/terraform/backends.mdx (2)
176-195: Auto-generation priority and metadata.name usage are clearly documented.Lines 176–182 correctly specify the three-step priority (
metadata.name→metadata.component→ component name) with slash-to-dash normalization. The tip (lines 184–195) reinforces this with a practical versioned-component example. The cross-reference toTerraform Workspacesdocumentation helps users understand howmetadata.nameconnects workspace generation to state paths.
155-175: Update context: workspace_key_prefix auto-generation.Line 155 notes
workspace_key_prefixis "optional," and lines 176–182 explain auto-generation. This clarifies intent well—no explicit setting required if you rely on defaults. Good progression from manual example (lines 157–174) to auto-generation explanation.website/docs/core-concepts/components/terraform/workspaces.mdx (1)
194-240: Duplication claim is unsubstantiated—section appears only once in the file.The grep verification confirms there is exactly one instance of "How Workspaces Relate to State Paths" in the workspaces.mdx file. The new content is clean, clearly explains the two-level S3 state hierarchy, documents the auto-generation priority (explicit backend →
metadata.name→metadata.component→ component name), and provides a practical YAML example for versioned components. The cross-reference to backends documentation supports discoverability.
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
…emented 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
…ace_template
Fixed confusing workspace_key_prefix examples and added comprehensive
documentation for the workspace configuration system.
**Changes:**
1. **Fixed confusing backend examples** (configure-terraform-backend.mdx, backends.mdx)
- Replaced placeholder text with realistic values
- Changed from: `workspace_key_prefix = "<component name, e.g. vpc>"`
- Changed to: `workspace_key_prefix = "vpc" # Or any stable identifier`
2. **Added comprehensive workspace_key_prefix documentation** (vendor-manifest.mdx)
- Priority order table showing 4-level calculation
- Recommended approach using metadata.name (NEW feature)
- Alternative explicit override approach
- Legacy manual workaround (pre-metadata.name)
- Clear "Result:" comments showing effective calculated values
3. **Documented terraform_workspace_template** (workspaces.mdx)
- Previously undocumented feature with full Go template support
- Priority order: template > pattern > workspace > auto-generated
- Usage examples with Sprig functions
- When to use guide (templates vs patterns vs static)
4. **Added workspace NAME vs KEY PREFIX clarification** (workspaces.mdx)
- Note box distinguishing the two independent concepts
- Workspace NAME: controlled by terraform_workspace_template/pattern/workspace
- Workspace KEY PREFIX: controlled by metadata.name or explicit backend config
- State path diagram showing both parts: {workspace_key_prefix}/{workspace}/terraform.tfstate
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
Added links to official HashiCorp Terraform documentation for workspace and workspace_key_prefix concepts to clarify these are Terraform features, not Atmos inventions. **Changes:** - Added link to Terraform workspaces documentation - Added link to S3 backend workspace_key_prefix parameter documentation - Clarified these are "Terraform concepts" in the note box - Added references to official docs in vendor-manifest.mdx **References:** - https://developer.hashicorp.com/terraform/cli/workspaces - https://developer.hashicorp.com/terraform/language/state/workspaces - https://developer.hashicorp.com/terraform/language/backend/s3 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Replaced "Advanced:" heading with PillBox component to match design pattern documentation style. **Changes:** - Import PillBox component - Replace "### Advanced: Using Go Templates" with "### Using Go Templates" + PillBox - Consistent with design patterns documentation style 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Changed "Workspace NAME vs Workspace KEY PREFIX" to "Workspace Name vs Workspace Key Prefix" for better readability. All-caps style is harder to read and less professional. **Changes:** - Note box title: "NAME" → "Name", "KEY PREFIX" → "Key Prefix" - Bullet points: "Workspace NAME" → "Workspace name", "Workspace KEY PREFIX" → "Workspace key prefix" - Maintained bold emphasis on the terms 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Changed to proper title case: - "Workspace name" → "Workspace Name" - "Workspace key prefix" → "Workspace Key Prefix" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
website/docs/quick-start/advanced/configure-terraform-backend.mdx (1)
195-218: Update documentation to include metadata.name in workspace key precedence.The current documentation explains that without
workspace_key_prefix, the component name is used automatically with slashes replaced by dashes, but doesn't mention the newmetadata.namefeature introduced in this PR. Update this section to document the new workspace key precedence and recommendmetadata.nameas the stable, logical component identity for workspace keys.Consider restructuring this section to explain the workspace key generation order:
- Explicit
backend.s3.workspace_key_prefix(highest priority)metadata.name(recommended stable identity—new in this PR)- Component identity (
metadata.component)- Component path/name (fallback, auto-normalized slashes to dashes)
Add an example showing how to use
metadata.namefor workspace key stability, similar to how versioned components can benefit from this approach.
🧹 Nitpick comments (4)
website/docs/quick-start/advanced/configure-terraform-backend.mdx (3)
139-139: Clarify the preferred approach for stable workspace identifiers.The documentation currently guides users to set explicit
workspace_key_prefixvalues or rely on the component name (with slashes replaced by dashes), but this PR introducesmetadata.nameas the preferred stable identifier for workspace keys. Update the comment to mentionmetadata.nameas the recommended approach in the new workspace key precedence order: explicit backend prefix →metadata.name→ component identity → component path.- workspace_key_prefix = "vpc" # Or any stable identifier for your component + workspace_key_prefix = "vpc" # Or better: use metadata.name for stable identity
320-322: Clarify automatic workspace_key_prefix generation now includes metadata.name.This paragraph states that Atmos will "automatically add
workspace_key_prefixfor the component," but doesn't explain the new role ofmetadata.namein this automatic generation. Clarify thatmetadata.name(when defined) is now the preferred identifier used during this automatic process, as part of the new precedence order.
388-392: Consider showing metadata.name as an alternative approach in multi-instance examples.These examples demonstrate explicit
workspace_key_prefixconfiguration for multiple component instances (vpc/1andvpc/2). With the newmetadata.namefeature, these could be simplified by definingmetadata.nameat a base component level, reducing duplication and improving maintainability. Consider adding an example showing howmetadata.namecan serve as a stable identity across both instances.Also applies to: 407-410
docs/prd/workspace-key-prefixes.md (1)
244-247: Streamline parallel sentence structure to improve readability.Three consecutive sentences open with "Update", which creates mechanical repetition. While this emphasizes the parallel changes needed across backend implementations, the effect is slightly awkward.
Update `setS3BackendDefaults()` similarly for `prefix`. -Update `setGCSBackendDefaults()` similarly for `prefix`. +Apply the same changes to `setGCSBackendDefaults()` for the `prefix` field. -Update `setAzureBackendKey()` similarly for `key`. +Do likewise for `setAzureBackendKey()` to handle the `key` field.Alternatively, consolidate into a list format for clearer parallelism:
-Update `setS3BackendDefaults()` similarly for `prefix`. - -Update `setGCSBackendDefaults()` similarly for `prefix`. - -Update `setAzureBackendKey()` similarly for `key`. +Update backend default functions similarly: +- `setS3BackendDefaults()` for `prefix` +- `setGCSBackendDefaults()` for `prefix` +- `setAzureBackendKey()` for `key`
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (7)
docs/prd/metadata-inheritance.md(1 hunks)docs/prd/workspace-key-prefixes.md(1 hunks)website/blog/2025-11-21-metadata-name-workspace-keys.mdx(1 hunks)website/docs/core-concepts/components/terraform/backends.mdx(2 hunks)website/docs/core-concepts/components/terraform/workspaces.mdx(2 hunks)website/docs/core-concepts/vendor/vendor-manifest.mdx(1 hunks)website/docs/quick-start/advanced/configure-terraform-backend.mdx(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- website/blog/2025-11-21-metadata-name-workspace-keys.mdx
🚧 Files skipped from review as they are similar to previous changes (1)
- website/docs/core-concepts/components/terraform/backends.mdx
🧰 Additional context used
📓 Path-based instructions (2)
website/**
📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)
website/**: Update website documentation in thewebsite/directory when adding new features, ensure consistency between CLI help text and website documentation, and follow the website's documentation structure and style
Keep website code in thewebsite/directory, follow the existing website architecture and style, and test website changes locally before committing
Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases
Files:
website/docs/quick-start/advanced/configure-terraform-backend.mdxwebsite/docs/core-concepts/components/terraform/workspaces.mdxwebsite/docs/core-concepts/vendor/vendor-manifest.mdx
docs/prd/**/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
Create PRD documentation in docs/prd/ using kebab-case filenames (e.g., command-registry-pattern.md, error-handling-strategy.md).
Files:
docs/prd/metadata-inheritance.mddocs/prd/workspace-key-prefixes.md
🧠 Learnings (12)
📚 Learning: 2024-11-02T15:35:09.958Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 759
File: internal/exec/terraform.go:366-368
Timestamp: 2024-11-02T15:35:09.958Z
Learning: In `internal/exec/terraform.go`, the workspace cleaning code under both the general execution path and within the `case "init":` block is intentionally duplicated because the code execution paths are different. The `.terraform/environment` file should be deleted before executing `terraform init` in both scenarios to ensure a clean state.
Applied to files:
website/docs/quick-start/advanced/configure-terraform-backend.mdxwebsite/docs/core-concepts/components/terraform/workspaces.mdx
📚 Learning: 2025-03-18T12:26:25.329Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1149
File: tests/snapshots/TestCLICommands_atmos_vendor_pull_ssh.stderr.golden:7-7
Timestamp: 2025-03-18T12:26:25.329Z
Learning: In the Atmos project, typos or inconsistencies in test snapshot files (such as "terrafrom" instead of "terraform") may be intentional as they capture the exact output of commands and should not be flagged as issues requiring correction.
Applied to files:
website/docs/quick-start/advanced/configure-terraform-backend.mdx
📚 Learning: 2025-04-25T20:54:19.701Z
Learnt from: mcalhoun
Repo: cloudposse/atmos PR: 963
File: website/docs/core-concepts/projects/configuration/stores.mdx:286-286
Timestamp: 2025-04-25T20:54:19.701Z
Learning: For the AWS SSM Parameter Store implementation in Atmos, support for `read_role_arn` and `write_role_arn` options is essential to enable cross-account access, allowing users to run operations like `terraform plan` in multiple accounts while accessing values across keystores. Azure Key Vault would need similar capabilities for cross-tenant/subscription authentication.
Applied to files:
website/docs/quick-start/advanced/configure-terraform-backend.mdx
📚 Learning: 2025-09-10T21:17:55.273Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: toolchain/http_client_test.go:3-10
Timestamp: 2025-09-10T21:17:55.273Z
Learning: In the cloudposse/atmos repository, imports should never be changed as per samtholiya's coding guidelines.
Applied to files:
website/docs/core-concepts/vendor/vendor-manifest.mdx
📚 Learning: 2025-01-25T03:51:57.689Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Applied to files:
website/docs/core-concepts/vendor/vendor-manifest.mdx
📚 Learning: 2025-07-05T20:59:02.914Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1363
File: internal/exec/template_utils.go:18-18
Timestamp: 2025-07-05T20:59:02.914Z
Learning: In the Atmos project, gomplate v4 is imported with a blank import (`_ "github.com/hairyhenderson/gomplate/v4"`) alongside v3 imports to resolve AWS SDK version conflicts. V3 uses older AWS SDK versions that conflict with newer AWS modules used by Atmos. A full migration to v4 requires extensive refactoring due to API changes and should be handled in a separate PR.
Applied to files:
website/docs/core-concepts/vendor/vendor-manifest.mdx
📚 Learning: 2025-11-01T20:24:29.557Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1714
File: NOTICE:0-0
Timestamp: 2025-11-01T20:24:29.557Z
Learning: In the cloudposse/atmos repository, the NOTICE file is programmatically generated and should not be manually edited. Issues with dependency license URLs in NOTICE will be resolved when upstream package metadata is corrected.
Applied to files:
website/docs/core-concepts/vendor/vendor-manifest.mdx
📚 Learning: 2025-08-29T20:57:35.423Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1433
File: cmd/theme_list.go:33-36
Timestamp: 2025-08-29T20:57:35.423Z
Learning: In the Atmos codebase, avoid using viper.SetEnvPrefix("ATMOS") with viper.AutomaticEnv() because canonical environment variable names are not exclusive to Atmos and could cause conflicts. Instead, use selective environment variable binding through the setEnv function in pkg/config/load.go with bindEnv(v, "config.key", "ENV_VAR_NAME") for specific environment variables.
Applied to files:
website/docs/core-concepts/vendor/vendor-manifest.mdx
📚 Learning: 2024-10-31T01:22:09.586Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 737
File: examples/demo-vendoring/vendor.d/vendor1.yaml:10-11
Timestamp: 2024-10-31T01:22:09.586Z
Learning: In `examples/demo-vendoring/vendor.d/vendor1.yaml`, when specifying the source for the `ipinfo` component, it's acceptable to use `main` as the version reference if pinning to a specific version is not practical.
Applied to files:
website/docs/core-concepts/vendor/vendor-manifest.mdx
📚 Learning: 2025-11-08T19:56:18.660Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1697
File: internal/exec/oci_utils.go:0-0
Timestamp: 2025-11-08T19:56:18.660Z
Learning: In the Atmos codebase, when a function receives an `*schema.AtmosConfiguration` parameter, it should read configuration values from `atmosConfig.Settings` fields rather than using direct `os.Getenv()` or `viper.GetString()` calls. The Atmos pattern is: viper.BindEnv in cmd/root.go binds environment variables → Viper unmarshals into atmosConfig.Settings via mapstructure → business logic reads from the Settings struct. This provides centralized config management, respects precedence, and enables testability. Example: `atmosConfig.Settings.AtmosGithubToken` instead of `os.Getenv("ATMOS_GITHUB_TOKEN")` in functions like `getGHCRAuth` in internal/exec/oci_utils.go.
Applied to files:
website/docs/core-concepts/vendor/vendor-manifest.mdx
📚 Learning: 2024-10-27T16:59:26.187Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 729
File: internal/exec/help.go:48-51
Timestamp: 2024-10-27T16:59:26.187Z
Learning: In the Atmos CLI help messages, when providing examples that include the version number, use the actual version variable (e.g., `version.Version`) instead of placeholders like `<version>`.
Applied to files:
website/docs/core-concepts/vendor/vendor-manifest.mdx
📚 Learning: 2025-10-07T00:25:16.333Z
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.
Applied to files:
docs/prd/metadata-inheritance.md
🪛 LanguageTool
website/docs/core-concepts/components/terraform/workspaces.mdx
[typographical] ~234-~234: In American English, use a period after an abbreviation.
Context: ... behavior :::tip When to Use Templates vs Patterns - **Use `terraform_workspace_t...
(MISSING_PERIOD_AFTER_ABBREVIATION)
[grammar] ~239-~239: Please add a punctuation mark at the end of paragraph.
Context: ...g/Gomplate functions - Complex naming rules - **Use terraform_workspace_pattern*...
(PUNCTUATION_PARAGRAPH_END)
[typographical] ~260-~260: In American English, use a period after an abbreviation.
Context: ...orm.tfstate ``` :::note Workspace Name vs Workspace Key Prefix These are two sepa...
(MISSING_PERIOD_AFTER_ABBREVIATION)
docs/prd/metadata-inheritance.md
[style] ~26-~26: Since ownership is already implied, this phrasing may be redundant.
Context: ...d entirely - each component must define its own metadata. ### Problems This Causes ##...
(PRP_OWN)
[grammar] ~354-~354: Please add a punctuation mark at the end of paragraph.
Context: ... Exclude metadata.inherits from being inherited 2. Modify `internal/exec/stack_process...
(PUNCTUATION_PARAGRAPH_END)
docs/prd/workspace-key-prefixes.md
[typographical] ~66-~66: Consider using a typographic opening quote here.
Context: ...e metadata-inheritance.md) - Represents "what this component IS" vs "where its co...
(EN_QUOTES)
[typographical] ~66-~66: Consider using a typographic close quote here.
Context: ...md) - Represents "what this component IS" vs "where its code lives" ### Updated ...
(EN_QUOTES)
[typographical] ~66-~66: Consider using a typographic opening quote here.
Context: ... Represents "what this component IS" vs "where its code lives" ### Updated Calcu...
(EN_QUOTES)
[typographical] ~66-~66: Consider using a typographic close quote here.
Context: ...s component IS" vs "where its code lives" ### Updated Calculation Logic **New p...
(EN_QUOTES)
[style] ~246-~246: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...endDefaults()similarly forprefix. Update setAzureBackendKey()similarly fork...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Acceptance Tests (windows)
- GitHub Check: Summary
🔇 Additional comments (12)
docs/prd/metadata-inheritance.md (3)
73-121: Clear and comprehensive inheritance specification.The inheritance behavior table and special-case definitions (lines 107-121) effectively communicate which metadata fields propagate and why
metadata.type: abstractis excluded. This directly supports the PR objective of preventing abstract components from becoming deployable through inheritance.
140-166: Workspace key precedence logic is well-documented and aligns with implementation intent.The four-level priority order (explicit backend prefix → metadata.name → metadata.component → component name) matches the PR objectives. The pseudocode at lines 153-159 provides clarity for implementers.
285-325: Breaking change assessment is prudent and migration path is practical.The low-risk evaluation correctly identifies that most existing codebases don't populate metadata in abstract base components, and the override mechanism provides an escape hatch. The two migration strategies (disable inheritance or override specific fields) are straightforward for users encountering unexpected behavior.
docs/prd/workspace-key-prefixes.md (4)
69-101: Priority order and pseudocode are precise and implementable.The table at lines 71–77 and the accompanying pseudocode (lines 81–101) clearly define the four-level priority with explicit handling for each case. This directly implements the PR objective for workspace key precedence and ensures explicit backend configuration always wins (priority 1).
113-202: Use cases effectively demonstrate practical value and backwards compatibility.Five scenarios span real problems (versioned components, release tracks, multiple instances) and reassure users that existing configurations without
metadata.namecontinue working unchanged. Use Case 5 (lines 204–218) is particularly valuable for adoption confidence.
327-372: Migration guidance balances pragmatism with safety.The distinction between new projects (straightforward adoption) and existing projects (careful consideration of state location) shows appropriate caution. The three-step migration path (lines 350–372) with state-preservation alternatives gives users agency over their transition.
382-384: Cross-reference to metadata inheritance establishes clear dependency.The dependency note correctly identifies that for
metadata.nameto be inherited from base components, the metadata inheritance feature must be enabled. This ensures users understand the interaction between the two features.website/docs/core-concepts/components/terraform/workspaces.mdx (4)
260-276: Fix punctuation in note about Workspace Name vs Workspace Key Prefix.Line 260: ":::note Workspace Name vs Workspace Key Prefix" needs a period after the abbreviation "vs" in American English.
Apply this diff:
-:::note Workspace Name vs Workspace Key Prefix +:::note Workspace Name vs. Workspace Key Prefix
318-320: Good addition of Terraform Backends reference.The new reference link complements the workspace documentation and provides readers with guidance on backend configuration.
195-313: Overall: Strong documentation aligned with PR objectives.The new sections effectively document metadata.name as a stable workspace key identity and provide comprehensive guidance on workspace naming strategies (Go templates, patterns, and static values). The content complements the backend documentation and includes practical examples.
Minor punctuation issues flagged above should be addressed. Beyond that, the documentation achieves the PR goal of explaining metadata.name-driven stability and improving workspace configuration clarity.
As a follow-up, ensure that:
- The automatic Terraform workspace calculation and default stack name behavior still accurately reflects the current implementation after metadata inheritance changes
- The workspace_key_prefix priority order (explicit backend → metadata.name → component identity → component path) is consistently applied across all backend types in the implementation
281-313: Documentation accurately reflects implementation—workspace_key_prefix priority is consistent across all backends.Verification confirms that the documented priority order (explicit backend → metadata.name → metadata.component → Atmos component name) is correctly and consistently implemented:
- S3 backend (
setS3BackendDefaults): Usesworkspace_key_prefixwith documented priority- GCS backend (
setGCSBackendDefaults): Usesprefixwith same priority order- Azure backend (
setAzureBackendKey): Useskeywith same priority orderAll three implementations follow the exact priority sequence described in lines 281-289, and the practical example showing how
metadata.nameprevents version information from leaking into state paths is accurate.website/docs/core-concepts/vendor/vendor-manifest.mdx (1)
555-624: Documentation is technically accurate and well-structured; no corrections needed.The verification confirms that the workspace key prefix guidance in lines 553-624 is correct and properly implemented:
✓ Priority table verified: The four-level priority (explicit backend config → metadata.name → metadata.component → component name) exactly matches the implementation in
internal/exec/stack_processor_backend.go✓ YAML examples verified: All examples align with actual test cases in
stack_processor_backend_test.go, including the automatic slash-to-dash conversion (e.g.,network/vpc→network-vpc)✓ Backend coverage verified: S3, GCS, and Azure backends all follow identical priority logic with the same documentation pattern
✓ Contextual placement verified: The section follows logically from the "Vendoring Multiple Versions" section and precedes "Vendoring from OCI Registries"
✓ Documentation style verified: Code blocks, YAML formatting, and admonitions (tip block, important note) are consistent with the website's established patterns
The section effectively demonstrates why
metadata.namesolves the state migration problem when upgrading component versions, with clear before/after comparisons. The legacy section appropriately documents the prior manual workaround approach.The optional cross-reference suggestion from the review (linking to metadata inheritance documentation) would be a nice-to-have but is not necessary for documentation completeness—users can search for metadata-related topics independently.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (4)
docs/prd/metadata-inheritance.md (2)
26-26: Minor: Phrasing could be tightened.Line 26 says "each component must define its own metadata" — the subject is implied by context. Consider: "...only that
metadatais excluded entirely from inheritance" (removes "each component must define its own").
329-370: Implementation section is detailed and references real code paths.Schema changes (lines 329–345), stack processor changes (lines 351–363), and JSON schema updates (lines 365–369) are concrete and point to actual files. This is helpful for reviewers tracking implementation.
One note: Line 354 is missing a period at the end of the "Exclude
metadata.inherits..." item. Add punctuation:- - Exclude `metadata.inherits` from being inherited + - Exclude `metadata.inherits` from being inherited.website/docs/core-concepts/components/terraform/workspaces.mdx (1)
195-233: New section on Go templates is well-structured and timely.The "Using Go Templates for Workspace Names" section (lines 195–232) effectively bridges simple patterns and advanced templating. The priority order (terraform_workspace_template > pattern > terraform_workspace > auto-generated) is clear and matches the PRD. The tip (lines 234–247) helps users choose the right tool.
Minor: Line 234 should read "Use
terraform_workspace_template..." with a period after the closing backtick. Similarly, line 239 and line 245 need periods at the end of list items for consistency.docs/prd/workspace-key-prefixes.md (1)
220-283: Implementation section is concrete and actionable.Lines 224–242 show the updated
setS3BackendDefaults()function with metadata parameter. Signature change (lines 249–259) is clear. Schema changes (lines 265–282) specify JSON schema addition formetadata.name. Function signature updates tosetGCSBackendDefaults()andsetAzureBackendKey()are mentioned (lines 245–247).One note: Line 246 has three successive sentences beginning with "Update": "Update
setGCSBackendDefaults()similarly..." and "UpdatesetAzureBackendKey()similarly...". Consider varying sentence structure:-Update `setGCSBackendDefaults()` similarly for `prefix`. +Apply the same logic to `setGCSBackendDefaults()` for `prefix`. -Update `setAzureBackendKey()` similarly for `key`. +Apply the same logic to `setAzureBackendKey()` for `key`.This is minor but improves readability.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (7)
docs/prd/metadata-inheritance.md(1 hunks)docs/prd/workspace-key-prefixes.md(1 hunks)website/blog/2025-11-21-metadata-name-workspace-keys.mdx(1 hunks)website/docs/core-concepts/components/terraform/backends.mdx(2 hunks)website/docs/core-concepts/components/terraform/workspaces.mdx(2 hunks)website/docs/core-concepts/vendor/vendor-manifest.mdx(1 hunks)website/docs/quick-start/advanced/configure-terraform-backend.mdx(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- website/docs/quick-start/advanced/configure-terraform-backend.mdx
🚧 Files skipped from review as they are similar to previous changes (2)
- website/docs/core-concepts/components/terraform/backends.mdx
- website/blog/2025-11-21-metadata-name-workspace-keys.mdx
🧰 Additional context used
📓 Path-based instructions (2)
website/**
📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)
website/**: Update website documentation in thewebsite/directory when adding new features, ensure consistency between CLI help text and website documentation, and follow the website's documentation structure and style
Keep website code in thewebsite/directory, follow the existing website architecture and style, and test website changes locally before committing
Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases
Files:
website/docs/core-concepts/components/terraform/workspaces.mdxwebsite/docs/core-concepts/vendor/vendor-manifest.mdx
docs/prd/**/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
Create PRD documentation in docs/prd/ using kebab-case filenames (e.g., command-registry-pattern.md, error-handling-strategy.md).
Files:
docs/prd/workspace-key-prefixes.mddocs/prd/metadata-inheritance.md
🧠 Learnings (9)
📚 Learning: 2024-11-02T15:35:09.958Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 759
File: internal/exec/terraform.go:366-368
Timestamp: 2024-11-02T15:35:09.958Z
Learning: In `internal/exec/terraform.go`, the workspace cleaning code under both the general execution path and within the `case "init":` block is intentionally duplicated because the code execution paths are different. The `.terraform/environment` file should be deleted before executing `terraform init` in both scenarios to ensure a clean state.
Applied to files:
website/docs/core-concepts/components/terraform/workspaces.mdx
📚 Learning: 2025-01-25T03:51:57.689Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Applied to files:
website/docs/core-concepts/components/terraform/workspaces.mdx
📚 Learning: 2025-07-05T20:59:02.914Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1363
File: internal/exec/template_utils.go:18-18
Timestamp: 2025-07-05T20:59:02.914Z
Learning: In the Atmos project, gomplate v4 is imported with a blank import (`_ "github.com/hairyhenderson/gomplate/v4"`) alongside v3 imports to resolve AWS SDK version conflicts. V3 uses older AWS SDK versions that conflict with newer AWS modules used by Atmos. A full migration to v4 requires extensive refactoring due to API changes and should be handled in a separate PR.
Applied to files:
website/docs/core-concepts/vendor/vendor-manifest.mdx
📚 Learning: 2025-08-29T20:57:35.423Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1433
File: cmd/theme_list.go:33-36
Timestamp: 2025-08-29T20:57:35.423Z
Learning: In the Atmos codebase, avoid using viper.SetEnvPrefix("ATMOS") with viper.AutomaticEnv() because canonical environment variable names are not exclusive to Atmos and could cause conflicts. Instead, use selective environment variable binding through the setEnv function in pkg/config/load.go with bindEnv(v, "config.key", "ENV_VAR_NAME") for specific environment variables.
Applied to files:
website/docs/core-concepts/vendor/vendor-manifest.mdx
📚 Learning: 2024-10-31T01:22:09.586Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 737
File: examples/demo-vendoring/vendor.d/vendor1.yaml:10-11
Timestamp: 2024-10-31T01:22:09.586Z
Learning: In `examples/demo-vendoring/vendor.d/vendor1.yaml`, when specifying the source for the `ipinfo` component, it's acceptable to use `main` as the version reference if pinning to a specific version is not practical.
Applied to files:
website/docs/core-concepts/vendor/vendor-manifest.mdx
📚 Learning: 2025-11-08T19:56:18.660Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1697
File: internal/exec/oci_utils.go:0-0
Timestamp: 2025-11-08T19:56:18.660Z
Learning: In the Atmos codebase, when a function receives an `*schema.AtmosConfiguration` parameter, it should read configuration values from `atmosConfig.Settings` fields rather than using direct `os.Getenv()` or `viper.GetString()` calls. The Atmos pattern is: viper.BindEnv in cmd/root.go binds environment variables → Viper unmarshals into atmosConfig.Settings via mapstructure → business logic reads from the Settings struct. This provides centralized config management, respects precedence, and enables testability. Example: `atmosConfig.Settings.AtmosGithubToken` instead of `os.Getenv("ATMOS_GITHUB_TOKEN")` in functions like `getGHCRAuth` in internal/exec/oci_utils.go.
Applied to files:
website/docs/core-concepts/vendor/vendor-manifest.mdx
📚 Learning: 2024-10-27T16:59:26.187Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 729
File: internal/exec/help.go:48-51
Timestamp: 2024-10-27T16:59:26.187Z
Learning: In the Atmos CLI help messages, when providing examples that include the version number, use the actual version variable (e.g., `version.Version`) instead of placeholders like `<version>`.
Applied to files:
website/docs/core-concepts/vendor/vendor-manifest.mdx
📚 Learning: 2024-11-23T00:13:22.004Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 801
File: examples/quick-start-advanced/Dockerfile:9-9
Timestamp: 2024-11-23T00:13:22.004Z
Learning: When updating the `ATMOS_VERSION` in Dockerfiles, the team prefers to pin to the next future version when the PR merges, even if the version is not yet released.
Applied to files:
website/docs/core-concepts/vendor/vendor-manifest.mdx
📚 Learning: 2025-10-07T00:25:16.333Z
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.
Applied to files:
docs/prd/metadata-inheritance.md
🪛 LanguageTool
website/docs/core-concepts/components/terraform/workspaces.mdx
[typographical] ~234-~234: In American English, use a period after an abbreviation.
Context: ... behavior :::tip When to Use Templates vs Patterns - **Use `terraform_workspace_t...
(MISSING_PERIOD_AFTER_ABBREVIATION)
[grammar] ~239-~239: Please add a punctuation mark at the end of paragraph.
Context: ...g/Gomplate functions - Complex naming rules - **Use terraform_workspace_pattern*...
(PUNCTUATION_PARAGRAPH_END)
[typographical] ~260-~260: In American English, use a period after an abbreviation.
Context: ...orm.tfstate ``` :::note Workspace Name vs Workspace Key Prefix These are two sepa...
(MISSING_PERIOD_AFTER_ABBREVIATION)
docs/prd/workspace-key-prefixes.md
[typographical] ~66-~66: Consider using a typographic opening quote here.
Context: ...e metadata-inheritance.md) - Represents "what this component IS" vs "where its co...
(EN_QUOTES)
[typographical] ~66-~66: Consider using a typographic close quote here.
Context: ...md) - Represents "what this component IS" vs "where its code lives" ### Updated ...
(EN_QUOTES)
[typographical] ~66-~66: Consider using a typographic opening quote here.
Context: ... Represents "what this component IS" vs "where its code lives" ### Updated Calcu...
(EN_QUOTES)
[typographical] ~66-~66: Consider using a typographic close quote here.
Context: ...s component IS" vs "where its code lives" ### Updated Calculation Logic **New p...
(EN_QUOTES)
[style] ~246-~246: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...endDefaults()similarly forprefix. Update setAzureBackendKey()similarly fork...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
docs/prd/metadata-inheritance.md
[style] ~26-~26: Since ownership is already implied, this phrasing may be redundant.
Context: ...d entirely - each component must define its own metadata. ### Problems This Causes ##...
(PRP_OWN)
[grammar] ~354-~354: Please add a punctuation mark at the end of paragraph.
Context: ... Exclude metadata.inherits from being inherited 2. Modify `internal/exec/stack_process...
(PUNCTUATION_PARAGRAPH_END)
🪛 markdownlint-cli2 (0.18.1)
docs/prd/workspace-key-prefixes.md
5-5: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
docs/prd/metadata-inheritance.md
5-5: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Summary
🔇 Additional comments (12)
website/docs/core-concepts/vendor/vendor-manifest.mdx (2)
553-591: Excellent addition—priority order and problem explanation are clear.The new section effectively educates users on
metadata.nameas the stable identity for versioned components. The priority table and YAML examples clearly show the problem (version-leaking into state paths) and the recommended solution. The callout at line 586 reinforces why this matters.Minor suggestion: The phrase "When you upgrade to vpc/2.0.0, workspace_key_prefix STAYS vpc" (line 582) could be slightly clearer by saying "...the value of
workspace_key_prefixremainsvpc" to avoid ambiguity about what "STAYS" refers to.
592-625: Good coverage of alternatives and legacy patterns.The explicit override (592–606) and legacy workaround sections (608–622) provide clear migration paths. The distinction between the three approaches is helpful.
Note at line 626–628 correctly flags non-S3 backends but could link to the backend-specific documentation if available (e.g., GCS
prefixor Azurekey) for completeness.docs/prd/metadata-inheritance.md (3)
103-121: Inheritance behavior table is clear and well-motivated.The table correctly documents which fields inherit and which don't. The special treatment of
metadata.type: abstract(marked as partial, with justification) andmetadata.inherits(excluded) aligns with the problem statement and prevents abstract components from being inherited as deployable. Good.
168-284: Use cases are practical and cover key patterns.The four use cases (versioned components, release tracks, governance, multiple instances) effectively illustrate the feature's value. Each example shows both the base component definition and derived usage, making the inheritance flow clear.
285-326: Breaking change assessment is realistic and provides migration path.The analysis correctly identifies low risk (most users don't set metadata in abstract base components, derived components can override). The migration path (disable via
stacks.inherit.metadata: falseor override specific fields) is practical. Good risk communication.website/docs/core-concepts/components/terraform/workspaces.mdx (2)
249-276: "How Workspaces Relate to State Paths" section adds essential clarity.This section (lines 249–276) explains the two-level hierarchy (workspace_key_prefix + workspace) and explicitly distinguishes the two concepts. This is a critical mental model for users and was previously missing. The :::note callout (lines 260–276) is especially valuable for preventing confusion.
The ASCII diagram at lines 253–258 clearly shows the S3 path structure.
281-313: workspace_key_prefix auto-generation guidance is accurate and practical.Priority order (lines 285–288) and the example (lines 294–309) correctly show how
metadata.nameprovides stable state paths across version upgrades. The connection to the design-patterns doc (line 312) is helpful for users implementing versioned components.docs/prd/workspace-key-prefixes.md (5)
68-101: Priority logic and pseudocode are clear and implementable.The priority order (explicit backend > metadata.name > metadata.component > Atmos component name) is consistent across all docs. The pseudocode (lines 82–100) clearly shows the logic and fallback behavior. Good implementation guidance.
103-111: Backward compatibility claim is well-justified.Lines 103–111 correctly argue that metadata.name is optional and falls back gracefully to current behavior. No breaking change. Clear statement.
113-219: Use cases are comprehensive and realistic.Five use cases (versioned folders, release tracks, inheritance, multiple instances, no-metadata) cover real patterns. Each includes concrete YAML examples. Use Case 5 (lines 204–218) explicitly addresses backward compatibility by showing configs without
metadata.namestill work. Good coverage.
312-373: Migration guide is practical and well-differentiated.Lines 312–373 separate guidance for new projects (start with metadata.name) vs existing projects (two scenarios: with/without explicit workspace_key_prefix). The scenario with existing versioned state (lines 348–372) correctly warns that adding metadata.name without careful planning could "lose" the existing state if the name doesn't match the current key. Good risk communication.
374-390: Success criteria and dependencies are clear.Lines 374–390 establish measurable success criteria (5 items) and explicitly note dependency on metadata-inheritance.md feature. Good closure for a comprehensive PRD.
Fixed missing terminal punctuation and standardized formatting: **docs/prd/metadata-inheritance.md:** - Added period to end of bullet "Exclude metadata.inherits from being inherited" **website/docs/core-concepts/components/terraform/workspaces.mdx:** - Changed "When to Use Templates vs Patterns" → "When to Use Templates vs. Patterns" - Added periods to end of bullets under terraform_workspace_pattern - Added period to end of bullet under terraform_workspace **Note:** docs/prd/metadata-inheritance.md and docs/prd/workspace-key-prefixes.md already have proper heading structure with "## Status" followed by "**Implemented**" on the next line, which is correct Markdown format. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Focus on user pain points (governance at scale) rather than technical details. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
docs/prd/metadata-inheritance.md (1)
3-5: Use heading instead of emphasis for Status section.Line 5 uses
**Implemented**(bold), which violates markdownlint MD036. Per coding guidelines fordocs/prd/**/*.md, use a proper Markdown heading to maintain visual hierarchy and enable proper documentation indexing.## Status -**Implemented** +### Implemented
🧹 Nitpick comments (2)
website/docs/core-concepts/components/terraform/workspaces.mdx (2)
234-247: Minor: Fix punctuation consistency and reduce repetition in "When to Use" section.The section introduces three use cases but repeats "when you need" across all three bullets (lines 235, 241, 245). Additionally, line 239 ("Complex naming rules") lacks the ending period that the other bullets have.
Apply this diff for consistency:
:::tip When to Use Templates vs. Patterns -- **Use `terraform_workspace_template`** when you need: +- **Use `terraform_workspace_template`** for: - String manipulation (upper/lower case, substring, etc.) - Conditional logic - Access to Sprig/Gomplate functions - - Complex naming rules + - Complex naming rules. -- **Use `terraform_workspace_pattern`** when you need: +- **Use `terraform_workspace_pattern`** for: - Simple token replacement with context variables. - Straightforward naming patterns. -- **Use `terraform_workspace`** when you need: +- **Use `terraform_workspace`** for: - A fixed, static workspace name.This removes the repetitive phrase and adds the missing period to the "Complex naming rules" bullet.
260-260: Minor: Add period after abbreviation in note title.Line 260 title should use "vs." (with period) to follow American English conventions.
-:::note Workspace Name vs Workspace Key Prefix +:::note Workspace Name vs. Workspace Key Prefix
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
docs/prd/metadata-inheritance.md(1 hunks)website/blog/2025-11-21-metadata-inheritance.mdx(1 hunks)website/docs/core-concepts/components/terraform/workspaces.mdx(2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
website/**
📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)
website/**: Update website documentation in thewebsite/directory when adding new features, ensure consistency between CLI help text and website documentation, and follow the website's documentation structure and style
Keep website code in thewebsite/directory, follow the existing website architecture and style, and test website changes locally before committing
Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases
Files:
website/docs/core-concepts/components/terraform/workspaces.mdxwebsite/blog/2025-11-21-metadata-inheritance.mdx
website/blog/**/*.mdx
📄 CodeRabbit inference engine (CLAUDE.md)
PRs labeled minor/major MUST include blog post at website/blog/YYYY-MM-DD-feature-name.mdx with YAML front matter, after intro, tags (feature/enhancement/bugfix/contributors), and author (committer's GitHub username).
Files:
website/blog/2025-11-21-metadata-inheritance.mdx
docs/prd/**/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
Create PRD documentation in docs/prd/ using kebab-case filenames (e.g., command-registry-pattern.md, error-handling-strategy.md).
Files:
docs/prd/metadata-inheritance.md
🧠 Learnings (5)
📚 Learning: 2024-11-02T15:35:09.958Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 759
File: internal/exec/terraform.go:366-368
Timestamp: 2024-11-02T15:35:09.958Z
Learning: In `internal/exec/terraform.go`, the workspace cleaning code under both the general execution path and within the `case "init":` block is intentionally duplicated because the code execution paths are different. The `.terraform/environment` file should be deleted before executing `terraform init` in both scenarios to ensure a clean state.
Applied to files:
website/docs/core-concepts/components/terraform/workspaces.mdx
📚 Learning: 2025-01-25T03:51:57.689Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Applied to files:
website/docs/core-concepts/components/terraform/workspaces.mdx
📚 Learning: 2025-03-18T12:26:25.329Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1149
File: tests/snapshots/TestCLICommands_atmos_vendor_pull_ssh.stderr.golden:7-7
Timestamp: 2025-03-18T12:26:25.329Z
Learning: In the Atmos project, typos or inconsistencies in test snapshot files (such as "terrafrom" instead of "terraform") may be intentional as they capture the exact output of commands and should not be flagged as issues requiring correction.
Applied to files:
website/docs/core-concepts/components/terraform/workspaces.mdx
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to website/blog/**/*.mdx : PRs labeled minor/major MUST include blog post at website/blog/YYYY-MM-DD-feature-name.mdx with YAML front matter, <!--truncate--> after intro, tags (feature/enhancement/bugfix/contributors), and author (committer's GitHub username).
Applied to files:
website/blog/2025-11-21-metadata-inheritance.mdx
📚 Learning: 2025-10-07T00:25:16.333Z
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.
Applied to files:
website/blog/2025-11-21-metadata-inheritance.mdxdocs/prd/metadata-inheritance.md
🪛 LanguageTool
website/docs/core-concepts/components/terraform/workspaces.mdx
[grammar] ~239-~239: Please add a punctuation mark at the end of paragraph.
Context: ...g/Gomplate functions - Complex naming rules - **Use terraform_workspace_pattern*...
(PUNCTUATION_PARAGRAPH_END)
[style] ~241-~241: This word has been used in one of the immediately preceding sentences. Using a synonym could make your text more interesting to read, unless the repetition is intentional.
Context: ...terraform_workspace_pattern`** when you need: - Simple token replacement with cont...
(EN_REPEATEDWORDS_NEED)
[style] ~245-~245: This word has been used in one of the immediately preceding sentences. Using a synonym could make your text more interesting to read, unless the repetition is intentional.
Context: ... Use terraform_workspace when you need: - A fixed, static workspace name. ::...
(EN_REPEATEDWORDS_NEED)
[typographical] ~260-~260: In American English, use a period after an abbreviation.
Context: ...orm.tfstate ``` :::note Workspace Name vs Workspace Key Prefix These are two sepa...
(MISSING_PERIOD_AFTER_ABBREVIATION)
docs/prd/metadata-inheritance.md
[style] ~26-~26: Since ownership is already implied, this phrasing may be redundant.
Context: ...d entirely - each component must define its own metadata. ### Problems This Causes ##...
(PRP_OWN)
🪛 markdownlint-cli2 (0.18.1)
docs/prd/metadata-inheritance.md
5-5: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Acceptance Tests (macos)
- GitHub Check: Acceptance Tests (linux)
- GitHub Check: Acceptance Tests (windows)
- GitHub Check: Summary
🔇 Additional comments (4)
website/blog/2025-11-21-metadata-inheritance.mdx (1)
1-70: Blog post meets all coding guidelines.YAML frontmatter, filename format, author attribution, tags, and truncate delimiter all align with
website/blog/**/*.mdxrequirements. The narrative structure (problem → solution → configuration) is clear and the YAML examples effectively illustrate the feature.website/docs/core-concepts/components/terraform/workspaces.mdx (3)
11-11: Import addition approved.The
PillBoxcomponent import aligns with its usage on line 197 for the "Advanced" label.
195-227: Excellent documentation of metadata.name and workspace key generation.The new sections thoroughly document the Go template workflow, priority order for workspace configuration, and the metadata.name-driven auto-generation of workspace_key_prefix. The versioned component example (lines 294-303) effectively illustrates how metadata.name prevents version information from leaking into state paths—directly supporting the PR's key feature.
Also applies to: 228-232, 281-314
1-373: Documentation structure and style compliant.The changes follow the existing website documentation patterns with proper use of MDX components (File, Terminal, PillBox), consistent formatting, and clear section organization. The content depth and examples are appropriate for the feature scope.
what
Feature Implementation:
stacks.inherit.metadata)metadata.nameas a stable logical component identity for workspace key prefixesinheritfield inatmos describe configoutputBug Fixes:
metadata.type: abstractfrom inheritance to prevent abstract components from becoming deployableExecuteDescribeStacksto ensure inherited metadata fields (liketerraform_workspace) are resolved when describing stacksterraform_workspacetakes precedence over inherited/imported patternsDocumentation:
metadata.nameconvention: first-level component folder relative to component base pathworkspace_key_prefixpatterns across version management documentationmetadata.namemetadata.nameover manual settingsTests:
metadata.namemetadata.type: abstractexclusionstacks.inheritfield in describe config outputwhy
Feature Justification:
metadata.nameprovides a stable, predictable workspace key that doesn't change when component paths are refactoredBug Justification:
metadata.type: abstract, abstract base components could become deployable when inherited, breaking the abstract component patternExecuteDescribeStackswas only merging YAML imports but not applying component inheritance, causing inherited metadata fields to be ignoredBuildTerraformWorkspaceDocumentation Justification:
metadata.namefeature was implemented but documentation still showed old manualworkspace_key_prefixpatterns, creating confusion and encouraging error-prone workaroundsmetadata.name= top-level component folderreferences
TestDescribeStacksWithFilter7which validates inheritedterraform_workspacemetadataSummary by CodeRabbit
New Features
Behavior / Bug Fixes
Configuration
Documentation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.