Skip to content

Conversation

@osterman
Copy link
Member

@osterman osterman commented Jan 15, 2026

what

  • Added registerCustomMaskPatterns() to load user-defined patterns and literals from atmos.yaml config
  • Updated masker to support custom replacement strings from config settings
  • Fixed all output paths to route through io layer for automatic secret masking
  • Created examples/secrets-masking/ directory demonstrating the feature with test configs and components

why

Secrets matching user-defined patterns are now automatically masked across all CLI output (terraform, logs, auth commands, docs, help text, etc.), preventing accidental exposure while maintaining the ability to customize masking behavior per environment.

references

Implements custom pattern/literal loading for the secrets masking feature that was already configured in the schema but not being loaded or applied.

Summary by CodeRabbit

  • New Features

    • Global secrets masking: configurable enable/disable, custom regex patterns, literal values, and configurable replacement text; applied across CLI, logs, docs and tooling.
    • Added an Example Creator agent to generate self-contained demo examples and mocks.
  • Documentation

    • Expanded secrets-masking docs, new agent guide, embedded examples, updated examples list, and a blog post announcing custom masking.
  • Tests

    • New/updated test cases and snapshots to reflect masking behavior.
  • Chores

    • Visible telemetry notice with opt-out instructions.

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

- Added registerCustomMaskPatterns() to load custom patterns and literals from atmos.yaml config
- Updated masker to support custom replacement strings from config
- Fixed all output paths to route through io layer for automatic masking (shell, logs, auth, docs, help, version)
- Created examples/secrets-masking/ directory demonstrating the feature with test configs and components

This ensures secrets matching user-defined patterns are automatically masked across all CLI output.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@osterman osterman requested review from a team as code owners January 15, 2026 19:59
@github-actions github-actions bot added the size/l Large size PR label Jan 15, 2026
@github-actions
Copy link

github-actions bot commented Jan 15, 2026

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

None

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 15, 2026

📝 Walkthrough

Walkthrough

Adds configurable terminal secrets masking (patterns, literals, replacement), routes CLI stdout/stderr/logs through a MaskWriter, loads custom mask patterns from atmos.yaml, adjusts masker behavior and tests, adds a secrets-masking example with tests/snapshots, and adds Example Creator agent documentation.

Changes

