autojanet/skills/terrashark/references/coding-standards.md
Zoë cfec11bb46
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
fix: convert skill submodules to plain directories
stop-slop, taste-skill, terrashark had embedded .git dirs causing
Woodpecker clone to fail on submodule update.
2026-05-30 15:44:44 -07:00

3.5 KiB

Coding Standards

Use this guide for implementation-level consistency in Terraform/OpenTofu code generation.

Naming and metadata

  • use names that reflect business purpose (payments_api, audit_kms), not temporary implementation details
  • reserve this for real singleton resources only
  • centralize tags/labels in locals and apply consistently
  • normalize provider-constrained identifiers before use (for example, RDS identifiers and snapshot identifiers)

Identifier normalization pattern

Some resources reject characters that are valid in domains or service names. Example: . in RDS identifiers.

Use a normalization local and reuse it consistently:

locals {
  raw_name        = "${var.domain}-prod"
  normalized_name = regexreplace(lower(local.raw_name), "[^a-z0-9-]", "-")
}

Then use local.normalized_name for fields like identifier and final_snapshot_identifier.

Resource block ordering

Preferred order inside resource blocks:

  1. identity/core arguments
  2. behavior/config arguments
  3. nested blocks
  4. tags/labels
  5. lifecycle/meta-arguments

This keeps diffs predictable and reviewable.

Variable contract style

Variable attribute order:

  1. description
  2. type
  3. default (if used)
  4. nullable
  5. sensitive
  6. validation

Prefer explicit objects with optional() over untyped maps for long-lived module contracts.

Iteration and identity

  • count: optional singleton toggles (0 or 1)
  • for_each: any collection with stable logical identities
  • never use list index as long-lived identity key

Set-type handling

Use these rules to avoid ordering bugs and test failures:

  • never index sets directly; convert with sort(tolist(...)) when order matters
  • use for_each with toset(...) only when identity is the value itself
  • for stable diff output, transform sets to sorted lists in outputs
  • in tests, prefer contains() or set equality over positional assertions

Outputs

  • expose only stable interfaces needed by consumers
  • mark secret-bearing outputs as sensitive = true
  • avoid dumping entire provider objects

Version and lock discipline

  • set runtime floor in required_version
  • bound provider and module versions
  • commit lockfile changes intentionally
  • keep upgrade PRs separate from functional changes where possible

Feature guard table (ordered by common LLM mistakes)

Use this when deciding what to emit for a given runtime floor.

Feature Min version LLM error pattern
moved blocks 1.1+ omitted during refactor, causing destroy/create
for_each over count for stable identities 0.12+ model defaults to count for every collection
write_only arguments 1.11+ model uses sensitive and assumes state is safe
optional() defaults 1.3+ model emits wrapper variables and loose maps
cross-variable validation 1.9+ model pushes checks into postconditions only
declarative import blocks 1.5+ model recommends ad-hoc CLI import only
check blocks 1.5+ model ignores runtime assertions entirely
removed blocks 1.7+ model deletes resources with no lifecycle transition
provider-defined functions 1.8+ model overuses data sources for transformations

If target runtime is below a feature floor, emit fallback guidance explicitly.

Review checklist

  • typed inputs and validations present
  • iteration model chosen for address stability
  • no plaintext secret defaults
  • version constraints and lockfile strategy are explicit
  • migration-sensitive changes include moved/import plan