@goodbones/core 0.1.0-beta.1 → 0.1.0-beta.11
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.
- package/build/dts/core/coverage.d.ts +20 -0
- package/build/dts/core/coverage.d.ts.map +1 -1
- package/build/dts/core/graph.d.ts +2 -0
- package/build/dts/core/graph.d.ts.map +1 -1
- package/build/dts/core/imports.d.ts +3 -1
- package/build/dts/core/imports.d.ts.map +1 -1
- package/build/dts/core/slack.d.ts +22 -0
- package/build/dts/core/slack.d.ts.map +1 -0
- package/build/dts/core/structure.d.ts +1 -0
- package/build/dts/core/structure.d.ts.map +1 -1
- package/build/dts/domain/architecture-config.d.ts +19 -3
- package/build/dts/domain/architecture-config.d.ts.map +1 -1
- package/build/dts/domain/architecture-error.d.ts +8 -0
- package/build/dts/domain/architecture-error.d.ts.map +1 -1
- package/build/dts/domain/facts.d.ts +1 -0
- package/build/dts/domain/facts.d.ts.map +1 -1
- package/build/dts/domain/manifest-location.d.ts +9 -0
- package/build/dts/domain/manifest-location.d.ts.map +1 -0
- package/build/dts/domain/snapshot.d.ts +356 -0
- package/build/dts/domain/snapshot.d.ts.map +1 -0
- package/build/dts/domain/violation.d.ts +1 -1
- package/build/dts/domain/violation.d.ts.map +1 -1
- package/build/dts/index.d.ts +22 -10
- package/build/dts/index.d.ts.map +1 -1
- package/build/dts/infrastructure/file-system-fake.d.ts.map +1 -1
- package/build/dts/infrastructure/file-system-live.d.ts.map +1 -1
- package/build/dts/infrastructure/manifest-file.d.ts +11 -2
- package/build/dts/infrastructure/manifest-file.d.ts.map +1 -1
- package/build/dts/infrastructure/manifest-include.d.ts +16 -0
- package/build/dts/infrastructure/manifest-include.d.ts.map +1 -0
- package/build/dts/infrastructure/syntax-matcher-fake.d.ts +10 -0
- package/build/dts/infrastructure/syntax-matcher-fake.d.ts.map +1 -0
- package/build/dts/infrastructure/walk.d.ts +12 -1
- package/build/dts/infrastructure/walk.d.ts.map +1 -1
- package/build/dts/load/extension.d.ts +33 -0
- package/build/dts/load/extension.d.ts.map +1 -0
- package/build/dts/load/policy.d.ts +10 -0
- package/build/dts/load/policy.d.ts.map +1 -1
- package/build/dts/manifest/compile.d.ts +11 -1
- package/build/dts/manifest/compile.d.ts.map +1 -1
- package/build/dts/manifest/expand.d.ts +27 -0
- package/build/dts/manifest/expand.d.ts.map +1 -0
- package/build/dts/manifest/extension.d.ts +8 -0
- package/build/dts/manifest/extension.d.ts.map +1 -0
- package/build/dts/manifest/glob.d.ts +1 -0
- package/build/dts/manifest/glob.d.ts.map +1 -1
- package/build/dts/manifest/infer.d.ts +55 -0
- package/build/dts/manifest/infer.d.ts.map +1 -0
- package/build/dts/manifest/json-schema.d.ts +14 -0
- package/build/dts/manifest/json-schema.d.ts.map +1 -0
- package/build/dts/manifest/manifest.d.ts +26 -1
- package/build/dts/manifest/manifest.d.ts.map +1 -1
- package/build/dts/ports/file-system.d.ts +1 -0
- package/build/dts/ports/file-system.d.ts.map +1 -1
- package/build/dts/ports/language.d.ts +4 -0
- package/build/dts/ports/language.d.ts.map +1 -1
- package/build/dts/ports/syntax-matcher.d.ts +21 -0
- package/build/dts/ports/syntax-matcher.d.ts.map +1 -0
- package/build/dts/testing.d.ts +1 -0
- package/build/dts/testing.d.ts.map +1 -1
- package/build/esm/core/coverage.js +107 -32
- package/build/esm/core/coverage.js.map +1 -1
- package/build/esm/core/graph.js +45 -0
- package/build/esm/core/graph.js.map +1 -1
- package/build/esm/core/imports.js +14 -9
- package/build/esm/core/imports.js.map +1 -1
- package/build/esm/core/slack.js +76 -0
- package/build/esm/core/slack.js.map +1 -0
- package/build/esm/core/structure.js +6 -3
- package/build/esm/core/structure.js.map +1 -1
- package/build/esm/domain/architecture-config.js +28 -4
- package/build/esm/domain/architecture-config.js.map +1 -1
- package/build/esm/domain/architecture-error.js +27 -0
- package/build/esm/domain/architecture-error.js.map +1 -1
- package/build/esm/domain/manifest-location.js +21 -0
- package/build/esm/domain/manifest-location.js.map +1 -0
- package/build/esm/domain/snapshot.js +181 -0
- package/build/esm/domain/snapshot.js.map +1 -0
- package/build/esm/domain/violation.js.map +1 -1
- package/build/esm/index.js +28 -9
- package/build/esm/index.js.map +1 -1
- package/build/esm/infrastructure/file-system-fake.js +10 -0
- package/build/esm/infrastructure/file-system-fake.js.map +1 -1
- package/build/esm/infrastructure/file-system-live.js +9 -1
- package/build/esm/infrastructure/file-system-live.js.map +1 -1
- package/build/esm/infrastructure/manifest-file.js +158 -7
- package/build/esm/infrastructure/manifest-file.js.map +1 -1
- package/build/esm/infrastructure/manifest-include.js +187 -0
- package/build/esm/infrastructure/manifest-include.js.map +1 -0
- package/build/esm/infrastructure/syntax-matcher-fake.js +33 -0
- package/build/esm/infrastructure/syntax-matcher-fake.js.map +1 -0
- package/build/esm/infrastructure/walk.js +106 -4
- package/build/esm/infrastructure/walk.js.map +1 -1
- package/build/esm/load/extension.js +2 -0
- package/build/esm/load/extension.js.map +1 -0
- package/build/esm/load/policy.js +49 -2
- package/build/esm/load/policy.js.map +1 -1
- package/build/esm/manifest/compile.js +50 -27
- package/build/esm/manifest/compile.js.map +1 -1
- package/build/esm/manifest/expand.js +116 -0
- package/build/esm/manifest/expand.js.map +1 -0
- package/build/esm/manifest/extension.js +2 -0
- package/build/esm/manifest/extension.js.map +1 -0
- package/build/esm/manifest/glob.js +3 -0
- package/build/esm/manifest/glob.js.map +1 -1
- package/build/esm/manifest/infer.js +455 -0
- package/build/esm/manifest/infer.js.map +1 -0
- package/build/esm/manifest/json-schema.js +169 -0
- package/build/esm/manifest/json-schema.js.map +1 -0
- package/build/esm/manifest/manifest.js +127 -5
- package/build/esm/manifest/manifest.js.map +1 -1
- package/build/esm/ports/syntax-matcher.js +12 -0
- package/build/esm/ports/syntax-matcher.js.map +1 -0
- package/build/esm/testing.js +1 -0
- package/build/esm/testing.js.map +1 -1
- package/package.json +9 -3
- package/schema/architecture-node.schema.json +1518 -0
- package/schema/architecture.schema.json +4498 -0
- package/schema/conformance.schema.json +1019 -0
- package/src/core/coverage.ts +164 -34
- package/src/core/graph.ts +48 -0
- package/src/core/imports.ts +29 -13
- package/src/core/slack.ts +135 -0
- package/src/core/structure.ts +15 -8
- package/src/domain/architecture-config.ts +31 -4
- package/src/domain/architecture-error.ts +30 -0
- package/src/domain/facts.ts +9 -4
- package/src/domain/manifest-location.ts +41 -0
- package/src/domain/snapshot.ts +402 -0
- package/src/domain/violation.ts +4 -1
- package/src/index.ts +149 -7
- package/src/infrastructure/file-system-fake.ts +12 -0
- package/src/infrastructure/file-system-live.ts +8 -1
- package/src/infrastructure/manifest-file.ts +204 -8
- package/src/infrastructure/manifest-include.ts +318 -0
- package/src/infrastructure/syntax-matcher-fake.ts +51 -0
- package/src/infrastructure/walk.ts +127 -3
- package/src/load/extension.ts +66 -0
- package/src/load/policy.ts +77 -2
- package/src/manifest/compile.ts +81 -30
- package/src/manifest/expand.ts +183 -0
- package/src/manifest/extension.ts +41 -0
- package/src/manifest/glob.ts +5 -0
- package/src/manifest/infer.ts +643 -0
- package/src/manifest/json-schema.ts +210 -0
- package/src/manifest/manifest.ts +206 -10
- package/src/ports/file-system.ts +3 -0
- package/src/ports/language.ts +17 -0
- package/src/ports/syntax-matcher.ts +42 -0
- package/src/testing.ts +1 -0
|
@@ -0,0 +1,1019 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://dataquail.github.io/goodbones/schema/conformance.schema.json",
|
|
4
|
+
"title": "Conformance snapshot",
|
|
5
|
+
"description": "How far a repository's tree is from its architecture manifest, as `architecture conformance --json` reports it. See https://dataquail.github.io/goodbones/architecture-rules/enforcement/conformance/.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"version": {
|
|
9
|
+
"type": "number",
|
|
10
|
+
"enum": [
|
|
11
|
+
2
|
|
12
|
+
],
|
|
13
|
+
"description": "The shape of this document."
|
|
14
|
+
},
|
|
15
|
+
"manifest": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"properties": {
|
|
18
|
+
"path": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"description": "The file the policy was read from — the root file, when split with `include`."
|
|
21
|
+
},
|
|
22
|
+
"sha256": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"description": "A hash of that file's bytes, so two snapshots can say whether the policy changed between them."
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"required": [
|
|
28
|
+
"path",
|
|
29
|
+
"sha256"
|
|
30
|
+
],
|
|
31
|
+
"additionalProperties": false,
|
|
32
|
+
"description": "The policy this snapshot was taken against — the repository's own, or the one `--against` named."
|
|
33
|
+
},
|
|
34
|
+
"roots": {
|
|
35
|
+
"type": "array",
|
|
36
|
+
"items": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"description": "Repo-relative, with forward slashes."
|
|
39
|
+
},
|
|
40
|
+
"description": "The directories walked."
|
|
41
|
+
},
|
|
42
|
+
"files": {
|
|
43
|
+
"type": "number",
|
|
44
|
+
"allOf": [
|
|
45
|
+
{
|
|
46
|
+
"description": "Files walked."
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
"ok": {
|
|
51
|
+
"type": "boolean",
|
|
52
|
+
"description": "What `check` would exit with: true when no reportable violation, unresolved import, stale baseline entry or coverage shortfall exists."
|
|
53
|
+
},
|
|
54
|
+
"coverage": {
|
|
55
|
+
"type": "object",
|
|
56
|
+
"properties": {
|
|
57
|
+
"imports": {
|
|
58
|
+
"type": "object",
|
|
59
|
+
"properties": {
|
|
60
|
+
"covered": {
|
|
61
|
+
"type": "number",
|
|
62
|
+
"allOf": [
|
|
63
|
+
{
|
|
64
|
+
"description": "Files this family reaches."
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
"total": {
|
|
69
|
+
"type": "number",
|
|
70
|
+
"allOf": [
|
|
71
|
+
{
|
|
72
|
+
"description": "Files walked."
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
},
|
|
76
|
+
"floor": {
|
|
77
|
+
"type": "number",
|
|
78
|
+
"allOf": [
|
|
79
|
+
{
|
|
80
|
+
"description": "The fraction the manifest's `limits.coverage` states for this family, when it states one."
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"required": [
|
|
86
|
+
"covered",
|
|
87
|
+
"total"
|
|
88
|
+
],
|
|
89
|
+
"additionalProperties": false
|
|
90
|
+
},
|
|
91
|
+
"structure": {
|
|
92
|
+
"type": "object",
|
|
93
|
+
"properties": {
|
|
94
|
+
"covered": {
|
|
95
|
+
"type": "number",
|
|
96
|
+
"allOf": [
|
|
97
|
+
{
|
|
98
|
+
"description": "Files this family reaches."
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
"total": {
|
|
103
|
+
"type": "number",
|
|
104
|
+
"allOf": [
|
|
105
|
+
{
|
|
106
|
+
"description": "Files walked."
|
|
107
|
+
}
|
|
108
|
+
]
|
|
109
|
+
},
|
|
110
|
+
"floor": {
|
|
111
|
+
"type": "number",
|
|
112
|
+
"allOf": [
|
|
113
|
+
{
|
|
114
|
+
"description": "The fraction the manifest's `limits.coverage` states for this family, when it states one."
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
"required": [
|
|
120
|
+
"covered",
|
|
121
|
+
"total"
|
|
122
|
+
],
|
|
123
|
+
"additionalProperties": false
|
|
124
|
+
},
|
|
125
|
+
"members": {
|
|
126
|
+
"type": "object",
|
|
127
|
+
"properties": {
|
|
128
|
+
"covered": {
|
|
129
|
+
"type": "number",
|
|
130
|
+
"allOf": [
|
|
131
|
+
{
|
|
132
|
+
"description": "Files this family reaches."
|
|
133
|
+
}
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
"total": {
|
|
137
|
+
"type": "number",
|
|
138
|
+
"allOf": [
|
|
139
|
+
{
|
|
140
|
+
"description": "Files walked."
|
|
141
|
+
}
|
|
142
|
+
]
|
|
143
|
+
},
|
|
144
|
+
"floor": {
|
|
145
|
+
"type": "number",
|
|
146
|
+
"allOf": [
|
|
147
|
+
{
|
|
148
|
+
"description": "The fraction the manifest's `limits.coverage` states for this family, when it states one."
|
|
149
|
+
}
|
|
150
|
+
]
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
"required": [
|
|
154
|
+
"covered",
|
|
155
|
+
"total"
|
|
156
|
+
],
|
|
157
|
+
"additionalProperties": false
|
|
158
|
+
},
|
|
159
|
+
"surface": {
|
|
160
|
+
"type": "object",
|
|
161
|
+
"properties": {
|
|
162
|
+
"covered": {
|
|
163
|
+
"type": "number",
|
|
164
|
+
"allOf": [
|
|
165
|
+
{
|
|
166
|
+
"description": "Files this family reaches."
|
|
167
|
+
}
|
|
168
|
+
]
|
|
169
|
+
},
|
|
170
|
+
"total": {
|
|
171
|
+
"type": "number",
|
|
172
|
+
"allOf": [
|
|
173
|
+
{
|
|
174
|
+
"description": "Files walked."
|
|
175
|
+
}
|
|
176
|
+
]
|
|
177
|
+
},
|
|
178
|
+
"floor": {
|
|
179
|
+
"type": "number",
|
|
180
|
+
"allOf": [
|
|
181
|
+
{
|
|
182
|
+
"description": "The fraction the manifest's `limits.coverage` states for this family, when it states one."
|
|
183
|
+
}
|
|
184
|
+
]
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
"required": [
|
|
188
|
+
"covered",
|
|
189
|
+
"total"
|
|
190
|
+
],
|
|
191
|
+
"additionalProperties": false
|
|
192
|
+
},
|
|
193
|
+
"graph": {
|
|
194
|
+
"type": "object",
|
|
195
|
+
"properties": {
|
|
196
|
+
"covered": {
|
|
197
|
+
"type": "number",
|
|
198
|
+
"allOf": [
|
|
199
|
+
{
|
|
200
|
+
"description": "Files this family reaches."
|
|
201
|
+
}
|
|
202
|
+
]
|
|
203
|
+
},
|
|
204
|
+
"total": {
|
|
205
|
+
"type": "number",
|
|
206
|
+
"allOf": [
|
|
207
|
+
{
|
|
208
|
+
"description": "Files walked."
|
|
209
|
+
}
|
|
210
|
+
]
|
|
211
|
+
},
|
|
212
|
+
"floor": {
|
|
213
|
+
"type": "number",
|
|
214
|
+
"allOf": [
|
|
215
|
+
{
|
|
216
|
+
"description": "The fraction the manifest's `limits.coverage` states for this family, when it states one."
|
|
217
|
+
}
|
|
218
|
+
]
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
"required": [
|
|
222
|
+
"covered",
|
|
223
|
+
"total"
|
|
224
|
+
],
|
|
225
|
+
"additionalProperties": false
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
"required": [
|
|
229
|
+
"imports",
|
|
230
|
+
"structure",
|
|
231
|
+
"members",
|
|
232
|
+
"surface",
|
|
233
|
+
"graph"
|
|
234
|
+
],
|
|
235
|
+
"additionalProperties": false,
|
|
236
|
+
"description": "Per family, how many walked files it reaches. Structure counts enumerated folders only."
|
|
237
|
+
},
|
|
238
|
+
"conformance": {
|
|
239
|
+
"type": "object",
|
|
240
|
+
"properties": {
|
|
241
|
+
"residue": {
|
|
242
|
+
"type": "object",
|
|
243
|
+
"properties": {
|
|
244
|
+
"count": {
|
|
245
|
+
"type": "number",
|
|
246
|
+
"allOf": [
|
|
247
|
+
{
|
|
248
|
+
"description": "What the measure counts today."
|
|
249
|
+
}
|
|
250
|
+
]
|
|
251
|
+
},
|
|
252
|
+
"ceiling": {
|
|
253
|
+
"type": "number",
|
|
254
|
+
"allOf": [
|
|
255
|
+
{
|
|
256
|
+
"description": "The count the manifest's `limits.conformance` states for this measure, when it states one."
|
|
257
|
+
}
|
|
258
|
+
]
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
"required": [
|
|
262
|
+
"count"
|
|
263
|
+
],
|
|
264
|
+
"additionalProperties": false
|
|
265
|
+
},
|
|
266
|
+
"vacant": {
|
|
267
|
+
"type": "object",
|
|
268
|
+
"properties": {
|
|
269
|
+
"count": {
|
|
270
|
+
"type": "number",
|
|
271
|
+
"allOf": [
|
|
272
|
+
{
|
|
273
|
+
"description": "What the measure counts today."
|
|
274
|
+
}
|
|
275
|
+
]
|
|
276
|
+
},
|
|
277
|
+
"ceiling": {
|
|
278
|
+
"type": "number",
|
|
279
|
+
"allOf": [
|
|
280
|
+
{
|
|
281
|
+
"description": "The count the manifest's `limits.conformance` states for this measure, when it states one."
|
|
282
|
+
}
|
|
283
|
+
]
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
"required": [
|
|
287
|
+
"count"
|
|
288
|
+
],
|
|
289
|
+
"additionalProperties": false
|
|
290
|
+
},
|
|
291
|
+
"slack": {
|
|
292
|
+
"type": "object",
|
|
293
|
+
"properties": {
|
|
294
|
+
"count": {
|
|
295
|
+
"type": "number",
|
|
296
|
+
"allOf": [
|
|
297
|
+
{
|
|
298
|
+
"description": "What the measure counts today."
|
|
299
|
+
}
|
|
300
|
+
]
|
|
301
|
+
},
|
|
302
|
+
"ceiling": {
|
|
303
|
+
"type": "number",
|
|
304
|
+
"allOf": [
|
|
305
|
+
{
|
|
306
|
+
"description": "The count the manifest's `limits.conformance` states for this measure, when it states one."
|
|
307
|
+
}
|
|
308
|
+
]
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
"required": [
|
|
312
|
+
"count"
|
|
313
|
+
],
|
|
314
|
+
"additionalProperties": false
|
|
315
|
+
},
|
|
316
|
+
"concentration": {
|
|
317
|
+
"type": "object",
|
|
318
|
+
"properties": {
|
|
319
|
+
"count": {
|
|
320
|
+
"type": "number",
|
|
321
|
+
"allOf": [
|
|
322
|
+
{
|
|
323
|
+
"description": "What the measure counts today."
|
|
324
|
+
}
|
|
325
|
+
]
|
|
326
|
+
},
|
|
327
|
+
"ceiling": {
|
|
328
|
+
"type": "number",
|
|
329
|
+
"allOf": [
|
|
330
|
+
{
|
|
331
|
+
"description": "The count the manifest's `limits.conformance` states for this measure, when it states one."
|
|
332
|
+
}
|
|
333
|
+
]
|
|
334
|
+
}
|
|
335
|
+
},
|
|
336
|
+
"required": [
|
|
337
|
+
"count"
|
|
338
|
+
],
|
|
339
|
+
"additionalProperties": false
|
|
340
|
+
}
|
|
341
|
+
},
|
|
342
|
+
"required": [
|
|
343
|
+
"residue",
|
|
344
|
+
"vacant",
|
|
345
|
+
"slack",
|
|
346
|
+
"concentration"
|
|
347
|
+
],
|
|
348
|
+
"additionalProperties": false,
|
|
349
|
+
"description": "Per measure, the count `check` holds to the manifest's `limits.conformance`: residue files, vacant nodes, slack allowances, and fragment entries used at fewer than half the nodes granted them. The lists below name what each counts."
|
|
350
|
+
},
|
|
351
|
+
"residue": {
|
|
352
|
+
"type": "object",
|
|
353
|
+
"properties": {
|
|
354
|
+
"files": {
|
|
355
|
+
"type": "array",
|
|
356
|
+
"items": {
|
|
357
|
+
"type": "string",
|
|
358
|
+
"description": "Repo-relative, with forward slashes."
|
|
359
|
+
},
|
|
360
|
+
"description": "Files no family reaches, sorted."
|
|
361
|
+
},
|
|
362
|
+
"folders": {
|
|
363
|
+
"type": "array",
|
|
364
|
+
"items": {
|
|
365
|
+
"type": "string",
|
|
366
|
+
"description": "Repo-relative, with forward slashes."
|
|
367
|
+
},
|
|
368
|
+
"description": "Folders every walked file of which is residue, each the topmost such folder."
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
"required": [
|
|
372
|
+
"files",
|
|
373
|
+
"folders"
|
|
374
|
+
],
|
|
375
|
+
"additionalProperties": false,
|
|
376
|
+
"description": "What the policy has nothing to say about. A file in an open folder under no allowlist is claimed, not policed, and counts."
|
|
377
|
+
},
|
|
378
|
+
"vacant": {
|
|
379
|
+
"type": "array",
|
|
380
|
+
"items": {
|
|
381
|
+
"type": "object",
|
|
382
|
+
"properties": {
|
|
383
|
+
"node": {
|
|
384
|
+
"type": "string",
|
|
385
|
+
"description": "The manifest node."
|
|
386
|
+
},
|
|
387
|
+
"allowances": {
|
|
388
|
+
"type": "number",
|
|
389
|
+
"allOf": [
|
|
390
|
+
{
|
|
391
|
+
"description": "Distinct entries the node wrote, `allow` and `external` together."
|
|
392
|
+
}
|
|
393
|
+
]
|
|
394
|
+
}
|
|
395
|
+
},
|
|
396
|
+
"required": [
|
|
397
|
+
"node",
|
|
398
|
+
"allowances"
|
|
399
|
+
],
|
|
400
|
+
"additionalProperties": false
|
|
401
|
+
},
|
|
402
|
+
"description": "Nodes that state an import allowlist and select no walked file, in manifest order. Every allowance on one is unused by construction, so none is counted as slack; the node is a tier declared ahead of its first file, or a pattern that no longer matches. Residue is files no node reaches; this is nodes no file reaches."
|
|
403
|
+
},
|
|
404
|
+
"violations": {
|
|
405
|
+
"type": "array",
|
|
406
|
+
"items": {
|
|
407
|
+
"type": "object",
|
|
408
|
+
"properties": {
|
|
409
|
+
"fingerprint": {
|
|
410
|
+
"type": "string",
|
|
411
|
+
"description": "kind|rule|file|subject — line-independent, so it survives edits to the file it names; the baseline's key."
|
|
412
|
+
},
|
|
413
|
+
"kind": {
|
|
414
|
+
"type": "string",
|
|
415
|
+
"enum": [
|
|
416
|
+
"import",
|
|
417
|
+
"export",
|
|
418
|
+
"structure",
|
|
419
|
+
"member",
|
|
420
|
+
"surface",
|
|
421
|
+
"graph",
|
|
422
|
+
"campaign"
|
|
423
|
+
]
|
|
424
|
+
},
|
|
425
|
+
"ruleName": {
|
|
426
|
+
"type": "string",
|
|
427
|
+
"description": "The manifest node path the rule was lowered from."
|
|
428
|
+
},
|
|
429
|
+
"file": {
|
|
430
|
+
"type": "string",
|
|
431
|
+
"description": "Repo-relative, with forward slashes."
|
|
432
|
+
},
|
|
433
|
+
"subject": {
|
|
434
|
+
"anyOf": [
|
|
435
|
+
{
|
|
436
|
+
"type": "string"
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
"type": "null"
|
|
440
|
+
}
|
|
441
|
+
],
|
|
442
|
+
"description": "The other end of the violated relationship — the resolved target, the restricted symbol, the missing sibling — or null when the file alone is the violation."
|
|
443
|
+
},
|
|
444
|
+
"message": {
|
|
445
|
+
"type": "string"
|
|
446
|
+
},
|
|
447
|
+
"baselined": {
|
|
448
|
+
"type": "boolean",
|
|
449
|
+
"description": "Carried by the baseline, so `check` does not fail on it."
|
|
450
|
+
},
|
|
451
|
+
"ledgered": {
|
|
452
|
+
"type": "boolean",
|
|
453
|
+
"description": "For a campaign hit: carried by the objective's ledger, so `check` does not fail on it."
|
|
454
|
+
},
|
|
455
|
+
"objective": {
|
|
456
|
+
"type": "string",
|
|
457
|
+
"description": "For a campaign hit: the objective that fired."
|
|
458
|
+
},
|
|
459
|
+
"sector": {
|
|
460
|
+
"type": "string",
|
|
461
|
+
"description": "For a campaign hit: the sector the hit falls in."
|
|
462
|
+
},
|
|
463
|
+
"entry": {
|
|
464
|
+
"type": "string",
|
|
465
|
+
"description": "For a campaign hit: its ledger entry, relative to the sector's root."
|
|
466
|
+
}
|
|
467
|
+
},
|
|
468
|
+
"required": [
|
|
469
|
+
"fingerprint",
|
|
470
|
+
"kind",
|
|
471
|
+
"ruleName",
|
|
472
|
+
"file",
|
|
473
|
+
"subject",
|
|
474
|
+
"message",
|
|
475
|
+
"baselined",
|
|
476
|
+
"ledgered"
|
|
477
|
+
],
|
|
478
|
+
"additionalProperties": false
|
|
479
|
+
},
|
|
480
|
+
"description": "Every finding, baselined ones included, ordered so the ones cheapest to fix come first: by the height of the violated target in the import graph, leaves first."
|
|
481
|
+
},
|
|
482
|
+
"unresolved": {
|
|
483
|
+
"type": "array",
|
|
484
|
+
"items": {
|
|
485
|
+
"type": "object",
|
|
486
|
+
"properties": {
|
|
487
|
+
"file": {
|
|
488
|
+
"type": "string",
|
|
489
|
+
"description": "Repo-relative, with forward slashes."
|
|
490
|
+
},
|
|
491
|
+
"specifier": {
|
|
492
|
+
"type": "string"
|
|
493
|
+
},
|
|
494
|
+
"detail": {
|
|
495
|
+
"type": "string"
|
|
496
|
+
}
|
|
497
|
+
},
|
|
498
|
+
"required": [
|
|
499
|
+
"file",
|
|
500
|
+
"specifier",
|
|
501
|
+
"detail"
|
|
502
|
+
],
|
|
503
|
+
"additionalProperties": false
|
|
504
|
+
},
|
|
505
|
+
"description": "Imports the resolver could not turn into a file. Every rule about one enforces nothing."
|
|
506
|
+
},
|
|
507
|
+
"stale": {
|
|
508
|
+
"type": "array",
|
|
509
|
+
"items": {
|
|
510
|
+
"type": "string"
|
|
511
|
+
},
|
|
512
|
+
"description": "Baseline entries the code no longer produces."
|
|
513
|
+
},
|
|
514
|
+
"baseline": {
|
|
515
|
+
"type": "object",
|
|
516
|
+
"properties": {
|
|
517
|
+
"size": {
|
|
518
|
+
"type": "number",
|
|
519
|
+
"allOf": [
|
|
520
|
+
{
|
|
521
|
+
"description": "Entries in the baseline file."
|
|
522
|
+
}
|
|
523
|
+
]
|
|
524
|
+
}
|
|
525
|
+
},
|
|
526
|
+
"required": [
|
|
527
|
+
"size"
|
|
528
|
+
],
|
|
529
|
+
"additionalProperties": false,
|
|
530
|
+
"description": "The debt the policy is carrying. The ratchet: it may only shrink."
|
|
531
|
+
},
|
|
532
|
+
"cycles": {
|
|
533
|
+
"type": "number",
|
|
534
|
+
"allOf": [
|
|
535
|
+
{
|
|
536
|
+
"description": "Strongly connected components of more than one file, or a file importing itself, anywhere in the walked graph — in a cycles rule's scope or not."
|
|
537
|
+
}
|
|
538
|
+
]
|
|
539
|
+
},
|
|
540
|
+
"slack": {
|
|
541
|
+
"type": "array",
|
|
542
|
+
"items": {
|
|
543
|
+
"type": "object",
|
|
544
|
+
"properties": {
|
|
545
|
+
"node": {
|
|
546
|
+
"type": "string",
|
|
547
|
+
"description": "The manifest node that wrote the entry — or, when `fragment` is set, the `defs` fragment it was written in."
|
|
548
|
+
},
|
|
549
|
+
"kind": {
|
|
550
|
+
"type": "string",
|
|
551
|
+
"enum": [
|
|
552
|
+
"allow",
|
|
553
|
+
"external"
|
|
554
|
+
],
|
|
555
|
+
"description": "`allow` is a path glob under `imports.allow`; `external` a package name under `imports.external`."
|
|
556
|
+
},
|
|
557
|
+
"entry": {
|
|
558
|
+
"type": "string",
|
|
559
|
+
"description": "The entry as written, after alias expansion."
|
|
560
|
+
},
|
|
561
|
+
"fragment": {
|
|
562
|
+
"type": "string",
|
|
563
|
+
"description": "Present when the entry arrived through `use`. The nodes that referenced the fragment wrote one word, so the entry is reported once, against the fragment, rather than once per node."
|
|
564
|
+
},
|
|
565
|
+
"of": {
|
|
566
|
+
"type": "number",
|
|
567
|
+
"allOf": [
|
|
568
|
+
{
|
|
569
|
+
"description": "With `fragment`: how many non-vacant nodes were granted the entry through it. None of them uses it."
|
|
570
|
+
}
|
|
571
|
+
]
|
|
572
|
+
}
|
|
573
|
+
},
|
|
574
|
+
"required": [
|
|
575
|
+
"node",
|
|
576
|
+
"kind",
|
|
577
|
+
"entry"
|
|
578
|
+
],
|
|
579
|
+
"additionalProperties": false
|
|
580
|
+
},
|
|
581
|
+
"description": "Allowances no observed import uses, in manifest order, vacant nodes excluded. A manifest inferred from the tree has none on the day it is written; every entry here is permission nothing needs. An entry that arrived through `use` is reported once, against the fragment, and only when no node granted it uses it."
|
|
582
|
+
},
|
|
583
|
+
"concentration": {
|
|
584
|
+
"type": "array",
|
|
585
|
+
"items": {
|
|
586
|
+
"type": "object",
|
|
587
|
+
"properties": {
|
|
588
|
+
"fragment": {
|
|
589
|
+
"type": "string",
|
|
590
|
+
"description": "The `defs` fragment the entry was written in."
|
|
591
|
+
},
|
|
592
|
+
"kind": {
|
|
593
|
+
"type": "string",
|
|
594
|
+
"enum": [
|
|
595
|
+
"allow",
|
|
596
|
+
"external"
|
|
597
|
+
],
|
|
598
|
+
"description": "`allow` is a path glob under `imports.allow`; `external` a package name under `imports.external`."
|
|
599
|
+
},
|
|
600
|
+
"entry": {
|
|
601
|
+
"type": "string",
|
|
602
|
+
"description": "The entry as written, after alias expansion."
|
|
603
|
+
},
|
|
604
|
+
"usedAt": {
|
|
605
|
+
"type": "number",
|
|
606
|
+
"allOf": [
|
|
607
|
+
{
|
|
608
|
+
"description": "Nodes granted the entry through the fragment that use it."
|
|
609
|
+
}
|
|
610
|
+
]
|
|
611
|
+
},
|
|
612
|
+
"of": {
|
|
613
|
+
"type": "number",
|
|
614
|
+
"allOf": [
|
|
615
|
+
{
|
|
616
|
+
"description": "Non-vacant nodes granted the entry through the fragment."
|
|
617
|
+
}
|
|
618
|
+
]
|
|
619
|
+
}
|
|
620
|
+
},
|
|
621
|
+
"required": [
|
|
622
|
+
"fragment",
|
|
623
|
+
"kind",
|
|
624
|
+
"entry",
|
|
625
|
+
"usedAt",
|
|
626
|
+
"of"
|
|
627
|
+
],
|
|
628
|
+
"additionalProperties": false
|
|
629
|
+
},
|
|
630
|
+
"description": "Fragment entries used at some of the nodes granted them and not the rest. Not slack — the fragment's line is needed somewhere — but a per-file permission written as a many-node allowance, which is what an allowlist widened to make one build green looks like."
|
|
631
|
+
},
|
|
632
|
+
"adoption": {
|
|
633
|
+
"type": "object",
|
|
634
|
+
"properties": {
|
|
635
|
+
"unrestricted": {
|
|
636
|
+
"type": "array",
|
|
637
|
+
"items": {
|
|
638
|
+
"type": "string"
|
|
639
|
+
},
|
|
640
|
+
"description": "Nodes that say `unrestricted: true`."
|
|
641
|
+
},
|
|
642
|
+
"partial": {
|
|
643
|
+
"type": "array",
|
|
644
|
+
"items": {
|
|
645
|
+
"type": "string"
|
|
646
|
+
},
|
|
647
|
+
"description": "Nodes that say `partial: true`."
|
|
648
|
+
}
|
|
649
|
+
},
|
|
650
|
+
"required": [
|
|
651
|
+
"unrestricted",
|
|
652
|
+
"partial"
|
|
653
|
+
],
|
|
654
|
+
"additionalProperties": false,
|
|
655
|
+
"description": "The tiers that said \"not tightened yet\", by name; `limits` caps how many may."
|
|
656
|
+
},
|
|
657
|
+
"campaigns": {
|
|
658
|
+
"type": "array",
|
|
659
|
+
"items": {
|
|
660
|
+
"type": "object",
|
|
661
|
+
"properties": {
|
|
662
|
+
"id": {
|
|
663
|
+
"type": "string",
|
|
664
|
+
"description": "The campaign's id; its ledgers are under `<ledger>/<id>/`."
|
|
665
|
+
},
|
|
666
|
+
"title": {
|
|
667
|
+
"type": "string",
|
|
668
|
+
"description": "The campaign's title, when it states one."
|
|
669
|
+
},
|
|
670
|
+
"owner": {
|
|
671
|
+
"type": "string",
|
|
672
|
+
"description": "Who is running the campaign, as the manifest names them."
|
|
673
|
+
},
|
|
674
|
+
"count": {
|
|
675
|
+
"type": "number",
|
|
676
|
+
"allOf": [
|
|
677
|
+
{
|
|
678
|
+
"description": "Holdouts across every objective and sector."
|
|
679
|
+
}
|
|
680
|
+
]
|
|
681
|
+
},
|
|
682
|
+
"progress": {
|
|
683
|
+
"type": "number",
|
|
684
|
+
"allOf": [
|
|
685
|
+
{
|
|
686
|
+
"description": "Cleared over everything ever ledgered, across the campaign's objectives."
|
|
687
|
+
}
|
|
688
|
+
]
|
|
689
|
+
},
|
|
690
|
+
"objectives": {
|
|
691
|
+
"type": "array",
|
|
692
|
+
"items": {
|
|
693
|
+
"type": "object",
|
|
694
|
+
"properties": {
|
|
695
|
+
"id": {
|
|
696
|
+
"type": "string",
|
|
697
|
+
"description": "The objective's id; its ledger is `<ledger>/<campaign>/<objective>.json`."
|
|
698
|
+
},
|
|
699
|
+
"phase": {
|
|
700
|
+
"anyOf": [
|
|
701
|
+
{
|
|
702
|
+
"type": "string"
|
|
703
|
+
},
|
|
704
|
+
{
|
|
705
|
+
"type": "null"
|
|
706
|
+
}
|
|
707
|
+
],
|
|
708
|
+
"description": "The phase naming the objective, or `null` for one no phase names — in window everywhere."
|
|
709
|
+
},
|
|
710
|
+
"initial": {
|
|
711
|
+
"type": "number",
|
|
712
|
+
"allOf": [
|
|
713
|
+
{
|
|
714
|
+
"description": "Holdouts recorded as each sector entered the window, summed."
|
|
715
|
+
}
|
|
716
|
+
]
|
|
717
|
+
},
|
|
718
|
+
"allowed": {
|
|
719
|
+
"type": "number",
|
|
720
|
+
"allOf": [
|
|
721
|
+
{
|
|
722
|
+
"description": "Holdouts added since by `objectives concede` or a re-baseline, each with a concession."
|
|
723
|
+
}
|
|
724
|
+
]
|
|
725
|
+
},
|
|
726
|
+
"count": {
|
|
727
|
+
"type": "number",
|
|
728
|
+
"allOf": [
|
|
729
|
+
{
|
|
730
|
+
"description": "Holdouts in the ledger now, every sector summed."
|
|
731
|
+
}
|
|
732
|
+
]
|
|
733
|
+
},
|
|
734
|
+
"cleared": {
|
|
735
|
+
"type": "number",
|
|
736
|
+
"allOf": [
|
|
737
|
+
{
|
|
738
|
+
"description": "Holdouts removed by `objectives clear` because they stopped firing."
|
|
739
|
+
}
|
|
740
|
+
]
|
|
741
|
+
},
|
|
742
|
+
"closed": {
|
|
743
|
+
"type": "number",
|
|
744
|
+
"allOf": [
|
|
745
|
+
{
|
|
746
|
+
"description": "Holdouts still firing when a sector left the window — not progress."
|
|
747
|
+
}
|
|
748
|
+
]
|
|
749
|
+
},
|
|
750
|
+
"progress": {
|
|
751
|
+
"type": "number",
|
|
752
|
+
"allOf": [
|
|
753
|
+
{
|
|
754
|
+
"description": "`1 - count / (initial + allowed - closed)`: how much of everything ever ledgered has been paid down."
|
|
755
|
+
}
|
|
756
|
+
]
|
|
757
|
+
},
|
|
758
|
+
"lastCleared": {
|
|
759
|
+
"anyOf": [
|
|
760
|
+
{
|
|
761
|
+
"type": "string"
|
|
762
|
+
},
|
|
763
|
+
{
|
|
764
|
+
"type": "null"
|
|
765
|
+
}
|
|
766
|
+
],
|
|
767
|
+
"description": "When a holdout last left the ledger, ISO 8601 — the stall clock's reading; `null` with no ledger."
|
|
768
|
+
},
|
|
769
|
+
"concessions": {
|
|
770
|
+
"type": "number",
|
|
771
|
+
"allOf": [
|
|
772
|
+
{
|
|
773
|
+
"description": "How many times a count was allowed to go up."
|
|
774
|
+
}
|
|
775
|
+
]
|
|
776
|
+
},
|
|
777
|
+
"complete": {
|
|
778
|
+
"type": "boolean",
|
|
779
|
+
"description": "No holdouts remain."
|
|
780
|
+
},
|
|
781
|
+
"ledgered": {
|
|
782
|
+
"type": "boolean",
|
|
783
|
+
"description": "Whether a ledger exists. An objective with none has been declared and not yet cleared."
|
|
784
|
+
}
|
|
785
|
+
},
|
|
786
|
+
"required": [
|
|
787
|
+
"id",
|
|
788
|
+
"phase",
|
|
789
|
+
"initial",
|
|
790
|
+
"allowed",
|
|
791
|
+
"count",
|
|
792
|
+
"cleared",
|
|
793
|
+
"closed",
|
|
794
|
+
"progress",
|
|
795
|
+
"lastCleared",
|
|
796
|
+
"concessions",
|
|
797
|
+
"complete",
|
|
798
|
+
"ledgered"
|
|
799
|
+
],
|
|
800
|
+
"additionalProperties": false
|
|
801
|
+
},
|
|
802
|
+
"description": "Every objective, in manifest order."
|
|
803
|
+
},
|
|
804
|
+
"phases": {
|
|
805
|
+
"type": "array",
|
|
806
|
+
"items": {
|
|
807
|
+
"type": "object",
|
|
808
|
+
"properties": {
|
|
809
|
+
"id": {
|
|
810
|
+
"type": "string",
|
|
811
|
+
"description": "The phase's id."
|
|
812
|
+
},
|
|
813
|
+
"defined": {
|
|
814
|
+
"type": "boolean",
|
|
815
|
+
"description": "Whether the phase names criteria. An open phase has only an intent, and is last."
|
|
816
|
+
},
|
|
817
|
+
"sectors": {
|
|
818
|
+
"type": "number",
|
|
819
|
+
"allOf": [
|
|
820
|
+
{
|
|
821
|
+
"description": "How many sectors are derived to stand at this phase."
|
|
822
|
+
}
|
|
823
|
+
]
|
|
824
|
+
}
|
|
825
|
+
},
|
|
826
|
+
"required": [
|
|
827
|
+
"id",
|
|
828
|
+
"defined",
|
|
829
|
+
"sectors"
|
|
830
|
+
],
|
|
831
|
+
"additionalProperties": false
|
|
832
|
+
},
|
|
833
|
+
"description": "The ladder, in order, with how many sectors stand at each phase."
|
|
834
|
+
},
|
|
835
|
+
"sectors": {
|
|
836
|
+
"type": "array",
|
|
837
|
+
"items": {
|
|
838
|
+
"type": "object",
|
|
839
|
+
"properties": {
|
|
840
|
+
"name": {
|
|
841
|
+
"type": "string",
|
|
842
|
+
"description": "The sector's identity, as its perimeter names it."
|
|
843
|
+
},
|
|
844
|
+
"phase": {
|
|
845
|
+
"anyOf": [
|
|
846
|
+
{
|
|
847
|
+
"type": "string"
|
|
848
|
+
},
|
|
849
|
+
{
|
|
850
|
+
"type": "null"
|
|
851
|
+
}
|
|
852
|
+
],
|
|
853
|
+
"description": "The phase the sector is derived to stand at, or `null` when it is past the last one."
|
|
854
|
+
},
|
|
855
|
+
"reached": {
|
|
856
|
+
"anyOf": [
|
|
857
|
+
{
|
|
858
|
+
"type": "string"
|
|
859
|
+
},
|
|
860
|
+
{
|
|
861
|
+
"type": "null"
|
|
862
|
+
}
|
|
863
|
+
],
|
|
864
|
+
"description": "The furthest phase the sector's record says it has reached; `null` before its first `clear`."
|
|
865
|
+
},
|
|
866
|
+
"files": {
|
|
867
|
+
"type": "number",
|
|
868
|
+
"allOf": [
|
|
869
|
+
{
|
|
870
|
+
"description": "How many files the sector claims."
|
|
871
|
+
}
|
|
872
|
+
]
|
|
873
|
+
},
|
|
874
|
+
"residue": {
|
|
875
|
+
"type": "object",
|
|
876
|
+
"additionalProperties": {
|
|
877
|
+
"type": "number"
|
|
878
|
+
},
|
|
879
|
+
"description": "One dimension per objective in window for the sector: its holdouts there, never summed."
|
|
880
|
+
},
|
|
881
|
+
"stalled": {
|
|
882
|
+
"type": "boolean",
|
|
883
|
+
"description": "Holdouts remain for the sector and nothing has been cleared, attested or noted within `staleAfter`."
|
|
884
|
+
}
|
|
885
|
+
},
|
|
886
|
+
"required": [
|
|
887
|
+
"name",
|
|
888
|
+
"phase",
|
|
889
|
+
"reached",
|
|
890
|
+
"files",
|
|
891
|
+
"residue",
|
|
892
|
+
"stalled"
|
|
893
|
+
],
|
|
894
|
+
"additionalProperties": false
|
|
895
|
+
},
|
|
896
|
+
"description": "Every sector the perimeter births, by name."
|
|
897
|
+
},
|
|
898
|
+
"legacy": {
|
|
899
|
+
"type": "object",
|
|
900
|
+
"properties": {
|
|
901
|
+
"files": {
|
|
902
|
+
"type": "number",
|
|
903
|
+
"allOf": [
|
|
904
|
+
{
|
|
905
|
+
"description": "Files in the scope no sector claims."
|
|
906
|
+
}
|
|
907
|
+
]
|
|
908
|
+
},
|
|
909
|
+
"holdouts": {
|
|
910
|
+
"type": "number",
|
|
911
|
+
"allOf": [
|
|
912
|
+
{
|
|
913
|
+
"description": "Holdouts in the legacy, under the first phase's objectives — where a holdout moved out of a sector lands."
|
|
914
|
+
}
|
|
915
|
+
]
|
|
916
|
+
}
|
|
917
|
+
},
|
|
918
|
+
"required": [
|
|
919
|
+
"files",
|
|
920
|
+
"holdouts"
|
|
921
|
+
],
|
|
922
|
+
"additionalProperties": false,
|
|
923
|
+
"description": "The unclaimed remainder of the scope, which stands at the first phase and is not a sink."
|
|
924
|
+
},
|
|
925
|
+
"plan": {
|
|
926
|
+
"type": "object",
|
|
927
|
+
"properties": {
|
|
928
|
+
"refined": {
|
|
929
|
+
"type": "array",
|
|
930
|
+
"items": {
|
|
931
|
+
"type": "string"
|
|
932
|
+
},
|
|
933
|
+
"description": "Phases refined since the last `clear`: an open phase that gained criteria, or a new one. Free."
|
|
934
|
+
},
|
|
935
|
+
"changed": {
|
|
936
|
+
"type": "array",
|
|
937
|
+
"items": {
|
|
938
|
+
"type": "string"
|
|
939
|
+
},
|
|
940
|
+
"description": "Defined phases whose definition changed since the last `clear` — what a reviewer reads every time."
|
|
941
|
+
},
|
|
942
|
+
"unreceipted": {
|
|
943
|
+
"type": "array",
|
|
944
|
+
"items": {
|
|
945
|
+
"type": "string"
|
|
946
|
+
},
|
|
947
|
+
"description": "Changed phases carrying no new concession; `check` fails on them."
|
|
948
|
+
}
|
|
949
|
+
},
|
|
950
|
+
"required": [
|
|
951
|
+
"refined",
|
|
952
|
+
"changed",
|
|
953
|
+
"unreceipted"
|
|
954
|
+
],
|
|
955
|
+
"additionalProperties": false,
|
|
956
|
+
"description": "What changed in the plan, refinements and changes apart."
|
|
957
|
+
},
|
|
958
|
+
"stalled": {
|
|
959
|
+
"type": "boolean",
|
|
960
|
+
"description": "Holdouts remain and nothing has been cleared, attested or noted within the campaign's `staleAfter`."
|
|
961
|
+
},
|
|
962
|
+
"complete": {
|
|
963
|
+
"type": "boolean",
|
|
964
|
+
"description": "No holdouts remain in any objective."
|
|
965
|
+
},
|
|
966
|
+
"onComplete": {
|
|
967
|
+
"type": "string",
|
|
968
|
+
"enum": [
|
|
969
|
+
"keep",
|
|
970
|
+
"remove"
|
|
971
|
+
],
|
|
972
|
+
"description": "What the manifest asks once complete: keep the campaign as a guard, or remove it."
|
|
973
|
+
},
|
|
974
|
+
"ledgered": {
|
|
975
|
+
"type": "boolean",
|
|
976
|
+
"description": "Whether every objective has a ledger."
|
|
977
|
+
}
|
|
978
|
+
},
|
|
979
|
+
"required": [
|
|
980
|
+
"id",
|
|
981
|
+
"count",
|
|
982
|
+
"progress",
|
|
983
|
+
"objectives",
|
|
984
|
+
"phases",
|
|
985
|
+
"sectors",
|
|
986
|
+
"legacy",
|
|
987
|
+
"plan",
|
|
988
|
+
"stalled",
|
|
989
|
+
"complete",
|
|
990
|
+
"onComplete",
|
|
991
|
+
"ledgered"
|
|
992
|
+
],
|
|
993
|
+
"additionalProperties": false
|
|
994
|
+
},
|
|
995
|
+
"description": "Every campaign the manifest declares, in manifest order, with its burn-down. Campaign hits are not counted in `coverage` or `residue`: a campaign is scoped by construction."
|
|
996
|
+
}
|
|
997
|
+
},
|
|
998
|
+
"required": [
|
|
999
|
+
"version",
|
|
1000
|
+
"manifest",
|
|
1001
|
+
"roots",
|
|
1002
|
+
"files",
|
|
1003
|
+
"ok",
|
|
1004
|
+
"coverage",
|
|
1005
|
+
"conformance",
|
|
1006
|
+
"residue",
|
|
1007
|
+
"vacant",
|
|
1008
|
+
"violations",
|
|
1009
|
+
"unresolved",
|
|
1010
|
+
"stale",
|
|
1011
|
+
"baseline",
|
|
1012
|
+
"cycles",
|
|
1013
|
+
"slack",
|
|
1014
|
+
"concentration",
|
|
1015
|
+
"adoption",
|
|
1016
|
+
"campaigns"
|
|
1017
|
+
],
|
|
1018
|
+
"additionalProperties": false
|
|
1019
|
+
}
|