Cohort / File(s) Summary
Agent docs
/.claude/agents/README.md, /.claude/agents/example-creator.md
New Example Creator agent docs and authoring workflow for Atmos examples, mocks, tests, and EmbedFile-based website integration (documentation-only).
Masking core & config
pkg/io/context.go, pkg/io/global.go, pkg/io/masker.go, pkg/io/masker_test.go, pkg/io/streams_test.go
Load custom mask patterns/literals from atmos.yaml; masker gains configurable replacement and enabled flag; RegisterSecret preserves JSON/YAML structure; default replacement token changed to <MASKED>; many new/updated tests.
CLI output & formatting
cmd/auth_console.go, cmd/auth_login.go, cmd/help_template.go, cmd/root.go, cmd/version/formatters.go, main.go
Replace direct stdout/stderr writes with io.MaskWriter(...) so help, auth, version, and error outputs are routed through the masking layer.
Utilities, exec & logging
errors/error_funcs.go, internal/exec/shell_utils.go, pkg/list/list_instances.go, pkg/utils/doc_utils.go, pkg/utils/log_utils.go, pkg/utils/markdown_utils.go
Redirect utility outputs, shell exec streams, pager invocations, logging helpers, and markdown printing through MaskWriter; list output uses data.Writeln.
Secrets-masking example
examples/secrets-masking/*
examples/secrets-masking/README.md, .../atmos.yaml, .../components/terraform/secrets-demo/*, .../stacks/deploy/dev.yaml, .../.gitignore
New example demonstrating masking config (patterns, literals, replacement), Terraform mock component, stack config, README, CI/test cases, and .gitignore.
Docs & website
website/docs/.../settings/mask.mdx, website/blog/2026-01-15-custom-secrets-masking.mdx, website/src/data/roadmap.js, CLAUDE.md, examples/README.md
Expanded masking docs and examples, blog post, roadmap entry for secrets management, CLAUDE.md insert, and examples index update.
Tests / snapshots / test cases
tests/snapshots/*, tests/test-cases/secrets-masking.yaml
Added/updated CLI golden snapshots, test cases, and telemetry notice lines for secrets-masking flows.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant CLI
participant ConfigLoader
participant Masker
participant IO_Layer as MaskWriter
participant OutputSink as Stdout/Stderr/Log

CLI->>ConfigLoader: load atmos.yaml (patterns, literals, replacement)
ConfigLoader-->>Masker: register patterns & literals
CLI->>IO_Layer: request writer for stdout/stderr/log
IO_Layer-->>Masker: wrap writer (writes pass through masker)
CLI->>IO_Layer: write output
IO_Layer->>Masker: mask payload
Masker-->>OutputSink: emit masked payload
Note over Masker,OutputSink: help, auth, shell, pager, logs follow same flow

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • milldr
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 56.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main changes: implementing custom secrets masking patterns and fixing output routing across the CLI.

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

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

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

❤️ Share

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 15, 2026

📝 Walkthrough

Walkthrough

This PR integrates secrets masking across the CLI by replacing direct stdout/stderr writes with masked I/O wrappers throughout command handlers, utilities, and logging paths. It also adds configuration support for custom mask patterns and makes the masker replacement string configurable.

Changes

Cohort / File(s) Summary
Command handlers with output masking
cmd/auth_console.go, cmd/auth_login.go, cmd/help_template.go, cmd/root.go, cmd/version/formatters.go
Replace direct writes to os.Stderr/os.Stdout with ioLayer.MaskWriter wrapping; affects console URL output, authentication messages, debug logging, logger output routing, and version/release information display.
Core masking and configuration
pkg/io/masker.go, pkg/io/global.go, pkg/io/context.go
Add configurable replacement string to masker, introduce registerCustomMaskPatterns helper to register literals and regex patterns from config, and wire custom patterns into initialization flow.
Utility functions with output masking
pkg/utils/log_utils.go, pkg/utils/markdown_utils.go, pkg/utils/doc_utils.go, internal/exec/shell_utils.go
Apply masked writers to message printing, markdown rendering, paged documentation output, and shell command execution streams.
Error handling and CLI entry
errors/error_funcs.go, main.go, pkg/list/list_instances.go
Wrap error output with masked writers and update tree rendering return path to route through masking layer.
Example/demo for secrets masking
examples/secrets-masking/.gitignore, examples/secrets-masking/README.md, examples/secrets-masking/atmos.yaml, examples/secrets-masking/components/terraform/secrets-demo/*, examples/secrets-masking/stacks/deploy/dev.yaml
Add comprehensive example demonstrating masking of built-in patterns, custom regex, and literal values with Terraform demo component and stack configuration.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

minor

Suggested reviewers

  • aknysh
  • kevcube
  • jamengual
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the PR's main objectives: implementing custom secrets masking patterns and fixing output routing across all CLI output paths.
Docstring Coverage ✅ Passed Docstring coverage is 94.44% which is sufficient. The required threshold is 80.00%.

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

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

🧹 Recent nitpick comments
examples/secrets-masking/.gitignore (1)

6-6: Consider including the lock file in version control.

Modern Terraform practice typically commits .terraform.lock.hcl to ensure consistent provider versions across environments. Since this is an example directory, excluding it might lead users to miss this best practice when using it as a template.

📝 Optional adjustment
 .terraform
 *.tfstate
 *.tfstate.*
 *.tfplan
-.terraform.lock.hcl
examples/secrets-masking/README.md (1)

55-58: Minor consistency note.

The custom patterns section mentions internal-XXXX... and tkn_live_... formats, but the configuration example snippet (lines 17-27) only shows the demo-key- pattern. Consider expanding the example snippet to include all three patterns for completeness, or note that the full atmos.yaml contains additional patterns.

examples/secrets-masking/atmos.yaml (1)

32-38: Regex patterns look correct.

The patterns match their described examples accurately. The absence of anchors or word boundaries is appropriate for masking—secrets can appear mid-string in URLs, JSON, or logs. Consider verifying these patterns work as expected in the masking engine with test cases covering various output contexts.

pkg/list/list_instances.go (1)

438-438: Variable name data shadows the imported package.

The local variable data := extract.Metadata(instances) shadows your imported github.com/cloudposse/atmos/pkg/data package. Currently safe since the data.Writeln call at line 427 returns before this point, but this could trip up future refactors.

Consider renaming to instanceData or metadataRows.

♻️ Suggested rename
-	data := extract.Metadata(instances)
+	instanceData := extract.Metadata(instances)

And update the reference at line 470:

-	if err := r.Render(data); err != nil {
+	if err := r.Render(instanceData); err != nil {
pkg/utils/log_utils.go (3)

22-24: Missing perf.Track call.

Per repository policy, all public functions require performance tracking. Consider adding the tracking call.

Suggested addition
 func PrintMessage(message string) {
+	defer perf.Track(nil, "utils.PrintMessage")()
+
 	fmt.Fprintln(ioLayer.MaskWriter(os.Stdout), message)
 }

27-31: Same note on perf.Track.

Applies here too for consistency with codebase policy.

Suggested addition
 func PrintMessageInColor(message string, messageColor *color.Color) {
+	defer perf.Track(nil, "utils.PrintMessageInColor")()
+
 	if _, err := messageColor.Fprint(ioLayer.MaskWriter(os.Stdout), message); err != nil {
 		log.Trace("Failed to print colored message to stdout", "error", err)
 	}
 }

34-35: And here as well.

Suggested addition
 func PrintfMessageToTUI(message string, args ...any) {
+	defer perf.Track(nil, "utils.PrintfMessageToTUI")()
+
 	fmt.Fprintf(ioLayer.MaskWriter(os.Stderr), message, args...)
 }
errors/error_funcs.go (1)

82-92: Variable name maskedStderr is misleading.

The variable is just an alias to os.Stderr, not actually masked. Per the comment at line 283, this is intentional to avoid import cycles. Consider renaming to stderr or errOut for clarity.

Suggested rename
 func printPlainError(title string, err error, suggestion string) {
-	maskedStderr := os.Stderr
+	stderr := os.Stderr
 	if title != "" {
 		title = cases.Title(language.English).String(title)
-		fmt.Fprintf(maskedStderr, "\n%s: %v\n", title, err)
+		fmt.Fprintf(stderr, "\n%s: %v\n", title, err)
 	} else {
-		fmt.Fprintf(maskedStderr, "\nError: %v\n", err)
+		fmt.Fprintf(stderr, "\nError: %v\n", err)
 	}
 	if suggestion != "" {
-		fmt.Fprintf(maskedStderr, "%s\n", suggestion)
+		fmt.Fprintf(stderr, "%s\n", suggestion)
 	}
 }

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

❤️ Share

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

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 15, 2026
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In @.claude/agents/example-creator.md:
- Around line 161-164: The local_file resource "output" writes to
"${path.module}/output/${var.stage}.json" which can fail if the output directory
doesn't exist; update the Terraform config to ensure the directory exists before
writing (e.g., add a null_resource or local-exec that creates
"${path.module}/output" or switch filename to a guaranteed-existing parent) or
document that callers must create the output directory; reference the resource
name local_file "output" and the filename expression
"${path.module}/output/${var.stage}.json" when making the change.

In `@examples/secrets-masking/README.md`:
- Around line 55-62: The README claims multiple custom patterns but the provided
atmos.yaml example only defines demo-key-[A-Za-z0-9]{16}; update the README so
the docs and config match by either (A) adding the missing patterns
(internal-\\w+ or an appropriate regex for internal-XXXX..., and regexes for
tkn_live_... and tkn_test_...) into the atmos.yaml example, or (B) removing the
extra pattern mentions (internal-XXXX..., tkn_live_..., tkn_test_...) from the
descriptive list so it only references demo-key-[A-Za-z0-9]{16}; edit the
atmos.yaml example and the descriptive list accordingly to keep them consistent.
🧹 Nitpick comments (4)
cmd/auth_console.go (1)

193-198: Consider capturing maskedStderr for consistency.

Minor nit: printConsoleURL uses inline ioLayer.MaskWriter(os.Stderr) while other functions capture it first. Not a problem functionally—MaskWriter is lightweight—but capturing it once keeps the style uniform.

Optional: align with other functions
 func printConsoleURL(consoleURL string) {
 	labelStyle := lipgloss.NewStyle().Foreground(lipgloss.Color(theme.ColorGray))
 	urlStyle := lipgloss.NewStyle().Foreground(lipgloss.Color(theme.ColorCyan))
-	fmt.Fprintf(ioLayer.MaskWriter(os.Stderr), "\n%s\n%s\n", labelStyle.Render("Console URL:"), urlStyle.Render(consoleURL))
+	maskedStderr := ioLayer.MaskWriter(os.Stderr)
+	fmt.Fprintf(maskedStderr, "\n%s\n%s\n", labelStyle.Render("Console URL:"), urlStyle.Render(consoleURL))
 }
cmd/version/formatters.go (1)

246-286: formatReleaseListText not updated for masking.

Lines 252 and 284 still write directly to os.Stderr without wrapping. For consistency with formatReleaseDetailText, consider applying the same masking pattern here.

Apply masking to formatReleaseListText
 func formatReleaseListText(releases []*github.RepositoryRelease) error {
 	// Add current version if it's not in the list.
 	releases = addCurrentVersionIfMissing(releases)
+	maskedStderr := ioLayer.MaskWriter(os.Stderr)

 	if len(releases) == 0 {
-		fmt.Fprintln(os.Stderr, "No releases found")
+		fmt.Fprintln(maskedStderr, "No releases found")
 		return nil
 	}

 	// Build table rows.
 	// ... existing code ...

 	t, err := createVersionTable(rows)
 	if err != nil {
 		return err
 	}
-	fmt.Fprintln(os.Stderr, t)
+	fmt.Fprintln(maskedStderr, t)
 	return nil
 }
pkg/io/masker.go (1)

163-171: Consider using sort.Slice for clarity.

The bubble sort works but sort.Slice would be more idiomatic. Not blocking—literal counts are typically small.

♻️ Optional refactor
-	// Sort by length descending (longest first)
-	// This prevents shorter literals from being replaced before longer ones
-	for i := 0; i < len(literals); i++ {
-		for j := i + 1; j < len(literals); j++ {
-			if len(literals[j]) > len(literals[i]) {
-				literals[i], literals[j] = literals[j], literals[i]
-			}
-		}
-	}
+	// Sort by length descending (longest first)
+	// This prevents shorter literals from being replaced before longer ones
+	sort.Slice(literals, func(i, j int) bool {
+		return len(literals[i]) > len(literals[j])
+	})
pkg/utils/doc_utils.go (1)

3-13: Import ordering doesn't match guidelines.

Per coding guidelines, imports should be: stdlib, then 3rd-party, then Atmos packages. Here viper (3rd-party) appears after Atmos packages.

Suggested fix
 import (
 	"fmt"
 	"os"
 	"os/exec"
 	"strings"

+	"github.com/spf13/viper"
+
 	errUtils "github.com/cloudposse/atmos/errors"
 	ioLayer "github.com/cloudposse/atmos/pkg/io"
 	"github.com/cloudposse/atmos/pkg/perf"
-	"github.com/spf13/viper"
 )
📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 806f2e1 and 036dd9d.

📒 Files selected for processing (24)
  • .claude/agents/README.md
  • .claude/agents/example-creator.md
  • cmd/auth_console.go
  • cmd/auth_login.go
  • cmd/help_template.go
  • cmd/root.go
  • cmd/version/formatters.go
  • errors/error_funcs.go
  • examples/secrets-masking/.gitignore
  • examples/secrets-masking/README.md
  • examples/secrets-masking/atmos.yaml
  • examples/secrets-masking/components/terraform/secrets-demo/main.tf
  • examples/secrets-masking/components/terraform/secrets-demo/variables.tf
  • examples/secrets-masking/components/terraform/secrets-demo/versions.tf
  • examples/secrets-masking/stacks/deploy/dev.yaml
  • internal/exec/shell_utils.go
  • main.go
  • pkg/io/context.go
  • pkg/io/global.go
  • pkg/io/masker.go
  • pkg/list/list_instances.go
  • pkg/utils/doc_utils.go
  • pkg/utils/log_utils.go
  • pkg/utils/markdown_utils.go
🧰 Additional context used
📓 Path-based instructions (3)
**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands
Use interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations
All code must pass golangci-lint checks
Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using fmt.Errorf("context: %w", err), and consider using custom error types for domain-specific errors
Follow standard Go coding style: use gofmt and goimports to format code, prefer short descriptive variable names, use kebab-case for command-line flags, and snake_case for environment variables
Document all exported functions, types, and methods following Go's documentation conventions
Document complex logic with inline comments in Go code
Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults
Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging

**/*.go: All comments must end with periods (enforced by godot linter) in Go code
Organize imports into three groups separated by blank lines, sorted alphabetically: Go stdlib, 3rd-party (NOT cloudposse/atmos), then Atmos packages with maintained aliases (cfg, log, u, errUtils)
All errors MUST be wrapped using static errors defined in errors/errors.go - use errors.Join for combining errors, fmt.Errorf with %w for context, and errors.Is() for error checking
Never manually create mocks - use go.uber.org/mock/mockgen with //go:generate directives in Go code
Keep files small and focused - under 600 lines with one cmd/impl per file, co-locate tests, never use //revive:disable:file-length-limit
Use colors from pkg/ui/theme/colors.go for all UI theming in Go code
Code must be compatible with Linux, macOS, and Windows - use SDKs over binaries, use filepath.Join() instead of h...

