@intentius/terragucci 0.4.1 → 0.4.3

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.
@@ -0,0 +1,34 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://intentius.io/terragucci/schemas/audit/v1/audit.schema.json",
4
+ "title": "terragucci.audit/v1",
5
+ "description": "One line of audit.jsonl at the top of a reports prefix: an approval, apply, policy override or refused wave. Within v1 fields are only added, and an existing field never changes meaning.",
6
+ "type": "object",
7
+ "required": ["schema", "id", "kind", "project", "at", "who", "what", "digest", "result", "evidence"],
8
+ "properties": {
9
+ "schema": { "const": "terragucci.audit/v1" },
10
+ "id": { "type": "string", "description": "sha256: over where the entry came from; the same records give the same id." },
11
+ "kind": { "enum": ["approval-requested", "approval", "approval-revoked", "override-requested", "override", "override-revoked", "apply", "refused"] },
12
+ "project": { "type": "string", "description": "<host>/<path> of the repo." },
13
+ "at": { "type": "string", "description": "When it happened, ISO 8601." },
14
+ "who": { "type": ["string", "null"], "description": "The approver, the overrider, whoever removed the line, or for an apply the approver it applied under. Null when nobody did." },
15
+ "what": { "type": "string", "description": "The gate (wave-<k>) or, for an override, the root." },
16
+ "digest": { "type": ["string", "null"], "description": "The wave's set digest, or the digest an override binds. Null when a root failed to plan." },
17
+ "result": { "type": "string" },
18
+ "evidence": {
19
+ "type": "object",
20
+ "required": ["source"],
21
+ "properties": {
22
+ "source": { "enum": ["ledger", "report"] },
23
+ "branch": { "type": "string" },
24
+ "path": { "type": "string" },
25
+ "commit": { "type": "string" },
26
+ "bucket": { "type": "string" },
27
+ "key": { "type": "string" },
28
+ "url": { "type": "string" },
29
+ "job_url": { "type": "string" }
30
+ }
31
+ },
32
+ "detail": { "type": "object", "description": "What else the source says, by kind." }
33
+ }
34
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://intentius.io/terragucci/schemas/changes/v1/changes.schema.json",
4
+ "title": "terragucci.changes/v1",
5
+ "description": "changes.json in a project's directory of a reports prefix: one row per resource each applied tf-apply wave changed, newest first. Actions and attribute names, never a value. Within v1 fields are only added, and an existing field never changes meaning.",
6
+ "type": "object",
7
+ "required": ["schema", "changes"],
8
+ "properties": {
9
+ "schema": { "const": "terragucci.changes/v1" },
10
+ "changes": {
11
+ "type": "array",
12
+ "items": {
13
+ "type": "object",
14
+ "required": ["address", "type", "actions", "attributes", "root", "commit", "finished", "path", "plan_digest", "set_digest"],
15
+ "properties": {
16
+ "address": { "type": "string" },
17
+ "type": { "type": "string" },
18
+ "actions": { "type": "array", "items": { "enum": ["create", "update", "replace", "delete", "import", "move", "forget"] } },
19
+ "attributes": { "type": "array", "items": { "type": "string" }, "description": "The top-level attributes an update or a replacement changed, by name." },
20
+ "previous_address": { "type": "string", "description": "Where a moved resource was." },
21
+ "root": { "type": "string" },
22
+ "commit": { "type": "string" },
23
+ "wave": { "type": "integer" },
24
+ "finished": { "type": "string", "description": "When the wave finished." },
25
+ "path": { "type": "string", "description": "The wave's run directory, relative to the project's index.json." },
26
+ "plan_digest": { "type": ["string", "null"], "description": "The root's plan digest: the plan that applied." },
27
+ "set_digest": { "type": ["string", "null"], "description": "The wave's set digest, which its approval binds." },
28
+ "pull_request": { "type": "string" }
29
+ }
30
+ }
31
+ }
32
+ }
33
+ }
@@ -0,0 +1,162 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://intentius.io/terragucci/schemas/estate/v1/estate.schema.json",
4
+ "title": "terragucci.estate/v1",
5
+ "description": "estate.json at the top of a reports prefix, which terragucci estate builds from every project's index.json, inventory.json and changes.json. Within v1 fields are only added, and an existing field never changes meaning.",
6
+ "type": "object",
7
+ "required": ["schema", "generated", "totals", "projects", "recent"],
8
+ "properties": {
9
+ "schema": { "const": "terragucci.estate/v1" },
10
+ "generated": { "type": "string", "description": "When the page was built, ISO 8601. Every age on it is as of this time." },
11
+ "totals": {
12
+ "type": "object",
13
+ "required": ["projects", "waiting", "drifted_projects", "drifted_roots", "failed_roots", "unreadable"],
14
+ "properties": {
15
+ "projects": { "type": "integer" },
16
+ "waiting": { "type": "integer", "description": "Waves waiting for an approval." },
17
+ "drifted_projects": { "type": "integer" },
18
+ "drifted_roots": { "type": "integer" },
19
+ "failed_roots": { "type": "integer" },
20
+ "unreadable": { "type": "integer", "description": "Projects whose index could not be read." },
21
+ "overridden_roots": { "type": "integer", "description": "Roots the newest apply waves applied under a policy override. Absent when none." },
22
+ "resources": { "type": "integer", "description": "Resources across every project's inventory. Absent when no project has one." }
23
+ }
24
+ },
25
+ "projects": { "type": "array", "items": { "$ref": "#/$defs/project" } },
26
+ "recent": { "type": "array", "description": "The 20 newest runs across every project, newest first.", "items": { "$ref": "#/$defs/run" } },
27
+ "audit": {
28
+ "type": "object",
29
+ "description": "The audit trail beside the page, when terragucci audit wrote one.",
30
+ "required": ["page", "entries", "generated"],
31
+ "properties": {
32
+ "page": { "type": "string" },
33
+ "entries": { "type": "integer" },
34
+ "generated": { "type": "string" }
35
+ }
36
+ },
37
+ "history": {
38
+ "type": "object",
39
+ "description": "The resource history beside the page (history.json and history.html), when an apply changed a resource.",
40
+ "required": ["page", "resources", "generated"],
41
+ "properties": {
42
+ "page": { "type": "string" },
43
+ "resources": { "type": "integer", "description": "Addresses with at least one apply." },
44
+ "generated": { "type": "string" }
45
+ }
46
+ }
47
+ },
48
+ "$defs": {
49
+ "totals": {
50
+ "type": "object",
51
+ "required": ["create", "update", "replace", "delete"],
52
+ "properties": {
53
+ "create": { "type": "integer" },
54
+ "update": { "type": "integer" },
55
+ "replace": { "type": "integer" },
56
+ "delete": { "type": "integer" }
57
+ }
58
+ },
59
+ "run": {
60
+ "type": "object",
61
+ "description": "A run, from its index row.",
62
+ "required": ["project", "commit", "stage", "finished", "roots", "refused", "totals", "destroys"],
63
+ "properties": {
64
+ "project": { "type": "string" },
65
+ "commit": { "type": "string" },
66
+ "stage": { "enum": ["tf-plan", "tf-apply", "tf-drift"] },
67
+ "wave": { "type": "integer" },
68
+ "finished": { "type": "string" },
69
+ "roots": { "type": "integer" },
70
+ "changed": { "type": "integer" },
71
+ "failed": { "type": "integer" },
72
+ "refused": { "type": "integer" },
73
+ "totals": { "$ref": "#/$defs/totals" },
74
+ "destroys": { "type": "integer", "description": "How many destroys and replacements the run has." },
75
+ "approval": { "enum": ["waiting", "approved", "not-required"] },
76
+ "waiting_since": { "type": "string" },
77
+ "applied": { "type": "string" },
78
+ "overridden": { "type": "integer" },
79
+ "report": { "type": "string", "description": "The run's report.html, relative to the page or absolute on another bucket's address. Absent when the page cannot link it." },
80
+ "pull_request": { "type": "string" },
81
+ "pull_request_url": { "type": "string" },
82
+ "job_url": { "type": "string" }
83
+ }
84
+ },
85
+ "waiting": {
86
+ "type": "object",
87
+ "required": ["project", "wave", "commit", "since", "age_seconds"],
88
+ "properties": {
89
+ "project": { "type": "string" },
90
+ "wave": { "type": "integer" },
91
+ "commit": { "type": "string" },
92
+ "since": { "type": "string", "description": "When the wave began waiting for an approval of its digest." },
93
+ "age_seconds": { "type": "integer", "description": "Seconds it had waited at generated." },
94
+ "report": { "type": "string" }
95
+ }
96
+ },
97
+ "project": {
98
+ "type": "object",
99
+ "required": ["project", "status", "waiting", "drifted", "failed"],
100
+ "properties": {
101
+ "project": { "type": "string" },
102
+ "status": { "enum": ["ok", "no-index", "error"] },
103
+ "error": { "type": "string", "description": "Why the index could not be read." },
104
+ "index": { "type": "string", "description": "The project's index.html, when the page can link it." },
105
+ "plan": { "$ref": "#/$defs/run", "description": "The latest tf-plan." },
106
+ "drift": { "$ref": "#/$defs/run", "description": "The latest tf-drift." },
107
+ "apply": {
108
+ "type": "object",
109
+ "description": "The waves of the newest commit that ran tf-apply, by wave number.",
110
+ "required": ["commit", "waves"],
111
+ "properties": {
112
+ "commit": { "type": "string" },
113
+ "waves": { "type": "array", "items": { "$ref": "#/$defs/run" } }
114
+ }
115
+ },
116
+ "waiting": { "type": "array", "items": { "$ref": "#/$defs/waiting" } },
117
+ "drifted": { "type": "integer", "description": "Roots that drifted in the latest drift check." },
118
+ "failed": { "type": "integer", "description": "Roots that failed in the latest plan, drift check and apply waves." },
119
+ "overridden": { "type": "integer", "description": "Roots the newest commit's apply waves applied under a policy override. Absent when none." },
120
+ "inventory": { "$ref": "#/$defs/inventory", "description": "The resources its roots hold, from its inventory.json. Absent until an apply records them." }
121
+ }
122
+ },
123
+ "inventory": {
124
+ "type": "object",
125
+ "required": ["resources", "types", "roots"],
126
+ "properties": {
127
+ "resources": { "type": "integer" },
128
+ "types": {
129
+ "type": "array",
130
+ "description": "How many resources of each type, most first.",
131
+ "items": { "type": "object", "required": ["type", "count"], "properties": { "type": { "type": "string" }, "count": { "type": "integer" } } }
132
+ },
133
+ "roots": {
134
+ "type": "array",
135
+ "items": {
136
+ "type": "object",
137
+ "description": "One root's resources, as its newest applied wave left them.",
138
+ "required": ["root", "commit", "finished", "resources"],
139
+ "properties": {
140
+ "root": { "type": "string" },
141
+ "commit": { "type": "string" },
142
+ "finished": { "type": "string" },
143
+ "wave": { "type": "integer" },
144
+ "report": { "type": "string", "description": "The wave's report.html, when the page can link it." },
145
+ "resources": { "type": "array", "items": { "$ref": "#/$defs/resource" } }
146
+ }
147
+ }
148
+ }
149
+ }
150
+ },
151
+ "resource": {
152
+ "type": "object",
153
+ "required": ["address", "type", "provider"],
154
+ "properties": {
155
+ "address": { "type": "string" },
156
+ "type": { "type": "string" },
157
+ "provider": { "type": "string" },
158
+ "history": { "type": "string", "description": "Its section of history.html, when an apply changed it." }
159
+ }
160
+ }
161
+ }
162
+ }
@@ -0,0 +1,49 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://intentius.io/terragucci/schemas/history/v1/history.schema.json",
4
+ "title": "terragucci.history/v1",
5
+ "description": "history.json at the top of a reports prefix, which terragucci estate builds from every project's changes.json and the audit trail: each resource address with every apply that changed it, oldest first. Actions and attribute names, never a value. Within v1 fields are only added, and an existing field never changes meaning.",
6
+ "type": "object",
7
+ "required": ["schema", "generated", "audit", "resources"],
8
+ "properties": {
9
+ "schema": { "const": "terragucci.history/v1" },
10
+ "generated": { "type": "string" },
11
+ "audit": { "type": "boolean", "description": "Whether the audit trail was read for the approvers." },
12
+ "resources": {
13
+ "type": "array",
14
+ "items": {
15
+ "type": "object",
16
+ "required": ["id", "project", "root", "address", "type", "applies"],
17
+ "properties": {
18
+ "id": { "type": "string", "description": "Its anchor on history.html." },
19
+ "project": { "type": "string" },
20
+ "root": { "type": "string" },
21
+ "address": { "type": "string" },
22
+ "type": { "type": "string" },
23
+ "applies": {
24
+ "type": "array",
25
+ "description": "Oldest first.",
26
+ "items": {
27
+ "type": "object",
28
+ "required": ["actions", "attributes", "commit", "finished", "plan_digest", "set_digest"],
29
+ "properties": {
30
+ "actions": { "type": "array", "items": { "enum": ["create", "update", "replace", "delete", "import", "move", "forget"] } },
31
+ "attributes": { "type": "array", "items": { "type": "string" } },
32
+ "previous_address": { "type": "string" },
33
+ "commit": { "type": "string" },
34
+ "wave": { "type": "integer" },
35
+ "finished": { "type": "string" },
36
+ "plan_digest": { "type": ["string", "null"] },
37
+ "set_digest": { "type": ["string", "null"] },
38
+ "approver": { "type": ["string", "null"], "description": "Who approved the wave, from its apply entry in the audit trail; null when no gate held it. Absent when the audit trail has no entry for the wave." },
39
+ "approval": { "type": "string", "description": "The id of the approval entry in the audit trail." },
40
+ "report": { "type": "string" },
41
+ "pull_request": { "type": "string" }
42
+ }
43
+ }
44
+ }
45
+ }
46
+ }
47
+ }
48
+ }
49
+ }
@@ -0,0 +1,38 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://intentius.io/terragucci/schemas/inventory/v1/inventory.schema.json",
4
+ "title": "terragucci.inventory/v1",
5
+ "description": "inventory.json in a project's directory of a reports prefix: the resources each root holds, as its newest applied tf-apply wave left them. Addresses, types and providers, never a value. Within v1 fields are only added, and an existing field never changes meaning.",
6
+ "type": "object",
7
+ "required": ["schema", "roots"],
8
+ "properties": {
9
+ "schema": { "const": "terragucci.inventory/v1" },
10
+ "roots": {
11
+ "type": "array",
12
+ "description": "By root path.",
13
+ "items": {
14
+ "type": "object",
15
+ "required": ["root", "commit", "finished", "path", "resources"],
16
+ "properties": {
17
+ "root": { "type": "string" },
18
+ "commit": { "type": "string" },
19
+ "finished": { "type": "string", "description": "When the wave that recorded the list finished." },
20
+ "wave": { "type": "integer" },
21
+ "path": { "type": "string", "description": "The wave's run directory, relative to the project's index.json." },
22
+ "resources": {
23
+ "type": "array",
24
+ "items": {
25
+ "type": "object",
26
+ "required": ["address", "type", "provider"],
27
+ "properties": {
28
+ "address": { "type": "string" },
29
+ "type": { "type": "string" },
30
+ "provider": { "type": "string" }
31
+ }
32
+ }
33
+ }
34
+ }
35
+ }
36
+ }
37
+ }
38
+ }
@@ -0,0 +1,66 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://intentius.io/terragucci/schemas/notify/v1/notify.schema.json",
4
+ "title": "terragucci.notify/v1",
5
+ "description": "The event terragucci notify posts to the generic webhook when a tf-apply wave waits, is refused or fails. The schema changes only when a field is removed or changes meaning; new fields can appear without a bump.",
6
+ "type": "object",
7
+ "required": ["schema", "id", "event", "sent_at", "project", "wave", "roots"],
8
+ "properties": {
9
+ "schema": { "const": "terragucci.notify/v1" },
10
+ "id": { "type": "string", "description": "sha256 hex over the project, the wave, the event and the set digest (the commit when there is none): the same for every post of one wave's event about one digest." },
11
+ "event": { "enum": ["waiting", "refused", "failed"] },
12
+ "sent_at": { "type": "string", "description": "When the job posted it, ISO 8601." },
13
+ "project": { "type": "string", "description": "<host>/<path> of the repo." },
14
+ "forge": { "enum": ["github", "gitlab", "forgejo"] },
15
+ "repo": { "type": "string", "description": "owner/name on GitHub and Forgejo, the project path on GitLab." },
16
+ "sha": { "type": "string", "description": "The commit the wave applied." },
17
+ "pr": { "type": "integer", "description": "The pull or merge request the job applied, when a comment started it." },
18
+ "wave": { "type": "integer" },
19
+ "roots": { "type": "array", "items": { "type": "string" }, "description": "The wave's roots; for a refused or denied wave, the roots that moved or were denied; for a failed one, the roots that failed." },
20
+ "run_url": { "type": "string" },
21
+ "report_url": { "type": "string" },
22
+ "outcome": { "$ref": "#/$defs/outcome" }
23
+ },
24
+ "$defs": {
25
+ "outcome": {
26
+ "type": "object",
27
+ "description": "terragucci.outcome/v1, as stage tf-apply wrote it to TG_OUTCOME_JSON.",
28
+ "required": ["schema", "status", "exit", "wave", "roots"],
29
+ "properties": {
30
+ "schema": { "const": "terragucci.outcome/v1" },
31
+ "status": { "enum": ["applied", "waiting", "refused", "failed"] },
32
+ "exit": { "type": "integer" },
33
+ "wave": { "type": "integer" },
34
+ "roots": { "type": "array", "items": { "type": "string" } },
35
+ "line": { "type": "string" },
36
+ "set_digest": { "type": "string" },
37
+ "gate": {
38
+ "type": "object",
39
+ "required": ["name", "branch", "path"],
40
+ "properties": { "name": { "type": "string" }, "branch": { "type": "string" }, "path": { "type": "string" } }
41
+ },
42
+ "approval": { "enum": ["not-requested", "waiting", "approved", "not-required"] },
43
+ "approval_mode": { "enum": ["ledger", "pr-review", "sealed"] },
44
+ "approve_command": { "type": "string" },
45
+ "waiting_since": { "type": "string" },
46
+ "review": {
47
+ "type": "object",
48
+ "required": ["pull_request", "url"],
49
+ "properties": { "pull_request": { "type": "integer" }, "url": { "type": "string" } }
50
+ },
51
+ "refused": {
52
+ "type": "object",
53
+ "required": ["reason", "roots"],
54
+ "properties": {
55
+ "reason": { "enum": ["approval", "review", "override", "policy"] },
56
+ "approved": { "type": "string" },
57
+ "by": { "type": "string" },
58
+ "roots": { "type": "array", "items": { "type": "string" } }
59
+ }
60
+ },
61
+ "policy_denied": { "type": "array", "items": { "type": "string" } },
62
+ "failed_roots": { "type": "array", "items": { "type": "string" } }
63
+ }
64
+ }
65
+ }
66
+ }
@@ -0,0 +1,57 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://intentius.io/terragucci/schemas/report-index/v1/report-index.schema.json",
4
+ "title": "terragucci.report-index/v1",
5
+ "description": "A reports bucket's index.json: one row per run, newest first. Within v1 fields are only added, and an existing field never changes meaning.",
6
+ "type": "object",
7
+ "required": ["schema", "reports"],
8
+ "properties": {
9
+ "schema": { "const": "terragucci.report-index/v1" },
10
+ "reports": {
11
+ "type": "array",
12
+ "description": "Newest first: up to 500 rows, then the newest row of each project, stage and wave beyond them.",
13
+ "items": { "$ref": "#/$defs/row" }
14
+ }
15
+ },
16
+ "$defs": {
17
+ "totals": {
18
+ "type": "object",
19
+ "required": ["create", "update", "replace", "delete"],
20
+ "properties": {
21
+ "create": { "type": "integer" },
22
+ "update": { "type": "integer" },
23
+ "replace": { "type": "integer" },
24
+ "delete": { "type": "integer" }
25
+ }
26
+ },
27
+ "row": {
28
+ "type": "object",
29
+ "required": ["project", "commit", "stage", "finished", "path", "roots", "groups", "totals", "refused", "destroys"],
30
+ "properties": {
31
+ "project": { "type": "string", "description": "<host>/<path> of the repo." },
32
+ "commit": { "type": "string" },
33
+ "stage": { "enum": ["tf-plan", "tf-apply", "tf-drift"] },
34
+ "wave": { "type": "integer", "description": "The wave of a tf-apply run." },
35
+ "finished": { "type": "string", "description": "When the run finished, ISO 8601." },
36
+ "path": { "type": "string", "description": "The run's directory, relative to this index: <yyyy>/<mm>/<commit>/<stage>[-wave-N] in a project's index, prefixed with the project in the top index." },
37
+ "roots": { "type": "integer" },
38
+ "groups": { "type": "integer" },
39
+ "totals": { "$ref": "#/$defs/totals" },
40
+ "refused": { "type": "integer", "description": "Roots that refused to plan." },
41
+ "failed": { "type": "integer", "description": "Roots that failed to plan or apply. Absent on rows written before it was kept." },
42
+ "changed": { "type": "integer", "description": "Roots with at least one change; on a tf-drift row, the roots that drifted." },
43
+ "approval": { "enum": ["waiting", "approved", "not-required"], "description": "A tf-apply wave's gate." },
44
+ "waiting_since": { "type": "string", "description": "When a waiting wave began waiting for an approval of its digest." },
45
+ "applied": { "type": "string", "description": "When a tf-apply wave finished applying." },
46
+ "overridden": { "type": "integer", "description": "Roots the policy denied that a recorded override let through. Absent when none." },
47
+ "destroys": { "type": "array", "items": { "type": "string" }, "description": "Destroys and replacements as `<root>: <address>`, at most 50." },
48
+ "destroys_total": { "type": "integer", "description": "How many destroys and replacements there are, when there are more than the row lists." },
49
+ "commit_url": { "type": "string" },
50
+ "pull_request": { "type": "string" },
51
+ "pull_request_url": { "type": "string" },
52
+ "job_url": { "type": "string" },
53
+ "trace_url": { "type": "string" }
54
+ }
55
+ }
56
+ }
57
+ }
@@ -169,6 +169,26 @@
169
169
  }
