Skip to content

docs(cli): add structured CLI reference for undocumented flags (filters, purchase-safety, cloud-setup)#1090

Open
cristim wants to merge 8 commits into
mainfrom
docs/cli-reference
Open

docs(cli): add structured CLI reference for undocumented flags (filters, purchase-safety, cloud-setup)#1090
cristim wants to merge 8 commits into
mainfrom
docs/cli-reference

Conversation

@cristim

@cristim cristim commented Jun 7, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds docs/cli/ hierarchy: index + three topic pages covering every CLI flag, the purchase-safety guardrails, and the configure-azure/configure-gcp subcommands -- all previously absent from user-facing docs
  • Explicitly calls out the --min-savings-pct percentage vs GUI min_savings dollar naming distinction to prevent silent misconfiguration (gap analysis P3)
  • Updates .gitignore so docs/cli/ is tracked while docs/code-review/ and other scratch dirs remain ignored
  • Adds a short "CLI Reference" pointer block to README.md

File tree created

docs/cli/
  README.md          -- index + complete flag reference table (all ~35 root flags)
  filtering.md       -- scoping + threshold filters with examples
  purchase-safety.md -- dry-run/purchase interaction, audit-log, idempotency, rebuy-window-days
  cloud-setup.md     -- configure-azure and configure-gcp subcommand docs

Flags verified against source

All flags verified against cmd/main.go (init() block), cmd/configure_azure.go, cmd/configure_gcp.go, cmd/validators.go, and cmd/multi_service.go.

Test plan

  • Confirm docs/cli/ files appear in the PR diff (not filtered by .gitignore)
  • Confirm docs/code-review/ files do NOT appear in the diff
  • Check all internal markdown links resolve (no broken cross-references)
  • Spot-check flag names and defaults against cmd/main.go init() block

Closes #1088

Summary by CodeRabbit

  • Documentation
    • Added comprehensive CLI documentation suite with command reference, flag guide, and detailed filtering options.
    • Documented purchase safety controls, audit logging, and pre-flight safety checks.
    • Added cloud credential setup guide for AWS, GCP, and Azure deployments.
    • Updated README with quick links to CLI reference materials.

@cristim cristim added triaged Item has been triaged priority/p2 Backlog-worthy severity/low Minor harm urgency/this-quarter Within the quarter impact/many Affects most users effort/m Days type/docs Documentation labels Jun 7, 2026
@coderabbitai

coderabbitai Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@cristim, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 25 minutes and 56 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1f981303-f526-4817-9a52-baa95b59291d

📥 Commits

Reviewing files that changed from the base of the PR and between cc3c323 and d769b95.

📒 Files selected for processing (6)
  • .gitignore
  • README.md
  • docs/cli/README.md
  • docs/cli/cloud-setup.md
  • docs/cli/filtering.md
  • docs/cli/purchase-safety.md
📝 Walkthrough

Walkthrough

This PR adds comprehensive CLI reference documentation for previously undocumented cudly flags and subcommands. The changes include repository structure updates (.gitignore and README linking), a CLI reference index with consolidated flag tables, and four new topic-specific documentation pages covering filtering behavior, cloud credential bootstrap workflows, and purchase-safety guardrails.

Changes

CLI Documentation Structure