Files:

  • pkg/utils/log_utils.go
  • pkg/list/list_instances.go
  • pkg/io/global.go
  • internal/exec/shell_utils.go
  • pkg/io/masker.go
  • errors/error_funcs.go
  • pkg/utils/markdown_utils.go
  • main.go
  • cmd/help_template.go
  • cmd/root.go
  • cmd/version/formatters.go
  • pkg/io/context.go
  • cmd/auth_login.go
  • cmd/auth_console.go
  • pkg/utils/doc_utils.go
**/{pkg,internal,cmd}/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Add defer perf.Track(atmosConfig, "pkg.FuncName")() plus blank line to all public functions, using nil if no atmosConfig param - exceptions: trivial getters/setters, command constructors, simple factories, functions delegating to tracked functions

Files:

  • pkg/utils/log_utils.go
  • pkg/list/list_instances.go
  • pkg/io/global.go
  • internal/exec/shell_utils.go
  • pkg/io/masker.go
  • pkg/utils/markdown_utils.go
  • cmd/help_template.go
  • cmd/root.go
  • cmd/version/formatters.go
  • pkg/io/context.go
  • cmd/auth_login.go
  • cmd/auth_console.go
  • pkg/utils/doc_utils.go
cmd/**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

cmd/**/*.go: Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under cmd/ directory
Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions
Provide meaningful feedback to users and include progress indicators for long-running operations in CLI commands

Files:

  • cmd/help_template.go
  • cmd/root.go
  • cmd/version/formatters.go
  • cmd/auth_login.go
  • cmd/auth_console.go