170
170
  }
171
171
  }
172
+ },
173
+ "resources": {
174
+ "description": "On a tf-apply wave, a root that applied or had nothing to apply: every managed resource it holds afterwards, from the plan's planned values. Never a value (minor 14).",
175
+ "type": "array",
176
+ "items": { "$ref": "#/$defs/resource" }
177
+ },
178
+ "applied_changes": {
179
+ "description": "On a tf-apply wave, a root that applied: what the apply did to each resource, and the top-level attributes an update or a replacement changed, by name. Never a value (minor 15).",
180
+ "type": "array",
181
+ "items": {
182
+ "type": "object",
183
+ "required": ["address", "type", "actions", "attributes"],
184
+ "properties": {
185
+ "address": { "type": "string" },
186
+ "type": { "type": "string" },
187
+ "actions": { "type": "array", "items": { "enum": ["create", "update", "replace", "delete", "import", "move", "forget"] } },
188
+ "attributes": { "type": "array", "items": { "type": "string" } },
189
+ "previous_address": { "type": "string" }
190
+ }
191
+ }
172
192
  }
173
193
  }
174
194
  }
@@ -190,7 +210,27 @@
190
210
  "required": ["branch", "path"],
191
211
  "properties": { "branch": { "type": "string" }, "path": { "type": "string" } }
192
212
  },
193
- "waiting_since": { "type": "string", "description": "On a waiting wave, when it began waiting for an approval of this digest (minor 8)." }
213
+ "waiting_since": { "type": "string", "description": "On a waiting wave, when it began waiting for an approval of this digest (minor 8)." },
214
+ "refused": {
215
+ "type": "object",
216
+ "description": "Why a tf-apply wave applied nothing although it planned: its plans changed after an approval, a review or an override, or the policy denied a root (minor 11).",
217
+ "required": ["reason", "roots"],
218
+ "properties": {
219
+ "reason": { "enum": ["approval", "review", "override", "policy"] },
220
+ "approved": { "type": "string" },
221
+ "by": { "type": "string" },
222
+ "roots": { "type": "array", "items": { "type": "string" } }
223
+ }
224
+ },
225
+ "review": {
226
+ "type": "object",
227
+ "description": "A waiting tf-apply wave under approval: pr-review: the pull request whose approving review of its head would approve the wave, and the page to review it on (minor 13).",
228
+ "required": ["pull_request", "url"],
229
+ "properties": {
230
+ "pull_request": { "type": "integer" },
231
+ "url": { "type": "string" }
232
+ }
233
+ }
194
234
  }
195
235
  }
196
236
  },
@@ -238,6 +278,33 @@
238
278
  "overriders": { "type": "array", "items": { "type": "string" }, "description": "Who may override a denial, from policy.override at base (minor 10)." }