Layer / File(s) Summary
Repository structure and main entry point
.gitignore, README.md
Updated .gitignore to selectively track docs/cli/ while ignoring other docs/ subdirectories; added a new "CLI Reference" section in the main README linking to the comprehensive CLI documentation.
CLI command and flag reference index
docs/cli/README.md
Created a comprehensive CLI reference documenting the cudly root command and subcommands (configure-azure, configure-gcp), with a complete flag reference table organized by functional categories: service selection, coverage/sizing, purchase execution/safety, recommendation filters, scoping filters, target-coverage helpers, input/output, authentication, and subcommand flags.
Filtering behavior documentation
docs/cli/filtering.md
Documented CLI filtering in two categories: scoping filters (account, region, engine, instance type, Savings Plan type, extended-support toggle) with startup validation and matching rules; threshold filters (min-count, min-savings-pct, max-break-even-months, max-instances, min-pool-size) with specific semantics including the percentage-vs-dollar naming distinction between CLI and GUI/API. Includes evaluation order, AND-composition rules, and multi-filter usage examples.
Cloud credential bootstrap subcommands
docs/cli/cloud-setup.md
Documented the configure-azure and configure-gcp one-time bootstrap subcommands, including deployment context for self-hosted AWS Lambda/GCP Cloud Run/Azure Container Apps, credential storage in AWS Secrets Manager, required roles and permissions, interactive and non-interactive usage flows, service account JSON requirements for GCP, and usage notes for first-time Terraform deployment vs subsequent credential rotation.
Purchase safety guardrails and decision logic
docs/cli/purchase-safety.md
Documented purchase-mode controls combining --purchase and --dry-run flags, interactive confirmation bypass via --yes, audit logging via --audit-log with JSONL format and pre-call write semantics, duplicate purchase prevention using --idempotency-window, pre-expiry replacement sizing via --rebuy-window-days, AWS rate-limit respecting delays, and a production safety checklist for pre-flight verification steps before real purchases.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested labels

type/chore

Poem

🐰 A warren of docs now guides the way,
From filters fine to purchases' sway,
Each CLI flag gets its careful say,
Cloud bootstrap paths light up the day,
Safe purchases bloom where guardrails play! 🌱

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main change: adding structured CLI documentation for previously undocumented flags and subcommands.
Linked Issues check ✅ Passed All coding objectives from issue #1088 are met: the PR adds docs/cli/ hierarchy with README.md (flag reference), filtering.md, purchase-safety.md, and cloud-setup.md; documents missing flags and subcommands; calls out CLI vs GUI naming distinction; and links from main README.
Out of Scope Changes check ✅ Passed All changes are in scope: .gitignore and README.md updates directly support the new docs/cli/ hierarchy; all new files are CLI documentation matching the #1088 requirements.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/cli-reference

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

@cristim

cristim commented Jun 7, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

cristim commented Jun 8, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review


Generated by Claude Code

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

@cristim I'll review the changes now.


🧠 Learnings used
Learnt from: cristim
Repo: LeanerCloud/CUDly PR: 0
File: :0-0
Timestamp: 2026-05-05T15:44:54.463Z
Learning: In the LeanerCloud/CUDly repository, when a CodeRabbit review flags something as "outside-diff" that was already implemented in an earlier commit of the same PR, it is likely a stale-snapshot artifact where the review diff was generated against a pre-fix view. The inline comment convention `(CR pass on PR #<number> Finding N)` is used by the maintainer (cristim) to mark lines that were changed in direct response to a prior CodeRabbit review pass.

Learnt from: cristim
Repo: LeanerCloud/CUDly PR: 339
File: providers/aws/recommendations/coverage.go:177-205
Timestamp: 2026-05-13T21:30:43.093Z
Learning: In the CUDly project (LeanerCloud/CUDly), the CLI flag for target-based coverage sizing is `--target-coverage` (not `--target-utilization`). The PR renamed it during design iteration: "utilization" (how full each RI is) stays ~100% under the new sizing, while "coverage" (% of demand covered) is the user-facing knob. `ce:GetReservationCoverage` is required only when `--target-coverage` is set, gated by `cfg.TargetCoverage <= 0` in `cmd/multi_service.go`. The legacy `--coverage` path is unaffected and pays no CE cost or IAM change.
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cristim

cristim commented Jun 8, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@cristim

cristim commented Jun 8, 2026

Copy link
Copy Markdown
Member Author

Pushed a follow-up commit adding two real root flags that were missing from the "Complete flag reference" table: --regions (-r) and --coverage-lookback-days. The table now matches all 35 cmd/main.go flags.

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