🧠 Learnings (86)
📓 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.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: docs/prd/tool-dependencies-integration.md:58-64
Timestamp: 2025-12-13T06:07:37.766Z
Learning: cloudposse/atmos: For PRD docs (docs/prd/*.md), markdownlint issues like MD040/MD010/MD034 can be handled in a separate documentation cleanup commit and should not block the current PR.
📚 Learning: 2025-09-13T18:06:07.674Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: toolchain/list.go:39-42
Timestamp: 2025-09-13T18:06:07.674Z
Learning: In the cloudposse/atmos repository, for UI messages in the toolchain package, use utils.PrintfMessageToTUI instead of log.Error or fmt.Fprintln(os.Stderr, ...). Import pkg/utils with alias "u" to follow the established pattern.

Applied to files:

  • pkg/utils/log_utils.go
  • pkg/io/global.go
  • internal/exec/shell_utils.go
  • errors/error_funcs.go
  • pkg/utils/markdown_utils.go
  • main.go
  • cmd/help_template.go
  • cmd/version/formatters.go
  • cmd/auth_console.go
  • pkg/utils/doc_utils.go
📚 Learning: 2025-02-21T20:56:05.539Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1077
File: pkg/downloader/custom_github_detector.go:0-0
Timestamp: 2025-02-21T20:56:05.539Z
Learning: The `github.com/charmbracelet/log` package should be imported with the alias `log` according to the project's import alias configuration.

Applied to files:

  • pkg/utils/log_utils.go
  • pkg/utils/markdown_utils.go
  • cmd/version/formatters.go
  • cmd/auth_login.go
📚 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:

  • pkg/utils/log_utils.go
  • pkg/list/list_instances.go
  • pkg/io/global.go
  • internal/exec/shell_utils.go
  • pkg/utils/markdown_utils.go
  • main.go
  • cmd/help_template.go
  • cmd/version/formatters.go
  • cmd/auth_login.go
  • cmd/auth_console.go
  • pkg/utils/doc_utils.go
📚 Learning: 2024-10-28T01:51:30.811Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:329-332
Timestamp: 2024-10-28T01:51:30.811Z
Learning: In the Atmos Go code, when deleting directories or handling file paths (e.g., in `terraform_clean.go`), always resolve the absolute path using `filepath.Abs` and use the logger `u.LogWarning` for logging messages instead of using `fmt.Printf`.

Applied to files:

  • pkg/utils/log_utils.go
  • main.go
  • cmd/root.go
  • cmd/version/formatters.go
📚 Learning: 2025-02-21T20:56:20.761Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1077
File: pkg/downloader/custom_github_detector_test.go:0-0
Timestamp: 2025-02-21T20:56:20.761Z
Learning: The `github.com/charmbracelet/log` package should be imported with the alias `log`, not `clog`.

Applied to files:

  • pkg/utils/log_utils.go
  • pkg/utils/markdown_utils.go
  • cmd/version/formatters.go
  • cmd/auth_login.go
📚 Learning: 2026-01-04T00:55:21.720Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.720Z
Learning: Applies to **/{pkg,internal,cmd}/**/*.go : Add `defer perf.Track(atmosConfig, "pkg.FuncName")()` plus blank line to all public functions, using `nil` if no atmosConfig param - exceptions: trivial getters/setters, command constructors, simple factories, functions delegating to tracked functions

Applied to files:

  • pkg/utils/log_utils.go
  • pkg/list/list_instances.go
  • pkg/io/global.go
  • internal/exec/shell_utils.go
  • pkg/utils/markdown_utils.go
  • cmd/help_template.go
  • cmd/auth_login.go
  • cmd/auth_console.go
📚 Learning: 2026-01-04T00:55:21.720Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.720Z
Learning: Applies to **/*.go : Organize imports into three groups separated by blank lines, sorted alphabetically: Go stdlib, 3rd-party (NOT cloudposse/atmos), then Atmos packages with maintained aliases (`cfg`, `log`, `u`, `errUtils`)

Applied to files:

  • pkg/utils/log_utils.go
  • pkg/list/list_instances.go
  • internal/exec/shell_utils.go
  • pkg/utils/markdown_utils.go
  • cmd/help_template.go
  • cmd/auth_login.go
  • cmd/auth_console.go
📚 Learning: 2026-01-04T00:55:21.720Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.720Z
Learning: Separate I/O (streams) from UI (formatting) using two-layer architecture - use `pkg/io/` for streams and `pkg/ui/` for formatting

Applied to files:

  • pkg/utils/log_utils.go
  • internal/exec/shell_utils.go
  • pkg/utils/markdown_utils.go
  • main.go
  • cmd/help_template.go
  • cmd/version/formatters.go
  • cmd/auth_login.go
  • cmd/auth_console.go
  • pkg/utils/doc_utils.go
📚 Learning: 2026-01-04T00:55:21.720Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.720Z
Learning: Applies to **/*.go : Use colors from `pkg/ui/theme/colors.go` for all UI theming in Go code

Applied to files:

  • pkg/utils/log_utils.go
  • cmd/help_template.go
📚 Learning: 2024-10-31T19:25:41.298Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:233-235
Timestamp: 2024-10-31T19:25:41.298Z
Learning: When specifying color values in functions like `confirmDeleteTerraformLocal` in `internal/exec/terraform_clean.go`, avoid hardcoding color values. Instead, use predefined color constants or allow customization through configuration settings to improve accessibility and user experience across different terminals and themes.

Applied to files:

  • pkg/utils/log_utils.go
  • cmd/help_template.go
📚 Learning: 2025-12-21T04:10:29.030Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1891
File: internal/exec/describe_affected.go:468-468
Timestamp: 2025-12-21T04:10:29.030Z
Learning: In Go, package-level declarations (constants, variables, types, and functions) are visible to all files in the same package without imports. During reviews in cloudposse/atmos (and similar Go codebases), before suggesting to declare a new identifier, first check if it already exists in another file of the same package. If it exists, you can avoid adding a new declaration; if not, proceed with a proper package-level declaration. 

Applied to files:

  • pkg/utils/log_utils.go
  • pkg/list/list_instances.go
  • pkg/io/global.go
  • internal/exec/shell_utils.go
  • pkg/io/masker.go
  • errors/error_funcs.go
  • pkg/utils/markdown_utils.go
  • main.go
  • cmd/help_template.go
  • cmd/root.go
  • cmd/version/formatters.go
  • pkg/io/context.go
  • cmd/auth_login.go
  • cmd/auth_console.go
  • pkg/utils/doc_utils.go
📚 Learning: 2026-01-04T00:55:21.720Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.720Z
Learning: Use `ui.Write/Writef/Writeln()` and `ui.Success/Error/Warning/Info()` for human messages to stderr in Go commands

Applied to files:

  • pkg/utils/log_utils.go
  • internal/exec/shell_utils.go
  • errors/error_funcs.go
  • main.go
  • cmd/auth_console.go
📚 Learning: 2025-02-03T06:00:11.419Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/describe_config.go:20-20
Timestamp: 2025-02-03T06:00:11.419Z
Learning: Commands should use `PrintErrorMarkdownAndExit` with empty title and suggestion (`"", err, ""`) for general error handling. Specific titles like "Invalid Usage" or "File Not Found" should only be used for validation or specific error scenarios.

Applied to files:

  • pkg/utils/log_utils.go
  • errors/error_funcs.go
  • main.go
  • cmd/auth_console.go
📚 Learning: 2025-11-07T14:52:55.217Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1761
File: docs/prd/claude-agent-architecture.md:331-439
Timestamp: 2025-11-07T14:52:55.217Z
Learning: In the cloudposse/atmos repository, Claude agents are used as interactive tools, not in automated/headless CI/CD contexts. Agent documentation and patterns should assume synchronous human interaction.

Applied to files:

  • .claude/agents/README.md
  • .claude/agents/example-creator.md
📚 Learning: 2025-01-08T19:01:32.938Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 899
File: examples/tests/test-vendor/test-components/main.tf:1-7
Timestamp: 2025-01-08T19:01:32.938Z
Learning: In the examples/tests directory of the atmos project, code examples are intentionally kept minimal and simple to facilitate understanding. Avoid suggesting additional complexity or validations that might make the examples harder to follow.

Applied to files:

  • .claude/agents/README.md
  • examples/secrets-masking/atmos.yaml
  • .claude/agents/example-creator.md
📚 Learning: 2025-02-18T13:13:11.497Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1068
File: tests/snapshots/TestCLICommands_atmos_terraform_help.stdout.golden:59-64
Timestamp: 2025-02-18T13:13:11.497Z
Learning: For Atmos CLI help text, angle brackets in command examples and flag descriptions should be escaped using HTML entities (e.g., `&lt;component&gt;`) rather than converted to backticks or other markdown formatting.

Applied to files:

  • .claude/agents/README.md
📚 Learning: 2025-09-13T16:39:20.007Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.

Applied to files:

  • .claude/agents/README.md
  • examples/secrets-masking/README.md
📚 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:

  • pkg/list/list_instances.go
📚 Learning: 2024-12-11T18:40:12.808Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 844
File: cmd/helmfile.go:37-37
Timestamp: 2024-12-11T18:40:12.808Z
Learning: In the atmos project, `cliConfig` is initialized within the `cmd` package in `root.go` and can be used in other command files.

Applied to files:

  • pkg/list/list_instances.go
  • main.go
  • cmd/help_template.go
  • cmd/version/formatters.go
  • cmd/auth_login.go
  • cmd/auth_console.go
📚 Learning: 2024-10-23T21:36:40.262Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 740
File: cmd/cmd_utils.go:340-359
Timestamp: 2024-10-23T21:36:40.262Z
Learning: In the Go codebase for Atmos, when reviewing functions like `checkAtmosConfig` in `cmd/cmd_utils.go`, avoid suggesting refactoring to return errors instead of calling `os.Exit` if such changes would significantly increase the scope due to the need to update multiple call sites.

Applied to files:

  • pkg/list/list_instances.go
  • pkg/io/global.go
  • internal/exec/shell_utils.go
  • pkg/utils/markdown_utils.go
  • main.go
  • cmd/help_template.go
  • cmd/root.go
  • cmd/version/formatters.go
  • cmd/auth_console.go
  • pkg/utils/doc_utils.go
📚 Learning: 2025-05-30T03:21:37.197Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1274
File: go.mod:63-63
Timestamp: 2025-05-30T03:21:37.197Z
Learning: The redis dependency (github.com/redis/go-redis/v9) in the atmos project is only used in tests, not in production code.

Applied to files:

  • pkg/list/list_instances.go
  • cmd/auth_login.go
📚 Learning: 2025-08-16T23:33:07.477Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1405
File: internal/exec/describe_dependents_test.go:651-652
Timestamp: 2025-08-16T23:33:07.477Z
Learning: In the cloudposse/atmos Go codebase, ExecuteDescribeDependents expects a pointer to AtmosConfiguration (*schema.AtmosConfiguration), so when calling it with a value returned by cfg.InitCliConfig (which returns schema.AtmosConfiguration), the address-of operator (&) is necessary: ExecuteDescribeDependents(&atmosConfig, ...).

Applied to files:

  • pkg/list/list_instances.go
  • cmd/auth_console.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:

  • pkg/list/list_instances.go
  • pkg/io/global.go
  • examples/secrets-masking/atmos.yaml
  • cmd/help_template.go
  • pkg/io/context.go
  • cmd/auth_login.go
  • cmd/auth_console.go
  • examples/secrets-masking/README.md
  • pkg/utils/doc_utils.go
📚 Learning: 2025-08-16T23:32:40.412Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1405
File: internal/exec/describe_dependents_test.go:455-456
Timestamp: 2025-08-16T23:32:40.412Z
Learning: In the cloudposse/atmos Go codebase, `InitCliConfig` returns a `schema.AtmosConfiguration` value (not a pointer), while `ExecuteDescribeDependents` expects a `*schema.AtmosConfiguration` pointer parameter. Therefore, when passing the result of `InitCliConfig` to `ExecuteDescribeDependents`, use `&atmosConfig` to pass the address of the value.

Applied to files:

  • pkg/list/list_instances.go
📚 Learning: 2026-01-04T00:55:21.720Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.720Z
Learning: Use `data.Write/Writef/Writeln()` and `data.WriteJSON/WriteYAML()` for pipeable stdout output in Go commands

Applied to files:

  • pkg/list/list_instances.go
  • internal/exec/shell_utils.go
📚 Learning: 2026-01-04T00:55:21.720Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.720Z
Learning: Never use `fmt.Fprintf(os.Stdout/Stderr, ...)` or `fmt.Println()` for output - use `data.*` or `ui.*` functions instead

Applied to files:

  • pkg/list/list_instances.go
  • errors/error_funcs.go
  • cmd/auth_console.go
📚 Learning: 2025-12-13T03:21:35.786Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1813
File: cmd/terraform/shell.go:28-73
Timestamp: 2025-12-13T03:21:35.786Z
Learning: In Atmos, when calling cfg.InitCliConfig, you must first populate the schema.ConfigAndStacksInfo struct with global flag values using flags.ParseGlobalFlags(cmd, v) rather than passing an empty struct. The LoadConfig function (pkg/config/load.go) reads config selection fields (AtmosConfigFilesFromArg, AtmosConfigDirsFromArg, BasePath, ProfilesFromArg) directly from the ConfigAndStacksInfo struct, NOT from Viper. Passing an empty struct causes config selection flags (--base-path, --config, --config-path, --profile) to be silently ignored. Correct pattern: parse flags → populate struct → call InitCliConfig. See cmd/terraform/plan_diff.go for reference implementation.

Applied to files:

  • pkg/io/global.go
  • cmd/help_template.go
📚 Learning: 2025-11-09T19:06:58.470Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1752
File: pkg/profile/list/formatter_table.go:27-29
Timestamp: 2025-11-09T19:06:58.470Z
Learning: In the cloudposse/atmos repository, performance tracking with `defer perf.Track()` is enforced on all functions via linting, including high-frequency utility functions, formatters, and renderers. This is a repository-wide policy to maintain consistency and avoid making case-by-case judgment calls about which functions should have profiling.

Applied to files:

  • pkg/io/global.go
  • internal/exec/shell_utils.go
  • pkg/utils/markdown_utils.go
  • cmd/auth_login.go
  • cmd/auth_console.go
  • pkg/utils/doc_utils.go
📚 Learning: 2025-11-30T04:16:24.155Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1821
File: pkg/merge/deferred.go:34-48
Timestamp: 2025-11-30T04:16:24.155Z
Learning: In the cloudposse/atmos repository, the `defer perf.Track()` guideline applies to functions that perform meaningful work (I/O, computation, external calls), but explicitly excludes trivial accessors/mutators (e.g., simple getters, setters with single integer increments, string joins, or map appends) where the tracking overhead would exceed the actual method cost and provide no actionable performance data. Hot-path methods called in tight loops should especially avoid perf.Track() if they perform only trivial operations.

Applied to files:

  • pkg/io/global.go
📚 Learning: 2025-12-13T06:10:13.688Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: errors/errors.go:184-203
Timestamp: 2025-12-13T06:10:13.688Z
Learning: cloudposse/atmos: For toolchain work, duplicate/unused error sentinels in errors/errors.go should be cleaned up in a separate refactor PR and not block feature PRs; canonical toolchain sentinels live under toolchain/registry with re-exports in toolchain/errors.go.

Applied to files:

  • pkg/io/global.go
  • internal/exec/shell_utils.go
📚 Learning: 2025-02-06T13:38:07.216Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 984
File: internal/exec/copy_glob.go:0-0
Timestamp: 2025-02-06T13:38:07.216Z
Learning: The `u.LogTrace` function in the `cloudposse/atmos` repository accepts `atmosConfig` as its first parameter, followed by the message string.

Applied to files:

  • pkg/io/global.go
  • cmd/root.go
  • cmd/version/formatters.go
📚 Learning: 2025-10-22T14:55:44.014Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1695
File: pkg/auth/manager.go:169-171
Timestamp: 2025-10-22T14:55:44.014Z
Learning: Go 1.20+ supports multiple %w verbs in fmt.Errorf, which returns an error implementing Unwrap() []error. This is valid and does not panic. Atmos uses Go 1.24.8 and configures errorlint with errorf-multi: true to validate this pattern.

Applied to files:

  • pkg/io/global.go
  • internal/exec/shell_utils.go
  • pkg/utils/markdown_utils.go
  • main.go
  • cmd/version/formatters.go
  • pkg/utils/doc_utils.go
📚 Learning: 2024-12-12T15:17:45.245Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: examples/demo-atmos.d/atmos.d/tools/helmfile.yml:10-10
Timestamp: 2024-12-12T15:17:45.245Z
Learning: In `examples/demo-atmos.d/atmos.d/tools/helmfile.yml`, when suggesting changes to `kubeconfig_path`, ensure that the values use valid Go template syntax.

Applied to files:

  • examples/secrets-masking/atmos.yaml
📚 Learning: 2024-11-25T17:17:15.703Z
Learnt from: RoseSecurity
Repo: cloudposse/atmos PR: 797
File: pkg/list/atmos.yaml:213-214
Timestamp: 2024-11-25T17:17:15.703Z
Learning: The file `pkg/list/atmos.yaml` is primarily intended for testing purposes.

Applied to files:

  • examples/secrets-masking/atmos.yaml
📚 Learning: 2025-01-25T15:21:40.413Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: examples/demo-atmos-cli-imports/atmos.yaml:8-8
Timestamp: 2025-01-25T15:21:40.413Z
Learning: In Atmos, when a directory is specified for configuration loading (e.g., in the `import` section of atmos.yaml), all files within that directory should be treated as Atmos configurations. Do not suggest restricting file extensions in directory-based glob patterns.

Applied to files:

  • examples/secrets-masking/atmos.yaml
📚 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:

  • examples/secrets-masking/atmos.yaml
  • .claude/agents/example-creator.md
📚 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:

  • examples/secrets-masking/atmos.yaml
📚 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:

  • examples/secrets-masking/atmos.yaml
  • .claude/agents/example-creator.md
  • examples/secrets-masking/stacks/deploy/dev.yaml
  • examples/secrets-masking/components/terraform/secrets-demo/main.tf
  • examples/secrets-masking/README.md
📚 Learning: 2026-01-09T04:49:35.038Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1907
File: demos/fixtures/acme/stacks/catalog/api.yaml:1-29
Timestamp: 2026-01-09T04:49:35.038Z
Learning: In the cloudposse/atmos demos/fixtures, components can provide Terraform outputs via `remote_state_backend.static` configuration blocks instead of traditional Terraform output blocks. This pattern is used for demo/fixture purposes to simulate cross-component state references without deploying actual infrastructure. The `!terraform.state` YAML function reads from these static backends.

Applied to files:

  • examples/secrets-masking/atmos.yaml
  • .claude/agents/example-creator.md
  • examples/secrets-masking/stacks/deploy/dev.yaml
  • examples/secrets-masking/components/terraform/secrets-demo/main.tf
  • examples/secrets-masking/README.md
📚 Learning: 2024-11-16T17:30:52.893Z
Learnt from: pkbhowmick
Repo: cloudposse/atmos PR: 786
File: internal/exec/shell_utils.go:159-162
Timestamp: 2024-11-16T17:30:52.893Z
Learning: For the `atmos terraform shell` command in `internal/exec/shell_utils.go`, input validation for the custom shell prompt is not required, as users will use this as a CLI tool and any issues will impact themselves.

Applied to files:

  • internal/exec/shell_utils.go
📚 Learning: 2025-10-11T19:11:58.965Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:0-0
Timestamp: 2025-10-11T19:11:58.965Z
Learning: For terraform apply interactivity checks in Atmos (internal/exec/terraform.go), use stdin TTY detection (e.g., `IsTTYSupportForStdin()` or checking `os.Stdin`) to determine if user prompts are possible. This is distinct from stdout/stderr TTY checks used for output display (like TUI rendering). User input requires stdin to be a TTY; output display requires stdout/stderr to be a TTY.

Applied to files:

  • internal/exec/shell_utils.go
📚 Learning: 2025-02-06T15:00:31.824Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: examples/demo-configuration/atmos.yaml:1-5
Timestamp: 2025-02-06T15:00:31.824Z
Learning: Keep demo configuration files minimal and focused on essential configurations, avoiding the inclusion of optional features that might make examples overly complex.

Applied to files:

  • .claude/agents/example-creator.md
📚 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:

  • .claude/agents/example-creator.md
📚 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:

  • .claude/agents/example-creator.md
📚 Learning: 2025-06-02T14:12:02.710Z
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning specific error variables (like `ErrWorkflowNoSteps`, `ErrInvalidFromStep`, `ErrInvalidWorkflowStepType`, `ErrWorkflowStepFailed`) instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions while maintaining excellent user-facing error formatting.

Applied to files:

  • errors/error_funcs.go
  • pkg/utils/markdown_utils.go
  • main.go
  • cmd/help_template.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging

Applied to files:

  • errors/error_funcs.go
  • main.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using `fmt.Errorf("context: %w", err)`, and consider using custom error types for domain-specific errors

Applied to files:

  • errors/error_funcs.go
  • main.go
📚 Learning: 2025-06-02T14:12:02.710Z
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning the error instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions.

Applied to files:

  • errors/error_funcs.go
  • pkg/utils/markdown_utils.go
📚 Learning: 2025-04-04T02:03:21.906Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1185
File: internal/exec/yaml_func_store.go:71-72
Timestamp: 2025-04-04T02:03:21.906Z
Learning: The codebase currently uses `log.Fatal` for error handling in library functions, which terminates the program. There is a plan to refactor this approach in a separate PR to improve API design by returning error messages instead of terminating execution.

Applied to files:

  • errors/error_funcs.go
  • main.go
📚 Learning: 2026-01-04T00:55:21.720Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.720Z
Learning: Applies to **/*.go : All errors MUST be wrapped using static errors defined in `errors/errors.go` - use `errors.Join` for combining errors, `fmt.Errorf` with `%w` for context, and `errors.Is()` for error checking

Applied to files:

  • errors/error_funcs.go
  • main.go
📚 Learning: 2024-10-12T18:38:28.458Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 715
File: pkg/logger/logger.go:21-32
Timestamp: 2024-10-12T18:38:28.458Z
Learning: In Go code, avoid prefixing struct names with 'I' (e.g., `IError`) as it can be confusing, suggesting an interface. Use descriptive names for structs to improve code clarity.

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2025-02-03T06:00:11.419Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/describe_config.go:20-20
Timestamp: 2025-02-03T06:00:11.419Z
Learning: The `describe config` command should use `PrintErrorMarkdownAndExit` with empty title and suggestion for consistency with other commands.

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2025-02-03T20:28:36.622Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/describe_config.go:20-20
Timestamp: 2025-02-03T20:28:36.622Z
Learning: Error messages should include descriptive titles when the error type is known/expected (e.g., "Invalid Usage", "File Not Found"). For functions that can return multiple types of errors, passing the error through without a specific title is preferred.

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2025-01-07T20:38:09.618Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 896
File: cmd/editor_config.go:37-40
Timestamp: 2025-01-07T20:38:09.618Z
Learning: Error handling suggestion for `cmd.Help()` in `cmd/editor_config.go` was deferred as the code is planned for future modifications.

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Provide meaningful feedback to users and include progress indicators for long-running operations in CLI commands

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2024-11-10T19:28:17.365Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 768
File: internal/exec/vendor_utils.go:0-0
Timestamp: 2024-11-10T19:28:17.365Z
Learning: When TTY is not supported, log the downgrade message at the Warn level using `u.LogWarning(cliConfig, ...)` instead of `fmt.Println`.

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2024-12-05T22:33:40.955Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 820
File: cmd/list_components.go:53-54
Timestamp: 2024-12-05T22:33:40.955Z
Learning: In the Atmos CLI Go codebase, using `u.LogErrorAndExit` within completion functions is acceptable because it logs the error and exits the command execution.

Applied to files:

  • errors/error_funcs.go
  • main.go
  • cmd/version/formatters.go
📚 Learning: 2026-01-04T00:55:21.720Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.720Z
Learning: Applies to **/*.go : Use `viper.BindEnv("ATMOS_VAR", "ATMOS_VAR", "FALLBACK")` for environment variables - ATMOS_ prefix required in Go code

Applied to files:

  • pkg/utils/markdown_utils.go
  • pkg/utils/doc_utils.go
📚 Learning: 2025-02-05T20:16:24.036Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: pkg/ui/markdown/renderer.go:75-75
Timestamp: 2025-02-05T20:16:24.036Z
Learning: The Purple constant for markdown rendering is defined in pkg/ui/markdown/colors.go.

Applied to files:

  • pkg/utils/markdown_utils.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:

  • examples/secrets-masking/.gitignore
📚 Learning: 2024-12-13T15:28:13.630Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 844
File: cmd/version.go:34-44
Timestamp: 2024-12-13T15:28:13.630Z
Learning: In `cmd/version.go`, when handling the `--check` flag in the `versionCmd`, avoid using `CheckForAtmosUpdateAndPrintMessage(cliConfig)` as it updates the cache timestamp, which may not be desired in this context.

Applied to files:

  • main.go
📚 Learning: 2025-04-04T02:03:23.676Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1185
File: internal/exec/yaml_func_store.go:26-26
Timestamp: 2025-04-04T02:03:23.676Z
Learning: The Atmos codebase currently uses `log.Fatal` for error handling in multiple places. The maintainers are aware this isn't an ideal pattern (should only be used in main() or init() functions) and plan to address it comprehensively in a separate PR. CodeRabbit should not flag these issues or push for immediate changes until that refactoring is complete.

Applied to files:

  • main.go
  • cmd/help_template.go
📚 Learning: 2025-01-30T19:30:59.120Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/workflow.go:74-74
Timestamp: 2025-01-30T19:30:59.120Z
Learning: Error handling for `cmd.Usage()` is not required in the Atmos CLI codebase, as confirmed by the maintainer.

Applied to files:

  • main.go
📚 Learning: 2025-12-13T04:37:25.223Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: cmd/root.go:0-0
Timestamp: 2025-12-13T04:37:25.223Z
Learning: In Atmos cmd/root.go Execute(), after cfg.InitCliConfig, we must call both toolchainCmd.SetAtmosConfig(&atmosConfig) and toolchain.SetAtmosConfig(&atmosConfig) so the CLI wrapper and the toolchain package receive configuration; missing either can cause nil-pointer panics in toolchain path resolution.

Applied to files:

  • main.go
📚 Learning: 2024-10-20T13:12:46.499Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 736
File: pkg/config/const.go:6-6
Timestamp: 2024-10-20T13:12:46.499Z
Learning: In `cmd/cmd_utils.go`, it's acceptable to have hardcoded references to `atmos.yaml` in logs, and it's not necessary to update them to use the `CliConfigFileName` constant.

Applied to files:

  • main.go
  • cmd/root.go
📚 Learning: 2025-01-18T15:18:35.475Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/root.go:172-178
Timestamp: 2025-01-18T15:18:35.475Z
Learning: The `showUsageAndExit` function in `cmd/cmd_utils.go` provides user feedback by showing error messages, command suggestions, and valid subcommands before terminating the program with `os.Exit(1)`. It never returns to the caller, making error handling unnecessary for calls to this function.

Applied to files:

  • main.go
📚 Learning: 2024-12-05T22:33:54.807Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 820
File: cmd/list_stacks.go:55-56
Timestamp: 2024-12-05T22:33:54.807Z
Learning: In the atmos project, the `u.LogErrorAndExit` function logs the error and exits the command execution appropriately within flag completion functions.

Applied to files:

  • main.go
📚 Learning: 2025-01-18T15:18:35.475Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/root.go:172-178
Timestamp: 2025-01-18T15:18:35.475Z
Learning: The `showUsageAndExit` function in `cmd/cmd_utils.go` terminates the program with `os.Exit(1)` and never returns to the caller, making error handling unnecessary for calls to this function.

Applied to files:

  • main.go
📚 Learning: 2025-09-05T14:57:37.360Z
Learnt from: RoseSecurity
Repo: cloudposse/atmos PR: 1448
File: cmd/ansible.go:26-28
Timestamp: 2025-09-05T14:57:37.360Z
Learning: The Atmos codebase uses a consistent pattern for commands that delegate to external tools: `PersistentFlags().Bool("", false, doubleDashHint)` where doubleDashHint provides help text about using double dashes to separate Atmos options from native command arguments. This pattern is used across terraform, packer, helmfile, atlantis, aws, and ansible commands.

Applied to files:

  • main.go
📚 Learning: 2024-11-07T20:16:15.381Z
Learnt from: pkbhowmick
Repo: cloudposse/atmos PR: 766
File: cmd/cmd_utils.go:177-178
Timestamp: 2024-11-07T20:16:15.381Z
Learning: In 'cmd/cmd_utils.go', using `os.Exit(1)` directly is acceptable in this context, and wrapping it with deferred cleanup is considered unnecessary.

Applied to files:

  • main.go
📚 Learning: 2025-09-10T22:38:42.212Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: pkg/auth/identities/aws/user.go:141-145
Timestamp: 2025-09-10T22:38:42.212Z
Learning: The user confirmed that the errors package has an error string wrapping format, contradicting the previous learning about ErrWrappingFormat being invalid. The current usage of fmt.Errorf(errUtils.ErrWrappingFormat, errUtils.ErrAuthAwsFileManagerFailed, err) appears to be the correct pattern.

Applied to files:

  • main.go
📚 Learning: 2025-09-10T22:38:42.212Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: pkg/auth/identities/aws/user.go:141-145
Timestamp: 2025-09-10T22:38:42.212Z
Learning: ErrWrappingFormat is correctly defined as "%w: %w" in the errors package and is used throughout the codebase to wrap two error types together. The usage fmt.Errorf(errUtils.ErrWrappingFormat, errUtils.ErrAuthAwsFileManagerFailed, err) is the correct pattern when both arguments are error types.

Applied to files:

  • main.go
📚 Learning: 2025-12-13T04:37:40.435Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: cmd/toolchain/get.go:23-40
Timestamp: 2025-12-13T04:37:40.435Z
Learning: In Go CLI command files using Cobra, constrain the subcommand to accept at most one positional argument (MaximumNArgs(1)) so it supports both listing all items (zero args) and fetching a specific item (one arg). Define and parse flags with a standard parser (e.g., flags.NewStandardParser()) and avoid binding flags to Viper (no viper.BindEnv/BindPFlag). This promotes explicit argument handling and predictable flag behavior across command files.

Applied to files:

  • cmd/help_template.go
  • cmd/root.go
  • cmd/version/formatters.go
  • cmd/auth_login.go
  • cmd/auth_console.go
📚 Learning: 2025-01-28T21:24:59.898Z
Learnt from: mcalhoun
Repo: cloudposse/atmos PR: 980
File: cmd/root.go:95-122
Timestamp: 2025-01-28T21:24:59.898Z
Learning: In the Atmos project, log files are intentionally kept open for the entire program execution to efficiently handle logging throughout the program's lifecycle, rather than opening/closing the file for each log write.

Applied to files:

  • cmd/root.go
📚 Learning: 2025-12-13T06:10:25.156Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: internal/exec/workflow_utils.go:0-0
Timestamp: 2025-12-13T06:10:25.156Z
Learning: Atmos workflows: In internal/exec/workflow_utils.go ExecuteWorkflow, non-identity steps intentionally use baseWorkflowEnv, which is constructed from the parent environment with PATH modifications for the toolchain. Avoid appending os.Environ() again; prefer documenting this behavior and testing that standard environment variables are preserved.

Applied to files:

  • pkg/io/context.go
📚 Learning: 2025-12-24T04:29:23.938Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1891
File: pkg/ci/terraform/templates/apply.md:17-17
Timestamp: 2025-12-24T04:29:23.938Z
Learning: In the cloudposse/atmos repository, Terraform CI templates (pkg/ci/terraform/templates/*.md) are rendered using TerraformTemplateContext (defined in pkg/ci/terraform/context.go), not the base ci.TemplateContext. TerraformTemplateContext provides top-level fields: .Resources (ci.ResourceCounts), .HasChanges() method, and .HasDestroy field, which are correctly accessed directly in templates without a .Result prefix.

Applied to files:

  • examples/secrets-masking/components/terraform/secrets-demo/main.tf
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to README.md : Update README.md with new commands and features

Applied to files:

  • examples/secrets-masking/README.md
📚 Learning: 2024-12-12T17:13:53.409Z
Learnt from: RoseSecurity
Repo: cloudposse/atmos PR: 848
File: pkg/utils/doc_utils.go:19-22
Timestamp: 2024-12-12T17:13:53.409Z
Learning: In `pkg/utils/doc_utils.go`, the `DisplayDocs` function uses the `PAGER` environment variable, which is intentionally user-configurable to allow users to specify custom pager commands that fit their workflow; adding validation to restrict it is not desired.

Applied to files:

  • pkg/utils/doc_utils.go
📚 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:

  • pkg/utils/doc_utils.go
📚 Learning: 2025-04-23T15:02:50.246Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1202
File: pkg/utils/yaml_func_exec.go:104-104
Timestamp: 2025-04-23T15:02:50.246Z
Learning: In the Atmos codebase, direct calls to `os.Getenv` should be avoided. Instead, use `viper.BindEnv` for environment variable access. This provides a consistent approach to configuration management across the codebase.

Applied to files:

  • pkg/utils/doc_utils.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Use Viper for managing configuration, environment variables, and flags in CLI commands

Applied to files:

  • pkg/utils/doc_utils.go
📚 Learning: 2024-11-01T15:44:12.617Z
Learnt from: RoseSecurity
Repo: cloudposse/atmos PR: 757
File: cmd/docs.go:42-59
Timestamp: 2024-11-01T15:44:12.617Z
Learning: In `cmd/docs.go`, when implementing width detection for the `docsCmd` command, it's acceptable to keep the code inline without extracting it into a separate function, as per the user's preference for compact readability and maintainability in Go code.

Applied to files:

  • pkg/utils/doc_utils.go
📚 Learning: 2025-05-22T19:58:32.988Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected.go:122-123
Timestamp: 2025-05-22T19:58:32.988Z
Learning: The "pager" flag is defined as a PersistentFlag at the describe command level in cmd/describe.go, making it available to all subcommands including describeAffectedCmd without needing to redeclare it.

Applied to files:

  • pkg/utils/doc_utils.go
📚 Learning: 2024-11-01T14:45:32.417Z
Learnt from: RoseSecurity
Repo: cloudposse/atmos PR: 757
File: cmd/docs.go:52-54
Timestamp: 2024-11-01T14:45:32.417Z
Learning: In `cmd/docs.go`, capping the terminal width at 120 columns is considered acceptable and preferred after testing.

Applied to files:

  • pkg/utils/doc_utils.go
📚 Learning: 2025-09-23T04:43:31.857Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1430
File: pkg/config/config.go:98-107
Timestamp: 2025-09-23T04:43:31.857Z
Learning: In the Atmos codebase, NO_PAGER environment variable handling is intentionally kept as direct os.Getenv() access in pkg/config/config.go rather than using Viper binding, because adding no_pager to the config file would be confusing for users. This is an acknowledged exception to the normal Viper binding pattern for environment variables.

Applied to files:

  • pkg/utils/doc_utils.go
🧬 Code graph analysis (11)
pkg/utils/log_utils.go (3)
pkg/io/global.go (1)
  • MaskWriter (179-199)
pkg/terminal/terminal.go (2)
  • Stdout (84-84)
  • Stderr (85-85)
pkg/logger/log.go (1)
  • Trace (14-16)
pkg/io/global.go (4)
pkg/io/interfaces.go (2)
  • Masker (73-103)
  • Config (106-113)
pkg/perf/perf.go (1)
  • Track (121-138)
pkg/schema/schema.go (2)
  • Settings (989-993)
  • Terminal (286-299)
pkg/logger/log.go (1)
  • Warn (44-46)
internal/exec/shell_utils.go (3)
pkg/terminal/terminal.go (2)
  • Stdout (84-84)
  • Stderr (85-85)
pkg/io/global.go (1)
  • MaskWriter (179-199)
pkg/utils/shell_utils.go (1)
  • ShellRunner (65-103)
pkg/io/masker.go (3)
pkg/io/interfaces.go (2)
  • Config (106-113)
  • Masker (73-103)
pkg/terminal/terminal.go (2)
  • Config (115-131)
  • Terminal (49-77)
pkg/schema/schema.go (2)
  • Settings (989-993)
  • Terminal (286-299)
pkg/utils/markdown_utils.go (1)
pkg/io/global.go (1)
  • MaskWriter (179-199)
main.go (1)
pkg/io/global.go (1)
  • MaskWriter (179-199)
cmd/root.go (2)
pkg/io/global.go (1)
  • MaskWriter (179-199)
pkg/schema/schema.go (1)
  • Logs (547-550)
cmd/version/formatters.go (2)
pkg/io/global.go (1)
  • MaskWriter (179-199)
pkg/utils/markdown_utils.go (1)
  • PrintfMarkdownToTUI (90-94)
cmd/auth_login.go (1)
pkg/io/global.go (1)
  • MaskWriter (179-199)
cmd/auth_console.go (2)
pkg/io/global.go (1)
  • MaskWriter (179-199)
pkg/utils/url_utils.go (1)
  • OpenUrl (13-39)
pkg/utils/doc_utils.go (1)
pkg/io/global.go (1)
  • MaskWriter (179-199)
🪛 LanguageTool
.claude/agents/example-creator.md

[typographical] ~210-~210: To join two clauses or introduce examples, consider using an em dash.
Context: ...rr/Info - components.terraform.* flags - Safe defaults ## README.md Template ``...

(DASH_RULE)


[uncategorized] ~342-~342: The official name of this software platform is spelled with a capital “H”.
Context: ... ## GitHub Workflow Integration Add to .github/workflows/test.yml mock job matrix: `...

(GITHUB)


[typographical] ~379-~379: Consider using a typographic opening quote here.
Context: ...h <EmbedFile filePath="..." /> 5. Add "See Full Example" link to the example di...

(EN_QUOTES)


[typographical] ~379-~379: Consider using a typographic close quote here.
Context: ...ePath="..." />` 5. Add "See Full Example" link to the example directory ### Bene...

(EN_QUOTES)


[typographical] ~412-~412: To join two clauses or introduce examples, consider using an em dash.
Context: ...ion 1. examples/demo-{name}/README.md - Main example docs 2. `examples/demo-{nam...

(DASH_RULE)


[uncategorized] ~438-~438: The official name of this software platform is spelled with a capital “H”.
Context: ...# 7. Update Workflow (Optional) Add to .github/workflows/test.yml mock job matrix if ...

(GITHUB)

examples/secrets-masking/README.md

[style] ~48-~48: Consider using the typographical ellipsis character here instead.
Context: ...lways active): - AWS Access Key IDs (AKIA...) - AWS Secret Access Keys - GitH...

(ELLIPSIS)


[style] ~50-~50: Consider using the typographical ellipsis character here instead.
Context: ... Secret Access Keys - GitHub tokens (ghp_..., gho_..., ghu_...) - Generic AP...

(ELLIPSIS)


[style] ~50-~50: Consider using the typographical ellipsis character here instead.
Context: ...ess Keys - GitHub tokens (ghp_..., gho_..., ghu_...) - Generic API keys and ...

(ELLIPSIS)


[style] ~50-~50: Consider using the typographical ellipsis character here instead.
Context: ... - GitHub tokens (ghp_..., gho_..., ghu_...) - Generic API keys and passwords ...

(ELLIPSIS)


[style] ~58-~58: Consider using the typographical ellipsis character here instead.
Context: ...XXXX...format -tkn_live_...andtkn_test_...tokens 3. **Custom literals** (from...

(ELLIPSIS)

⏰ 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). (3)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (linux)
  • GitHub Check: Summary

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@osterman osterman added the minor New features that do not break anything label Jan 15, 2026
@github-actions
Copy link

Warning

Release Documentation Required

This PR is labeled minor or major and requires documentation updates:

  • Changelog entry - Add a blog post in website/blog/YYYY-MM-DD-feature-name.mdx
  • Roadmap update - Update website/src/data/roadmap.js with the new milestone

Alternatively: If this change doesn't require release documentation, remove the minor or major label.

- Fix Pattern C in example-creator agent to avoid subdirectory requirement
- Update README example to show all patterns matching the description

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@github-actions
Copy link

Warning

Release Documentation Required

This PR is labeled minor or major and requires documentation updates:

  • Changelog entry - Add a blog post in website/blog/YYYY-MM-DD-feature-name.mdx
  • Roadmap update - Update website/src/data/roadmap.js with the new milestone

Alternatively: If this change doesn't require release documentation, remove the minor or major label.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 15, 2026
@github-actions
Copy link

Warning

Release Documentation Required

This PR is labeled minor or major and requires documentation updates:

  • Changelog entry - Add a blog post in website/blog/YYYY-MM-DD-feature-name.mdx
  • Roadmap update - Update website/src/data/roadmap.js with the new milestone

Alternatively: If this change doesn't require release documentation, remove the minor or major label.

@github-actions
Copy link

Warning

Release Documentation Required

This PR is labeled minor or major and requires documentation updates:

  • Changelog entry - Add a blog post in website/blog/YYYY-MM-DD-feature-name.mdx
  • Roadmap update - Update website/src/data/roadmap.js with the new milestone

Alternatively: If this change doesn't require release documentation, remove the minor or major label.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 15, 2026
osterman and others added 2 commits January 15, 2026 20:05
…asking

- Add secrets-masking to examples/README.md index
- Create new "Secrets Management" initiative in roadmap with milestones
- Add blog post announcing custom secrets masking patterns

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

mergify bot commented Jan 16, 2026

Warning

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

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

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

- Reframe blog post around "provably safe" secrets management foundation
- Add "Why This Matters" section explaining comprehensive output coverage
- Update roadmap initiative tagline and description
- Emphasize that this ensures no bypass paths for secret leakage

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

mergify bot commented Jan 22, 2026

💥 This pull request now has conflicts. Could you fix it @osterman? 🙏

@mergify mergify bot added the conflict This PR has conflicts label Jan 22, 2026
Resolved conflict in examples/README.md by including both new examples:
- secrets-masking (from this branch)
- stack-names (from main)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Regenerated snapshots to account for schema changes from main branch.

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

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@website/src/data/roadmap.js`:
- Line 440: Update the milestone entry whose label is 'Configurable replacement
string' (the object with properties status: 'shipped', quarter: 'q1-2026', pr:
1972) so its description and benefits mention the current default replacement
token "<MASKED>" instead of the old "***MASKED***"; specifically change the
description text to say the default is "<MASKED>" and adjust the benefits
example to reference "<MASKED>" (or show both formats if desired) so the
displayed milestone matches the codebase's actual default.
- Around line 435-436: The progress field currently hardcoded as progress: 50
(next to status: 'in-progress') is wrong; update that object's progress to
reflect (shippedMilestones / totalMilestones) * 100 — for 5 shipped out of 6
total set progress to ~83 (e.g., Math.round((5/6)*100) or 83.33) so the progress
value matches the shipped/total calculation.
🧹 Nitpick comments (1)
CLAUDE.md (1)

54-74: Clarify agents are interactive (not headless/CI).

Add a short line to prevent automation misuse and align with existing agent guidance. As per learnings, this repo treats agents as synchronous, human-in-the-loop tools.

💡 Suggested wording
 **Benefits:** Agents are domain experts with deep knowledge of patterns, PRDs, and subsystem architecture. They ensure consistency and best practices.
+
+**Note:** Agents are intended for interactive, human-in-the-loop use (not headless CI automation).

- Update progress percentage from 50% to 83% (5/6 milestones shipped)
- Fix default token reference from ***MASKED*** to <MASKED>

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 23, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@pkg/io/masker_test.go`:
- Around line 569-586: The test TestMasker_RegisterSecret_WithEscaping currently
only checks that Mask(input) differs from input which can give false positives;
instead compute the concrete expected JSON by first getting the masked form of
the raw secret (e.g., maskedSecret := m.Mask(secretWithNewline)) and then assert
equality against the exact escaped JSON string built from that maskedSecret
(e.g., expected := `{"value":"` + maskedSecret + `"}`) when calling
m.Mask(input); also add an assertion that masking the plain secret
(m.Mask(secretWithNewline)) equals maskedSecret to ensure both plain and
JSON-escaped forms are handled by RegisterSecret/RegisterSecret usage with
newMasker and RegisterSecret.

@aknysh aknysh merged commit acf68be into main Jan 23, 2026
60 checks passed
@aknysh aknysh deleted the osterman/secrets-masking branch January 23, 2026 21:55
@mergify mergify bot removed the needs-cloudposse Needs Cloud Posse assistance label Jan 23, 2026
@github-actions
Copy link

Warning

Release Documentation Required

This PR is labeled minor or major and requires documentation updates:

  • Changelog entry - Add a blog post in website/blog/YYYY-MM-DD-feature-name.mdx
  • Roadmap update - Update website/src/data/roadmap.js with the new milestone

Alternatively: If this change doesn't require release documentation, remove the minor or major label.

@github-actions
Copy link

These changes were released in v1.204.1-rc.5.

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

Labels

minor New features that do not break anything size/xl Extra large size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants