@intentius/chant-lexicon-terraform 0.58.0 → 0.59.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/README.md +9 -0
  2. package/dist/composites/terraform-adopt-op.d.ts +7 -2
  3. package/dist/composites/terraform-adopt-op.d.ts.map +1 -1
  4. package/dist/composites/terraform-apply-op.d.ts +8 -2
  5. package/dist/composites/terraform-apply-op.d.ts.map +1 -1
  6. package/dist/composites/terraform-watch-op.d.ts +30 -7
  7. package/dist/composites/terraform-watch-op.d.ts.map +1 -1
  8. package/dist/hcl/parse.d.ts +14 -0
  9. package/dist/hcl/parse.d.ts.map +1 -1
  10. package/dist/integrity.json +7 -5
  11. package/dist/lint/audit-catalog.d.ts +2 -2
  12. package/dist/lint/audit-catalog.d.ts.map +1 -1
  13. package/dist/lint/audit-lineage.d.ts +39 -12
  14. package/dist/lint/audit-lineage.d.ts.map +1 -1
  15. package/dist/lint/post-synth/index.d.ts.map +1 -1
  16. package/dist/lint/post-synth/tf001.d.ts +40 -6
  17. package/dist/lint/post-synth/tf001.d.ts.map +1 -1
  18. package/dist/lint/post-synth/tf015.d.ts +11 -2
  19. package/dist/lint/post-synth/tf015.d.ts.map +1 -1
  20. package/dist/lint/post-synth/tf026.d.ts +7 -0
  21. package/dist/lint/post-synth/tf026.d.ts.map +1 -1
  22. package/dist/lint/post-synth/tf027.d.ts +30 -0
  23. package/dist/lint/post-synth/tf027.d.ts.map +1 -0
  24. package/dist/lint/post-synth/tf028.d.ts +33 -0
  25. package/dist/lint/post-synth/tf028.d.ts.map +1 -0
  26. package/dist/lsp/option-keys.d.ts.map +1 -1
  27. package/dist/manifest.json +1 -1
  28. package/dist/okf/index.md +2 -0
  29. package/dist/okf/rules/TF027.md +11 -0
  30. package/dist/okf/rules/TF028.md +11 -0
  31. package/dist/op/activities/terraform.d.ts +32 -11
  32. package/dist/op/activities/terraform.d.ts.map +1 -1
  33. package/dist/op/builders.d.ts +7 -5
  34. package/dist/op/builders.d.ts.map +1 -1
  35. package/dist/op/resolve-root-mode.d.ts +29 -15
  36. package/dist/op/resolve-root-mode.d.ts.map +1 -1
  37. package/dist/plugin.d.ts.map +1 -1
  38. package/dist/rules/tf001.ts +70 -14
  39. package/dist/rules/tf015.ts +11 -2
  40. package/dist/rules/tf026.ts +6 -2
  41. package/dist/rules/tf027.ts +74 -0
  42. package/dist/rules/tf028.ts +96 -0
  43. package/dist/validate.d.ts.map +1 -1
  44. package/package.json +2 -2
  45. package/src/__fixtures__/ACCEPTANCE.md +181 -0
  46. package/src/__fixtures__/remote-backend/main.tf +34 -0
  47. package/src/__fixtures__/with-backend/main.tf +7 -0
  48. package/src/codegen/lint-rules-page.test.ts +18 -1
  49. package/src/composites/terraform-adopt-op.acceptance.test.ts +46 -19
  50. package/src/composites/terraform-adopt-op.test.ts +9 -4
  51. package/src/composites/terraform-adopt-op.ts +8 -3
  52. package/src/composites/terraform-apply-op.acceptance.test.ts +14 -9
  53. package/src/composites/terraform-apply-op.test.ts +13 -5
  54. package/src/composites/terraform-apply-op.ts +23 -7
  55. package/src/composites/terraform-watch-op.test.ts +85 -4
  56. package/src/composites/terraform-watch-op.ts +59 -8
  57. package/src/hcl/parse.ts +20 -0
  58. package/src/lint/audit-catalog.ts +26 -2
  59. package/src/lint/audit-lineage.ts +79 -14
  60. package/src/lint/audit.test.ts +171 -3
  61. package/src/lint/post-synth/fixtures/TF001/negative-cloud.tf +28 -0
  62. package/src/lint/post-synth/fixtures/TF001/negative.tf +4 -2
  63. package/src/lint/post-synth/fixtures/TF001/positive-local.tf +31 -0
  64. package/src/lint/post-synth/fixtures/TF014/negative/main.tf +2 -2
  65. package/src/lint/post-synth/fixtures/TF014/positive/main.tf +2 -2
  66. package/src/lint/post-synth/fixtures/TF020/scoped/main.tf +2 -2
  67. package/src/lint/post-synth/fixtures/TF027/live-default/main.tf +9 -0
  68. package/src/lint/post-synth/fixtures/TF027/live-untagged-delete/main.tf +13 -0
  69. package/src/lint/post-synth/fixtures/TF027/live-untagged-delete-scoped/main.tf +17 -0
  70. package/src/lint/post-synth/fixtures/TF027/live-untagged-report/main.tf +13 -0
  71. package/src/lint/post-synth/fixtures/TF028/live/main.tf +9 -0
  72. package/src/lint/post-synth/fixtures/TF028/stock/main.tf +10 -0
  73. package/src/lint/post-synth/index.ts +4 -0
  74. package/src/lint/post-synth/live-refusals-config-format.test.ts +143 -0
  75. package/src/lint/post-synth/module-rules.test.ts +1 -1
  76. package/src/lint/post-synth/post-synth.test.ts +64 -6
  77. package/src/lint/post-synth/tf001.ts +70 -14
  78. package/src/lint/post-synth/tf015.ts +11 -2
  79. package/src/lint/post-synth/tf026.ts +6 -2
  80. package/src/lint/post-synth/tf027.test.ts +62 -0
  81. package/src/lint/post-synth/tf027.ts +74 -0
  82. package/src/lint/post-synth/tf028.test.ts +92 -0
  83. package/src/lint/post-synth/tf028.ts +96 -0
  84. package/src/lsp/option-keys.ts +3 -2
  85. package/src/op/activities/choudoufu.acceptance.test.ts +7 -23
  86. package/src/op/activities/choudoufu.test.ts +49 -17
  87. package/src/op/activities/terraform.ts +67 -29
  88. package/src/op/builders.ts +7 -5
  89. package/src/op/resolve-root-mode.ts +29 -15
  90. package/src/plugin.test.ts +38 -0
  91. package/src/plugin.ts +122 -31
  92. package/src/validate.ts +10 -1
@@ -52,10 +52,15 @@ export declare const DEFAULT_LIVE_PLAN_DOCUMENT_FILE = "chant.live-plan.json";
52
52
  * ([choudoufu #878](https://github.com/INTENTIUS/choudoufu/issues/878), PR
53
53
  * 889): under a live block `plan -out=FILE` is accepted and `apply FILE`
54
54
  * re-plans the live system and refuses on a mismatch with exit status 3.
55
- * {@link terraformApply} depends on that refusal existing, so the floor is
56
- * the release that shipped it rather than the one before.
55
+ * v0.14.0 brought the `-json` document on a configuration that names its own
56
+ * estate ([choudoufu #894](https://github.com/INTENTIUS/choudoufu/issues/894),
57
+ * PR 915), which is the shape every chant live root has: before it,
58
+ * {@link choudoufuLivePlan} could not produce the document for a real root at
59
+ * all. {@link terraformApply} depends on the exit-3 refusal and
60
+ * `describeResources()` and both document-reading Ops depend on the document,
61
+ * so the floor is the release that shipped the later of the two.
57
62
  */
58
- export declare const MIN_CHOUDOUFU_VERSION = "0.13.0";
63
+ export declare const MIN_CHOUDOUFU_VERSION = "0.14.0";
59
64
  /**
60
65
  * choudoufu's own refusal summary for `-out` on the `live-plan -estate`
61
66
  * surface (`internal/command/live_mode.go`). That is the one surface where a
@@ -396,10 +401,18 @@ export declare function terraformApplyCommand(opts: {
396
401
  planFile: string;
397
402
  }): string;
398
403
  /**
399
- * `live-plan -detailed-exitcode -json -estate=<estate>`. `-json` is what
404
+ * `live-plan -detailed-exitcode [-json] [-estate=<estate>]`. `-json` is what
400
405
  * prints GitHub issue #788's document instead of the plan; the human render
401
406
  * needs a second invocation without it (see {@link choudoufuLivePlan}).
402
407
  *
408
+ * `estate` is omitted exactly when the configuration names its own estate.
409
+ * choudoufu refuses `-estate` beside a `live` block or an `estate.chdf.hcl`
410
+ * sidecar ("Estate named by both the live block and -estate"), and since
411
+ * v0.14.0 it does not need one: the run reads the declared name itself and
412
+ * prints the same document ([choudoufu #894](https://github.com/INTENTIUS/choudoufu/issues/894),
413
+ * PR 915). The flag is still how a root that declares nothing names an
414
+ * estate for the run.
415
+ *
403
416
  * `adoptionOnly` makes that second invocation print the adoption ledger and
404
417
  * nothing else (GitHub issue #587). It is refused here alongside `json`
405
418
  * because choudoufu refuses the pair itself, and a builder that emitted a
@@ -408,7 +421,7 @@ export declare function terraformApplyCommand(opts: {
408
421
  */
409
422
  export declare function choudoufuLivePlanCommand(opts: {
410
423
  binary: string;
411
- estate: string;
424
+ estate?: string;
412
425
  json: boolean;
413
426
  adoptionOnly?: boolean;
414
427
  noColor?: boolean;
@@ -464,7 +477,7 @@ export declare function parseChoudoufuPlanSummary(text: string): PlanChangeCount
464
477
  export declare function isOlderVersion(version: string, min: string): boolean;
465
478
  /**
466
479
  * Extract the release version from `choudoufu version`'s human-readable
467
- * output: `"choudoufu v0.12.0 (based on OpenTofu v1.13.0)\non darwin_arm64"`.
480
+ * output: `"choudoufu v0.13.0 (based on OpenTofu v1.13.0)\non darwin_arm64"`.
468
481
  * `choudoufu version -json`'s `terraform_version` field is the wrong number
469
482
  * here: it names the upstream OpenTofu base this build forked from, not the
470
483
  * choudoufu release itself (`internal/command/views/version.go`), so this
@@ -552,11 +565,19 @@ export declare function terraformShow(args: TerraformShowArgs, signal?: AbortSig
552
565
  */
553
566
  /**
554
567
  * The JSON document within a `live-plan -json` stdout: everything from the
555
- * first line that is a bare `{` to the end. Stock keeps stdout to the
556
- * document; choudoufu's `-estate` path precedes it with refresh progress
557
- * lines (choudoufu #894). Returns the input unchanged when no such line
558
- * exists, so a clean stdout parses as before and a broken one fails in
559
- * `JSON.parse` with the real text in the error.
568
+ * first line that is a bare `{` to the end. Returns the input unchanged when
569
+ * no such line exists.
570
+ *
571
+ * Defensive, and kept deliberately. choudoufu v0.14.0 keeps `-json` stdout to
572
+ * the document on every form of live root, so on a supported binary this
573
+ * returns its input unchanged and the slice never fires: it was written for
574
+ * the `-estate` path's refresh progress lines
575
+ * ([choudoufu #894](https://github.com/INTENTIUS/choudoufu/issues/894), fixed
576
+ * in PR 915, which routes every human-prose renderer of a `-json` run through
577
+ * `views.View.StdoutOnStderr()`). What it buys is that a future writer put
578
+ * back on stdout ahead of the document costs a stale slice rather than a
579
+ * `JSON.parse` failure, and a stdout carrying no document at all still fails
580
+ * in `JSON.parse` with the real text in the error.
560
581
  */
561
582
  export declare function liveDocumentFrom(stdout: string): string;
562
583
  export declare function choudoufuLivePlan(args: ChoudoufuLivePlanArgs & {
@@ -1 +1 @@
1
- {"version":3,"file":"terraform.d.ts","sourceRoot":"","sources":["../../../src/op/activities/terraform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAOH,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,aAAa,CAAC;AAWrB,wEAAwE;AACxE,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAEhD,wEAAwE;AACxE,eAAO,MAAM,wBAAwB,cAAc,CAAC;AAEpD,gHAAgH;AAChH,eAAO,MAAM,+BAA+B,yBAAyB,CAAC;AAEtE;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,WAAW,CAAC;AAE9C;;;;;;;;GAQG;AACH,eAAO,MAAM,+BAA+B,mEACsB,CAAC;AAEnE,mHAAmH;AACnH,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAE9C,wGAAwG;AACxG,eAAO,MAAM,mCAAmC,wDAAwD,CAAC;AAEzG,0GAA0G;AAC1G,eAAO,MAAM,8BAA8B,oDAAoD,CAAC;AAIhG,8EAA8E;AAC9E,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D,8EAA8E;IAC9E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D,8FAA8F;IAC9F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAsB,SAAQ,iBAAiB;IAC9D;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;IAC5D,mHAAmH;IACnH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8FAA8F;IAC9F,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,MAAM,sBAAsB,GAAG,iBAAiB,CAAC;AAEvD,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D;;;;;OAKG;IACH,SAAS,EAAE,iBAAiB,EAAE,CAAC;IAC/B;;;;OAIG;IACH,SAAS,CAAC,EAAE,iBAAiB,EAAE,CAAC;CACjC;AAED,2CAA2C;AAC3C,MAAM,WAAW,mBAAmB;IAClC,uEAAuE;IACvE,GAAG,EAAE,MAAM,CAAC;IACZ,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,2DAA2D;AAC3D,MAAM,WAAW,gBAAgB;IAC/B,qGAAqG;IACrG,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,+FAA+F;AAC/F,MAAM,WAAW,mBAAoB,SAAQ,gBAAgB;IAC3D,mGAAmG;IACnG,OAAO,EAAE,OAAO,CAAC;IACjB,+FAA+F;IAC/F,QAAQ,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,iDAAiD;IACjD,IAAI,EAAE,OAAO,CAAC;IACd,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,wBAAwB,GAAG,mBAAmB,GAAG,cAAc,CAAC;AAE5E,4CAA4C;AAC5C,MAAM,WAAW,oBAAoB;IACnC,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,qFAAqF;IACrF,OAAO,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,OAAO,CAAC,EAAE,wBAAwB,CAAC;IACnC,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qEAAqE;AACrE,MAAM,WAAW,qBAAqB;IACpC,0FAA0F;IAC1F,OAAO,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,uBAAwB,SAAQ,qBAAqB,EAAE,gBAAgB;IACtF,wFAAwF;IACxF,KAAK,EAAE,OAAO,CAAC;IACf,2FAA2F;IAC3F,IAAI,EAAE,OAAO,CAAC;IACd;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;OAMG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,iHAAiH;IACjH,SAAS,EAAE,iBAAiB,EAAE,CAAC;IAC/B,kGAAkG;IAClG,SAAS,EAAE,iBAAiB,EAAE,CAAC;IAC/B,0FAA0F;IAC1F,SAAS,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,yHAAyH;IACzH,YAAY,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,6CAA6C;AAC7C,MAAM,WAAW,qBAAqB;IACpC,sFAAsF;IACtF,IAAI,EAAE,OAAO,CAAC;IACd,yHAAyH;IACzH,GAAG,EAAE,MAAM,CAAC;IACZ,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,yFAAyF;AACzF,MAAM,WAAW,eAAe;IAC9B,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAC;IACjB,uFAAuF;IACvF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,4CAA4C;AAC5C,MAAM,WAAW,oBAAoB;IACnC;;;;;;;OAOG;IACH,SAAS,EAAE,WAAW,CAAC;IACvB,mFAAmF;IACnF,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,oEAAoE;IACpE,YAAY,EAAE,MAAM,CAAC;IACrB,wFAAwF;IACxF,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,mFAAmF;IACnF,SAAS,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;CACb;AAED,gDAAgD;AAChD,MAAM,WAAW,wBAAwB;IACvC,8FAA8F;IAC9F,OAAO,EAAE,OAAO,CAAC;IACjB,4FAA4F;IAC5F,IAAI,EAAE,OAAO,CAAC;IACd,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;CACb;AAED,2CAA2C;AAC3C,MAAM,WAAW,mBAAoB,SAAQ,gBAAgB;IAC3D,kEAAkE;IAClE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,kCAAkC;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,CAEhE;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAK1G;AAED,wFAAwF;AACxF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GAAG,MAAM,CAQT;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,MAAM,CAMT;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAExF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,MAAM,CAcT;AAED,sDAAsD;AACtD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAI7G;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAE1E;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,OAAO,GAAG,qBAAqB,CAS7E;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAIvG;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,gBAAgB,CAYpE;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAMxE;AAgBD,iGAAiG;AACjG,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAOpE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG/E;AA8BD,4FAA4F;AAC5F,wBAAgB,oCAAoC,IAAI,IAAI,CAE3D;AAwED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,iBAAiB,EACvB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,mBAAmB,CAAC,CAa9B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,iBAAiB,EACvB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,mBAAmB,CAAC,CAoC9B;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,wBAAwB,GAAG,SAAS,CAI5F;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,kBAAkB,EACxB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,oBAAoB,CAAC,CAoC/B;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,iBAAiB,EACvB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,mBAAmB,CAAC,CA2B9B;AAmBD;;;;;;;;;;;;;;GAcG;AACH;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAIvD;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,qBAAqB,GAAG;IAAE,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,EACvD,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,uBAAuB,CAAC,CA4ElC;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,mBAAmB,EACzB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,qBAAqB,CAAC,CAWhC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,kBAAkB,EACxB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,oBAAoB,CAAC,CA8C/B;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,sBAAsB,EAC5B,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,wBAAwB,CAAC,CAuBnC"}
1
+ {"version":3,"file":"terraform.d.ts","sourceRoot":"","sources":["../../../src/op/activities/terraform.ts"],"names":[],"mappings":"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"}
@@ -48,11 +48,13 @@ export declare const terraformPlan: (root: string, opts?: WithStepRefs<Omit<Terr
48
48
  */
49
49
  export declare const terraformApply: (root: string, opts?: WithStepRefs<Omit<TerraformApplyArgs, "root">> & StepOpts) => NamedActivityStep;
50
50
  /**
51
- * `choudoufu live-plan -detailed-exitcode -json -estate=<estate>` in the
52
- * named root, plus the human render. The fully typed twin of the
53
- * `choudoufuLivePlan` activity (#2103). `opts` is {@link ChoudoufuLivePlanArgs}
54
- * itself, minus the positional `root`; `estate` is optional, auto-detected
55
- * from the root's `live` block or `estate.chdf.hcl` sidecar when omitted.
51
+ * `choudoufu live-plan -detailed-exitcode -json` in the named root, plus the
52
+ * human render. The fully typed twin of the `choudoufuLivePlan` activity
53
+ * (#2103). `opts` is {@link ChoudoufuLivePlanArgs} itself, minus the
54
+ * positional `root`; `estate` is optional, auto-detected from the root's
55
+ * `live` block or `estate.chdf.hcl` sidecar when omitted, and a root that
56
+ * declares one is run with no `-estate` at all, which is the only form
57
+ * choudoufu admits there (choudoufu #894, fixed in v0.14.0).
56
58
  * Defaults to the `longInfra` profile: like `terraformPlan`, this reads the
57
59
  * live system in full (the estate-wide sweep).
58
60
  *
@@ -1 +1 @@
1
- {"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../../src/op/builders.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,kBAAkB,EACnB,MAAM,wBAAwB,CAAC;AAEhC,kFAAkF;AAClF,KAAK,QAAQ,GAAG;IAAE,OAAO,CAAC,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GACxB,MAAM,MAAM,EACZ,OAAO,YAAY,CAAC,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,GAAG,QAAQ,KAC9D,iBAGF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,GACxB,MAAM,MAAM,EACZ,OAAO,YAAY,CAAC,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,GAAG,QAAQ,KAC9D,iBAGF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GACzB,MAAM,MAAM,EACZ,OAAO,YAAY,CAAC,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,GAAG,QAAQ,KAC/D,iBAGF,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,iBAAiB,GAC5B,MAAM,MAAM,EACZ,OAAO,YAAY,CAAC,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC,GAAG,QAAQ,KAClE,iBAOF,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAC1B,MAAM,MAAM,EACZ,OAAO,YAAY,CAAC,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC,GAAG,QAAQ,KAChE,iBAOF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC7B,MAAM,MAAM,EACZ,OAAO,YAAY,CAAC,IAAI,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC,GAAG,QAAQ,KACnE,iBAOF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GACzB,MAAM,MAAM,EACZ,MAAM,YAAY,CAAC,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,GAAG,QAAQ,KAC9D,iBAOF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GACxB,MAAM,MAAM,EACZ,OAAO,YAAY,CAAC,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,GAAG,QAAQ,KAC9D,iBAOF,CAAC"}
1
+ {"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../../src/op/builders.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,kBAAkB,EACnB,MAAM,wBAAwB,CAAC;AAEhC,kFAAkF;AAClF,KAAK,QAAQ,GAAG;IAAE,OAAO,CAAC,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GACxB,MAAM,MAAM,EACZ,OAAO,YAAY,CAAC,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,GAAG,QAAQ,KAC9D,iBAGF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,GACxB,MAAM,MAAM,EACZ,OAAO,YAAY,CAAC,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,GAAG,QAAQ,KAC9D,iBAGF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GACzB,MAAM,MAAM,EACZ,OAAO,YAAY,CAAC,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,GAAG,QAAQ,KAC/D,iBAGF,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,GAC5B,MAAM,MAAM,EACZ,OAAO,YAAY,CAAC,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC,GAAG,QAAQ,KAClE,iBAOF,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAC1B,MAAM,MAAM,EACZ,OAAO,YAAY,CAAC,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC,GAAG,QAAQ,KAChE,iBAOF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC7B,MAAM,MAAM,EACZ,OAAO,YAAY,CAAC,IAAI,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC,GAAG,QAAQ,KACnE,iBAOF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GACzB,MAAM,MAAM,EACZ,MAAM,YAAY,CAAC,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,GAAG,QAAQ,KAC9D,iBAOF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GACxB,MAAM,MAAM,EACZ,OAAO,YAAY,CAAC,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,GAAG,QAAQ,KAC9D,iBAOF,CAAC"}
@@ -1,31 +1,45 @@
1
1
  /**
2
2
  * Best-effort, synchronous read of whether a named `terraform.roots` entry is
3
3
  * live: `terraform.binary` is `"choudoufu"` and the root's directory declares
4
- * an estate — a `live { }` block or an `estate.chdf.hcl` sidecar (#2103).
4
+ * an estate, either a `live { }` block or an `estate.chdf.hcl` sidecar (#2103).
5
5
  *
6
- * Two callers decide something at build time, before any activity runs, and
7
- * neither can afford the async work `../op/activities/terraform.ts`'s own
6
+ * Three callers decide something at build time, before any activity runs, and
7
+ * none can afford the async work `../op/activities/terraform.ts`'s own
8
8
  * `resolveRoot` does (`loadChantConfigUpward`, a full `chant.config.ts`/`.json`
9
9
  * walk):
10
10
  *
11
- * - `TerraformApplyOp` (`../composites/terraform-apply-op.ts`) decides which
12
- * phase shape to build — a stock plan-file pairing or a live re-plan-at-
13
- * apply shape — before any step is emitted.
11
+ * - `TerraformApplyOp` (`../composites/terraform-apply-op.ts`) reads the
12
+ * mode to word the Gate phase's approval description, and to refuse a
13
+ * root whose `policy` block sets `undeclared_untagged = "delete"`. The
14
+ * mode no longer picks a phase shape: #2157 made the live and stock Apply
15
+ * steps one step, so both roots build the same phases.
16
+ * - `TerraformWatchOp` (`../composites/terraform-watch-op.ts`) cross-checks
17
+ * its hand-set `live` flag against the root's real mode and refuses a
18
+ * mismatch (#2216).
14
19
  * - TF101 (`../lint/rules/plan-before-apply.ts`) decides whether a
15
20
  * `terraformApply` call it is statically inspecting is exempt from the
16
21
  * plan-file pairing it otherwise enforces.
17
22
  *
18
- * Both run in the build process (`chant build`/`chant lint`) rather than in
19
- * an activity at run time, so a synchronous read is available, but only the
20
- * cheap half of it: `findProjectConfig` (`@intentius/chant/project-root`) is a plain, already-
21
- * synchronous upward filesystem walk, but a `chant.config.ts` is project-
22
- * authored code, and evaluating it synchronously outside chant's own
23
- * config-sandbox machinery is more than either caller's best-effort question
23
+ * All three run in the build process (`chant build`/`chant lint`) rather than
24
+ * in an activity at run time, so a synchronous read is available, but only the
25
+ * cheap half of it: `findProjectConfig` (`@intentius/chant/project-root`) is a
26
+ * plain, already-synchronous upward filesystem walk, but a `chant.config.ts`
27
+ * is project-authored code, and evaluating it synchronously outside chant's
28
+ * own config-sandbox machinery is more than any caller's best-effort question
24
29
  * is worth. So this reads `chant.config.json` only; a project on a `.ts`
25
30
  * config, or with no config discoverable at all, or naming no matching root,
26
- * resolves to `undefined` — "unknown" reads as "stock" to both callers, which
27
- * is the conservative direction: TF101 keeps firing, and the composite keeps
28
- * building the plan-file-carrying shape.
31
+ * resolves to `undefined`, and "unknown" reads as "stock" to every caller.
32
+ *
33
+ * That default is conservative for the two callers that only ever add a
34
+ * requirement by knowing more: TF101 keeps enforcing the plan-file pairing,
35
+ * and the watch Op keeps accepting the flag it was given. It is the
36
+ * permissive direction for the apply Op's policy refusal and for the watch
37
+ * Op's mismatch, which is why neither refusal is left to this function alone:
38
+ * TF027 and TF028 (`../lint/post-synth/`) ask the same questions of the
39
+ * parsed HCL the build already stamped `mode` onto, whatever the config file
40
+ * is written in, and those checks are the guarantee (#2216). Every project in
41
+ * this repository is on a `chant.config.ts`, so a refusal that resolves the
42
+ * mode through this function alone never fires for anyone.
29
43
  */
30
44
  export interface ResolvedRootMode {
31
45
  /** `"live"` when `terraform.binary` is `"choudoufu"` and the root declares an estate; `"state"` otherwise. */
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-root-mode.d.ts","sourceRoot":"","sources":["../../src/op/resolve-root-mode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAQH,MAAM,WAAW,gBAAgB;IAC/B,8GAA8G;IAC9G,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,+DAA+D;IAC/D,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAoBhG"}
1
+ {"version":3,"file":"resolve-root-mode.d.ts","sourceRoot":"","sources":["../../src/op/resolve-root-mode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAQH,MAAM,WAAW,gBAAgB;IAC/B,8GAA8G;IAC9G,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,+DAA+D;IAC/D,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAoBhG"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAyB9D;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,EAAE,aA6L7B,CAAC"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,aAAa,EAAE,MAAM,0BAA0B,CAAC;AA+DlF;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,EAAE,aAkP7B,CAAC"}
@@ -1,12 +1,25 @@
1
1
  /**
2
2
  * TF001: a root module keeps its state on local disk.
3
3
  *
4
- * A `terraform` block with no `backend "<type>"` and no `cloud {}` falls back
5
- * to the local backend, which puts `terraform.tfstate` in the working
6
- * directory. That file holds every attribute of every managed resource,
7
- * secrets included, and it is not shared, not locked, and not versioned. The
8
- * first apply from a second machine or a CI runner starts from an empty state
9
- * and proposes to create the estate again.
4
+ * Two ways a root gets there, and this reports both (#2218). A `terraform`
5
+ * block with no `backend "<type>"` and no `cloud {}` falls back to the local
6
+ * backend implicitly. A `backend "local"` block asks for the same backend by
7
+ * name. Either way `terraform.tfstate` lands in the working directory, and
8
+ * that file holds every attribute of every managed resource, secrets
9
+ * included, and it is not shared, not locked, and not versioned. The first
10
+ * apply from a second machine or a CI runner starts from an empty state and
11
+ * proposes to create the estate again.
12
+ *
13
+ * So the rule reads the backend block's TYPE LABEL rather than its presence:
14
+ * the id means "no remote backend", which is what its name, its message and
15
+ * its page have always argued. `cloud {}` counts as remote (it is Terraform
16
+ * Cloud / HCP state, held off the machine and locked). Every other backend
17
+ * type is taken as remote without a list to maintain, since `local` is the
18
+ * only backend Terraform ships that writes to the working directory.
19
+ *
20
+ * A root that keeps local state on purpose says so with a
21
+ * `# chant-ignore-block: TF001` on the line above its `terraform` block
22
+ * (chant #2111), which is what the three shipped examples do.
10
23
  *
11
24
  * One diagnostic per root, fired from the root's `terraform` block. A root
12
25
  * with no `terraform` block at all is not flagged: it declares no version
@@ -46,6 +59,39 @@ export function hasBlock(body: BlockBody, key: string): boolean {
46
59
  return typeof a.value === "object" && a.value !== null ? Object.keys(a.value).length > 0 : true;
47
60
  }
48
61
 
62
+ /** The one backend type that writes state to the working directory. */
63
+ export const LOCAL_BACKEND = "local";
64
+
65
+ /**
66
+ * The type labels of the `backend` blocks in a `terraform` block body.
67
+ *
68
+ * `backend` takes one label, so hcl2json nests it one level deeper than an
69
+ * unlabelled block: `backend "s3" { bucket = "b" }` is
70
+ * `{ backend: { s3: [{ bucket: "b" }] } }`, where `cloud { ... }` is just
71
+ * `{ cloud: [{ ... }] }`. The keys of that inner object are the labels, which
72
+ * is the only place the type survives the parse. A malformed body that puts
73
+ * an array or a scalar under `backend` yields no labels, and the caller then
74
+ * treats the root as having no remote backend, the same verdict a missing
75
+ * block gets.
76
+ */
77
+ export function backendTypes(body: BlockBody): string[] {
78
+ const a = attr(body, "backend");
79
+ if (a.kind === "absent") return [];
80
+ const value = a.value;
81
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return [];
82
+ return Object.keys(value);
83
+ }
84
+
85
+ /**
86
+ * Whether the body configures state somewhere other than the working
87
+ * directory: any `backend` block whose type is not `local`, or a `cloud`
88
+ * block.
89
+ */
90
+ export function hasRemoteBackend(body: BlockBody): boolean {
91
+ if (hasBlock(body, "cloud")) return true;
92
+ return backendTypes(body).some((type) => type !== LOCAL_BACKEND);
93
+ }
94
+
49
95
  export const tf001: PostSynthCheck = {
50
96
  id: "TF001",
51
97
  description: "Root module declares no remote backend",
@@ -64,23 +110,33 @@ export const tf001: PostSynthCheck = {
64
110
  if (flagged.has(root)) continue;
65
111
 
66
112
  const body = (typeof props.body === "object" && props.body !== null ? props.body : {}) as BlockBody;
67
- if (hasBlock(body, "backend") || hasBlock(body, "cloud")) continue;
113
+ if (hasRemoteBackend(body)) continue;
114
+
115
+ // What the root actually declares, so the message names it rather than
116
+ // saying "no remote backend" over a block the reader can see.
117
+ const found = backendTypes(body).includes(LOCAL_BACKEND)
118
+ ? 'the backend it declares is `backend "local"`'
119
+ : "there is no backend block at all";
68
120
 
69
121
  flagged.add(root);
70
122
  diagnostics.push({
71
123
  checkId: "TF001",
72
124
  severity: "warning",
73
125
  message:
74
- `Root module "${root}" declares no remote backend. State falls back to a local ` +
75
- "terraform.tfstate, which is unshared, unlocked and holds every resource attribute in " +
76
- 'plaintext. Add a `backend "<type>"` or a `cloud {}` block to the terraform block.',
126
+ `Root module "${root}" declares no remote backend: ${found}. State is a ` +
127
+ "terraform.tfstate in the working directory, which is unshared, unlocked and holds every " +
128
+ 'resource attribute in plaintext. Declare a `backend "<type>"` naming a remote type (`s3`, ' +
129
+ "`gcs`, `azurerm`, `http`) or a `cloud {}` block, or keep the local state on purpose with a " +
130
+ "`# chant-ignore-block: TF001` above the terraform block.",
77
131
  entity: name,
78
132
  lexicon: "terraform",
79
- // The missing-resource shape (chant #2113): there is no `backend`/
80
- // `cloud` block to point at, only the root that lacks one. `entity`
81
- // above still names the `terraform` block this fired from (by
133
+ // The missing-resource shape (chant #2113): there is no remote
134
+ // `backend`/`cloud` block to point at, only the root that lacks one.
135
+ // `entity` above still names the `terraform` block this fired from (by
82
136
  // convenience, not because that block is what's wrong), so `missing`
83
- // is what a suppression should key on instead.
137
+ // is what a suppression should key on instead. `kind` stays `backend`
138
+ // in both cases: what is absent is a remote backend, whether or not a
139
+ // `backend "local"` block is sitting where one should be.
84
140
  missing: { kind: "backend", scope: root },
85
141
  });
86
142
  }
@@ -2,8 +2,9 @@
2
2
  * TF015: a `backend` or `cloud` block inside a child module.
3
3
  *
4
4
  * Scope: child modules only. This is TF001's mirror image. TF001 wants a root
5
- * module to declare a backend, because a root without one keeps its state on
6
- * local disk. A child module must declare neither: state belongs to the root,
5
+ * module to declare a REMOTE backend, because a root without one keeps its
6
+ * state on local disk. A child module must declare neither: state belongs to
7
+ * the root,
7
8
  * one state per root however many modules it calls, and Terraform says so
8
9
  * directly, "A backend block can only appear in the root module" and the
9
10
  * same for `cloud`. Depending on the version, the block is ignored with a
@@ -15,6 +16,14 @@
15
16
  * along. The rest of that block is fine to keep: `required_version` and
16
17
  * `required_providers` are meaningful in a child module and are not reported
17
18
  * here.
19
+ *
20
+ * Label-blind on purpose (#2218). TF001 had to start reading the backend
21
+ * block's type label, since `local` is the state placement it warns about
22
+ * rather than a cure for it. Nothing of the sort applies here: what a child
23
+ * module may not do is name a backend at all, `local` included, and
24
+ * Terraform's own refusal ("A backend block can only appear in the root
25
+ * module") does not read the label either. `hasBlock` is the right test, and
26
+ * the `positive` fixture's child declares `backend "local"` for that reason.
18
27
  */
19
28
 
20
29
  import type {
@@ -28,8 +28,12 @@ import { LIVE_TYPE, type BlockBody } from "../../hcl/parse";
28
28
  /** Verbs that satisfy `delete: "never"` for the `undeclared_tagged` quadrant. */
29
29
  const SATISFIES_NEVER = new Set(["keep", "untag", "report"]);
30
30
 
31
- /** The `policy { }` block nested in a `live { }` block's body, hcl2json's own "one block, wrapped in an array" shape. */
32
- function policyBlockOf(liveBody: BlockBody): BlockBody | undefined {
31
+ /**
32
+ * The `policy { }` block nested in a `live { }` block's body, hcl2json's own
33
+ * "one block, wrapped in an array" shape. Exported for TF027 (`./tf027.ts`),
34
+ * which reads the other quadrant of the same block.
35
+ */
36
+ export function policyBlockOf(liveBody: BlockBody): BlockBody | undefined {
33
37
  const policy = liveBody["policy"];
34
38
  return Array.isArray(policy) && policy.length > 0 && typeof policy[0] === "object" && policy[0] !== null
35
39
  ? (policy[0] as BlockBody)
@@ -0,0 +1,74 @@
1
+ /**
2
+ * TF027: a live root's `policy` block sets `undeclared_untagged = "delete"`.
3
+ *
4
+ * The `undeclared_untagged` quadrant covers a live resource this estate never
5
+ * marked and the configuration does not declare, a resource chant does not
6
+ * own. `"delete"` there is account-scoped reconciliation: choudoufu compares
7
+ * the configuration against everything a `scope` block reaches and removes
8
+ * what is not in it. chant never proposes deleting a resource it does not
9
+ * own, and neither does an Op it generates, so the setting is refused on any
10
+ * live root the project builds, scoped or not. Narrowing the estate's own
11
+ * ownership answer (`undeclared_tagged`, which TF026 checks against
12
+ * `delete: "never"`) is the setting to reach for instead.
13
+ *
14
+ * `TerraformApplyOp` (`../../composites/terraform-apply-op.ts`) makes the
15
+ * same refusal when it builds, but only for a project on a `chant.config.json`
16
+ * whose root it can resolve synchronously (#2216): a `chant.config.ts` is
17
+ * project-authored code that `resolveRootModeSync` will not evaluate, so the
18
+ * composite reads the root as stock and never asks the policy question. This
19
+ * check reads `props.mode` off the parsed HCL instead, which the build stamps
20
+ * on every entity whatever the config file is written in, so it is the
21
+ * refusal that actually fires. It also fires for a live root with no apply Op
22
+ * at all, since the setting is a statement about the estate rather than about
23
+ * one Op.
24
+ *
25
+ * One diagnostic per root, fired from the root's `Terraform::Live` entity,
26
+ * the same entity TF024, TF025 and TF026 fire from.
27
+ */
28
+
29
+ import type {
30
+ PostSynthCheck,
31
+ PostSynthContext,
32
+ PostSynthDiagnostic,
33
+ } from "@intentius/chant/lint/post-synth";
34
+ import { isResourceDeclarable } from "@intentius/chant/declarable";
35
+ import { LIVE_TYPE, type BlockBody } from "../../hcl/parse";
36
+ import { policyBlockOf } from "./tf026";
37
+
38
+ export const tf027: PostSynthCheck = {
39
+ id: "TF027",
40
+ description: "Live root's policy block sets undeclared_untagged = \"delete\", which deletes resources chant does not own",
41
+
42
+ check(ctx: PostSynthContext): PostSynthDiagnostic[] {
43
+ const diagnostics: PostSynthDiagnostic[] = [];
44
+ const flagged = new Set<string>();
45
+
46
+ for (const [name, entity] of ctx.entities) {
47
+ if (entity.entityType !== LIVE_TYPE) continue;
48
+ if (!isResourceDeclarable(entity)) continue;
49
+ const props = entity.props as { root?: unknown; body?: unknown; mode?: unknown };
50
+ if (props.mode !== "live") continue;
51
+ const root = typeof props.root === "string" ? props.root : "";
52
+ if (flagged.has(root)) continue;
53
+
54
+ const body = (typeof props.body === "object" && props.body !== null ? props.body : {}) as BlockBody;
55
+ const policy = policyBlockOf(body);
56
+ if (!policy || policy["undeclared_untagged"] !== "delete") continue;
57
+
58
+ flagged.add(root);
59
+ diagnostics.push({
60
+ checkId: "TF027",
61
+ severity: "error",
62
+ message:
63
+ `Root module "${root}"'s policy block sets undeclared_untagged = "delete" (account-scoped ` +
64
+ "reconciliation, scoped by a `scope` block). chant never proposes deleting a resource it does " +
65
+ "not own, and neither does an Op it generates. Remove that setting from the policy block, or " +
66
+ "narrow the estate's ownership answer (undeclared_tagged) instead of the account's.",
67
+ entity: name,
68
+ lexicon: "terraform",
69
+ });
70
+ }
71
+
72
+ return diagnostics;
73
+ },
74
+ };
@@ -0,0 +1,96 @@
1
+ /**
2
+ * TF028: a live root is watched by a `TerraformWatchOp` built in stock mode.
3
+ *
4
+ * `TerraformWatchOp`'s `live` flag is declared, not detected: a composite is
5
+ * built by `chant build` without reading a root module's `.tf` files, so the
6
+ * Op author says which shape the Plan phase takes and, until #2216, nothing
7
+ * checked the answer against the root. Leaving it off a live root is silent
8
+ * and lossy. `live: true` swaps the Plan step for `choudoufuLivePlan`, whose
9
+ * single read of the live system answers three questions (drift, how many
10
+ * live resources sit at a declared identity carrying no marker, and how many
11
+ * of those an exact content match makes claimable); a stock `terraformPlan`
12
+ * step answers the first alone, so the watch reports drift and stays quiet
13
+ * about every unowned and adoptable resource in the estate.
14
+ *
15
+ * The check runs over the whole built graph because that is where both halves
16
+ * of the question are: the root's mode is stamped on every parsed entity by
17
+ * the build (`props.mode`, #2103), and the Op is a `Chant::Op` entity carrying
18
+ * the composite's own labels. `TerraformWatchOp` itself cross-checks the flag
19
+ * where it can (`../../op/resolve-root-mode.ts`), but that read is a
20
+ * `chant.config.json`-only one, so on a `chant.config.ts` project, which is
21
+ * every project in this repository, this check is what actually fires.
22
+ *
23
+ * Read off the labels the composite stamps rather than off the emitted step,
24
+ * since a stock `terraformPlan -out` step against a live root is correct in
25
+ * `TerraformApplyOp`: choudoufu v0.13.0 accepts `plan -out` and re-plans
26
+ * against the file at apply (#2157), so the apply Op builds one shape for
27
+ * both kinds of root and the step alone says nothing about a mistake.
28
+ *
29
+ * One diagnostic per Op, fired from the Op's entity.
30
+ */
31
+
32
+ import type {
33
+ PostSynthCheck,
34
+ PostSynthContext,
35
+ PostSynthDiagnostic,
36
+ } from "@intentius/chant/lint/post-synth";
37
+ import { isResourceDeclarable } from "@intentius/chant/declarable";
38
+ import { isOpEntity } from "@intentius/chant/op/resource";
39
+
40
+ /** The labels `TerraformWatchOp` stamps on the Op it builds (`../../composites/terraform-watch-op.ts`). */
41
+ interface WatchOpLabels {
42
+ Watch?: unknown;
43
+ TerraformRoot?: unknown;
44
+ TerraformMode?: unknown;
45
+ }
46
+
47
+ /** Every root name the build parsed as live: `terraform.binary: "choudoufu"` plus a declared estate. */
48
+ function liveRootsOf(ctx: PostSynthContext): Set<string> {
49
+ const roots = new Set<string>();
50
+ for (const entity of ctx.entities.values()) {
51
+ if (!isResourceDeclarable(entity)) continue;
52
+ const props = entity.props as { root?: unknown; mode?: unknown };
53
+ if (props.mode !== "live" || typeof props.root !== "string") continue;
54
+ roots.add(props.root);
55
+ }
56
+ return roots;
57
+ }
58
+
59
+ export const tf028: PostSynthCheck = {
60
+ id: "TF028",
61
+ description: "A live root is watched by a TerraformWatchOp built without live: true",
62
+
63
+ check(ctx: PostSynthContext): PostSynthDiagnostic[] {
64
+ const liveRoots = liveRootsOf(ctx);
65
+ if (liveRoots.size === 0) return [];
66
+
67
+ const diagnostics: PostSynthDiagnostic[] = [];
68
+
69
+ for (const [name, entity] of ctx.entities) {
70
+ if (!isOpEntity(entity)) continue;
71
+ const props = (entity as { props?: Record<string, unknown> }).props;
72
+ if (!props || typeof props.name !== "string") continue;
73
+ const labels = (typeof props.labels === "object" && props.labels !== null
74
+ ? props.labels
75
+ : {}) as WatchOpLabels;
76
+ if (labels.Watch !== "true") continue;
77
+ if (labels.TerraformMode === "live") continue;
78
+ const root = labels.TerraformRoot;
79
+ if (typeof root !== "string" || !liveRoots.has(root)) continue;
80
+
81
+ diagnostics.push({
82
+ checkId: "TF028",
83
+ severity: "error",
84
+ message:
85
+ `Op "${props.name}" watches root module "${root}" in stock mode, but that root runs choudoufu ` +
86
+ "with a declared estate. A stock plan reports drift alone and stays quiet about every unowned " +
87
+ `and adoptable resource in the estate. Set live: true on this TerraformWatchOp, or drop the ` +
88
+ "root's estate if it is not a live root.",
89
+ entity: name,
90
+ lexicon: "terraform",
91
+ });
92
+ }
93
+
94
+ return diagnostics;
95
+ },
96
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAA4B,KAAK,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAElG,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAKvF;;GAEG;AACH,wBAAsB,QAAQ,CAAC,IAAI,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAQpF"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAA4B,KAAK,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAElG,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAcvF;;GAEG;AACH,wBAAsB,QAAQ,CAAC,IAAI,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAQpF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/chant-lexicon-terraform",
3
- "version": "0.58.0",
3
+ "version": "0.59.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "src/",
@@ -56,7 +56,7 @@
56
56
  },
57
57
  "peerDependencies": {
58
58
  "zod": "^4.3.6",
59
- "@intentius/chant": "^0.58.0",
59
+ "@intentius/chant": "^0.59.0",
60
60
  "typescript": "^5.9.3"
61
61
  },
62
62
  "description": "terraform lexicon for chant, existing Terraform root modules as declarable entities",