@cristim, I'll review the follow-up commit now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cristim

cristim commented Jun 9, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🧹 Nitpick comments (2)
.gitignore (1)

134-137: Confirm .gitignore negation for docs/cli is correct (lines 134-137).

With docs/* followed by !docs/cli, Git does not ignore docs/cli/... paths (e.g., git check-ignore -v docs/cli/README.md returns no matching ignore rule), and docs/cli/* files are present in git ls-files. Optional: use !docs/cli/ (and/or !docs/cli/**) to make the intent more explicit.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.gitignore around lines 134 - 137, The current .gitignore uses the patterns
"docs/*" and "!docs/cli" which can be ambiguous for excluding the directory
contents; update the negation to explicitly include the directory and its
contents by changing the negation pattern to include a trailing slash and
wildcards (e.g., use "!docs/cli/" and/or "!docs/cli/**") so that files under
docs/cli are explicitly not ignored while keeping other docs/ subdirectories
ignored.
docs/cli/cloud-setup.md (1)

21-21: Fix the IAM-action claim in cloud-setup prerequisites

configure-azure / configure-gcp use cmd/secrets_store.go’s AWSSecretsStore.UpdateSecret, which calls secretsmanager.UpdateSecret with SecretString to write the credential JSON; so the documented secretsmanager:UpdateSecret permission is the correct one for these bootstrap commands (not PutSecretValue).

secretsmanager:PutSecretValue is used elsewhere by the server when syncing the admin password, so runtime permissions (separate from these CLI prerequisites) may need it, but this Prerequisites bullet for the bootstrap CLI commands does not.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/cli/cloud-setup.md` at line 21, Update the docs to correct the IAM
action: change the prerequisite to require secretsmanager:UpdateSecret (not
PutSecretValue) because the bootstrap CLI commands
(configure-azure/configure-gcp) call cmd/secrets_store.go's
AWSSecretsStore.UpdateSecret which uses secretsmanager.UpdateSecret with
SecretString; if needed, add a note that secretsmanager:PutSecretValue is used
elsewhere by the server for admin password sync and may be required at runtime
but is not part of the CLI bootstrap prerequisites.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/cli/filtering.md`:
- Line 74: Update the doc text to remove the misleading “partial prefixes”
wording and explicitly state that --include-instance-types and
--exclude-instance-types require exact full instance-type strings (e.g.,
db.t3.micro) because filtering uses exact membership checks (slices.Contains in
shouldIncludeInstanceType); mention that prefix matching is not supported and
users must enumerate each full instance type they want included or excluded.
- Line 40: Update the docs/cli/filtering.md claim: instead of saying omitting
--regions causes CUDly to auto-discover regions from Cost Explorer
recommendations, state that the code first enumerates all AWS regions via EC2
DescribeRegions (opted-in regions) and only falls back to Cost Explorer-derived
regions when region listing fails; also clarify that --include-regions and
--exclude-regions are applied as a post-recommendation filter (they filter
recommendations by rec.Region via shouldIncludeRegion) and do not change which
regions are queried, and note that if both --regions and --include-regions are
provided the queried regions come from --regions and results are then filtered
by the include/exclude lists.

In `@docs/cli/purchase-safety.md`:
- Around line 56-63: Update the documentation's audit record status list to
include the missing "skipped_covered" status: in the description of the audit
record's status field (the "status" audit field), add `"skipped_covered"` with a
brief note that it represents an idempotency hit where the recommendation was
already purchased within the window; mirror the exact status token
`"skipped_covered"` used in the code and keep wording consistent with the other
statuses ("success", "error", "skipped").
- Around line 20-25: Update the purchase-safety doc to reflect actual behavior:
change table row 2 to "Real purchases" because applyFlagsDryRun
(pkg/config/load.go) sets cfg.DryRun=false when --purchase is provided
(purchaseChanged), and cmd/multi_service.go computes isDryRun :=
!cfg.ActualPurchase || cfg.DryRun so with --purchase (ActualPurchase=true) and
cfg.DryRun=false you get real purchases; also add a note that runToolFromCSV
ignores cfg.DryRun and derives isDryRun := !cfg.ActualPurchase (so behavior
differs between code paths) and adjust any single-formula statements to show
these two separate rules.

In `@docs/cli/README.md`:
- Around line 3-9: The README incorrectly states the root CLI name; update the
docs to reflect the actual root cobra command Use: "ri-helper" as defined in
cmd/main.go: replace references to `cudly` with `ri-helper` (or add a short note
explaining that some builds ship the binary as `cudly` if you prefer to preserve
that alias), while keeping `configure-azure`, `configure-gcp` and the note that
`rekey` and `server` are separate binaries with their own main.go entrypoints
intact so the documented commands match the code.
- Line 29: Update the `--regions` documentation to correctly describe
auto-discovery: when `--regions` is empty non-Savings-Plan services enumerate
all opted-in AWS regions using EC2 DescribeRegions (not Cost Explorer), Cost
Explorer recommendations are only used as a fallback if the EC2 DescribeRegions
call fails, and Savings Plans with an empty `--regions` always target us-east-1;
keep mention that `--include-regions` / `--exclude-regions` are applied on top
of the resulting set.
- Around line 52-54: Update the docs to explicitly state that CSV mode (when
using the --input-csv option) computes isDryRun using isDryRun :=
!cfg.ActualPurchase (i.e., it ignores cfg.DryRun), so passing --purchase alone
can trigger real purchases from a CSV; adjust the README entries for --dry-run
and --purchase and the purchase-safety.md wording to call out this CSV exception
and advise requiring --dry-run=false when using --input-csv if you want to
prevent actual purchases; reference the isDryRun variable and
cfg.ActualPurchase/cfg.DryRun logic in the note so readers can find the code
behavior easily.

---

Nitpick comments:
In @.gitignore:
- Around line 134-137: The current .gitignore uses the patterns "docs/*" and
"!docs/cli" which can be ambiguous for excluding the directory contents; update
the negation to explicitly include the directory and its contents by changing
the negation pattern to include a trailing slash and wildcards (e.g., use
"!docs/cli/" and/or "!docs/cli/**") so that files under docs/cli are explicitly
not ignored while keeping other docs/ subdirectories ignored.

In `@docs/cli/cloud-setup.md`:
- Line 21: Update the docs to correct the IAM action: change the prerequisite to
require secretsmanager:UpdateSecret (not PutSecretValue) because the bootstrap
CLI commands (configure-azure/configure-gcp) call cmd/secrets_store.go's
AWSSecretsStore.UpdateSecret which uses secretsmanager.UpdateSecret with
SecretString; if needed, add a note that secretsmanager:PutSecretValue is used
elsewhere by the server for admin password sync and may be required at runtime
but is not part of the CLI bootstrap prerequisites.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4a6ca616-9ca2-4ce0-8cc8-ee40e05c3bef

📥 Commits

Reviewing files that changed from the base of the PR and between 2276bce and cc3c323.

📒 Files selected for processing (6)
  • .gitignore
  • README.md
  • docs/cli/README.md
  • docs/cli/cloud-setup.md
  • docs/cli/filtering.md
  • docs/cli/purchase-safety.md

Comment thread docs/cli/filtering.md Outdated
Comment thread docs/cli/filtering.md Outdated
Comment thread docs/cli/purchase-safety.md
Comment thread docs/cli/purchase-safety.md
Comment thread docs/cli/README.md Outdated
Comment thread docs/cli/README.md Outdated
Comment thread docs/cli/README.md Outdated
@cristim cristim changed the base branch from feat/multicloud-web-frontend to main June 9, 2026 15:39
@cristim

cristim commented Jun 9, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

cristim added a commit that referenced this pull request Jun 11, 2026
Address CodeRabbit review findings on PR #1090:

- README.md + filtering.md: when --regions is empty the code enumerates
  all opted-in regions via EC2 DescribeRegions (Savings Plans always
  query once via us-east-1); Cost Explorer-based discovery is only a
  fallback when region listing fails. --include/--exclude-regions
  filter fetched recommendations and do not constrain queried regions.
- README.md + purchase-safety.md: document that --input-csv mode
  computes isDryRun = !ActualPurchase and ignores --dry-run, so
  --purchase alone performs real purchases there; split the decision
  formula per code path and add a CSV-mode warning example.
- filtering.md: instance-type include/exclude lists match by exact
  string equality (slices.Contains); remove the incorrect "partial
  prefixes" claim.
- purchase-safety.md: add the missing skipped_covered audit status
  (idempotency hit).
- README.md: clarify the binary is built as cudly while the cobra root
  command is named ri-helper; fix the auto-generated CSV filename
  format (ri-helper-<mode>-<timestamp>.csv).
@cristim cristim force-pushed the docs/cli-reference branch from 971a91b to b912ab6 Compare June 11, 2026 05:59
@cristim

cristim commented Jun 11, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

cristim added 7 commits June 19, 2026 16:56
Adds four tracked markdown pages covering the full CLI surface:

- docs/cli/README.md: index with a complete flag reference table for all
  ~35 root-command flags, grouped by concern
- docs/cli/filtering.md: account/region/engine/instance-type/SP-type
  include-exclude filters plus threshold filters (min-count, min-savings-pct,
  max-break-even-months, min-pool-size, max-instances), with examples;
  explicitly calls out the --min-savings-pct percentage vs GUI min_savings
  dollar naming distinction (P3 trap from gap analysis)
- docs/cli/purchase-safety.md: --dry-run/--purchase interaction, --audit-log,
  --idempotency-window, --rebuy-window-days, DISABLE_PURCHASE_DELAY (internal
  only), and a pre-production safety checklist
- docs/cli/cloud-setup.md: configure-azure and configure-gcp subcommands,
  flags, guided vs non-interactive modes, and when to use vs SaaS onboarding

Updates .gitignore to expose docs/cli/ as a tracked directory (docs/* glob
replaces the previous docs/ directory ignore, preserving the ignore for
docs/code-review/ and other scratch dirs while allowing docs/cli/ through).

Links the new docs/cli/ index from README.md.

Closes #1088
Add language tags to all 20 bare fenced code blocks in docs/cli/*.md
(MD040) and replace the illustrative RSA private key marker in
cloud-setup.md with a placeholder to pass detect-private-key.
The "Complete flag reference" claimed all ~35 root flags but omitted two
real cmd/main.go flags: --regions (-r), the primary region scoping flag
(referenced in filtering.md but never tabulated), and
--coverage-lookback-days (default 30), which directly tunes the
--target-coverage sizing path the docs cover in depth. Add both to the
flag reference so the table matches the binary.
… deployment overview

- Remove false claim of a "SaaS offering" and "Settings UI": CUDly is
  self-hosted only; there is no managed/hosted tier.
- Replace all "CloudFormation stack" references with "Terraform
  deployment": the project deploys via Terraform (terraform/environments/
  aws|gcp|azure) driven by GitHub Actions workflows, not CloudFormation.
- Rewrite --stack-name flag description in both configure-azure and
  configure-gcp tables to describe what it actually does (naming prefix
  for Secrets Manager secret lookup).
- Add "Deployment overview" section documenting the three Terraform
  environments (AWS Lambda, GCP Cloud Run, Azure Container Apps) and the
  ci-cd-permissions bootstrap/runtime IAM split.
- Replace fabricated "When to use vs. SaaS onboarding" table with a
  minimal "Usage notes" table covering first-time setup and rotation.
cloud-setup.md "Deployment overview" had a near-verbatim copy of the
runtime/Terraform table that now lives in README.md under
"Deployment (self-hosted via Terraform)". Replace the duplicated table
with a short forward-reference link to the README section; keep the
CI/CD bootstrap note that is not in the README.

No other material duplication was found: the CLI docs carry genuinely
deeper detail (flag-by-flag reference with defaults and edge cases,
configure-azure/configure-gcp subcommand flags, filtering semantics,
purchase-safety mechanics) that the README does not cover.
Address CodeRabbit review findings on PR #1090:

- README.md + filtering.md: when --regions is empty the code enumerates
  all opted-in regions via EC2 DescribeRegions (Savings Plans always
  query once via us-east-1); Cost Explorer-based discovery is only a
  fallback when region listing fails. --include/--exclude-regions
  filter fetched recommendations and do not constrain queried regions.
- README.md + purchase-safety.md: document that --input-csv mode
  computes isDryRun = !ActualPurchase and ignores --dry-run, so
  --purchase alone performs real purchases there; split the decision
  formula per code path and add a CSV-mode warning example.
- filtering.md: instance-type include/exclude lists match by exact
  string equality (slices.Contains); remove the incorrect "partial
  prefixes" claim.
- purchase-safety.md: add the missing skipped_covered audit status
  (idempotency hit).
- README.md: clarify the binary is built as cudly while the cobra root
  command is named ri-helper; fix the auto-generated CSV filename
  format (ri-helper-<mode>-<timestamp>.csv).
The --idempotency-window flag is accepted and validated by the CLI but
its value is stored and never consumed by the purchase pipeline:
cfg.IdempotencyWindow is set but no code in cmd/ reads it to deduct
previously-purchased commitments from new recommendations. That
deduction path runs in the server-side scheduler, not the CLI loop.

Update purchase-safety.md and the flag reference table in README.md to
describe what the flag actually does (accepted/validated, no-op in CLI)
rather than claiming it subtracts prior purchases. Also correct the
audit-status list to note that skipped_covered is a schema-level value
used by the server path and is not emitted by CLI runs.
@cristim cristim force-pushed the docs/cli-reference branch from b912ab6 to 051bacf Compare June 19, 2026 15:11
@cristim

cristim commented Jun 19, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

- filtering.md: account-name resolution uses organizations:DescribeAccount
  (per-ID + cached), not organizations:ListAccounts. IAM-policy authors
  granting only ListAccounts on the prior wording would have hit a
  permission gap.
- filtering.md: scope the include/exclude conflict-check note to the three
  pairs actually validated at startup (regions, instance types, engines)
  and document that --include-accounts/--exclude-accounts and
  --include-sp-types/--exclude-sp-types fall through without that check,
  with exclude winning on overlap.
- README.md + purchase-safety.md: drop the "validated as a Go duration
  string" claim for --idempotency-window; the CLI does not parse the
  value at startup, only the server-side scheduler does.
@cristim

cristim commented Jun 26, 2026

Copy link
Copy Markdown
Member Author

Adversarial review - PR #1090

Reviewed against the stated risk surfaces (flag-doc accuracy, purchase-safety claims, cloud-setup samples, runnable examples, machine-specific paths, em-dashes, drift since open, base-branch). Net: three doc-accuracy fixes pushed in d769b9570, no blocking findings, no new follow-ups (the one underlying CLI bug already has an open issue).

What I checked

  • Random flag-name + default verification (5 picks) against cmd/main.go init() block on origin/main:
    • --services -s rds (main.go:119) - exact match
    • --target-coverage -u 0 (main.go:122) - exact match
    • --payment -p no-upfront (main.go:130) - exact match
    • --idempotency-window 24h (main.go:156) - exact match (validation claim corrected; see below)
    • --min-pool-size 0 (main.go:169) - exact match
  • configure-azure / configure-gcp flag set against cmd/configure_azure.go:75-82 and cmd/configure_gcp.go:76-81. Exact match for both, including the -i/-f shorthands.
  • Purchase-safety logic. Traced cmd/multi_service.go:85 (isDryRun := !cfg.ActualPurchase || cfg.DryRun) and cmd/multi_service.go:259 (isDryRun := !cfg.ActualPurchase in CSV mode). The four-cell table in purchase-safety.md and the --input-csv exception both match the code exactly. The "two-flag protection" framing for cloud-fetch mode is accurate.
  • --target-coverage API claim vs memory project_target_coverage_uses_coverage_api.md. Existing-coverage map is computed by providers/aws/recommendations/coverage.go:329 (costExplorerClient.GetReservationCoverage). The --coverage-lookback-days flag is correctly threaded through Config.CoverageLookbackDays -> fetchExistingCoverage -> GetRICoverageMap (per 0f6e284f9 / #794); the docs accurately scope it to "only affects --target-coverage" because fetchExistingCoverage early-returns when TargetCoverage <= 0.
  • --coverage ignored when --target-coverage is set. applySizing in cmd/helpers.go:463-468 routes to ApplyTargetCoverage when TargetCoverage > 0, else ApplyCoverage(cfg.Coverage). validators.go:88-91 info-logs when both are explicit. The doc's "Overrides --coverage when non-zero" phrasing matches.
  • Region discovery. cmd/multi_service_helpers.go:250-271 confirms: explicit --regions wins; SP queries default to us-east-1; otherwise getAllAWSRegions via EC2 DescribeRegions; on EC2 failure, fall back to discovery from CE recommendations. Doc matches.
  • --include-extended-support. Default false; flips the engine-version exclusion in processRecommendation -> adjustRecommendationForExcludedVersions. Doc matches.
  • --max-instances is a post-coverage cap. ApplyInstanceLimit in cmd/helpers.go:484-497 confirms it's applied after sizing. Doc framing ("final cut", "safety net") matches.
  • --include-instance-types format. validators.go:222-237 enforces a . separator. Doc claim "must contain a . separator; validated at startup" matches.
  • Examples runnable as-typed. Spot-checked five:
    • cudly --services rds --include-accounts prod-account,staging-account - dry-run by default, runnable
    • cudly --services elasticache --include-engines redis - runnable
    • cudly --input-csv recs.csv --purchase - .csv suffix satisfies validators.go:168; real purchase as documented
    • az role assignment create --assignee "<client-id>" --role "Reservations Administrator" --scope "/subscriptions/<subscription-id>" - placeholders are clearly templated, no machine-specific paths
    • cudly configure-azure --tenant-id ... --client-id ... --client-secret "$AZURE_SECRET" ... - --client-secret from env var idiom is the right pattern; the secure-stdin fallback (term.ReadPassword at configure_azure.go:237) matches the doc's "Read securely from stdin if omitted".
  • Memory feedback_no_yes_flag.md. The memory is a directive for the agent ("never pass --yes to cudly"), not a claim the flag doesn't exist. The flag IS defined (main.go:143); documenting it is correct. The doc rightly flags it with "Use with caution in automation".
  • Memory feedback_no_absolute_paths_in_code.md. Grepped for /Users/cristi|Dropbox_Maestral|/home/ in the new doc files: zero hits.
  • Em-dashes (U+2014) per global CLAUDE.md. Grepped the doc diff for U+2014 / U+2013: zero hits.
  • Memory feedback_pr_workflow.md. Base is main - correct (PR retargeted off the retired feat/multicloud-web-frontend).
  • Drift since docs(cli): add structured CLI reference for undocumented flags (filters, purchase-safety, cloud-setup) #1090 opened. The only cmd/main.go change post-opening was #794 (configurable --coverage-lookback-days), which the PR author already incorporated in faa596a51. The doc covers all 35 current root flags + the 16 configure-azure/configure-gcp flags - no missing flag, no removed flag still documented.
  • Migration-074->077 rebase risk. PR touches only .gitignore, README.md, and four files under docs/cli/. No migration files touched, so the per-project memory project_migration_number_collisions.md doesn't apply.

Fixes pushed in d769b9570 (in-scope doc accuracy)

  1. filtering.md - account-resolution API name. Doc said organizations:ListAccounts; the actual call is organizations:DescribeAccount (cmd/helpers.go:90, called per account ID and cached). The wrong name would have led IAM-policy authors to grant only ListAccounts and discover the gap only at runtime.
  2. filtering.md - scope of the include/exclude conflict check. The doc's general "rejected at startup" claim only holds for region, instance-type, and engine pairs (validators.go:178-191). Account and SP-type include/exclude pairs are NOT validated; when a value appears in both, exclude wins silently (cmd/multi_service_filters.go:172-189 for accounts; providers/aws/recommendations/parser_sp.go:372-382 for SP types). Added an explicit caveat.
  3. README.md + purchase-safety.md - --idempotency-window "validated" claim. The CLI binds it as a raw string (main.go:73, 156) and validators.go does not call time.ParseDuration on it. Only the server-side path parses it (pkg/config/load.go:130, 237, 357). Reworded both doc spots to drop "validated" while preserving the existing (accurate) "currently has no effect on CLI runs" caveat.

Follow-up (not filed - already tracked)

The underlying CLI bug behind fix (3) - --idempotency-window accepted but a no-op in the CLI purchase loop - is already tracked at #1262 (fix(cli): --idempotency-window silently ignored in CLI...). The doc PR's caveat (now corrected) is the right interim disclosure; no new issue needed.

CI state

Lint Code, Integration Tests, and Security Scanning are red, but on a docs/gitignore/README-only diff that's pre-existing repo-wide failure on main, not regression from this PR (same pattern as #1244's review notes). From a content-correctness standpoint the PR is mergeable once CR is clean.

Verdict

No blocking issues. The three fixes above are pushed; re-pinging CodeRabbit so the new commit goes through review. Once CR is clean, recommend merging.

cc @coderabbitai please review the docs/cli/ updates in d769b9570.

@cristim

cristim commented Jun 26, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

@cristim Thanks for the thorough adversarial pass and for pushing the three doc-accuracy fixes in d769b9570. I’ll review the latest docs/cli/ updates now.

(•ㅅ•)ゞ


✏️ Learnings added
Learnt from: cristim
URL: https://github.com/LeanerCloud/CUDly/pull/1090

Timestamp: 2026-06-26T17:54:39.714Z
Learning: In the LeanerCloud/CUDly repository, AWS account alias resolution used by the CLI docs should reference `organizations:DescribeAccount` in `cmd/helpers.go` (called per account ID and cached), not `organizations:ListAccounts`.

Learnt from: cristim
URL: https://github.com/LeanerCloud/CUDly/pull/1090

Timestamp: 2026-06-26T17:54:39.714Z
Learning: In the LeanerCloud/CUDly repository, include/exclude conflict validation at startup is limited to region, instance-type, and engine pairs in `validators.go`. Account overlaps in `cmd/multi_service_filters.go` and Savings Plan type overlaps in `providers/aws/recommendations/parser_sp.go` are not rejected; when a value is present in both include and exclude sets, exclude wins silently.

Learnt from: cristim
URL: https://github.com/LeanerCloud/CUDly/pull/1090

Timestamp: 2026-06-26T17:54:39.714Z
Learning: In the LeanerCloud/CUDly repository, the CLI flag `--idempotency-window` is bound as a raw string in `main.go` and is not duration-validated by `validators.go`; duration parsing exists only in the server-side config loader `pkg/config/load.go`. As of PR `#1090` review, the flag is effectively a no-op for CLI purchase runs, and the underlying bug is already tracked in GitHub issue `#1262`.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

Labels

effort/m Days impact/many Affects most users priority/p2 Backlog-worthy severity/low Minor harm triaged Item has been triaged type/docs Documentation urgency/this-quarter Within the quarter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs(cli): add structured CLI reference for undocumented flags (filters, purchase-safety, cloud-setup)

1 participant