@goodbones/core 0.1.0-beta.12 → 0.1.0-beta.13
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/bound.d.ts +11 -0
- package/build/dts/core/bound.d.ts.map +1 -0
- package/build/dts/core/coverage.d.ts.map +1 -1
- package/build/dts/domain/snapshot.d.ts +28 -0
- package/build/dts/domain/snapshot.d.ts.map +1 -1
- package/build/dts/index.d.ts +1 -0
- package/build/dts/index.d.ts.map +1 -1
- package/build/esm/core/bound.js +17 -0
- package/build/esm/core/bound.js.map +1 -0
- package/build/esm/core/coverage.js +4 -1
- package/build/esm/core/coverage.js.map +1 -1
- package/build/esm/domain/snapshot.js +10 -3
- package/build/esm/domain/snapshot.js.map +1 -1
- package/build/esm/index.js +1 -0
- package/build/esm/index.js.map +1 -1
- package/package.json +1 -1
- package/schema/architecture.schema.json +707 -3
- package/schema/conformance.schema.json +60 -3
- package/src/core/bound.ts +33 -0
- package/src/core/coverage.ts +3 -1
- package/src/domain/snapshot.ts +30 -3
- package/src/index.ts +8 -0
|
@@ -776,11 +776,68 @@
|
|
|
776
776
|
},
|
|
777
777
|
"complete": {
|
|
778
778
|
"type": "boolean",
|
|
779
|
-
"description": "No holdouts remain."
|
|
779
|
+
"description": "No holdouts remain; for a scalar objective, every sector is at its target."
|
|
780
780
|
},
|
|
781
781
|
"ledgered": {
|
|
782
782
|
"type": "boolean",
|
|
783
783
|
"description": "Whether a ledger exists. An objective with none has been declared and not yet cleared."
|
|
784
|
+
},
|
|
785
|
+
"measure": {
|
|
786
|
+
"type": "object",
|
|
787
|
+
"properties": {
|
|
788
|
+
"direction": {
|
|
789
|
+
"type": "string",
|
|
790
|
+
"enum": [
|
|
791
|
+
"down",
|
|
792
|
+
"up"
|
|
793
|
+
],
|
|
794
|
+
"description": "Which way is better."
|
|
795
|
+
},
|
|
796
|
+
"value": {
|
|
797
|
+
"type": "number",
|
|
798
|
+
"allOf": [
|
|
799
|
+
{
|
|
800
|
+
"description": "The number measured now, every sector in window summed."
|
|
801
|
+
}
|
|
802
|
+
]
|
|
803
|
+
},
|
|
804
|
+
"recorded": {
|
|
805
|
+
"type": "number",
|
|
806
|
+
"allOf": [
|
|
807
|
+
{
|
|
808
|
+
"description": "The number the ledger holds the sectors to, summed: the best `objectives clear` has written, plus conceded rises."
|
|
809
|
+
}
|
|
810
|
+
]
|
|
811
|
+
},
|
|
812
|
+
"target": {
|
|
813
|
+
"anyOf": [
|
|
814
|
+
{
|
|
815
|
+
"type": "number"
|
|
816
|
+
},
|
|
817
|
+
{
|
|
818
|
+
"type": "null"
|
|
819
|
+
}
|
|
820
|
+
],
|
|
821
|
+
"description": "The value at which the objective is met, or `null` for a standing measure that only ratchets."
|
|
822
|
+
},
|
|
823
|
+
"tolerance": {
|
|
824
|
+
"type": "number",
|
|
825
|
+
"allOf": [
|
|
826
|
+
{
|
|
827
|
+
"description": "How far either side of the record still counts as at it."
|
|
828
|
+
}
|
|
829
|
+
]
|
|
830
|
+
}
|
|
831
|
+
},
|
|
832
|
+
"required": [
|
|
833
|
+
"direction",
|
|
834
|
+
"value",
|
|
835
|
+
"recorded",
|
|
836
|
+
"target",
|
|
837
|
+
"tolerance"
|
|
838
|
+
],
|
|
839
|
+
"additionalProperties": false,
|
|
840
|
+
"description": "For a scalar objective: the number, where the holdout counts above are all 0."
|
|
784
841
|
}
|
|
785
842
|
},
|
|
786
843
|
"required": [
|
|
@@ -876,7 +933,7 @@
|
|
|
876
933
|
"additionalProperties": {
|
|
877
934
|
"type": "number"
|
|
878
935
|
},
|
|
879
|
-
"description": "One dimension per objective in window for the sector: its holdouts there, never summed."
|
|
936
|
+
"description": "One dimension per objective in window for the sector: its holdouts there, or a scalar's distance to its target, never summed."
|
|
880
937
|
},
|
|
881
938
|
"stalled": {
|
|
882
939
|
"type": "boolean",
|
|
@@ -961,7 +1018,7 @@
|
|
|
961
1018
|
},
|
|
962
1019
|
"complete": {
|
|
963
1020
|
"type": "boolean",
|
|
964
|
-
"description": "No holdouts remain in any objective."
|
|
1021
|
+
"description": "No holdouts remain in any objective, and every scalar with a target has reached it."
|
|
965
1022
|
},
|
|
966
1023
|
"onComplete": {
|
|
967
1024
|
"type": "string",
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// A number held to a limit from one side: a coverage floor (`up`, the value
|
|
2
|
+
// may not fall under it), a conformance ceiling (`down`, it may not rise over
|
|
3
|
+
// it), or a campaign's scalar objective, whose limit is the value its ledger
|
|
4
|
+
// last recorded. One comparison for all three, so "coverage ≥ N" has one
|
|
5
|
+
// meaning whether the manifest owns the number or a ledger does.
|
|
6
|
+
|
|
7
|
+
export type BoundDirection = "down" | "up";
|
|
8
|
+
|
|
9
|
+
export type Bound = {
|
|
10
|
+
// Which way is better: `down` for a ceiling, `up` for a floor.
|
|
11
|
+
readonly direction: BoundDirection;
|
|
12
|
+
readonly limit: number;
|
|
13
|
+
// How far past the limit, either way, still counts as at it.
|
|
14
|
+
readonly tolerance: number;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// `breached`: worse than the limit by more than the tolerance. `surpassed`:
|
|
18
|
+
// better by more than it. `within`: neither.
|
|
19
|
+
export type Standing = "within" | "breached" | "surpassed";
|
|
20
|
+
|
|
21
|
+
// How much worse than the limit the value is — negative when better.
|
|
22
|
+
export const shortfallOf = (bound: Bound, value: number): number =>
|
|
23
|
+
bound.direction === "down" ? value - bound.limit : bound.limit - value;
|
|
24
|
+
|
|
25
|
+
export const standingOf = (bound: Bound, value: number): Standing => {
|
|
26
|
+
const worse = shortfallOf(bound, value);
|
|
27
|
+
if (worse > bound.tolerance) return "breached";
|
|
28
|
+
if (-worse > bound.tolerance) return "surpassed";
|
|
29
|
+
return "within";
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const breaches = (bound: Bound, value: number): boolean =>
|
|
33
|
+
standingOf(bound, value) === "breached";
|
package/src/core/coverage.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { OPEN_LAYOUT } from "../domain/architecture-config.js";
|
|
2
|
+
import { breaches } from "./bound.js";
|
|
2
3
|
import type { CompiledGraph } from "./graph.js";
|
|
3
4
|
import type { CompiledImportRule } from "./imports.js";
|
|
4
5
|
import type { CompiledMemberRule } from "./members.js";
|
|
@@ -278,7 +279,8 @@ export const coverageShortfalls = (
|
|
|
278
279
|
];
|
|
279
280
|
return families.flatMap((family) => {
|
|
280
281
|
const floor = floors[family];
|
|
281
|
-
if (floor === undefined
|
|
282
|
+
if (floor === undefined) return [];
|
|
283
|
+
if (!breaches({ direction: "up", limit: floor, tolerance: 0 }, actual[family])) return [];
|
|
282
284
|
return [{ family, actual: actual[family], floor }];
|
|
283
285
|
});
|
|
284
286
|
};
|
package/src/domain/snapshot.ts
CHANGED
|
@@ -172,11 +172,35 @@ export const SnapshotObjective = Schema.Struct({
|
|
|
172
172
|
"When a holdout last left the ledger, ISO 8601 — the stall clock's reading; `null` with no ledger.",
|
|
173
173
|
),
|
|
174
174
|
concessions: describe(Schema.Finite, "How many times a count was allowed to go up."),
|
|
175
|
-
complete: describe(
|
|
175
|
+
complete: describe(
|
|
176
|
+
Schema.Boolean,
|
|
177
|
+
"No holdouts remain; for a scalar objective, every sector is at its target.",
|
|
178
|
+
),
|
|
176
179
|
ledgered: describe(
|
|
177
180
|
Schema.Boolean,
|
|
178
181
|
"Whether a ledger exists. An objective with none has been declared and not yet cleared.",
|
|
179
182
|
),
|
|
183
|
+
measure: Schema.optionalKey(
|
|
184
|
+
describe(
|
|
185
|
+
Schema.Struct({
|
|
186
|
+
direction: describe(Schema.Literals(["down", "up"]), "Which way is better."),
|
|
187
|
+
value: describe(Schema.Finite, "The number measured now, every sector in window summed."),
|
|
188
|
+
recorded: describe(
|
|
189
|
+
Schema.Finite,
|
|
190
|
+
"The number the ledger holds the sectors to, summed: the best `objectives clear` has written, plus conceded rises.",
|
|
191
|
+
),
|
|
192
|
+
target: describe(
|
|
193
|
+
Schema.NullOr(Schema.Finite),
|
|
194
|
+
"The value at which the objective is met, or `null` for a standing measure that only ratchets.",
|
|
195
|
+
),
|
|
196
|
+
tolerance: describe(
|
|
197
|
+
Schema.Finite,
|
|
198
|
+
"How far either side of the record still counts as at it.",
|
|
199
|
+
),
|
|
200
|
+
}),
|
|
201
|
+
"For a scalar objective: the number, where the holdout counts above are all 0.",
|
|
202
|
+
),
|
|
203
|
+
),
|
|
180
204
|
});
|
|
181
205
|
|
|
182
206
|
// One phase of the ladder, and how many sectors stand at it.
|
|
@@ -203,7 +227,7 @@ export const SnapshotSector = Schema.Struct({
|
|
|
203
227
|
files: describe(Schema.Finite, "How many files the sector claims."),
|
|
204
228
|
residue: describe(
|
|
205
229
|
Schema.Record(Schema.String, Schema.Finite),
|
|
206
|
-
"One dimension per objective in window for the sector: its holdouts there, never summed.",
|
|
230
|
+
"One dimension per objective in window for the sector: its holdouts there, or a scalar's distance to its target, never summed.",
|
|
207
231
|
),
|
|
208
232
|
stalled: describe(
|
|
209
233
|
Schema.Boolean,
|
|
@@ -261,7 +285,10 @@ export const SnapshotCampaign = Schema.Struct({
|
|
|
261
285
|
Schema.Boolean,
|
|
262
286
|
"Holdouts remain and nothing has been cleared, attested or noted within the campaign's `staleAfter`.",
|
|
263
287
|
),
|
|
264
|
-
complete: describe(
|
|
288
|
+
complete: describe(
|
|
289
|
+
Schema.Boolean,
|
|
290
|
+
"No holdouts remain in any objective, and every scalar with a target has reached it.",
|
|
291
|
+
),
|
|
265
292
|
onComplete: describe(
|
|
266
293
|
Schema.Literals(["keep", "remove"]),
|
|
267
294
|
"What the manifest asks once complete: keep the campaign as a guard, or remove it.",
|
package/src/index.ts
CHANGED
|
@@ -23,6 +23,14 @@ export {
|
|
|
23
23
|
staleEntriesOf,
|
|
24
24
|
unbaselined,
|
|
25
25
|
} from "./core/baseline.js";
|
|
26
|
+
export {
|
|
27
|
+
type Bound,
|
|
28
|
+
type BoundDirection,
|
|
29
|
+
breaches,
|
|
30
|
+
shortfallOf,
|
|
31
|
+
type Standing,
|
|
32
|
+
standingOf,
|
|
33
|
+
} from "./core/bound.js";
|
|
26
34
|
export {
|
|
27
35
|
type Coverage,
|
|
28
36
|
type CoverageFamily,
|