239
279
  }
240
280
  },
281
+ "cost": {
282
+ "description": "The cost estimate of a tf-plan run, when cost is on (minor 12): each root's monthly cost from the estimator, and the sums over the roots estimated.",
283
+ "type": "object",
284
+ "required": ["estimator", "currency", "monthly_delta", "monthly_total", "past_monthly_total", "roots"],
285
+ "properties": {
286
+ "estimator": { "type": "string" },
287
+ "currency": { "type": "string" },
288
+ "monthly_delta": { "type": ["number", "null"] },
289
+ "monthly_total": { "type": ["number", "null"] },
290
+ "past_monthly_total": { "type": ["number", "null"] },
291
+ "roots": {
292
+ "type": "array",
293
+ "items": {
294
+ "type": "object",
295
+ "required": ["root", "monthly_delta", "monthly_total", "past_monthly_total"],
296
+ "properties": {
297
+ "root": { "type": "string" },
298
+ "monthly_delta": { "type": ["number", "null"] },
299
+ "monthly_total": { "type": ["number", "null"] },
300
+ "past_monthly_total": { "type": ["number", "null"] },
301
+ "output": { "type": "string" },
302
+ "error": { "type": "string" }
303
+ }
304
+ }
305
+ }
306
+ }
307
+ },
241
308
  "intent": {
242
309
  "description": "The description check's decision (minor 5). Written by respond description; absent when it did not run.",
243
310
  "type": "object",
@@ -341,6 +408,15 @@
341
408
  }
342
409
  },
343
410
  "$defs": {
411
+ "resource": {
412
+ "type": "object",
413
+ "required": ["address", "type", "provider"],
414
+ "properties": {
415
+ "address": { "type": "string" },
416
+ "type": { "type": "string" },
417
+ "provider": { "type": "string", "description": "The provider's source address, such as registry.opentofu.org/hashicorp/aws." }
418
+ }
419
+ },
344
420
  "timingDetail": { "enum": ["resources", "aggregate", "none"] },
345
421
  "timingSource": { "description": "binary: terragucci timed each run of the binary; terragrunt: from Terragrunt's run report (minor 3).", "enum": ["binary", "terragrunt"] },
346
422
  "rootTimings": {