@voltro/plan 0.85.0 → 0.87.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.
@@ -1,6 +1,6 @@
1
1
  # Third-Party Notices — @voltro/plan
2
2
 
3
- This package depends on the open-source software listed below. Each is the
3
+ This package uses the open-source software listed below. Each is the
4
4
  property of its respective copyright holders and is used under the terms of
5
5
  its license. This file is provided for attribution; it grants no rights in
6
6
  @voltro/plan itself, which is proprietary (see LICENSE).
@@ -0,0 +1,118 @@
1
+ //#region src/canonical.ts
2
+ var e = (e) => JSON.stringify(t(e)), t = (e) => {
3
+ if (Array.isArray(e)) return e.map(t);
4
+ if (typeof e == "object" && e) {
5
+ let n = {};
6
+ for (let r of Object.keys(e).sort()) {
7
+ let i = e[r];
8
+ i !== void 0 && (n[r] = t(i));
9
+ }
10
+ return n;
11
+ }
12
+ return e;
13
+ }, n = new Uint32Array([
14
+ 1116352408,
15
+ 1899447441,
16
+ 3049323471,
17
+ 3921009573,
18
+ 961987163,
19
+ 1508970993,
20
+ 2453635748,
21
+ 2870763221,
22
+ 3624381080,
23
+ 310598401,
24
+ 607225278,
25
+ 1426881987,
26
+ 1925078388,
27
+ 2162078206,
28
+ 2614888103,
29
+ 3248222580,
30
+ 3835390401,
31
+ 4022224774,
32
+ 264347078,
33
+ 604807628,
34
+ 770255983,
35
+ 1249150122,
36
+ 1555081692,
37
+ 1996064986,
38
+ 2554220882,
39
+ 2821834349,
40
+ 2952996808,
41
+ 3210313671,
42
+ 3336571891,
43
+ 3584528711,
44
+ 113926993,
45
+ 338241895,
46
+ 666307205,
47
+ 773529912,
48
+ 1294757372,
49
+ 1396182291,
50
+ 1695183700,
51
+ 1986661051,
52
+ 2177026350,
53
+ 2456956037,
54
+ 2730485921,
55
+ 2820302411,
56
+ 3259730800,
57
+ 3345764771,
58
+ 3516065817,
59
+ 3600352804,
60
+ 4094571909,
61
+ 275423344,
62
+ 430227734,
63
+ 506948616,
64
+ 659060556,
65
+ 883997877,
66
+ 958139571,
67
+ 1322822218,
68
+ 1537002063,
69
+ 1747873779,
70
+ 1955562222,
71
+ 2024104815,
72
+ 2227730452,
73
+ 2361852424,
74
+ 2428436474,
75
+ 2756734187,
76
+ 3204031479,
77
+ 3329325298
78
+ ]), r = (e) => {
79
+ let t = new TextEncoder().encode(e), r = t.length * 8, i = new Uint8Array(t.length + 9 + 63 >> 6 << 6);
80
+ i.set(t), i[t.length] = 128;
81
+ let a = new DataView(i.buffer);
82
+ a.setUint32(i.length - 8, Math.floor(r / 4294967296)), a.setUint32(i.length - 4, r >>> 0);
83
+ let o = new Uint32Array([
84
+ 1779033703,
85
+ 3144134277,
86
+ 1013904242,
87
+ 2773480762,
88
+ 1359893119,
89
+ 2600822924,
90
+ 528734635,
91
+ 1541459225
92
+ ]), s = /* @__PURE__ */ new Uint32Array(64), c = (e, t) => e >>> t | e << 32 - t;
93
+ for (let e = 0; e < i.length; e += 64) {
94
+ for (let t = 0; t < 16; t++) s[t] = a.getUint32(e + t * 4);
95
+ for (let e = 16; e < 64; e++) {
96
+ let t = c(s[e - 15], 7) ^ c(s[e - 15], 18) ^ s[e - 15] >>> 3, n = c(s[e - 2], 17) ^ c(s[e - 2], 19) ^ s[e - 2] >>> 10;
97
+ s[e] = s[e - 16] + t + s[e - 7] + n >>> 0;
98
+ }
99
+ let [t, r, i, l, u, d, f, p] = [
100
+ o[0],
101
+ o[1],
102
+ o[2],
103
+ o[3],
104
+ o[4],
105
+ o[5],
106
+ o[6],
107
+ o[7]
108
+ ];
109
+ for (let e = 0; e < 64; e++) {
110
+ let a = p + (c(u, 6) ^ c(u, 11) ^ c(u, 25)) + (u & d ^ ~u & f) + n[e] + s[e] >>> 0, o = (c(t, 2) ^ c(t, 13) ^ c(t, 22)) + (t & r ^ t & i ^ r & i) >>> 0;
111
+ p = f, f = d, d = u, u = l + a >>> 0, l = i, i = r, r = t, t = a + o >>> 0;
112
+ }
113
+ o[0] = o[0] + t >>> 0, o[1] = o[1] + r >>> 0, o[2] = o[2] + i >>> 0, o[3] = o[3] + l >>> 0, o[4] = o[4] + u >>> 0, o[5] = o[5] + d >>> 0, o[6] = o[6] + f >>> 0, o[7] = o[7] + p >>> 0;
114
+ }
115
+ return [...o].map((e) => e.toString(16).padStart(8, "0")).join("");
116
+ }, i = (t) => `sha256:${r(e(t))}`;
117
+ //#endregion
118
+ export { e as canonicalJson, i as fingerprint, r as sha256Hex };
@@ -0,0 +1,116 @@
1
+ import { fingerprint as e } from "./canonical.js";
2
+ import { Schema as t } from "effect";
3
+ //#region src/closure.ts
4
+ var n = "voltro-plan-closure/v1", r = t.String.pipe(t.check(t.isMinLength(1))), i = t.String.pipe(t.check(t.isPattern(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:\d{2})$/))), a = t.String.pipe(t.check(t.isPattern(/^sha256:[a-f0-9]{64}$/))), o = (e) => {
5
+ let o = e.grammar, s = (e) => t.String.pipe(t.check(t.isPattern(e))), c = t.Struct({
6
+ id: s(o.closureRun),
7
+ pass: t.Literals(["contract", "adversarial"]),
8
+ reviewer: r,
9
+ reviewContext: r,
10
+ planRevision: a,
11
+ completedAt: i,
12
+ findingRefs: t.Array(s(o.finding)),
13
+ result: t.Literals(["passed", "findings"]),
14
+ toolVersion: r
15
+ }), l = t.Struct({
16
+ id: s(o.certificate),
17
+ plan: s(o.plan),
18
+ planRevision: a,
19
+ workItems: t.Array(s(o.workItem)),
20
+ evidenceRefs: t.Array(s(o.evidence)),
21
+ closureRuns: t.Array(s(o.closureRun)).pipe(t.check(t.isBetweenLength(2, 2))),
22
+ confirmedBy: r,
23
+ issuedAt: i,
24
+ toolVersion: r
25
+ });
26
+ return t.Struct({
27
+ schemaVersion: t.Literal(n),
28
+ plan: s(o.plan),
29
+ runs: t.Array(c),
30
+ certificates: t.Array(l)
31
+ });
32
+ }, s = (t, n, r, i = () => void 0, a = /* @__PURE__ */ new Map()) => {
33
+ let o = new Set(t.workItems.map((e) => e.id)), s = [...new Set(t.workItems.flatMap((e) => e.dependsOn).filter((e) => !o.has(e)))].sort();
34
+ return e({
35
+ instance: t,
36
+ dependencies: s.map((e) => {
37
+ let t = i(e);
38
+ return [e, t === "closed" ? "verified" : t ?? "missing"];
39
+ }),
40
+ decisions: [...new Set(t.workItems.flatMap((e) => e.links.adrs))].sort().map((e) => [e, a.get(e) ?? null]),
41
+ evidence: n.filter((e) => e.subjectRefs.some((e) => o.has(e))).map((e) => e.id).sort(),
42
+ findings: r.filter((e) => e.targetWorkItems.some((e) => o.has(e))).map((e) => [e.id, e.status]).sort()
43
+ });
44
+ }, c = (e, t) => {
45
+ if (e === void 0) return { state: "open" };
46
+ let n = new Map(e.runs.map((e) => [e.id, e])), r = [...e.certificates].reverse().find((e) => e.planRevision === t && e.closureRuns.every((e) => n.get(e)?.result === "passed" && n.get(e)?.planRevision === t));
47
+ if (r !== void 0) return {
48
+ state: "certified",
49
+ certificate: r
50
+ };
51
+ let i = [...e.runs].reverse().find((e) => e.pass === "contract" && e.result === "passed" && e.planRevision === t);
52
+ return i === void 0 ? { state: "open" } : {
53
+ state: "closure-1",
54
+ run: i
55
+ };
56
+ }, l = (e, t, n, r) => ({
57
+ outcome: "refused",
58
+ diagnostic: {
59
+ ruleId: e,
60
+ severity: "error",
61
+ message: t,
62
+ locator: { plan: r },
63
+ related: [],
64
+ nextAction: n
65
+ }
66
+ }), u = (e, t) => `${e}${String(Math.max(0, ...t.filter((t) => t.startsWith(e)).map((t) => Number(t.slice(e.length)))) + 1).padStart(3, "0")}`, d = (e, t, r, i, a, o, s, c) => {
67
+ let d = t.plan.id, f = t.workItems.filter((e) => e.mandatory && e.supersededBy === void 0), p = f.filter((e) => a(e.id) !== "verified" && a(e.id) !== "closed");
68
+ if (c.findings.length === 0 && p.length > 0) return l("closure/unverified-items", `${p.length} of ${f.length} mandatory items of ${d} are not verified (${p.slice(0, 3).map((e) => e.id).join(", ")}${p.length > 3 ? ", …" : ""})`, "Verify every mandatory item first: voltro plan status, voltro plan evidence add.", d);
69
+ let m = new Set(t.workItems.map((e) => e.id)), h = s.filter((e) => e.status === "open" && e.targetWorkItems.some((e) => m.has(e)));
70
+ for (let e of c.findings) if (!h.some((t) => t.id === e)) return l("closure/unknown-finding", `${e} is not an open finding against ${d}`, "Record the finding first, against the items it concerns.", d);
71
+ if (c.findings.length === 0 && h.length > 0) return l("closure/open-findings", `${h.length} finding(s) against ${d} are open (${h.map((e) => e.id).slice(0, 3).join(", ")})`, "Resolve them or accept the risk; then close again.", d);
72
+ let g = r?.runs ?? [];
73
+ if (c.pass === "adversarial" && c.findings.length === 0) {
74
+ let e = [...g].reverse().find((e) => e.pass === "contract" && e.result === "passed" && e.planRevision === i);
75
+ if (e === void 0) return l("closure/order", `${d} has no passed contract pass on its current revision`, "Run the contract pass first: voltro plan close <plan> --pass contract.", d);
76
+ if (e.reviewer === c.reviewer || e.reviewContext === c.reviewContext) return l("closure/same-context", `the adversarial pass needs another reviewer and another context than ${e.id} (${e.reviewer}, ${e.reviewContext})`, "Have someone else audit it, in their own context.", d);
77
+ }
78
+ let _ = t.plan.number, v = {
79
+ id: u(`CLR-${e.prefix}-${_}-`, g.map((e) => e.id)),
80
+ pass: c.pass,
81
+ reviewer: c.reviewer,
82
+ reviewContext: c.reviewContext,
83
+ planRevision: i,
84
+ completedAt: c.at,
85
+ findingRefs: [...c.findings].sort(),
86
+ result: c.findings.length === 0 ? "passed" : "findings",
87
+ toolVersion: c.toolVersion
88
+ }, y = null;
89
+ if (c.pass === "adversarial" && v.result === "passed") {
90
+ let t = [...g].reverse().find((e) => e.pass === "contract" && e.result === "passed" && e.planRevision === i);
91
+ y = {
92
+ id: u(`CRT-${e.prefix}-${_}-`, (r?.certificates ?? []).map((e) => e.id)),
93
+ plan: d,
94
+ planRevision: i,
95
+ workItems: f.map((e) => e.id).sort(),
96
+ evidenceRefs: o.filter((e) => e.subjectRefs.some((e) => m.has(e))).map((e) => e.id).sort(),
97
+ closureRuns: [t.id, v.id],
98
+ confirmedBy: c.reviewer,
99
+ issuedAt: c.at,
100
+ toolVersion: c.toolVersion
101
+ };
102
+ }
103
+ return {
104
+ outcome: "recorded",
105
+ file: {
106
+ schemaVersion: n,
107
+ plan: d,
108
+ runs: [...g, v],
109
+ certificates: [...r?.certificates ?? [], ...y === null ? [] : [y]]
110
+ },
111
+ run: v,
112
+ certificate: y
113
+ };
114
+ };
115
+ //#endregion
116
+ export { n as CLOSURE_SCHEMA_VERSION, o as closureFileSchema, c as closureState, d as decideClosure, s as planRevision };
@@ -0,0 +1,8 @@
1
+ //#region src/diagnostics.ts
2
+ var e = {
3
+ security: 0,
4
+ error: 1,
5
+ warning: 2
6
+ }, t = (e, t) => (e ?? "") < (t ?? "") ? -1 : +((e ?? "") > (t ?? "")), n = (n) => [...n].sort((n, r) => e[n.severity] - e[r.severity] || t(n.locator.plan, r.locator.plan) || t(n.locator.workItem, r.locator.workItem) || t(n.ruleId, r.ruleId) || t(n.locator.file, r.locator.file) || t(n.locator.path, r.locator.path) || t(n.message, r.message)), r = (e, t = !1) => e.some((e) => e.severity !== "warning" || t);
7
+ //#endregion
8
+ export { r as blocks, n as sortDiagnostics };
@@ -0,0 +1,16 @@
1
+ //#region src/envelope.ts
2
+ var e = "voltro-plan-command/v1", t = (t) => ({
3
+ schemaVersion: e,
4
+ ...t
5
+ }), n = {
6
+ ok: 0,
7
+ failed: 1,
8
+ usage: 2,
9
+ input: 3,
10
+ conflict: 4,
11
+ provider: 5,
12
+ security: 6,
13
+ internal: 70
14
+ };
15
+ //#endregion
16
+ export { e as COMMAND_SCHEMA_VERSION, n as EXIT, t as envelope };
@@ -0,0 +1,82 @@
1
+ import { canonicalJson as e } from "./canonical.js";
2
+ import { EVIDENCE_KINDS as t } from "./schema.js";
3
+ import { EXIT as n } from "./envelope.js";
4
+ //#region src/evidence.ts
5
+ var r = (e, t, n, r, i, a) => ({
6
+ outcome: "refused",
7
+ exit: a,
8
+ diagnostic: {
9
+ ruleId: e,
10
+ severity: t,
11
+ message: n,
12
+ locator: { workItem: i },
13
+ related: [],
14
+ nextAction: r
15
+ }
16
+ }), i = [
17
+ /-----BEGIN [A-Z ]*PRIVATE KEY-----/,
18
+ /\b[sr]k_(live|test)_[A-Za-z0-9]{16,}/,
19
+ /\bgh[pousr]_[A-Za-z0-9]{30,}/,
20
+ /\bAKIA[0-9A-Z]{16}\b/,
21
+ /\bxox[abprs]-[A-Za-z0-9-]{10,}/,
22
+ /\bBearer\s+[A-Za-z0-9._~+/-]{20,}/
23
+ ], a = (a, o, s) => {
24
+ let c = a.items.get(s.workItem)?.item;
25
+ if (c === void 0) return r("evidence/unknown-target", "error", `${s.workItem} is not a work item of this program`, "Name an existing work item.", s.workItem, n.failed);
26
+ if ([
27
+ s.title,
28
+ s.uri,
29
+ s.producedBy,
30
+ s.command ?? "",
31
+ s.environment ?? ""
32
+ ].some((e) => i.some((t) => t.test(e))) || /^[a-z][a-z0-9+.-]*:\/\/[^/@\s]*:[^/@\s]*@/i.test(s.uri)) return r("security/secret", "security", "the evidence carries a secret or a credential", "Remove it; reference where the result is kept, never a key.", c.id, n.security);
33
+ if (!t.includes(s.kind)) return r("evidence/kind", "error", `"${s.kind}" is not an evidence kind`, `Use one of: ${t.join(", ")}.`, c.id, n.usage);
34
+ if (/^http:\/\//i.test(s.uri)) return r("evidence/uri", "error", `${s.uri} is not https`, "Reference evidence over https, git: or a project-relative path.", c.id, n.failed);
35
+ if (s.uri.startsWith("/") || /^[A-Za-z]:[\\/]/.test(s.uri) || s.uri.split("/").includes("..")) return r("evidence/uri", "error", `${s.uri} is not portable`, "Use a path relative to the project root, or a URL.", c.id, n.failed);
36
+ let l = [c.id];
37
+ for (let e of s.proves) {
38
+ let t = /^[AE][0-9]{2}$/.test(e) ? `${c.id}-${e}` : e, i = c.acceptance.find((e) => e.id === t), a = c.evidenceRequirements.find((e) => e.id === t);
39
+ if (i === void 0 && a === void 0) return r("evidence/unknown-target", "error", `${t} is not a check or requirement of ${c.id}`, `Name one of ${[...c.acceptance, ...c.evidenceRequirements].map((e) => e.id).join(", ")}.`, c.id, n.failed);
40
+ if (a !== void 0 && !a.kinds.includes(s.kind)) return r("evidence/wrong-kind", "error", `${a.id} asks for ${a.kinds.join("/")}, not ${s.kind}`, "Add evidence of a kind the requirement names.", c.id, n.failed);
41
+ l.push(t);
42
+ }
43
+ let u = {
44
+ kind: s.kind,
45
+ title: s.title,
46
+ uri: s.uri,
47
+ result: s.result,
48
+ subjectRefs: [...new Set(l)],
49
+ producedBy: s.producedBy,
50
+ ...s.command === void 0 ? {} : { command: s.command },
51
+ ...s.environment === void 0 ? {} : { environment: s.environment },
52
+ ...s.fingerprint === void 0 ? {} : { fingerprint: s.fingerprint }
53
+ };
54
+ if (s.idempotencyKey !== void 0) {
55
+ let t = a.evidence.find((e) => e.idempotencyKey === s.idempotencyKey);
56
+ if (t !== void 0) {
57
+ let { id: i, observedAt: a, idempotencyKey: o, ...l } = t;
58
+ return e(l) === e(u) ? {
59
+ outcome: "same",
60
+ evidence: t
61
+ } : r("evidence/idempotency-conflict", "error", `the key "${s.idempotencyKey}" was used for other evidence (${t.id})`, "Use a new key for new evidence.", c.id, n.conflict);
62
+ }
63
+ }
64
+ let d = `EVD-${c.id}-`, f = 0n;
65
+ for (let e of a.evidence) {
66
+ if (!e.id.startsWith(d)) continue;
67
+ let t = BigInt(e.id.slice(d.length));
68
+ t > f && (f = t);
69
+ }
70
+ let p = String(f + 1n).padStart(3, "0");
71
+ return o.evidence.test(`${d}${p}`) ? {
72
+ outcome: "add",
73
+ evidence: {
74
+ id: `${d}${p}`,
75
+ ...u,
76
+ observedAt: s.observedAt,
77
+ ...s.idempotencyKey === void 0 ? {} : { idempotencyKey: s.idempotencyKey }
78
+ }
79
+ } : r("evidence/identifier", "error", `${c.id} cannot form a valid evidence identifier`, "Check the program identifier grammar.", c.id, n.failed);
80
+ };
81
+ //#endregion
82
+ export { a as decideEvidence };
package/dist/ids.js ADDED
@@ -0,0 +1,25 @@
1
+ //#region src/ids.ts
2
+ var e = /^[A-Z][A-Z0-9]{1,9}$/, t = (t) => {
3
+ if (!e.test(t)) throw Error(`plan id prefix "${t}" is not 2 to 10 capital letters or digits, starting with a letter`);
4
+ return {
5
+ prefix: t,
6
+ plan: RegExp(`^${t}-PLAN-[0-9]{2}$`),
7
+ workItem: RegExp(`^${t}-[0-9]{2}-[0-9]{3}$`),
8
+ acceptance: RegExp(`^${t}-[0-9]{2}-[0-9]{3}-A[0-9]{2}$`),
9
+ requirement: RegExp(`^${t}-[0-9]{2}-[0-9]{3}-E[0-9]{2}$`),
10
+ source: RegExp(`^SRC-${t}-[0-9]{2}-[0-9]{3}-[0-9]{3}$`),
11
+ evidence: RegExp(`^EVD-${t}-[0-9]{2}-[0-9]{3}-[0-9]{3,}$`),
12
+ finding: RegExp(`^FND-${t}-[0-9]{2}-[0-9]{3}-[0-9]{3}$`),
13
+ adr: RegExp(`^ADR-${t}-[0-9]{3}$`),
14
+ closureRun: RegExp(`^CLR-${t}-[0-9]{2}-[0-9]{3}$`),
15
+ certificate: RegExp(`^CRT-${t}-[0-9]{2}-[0-9]{3}$`)
16
+ };
17
+ }, n = (e) => {
18
+ let t = /-(?:PLAN-)?([0-9]{2})(?:-|$)/.exec(e);
19
+ return t === null ? null : t[1];
20
+ }, r = (e, t) => {
21
+ let n = RegExp(`(?:^|-)(${e.prefix}-[0-9]{2}-[0-9]{3})(?:-|$)`).exec(t);
22
+ return n === null ? null : n[1];
23
+ };
24
+ //#endregion
25
+ export { t as idGrammar, r as ownerItemOf, n as planNumberOf };
package/dist/impact.js ADDED
@@ -0,0 +1,65 @@
1
+ //#region src/impact.ts
2
+ var e = [
3
+ ".",
4
+ ":",
5
+ "/",
6
+ "-"
7
+ ], t = (t, n) => t === n || e.some((e) => n.startsWith(t + e) || t.startsWith(n + e)), n = (e, n) => {
8
+ let r = /* @__PURE__ */ new Map(), i = (e, t) => {
9
+ let n = r.get(e) ?? /* @__PURE__ */ new Set();
10
+ n.add(t), r.set(e, n);
11
+ };
12
+ for (let { item: r } of e.items.values()) for (let e of n.tags) for (let n of r.impactTags) t(e, n) && i(r.id, `tag ${n}`);
13
+ let a = [], o = new Map(e.instances.map(({ file: e, instance: t }) => [e, t])), s = /* @__PURE__ */ new Map();
14
+ for (let { item: t } of e.items.values()) for (let e of t.sourceRefs) {
15
+ let n = s.get(e.uri);
16
+ n === void 0 && (n = /* @__PURE__ */ new Set(), s.set(e.uri, n)), n.add(t.id);
17
+ }
18
+ for (let e of [...new Set(n.files)].sort()) {
19
+ let t = !1, n = o.get(e);
20
+ if (n !== void 0) {
21
+ t = !0;
22
+ for (let t of n.workItems) i(t.id, `its plan file ${e} changed`);
23
+ }
24
+ for (let n of s.get(e) ?? []) t = !0, i(n, `its source ${e} changed`);
25
+ t || a.push(e);
26
+ }
27
+ let c = /* @__PURE__ */ new Map();
28
+ for (let { item: t } of e.items.values()) for (let e of t.dependsOn) {
29
+ let n = c.get(e);
30
+ n === void 0 && (n = [], c.set(e, n)), n.push(t.id);
31
+ }
32
+ for (let e of c.values()) e.sort();
33
+ let l = /* @__PURE__ */ new Map(), u = [...r.keys()].sort().map((e) => [e]), d = new Set(r.keys());
34
+ for (let e = 0; e < u.length; e++) {
35
+ let t = u[e];
36
+ for (let e of c.get(t.at(-1)) ?? []) {
37
+ if (d.has(e)) continue;
38
+ d.add(e);
39
+ let n = [...t, e];
40
+ l.set(e, n), u.push(n);
41
+ }
42
+ }
43
+ let f = [...d], p = [...new Set(f.map((t) => e.items.get(t).item.ownerPlan))].sort(), m = p.flatMap((t) => {
44
+ let n = e.closure.get(t);
45
+ return n?.state === "certified" ? [{
46
+ plan: t,
47
+ certificate: n.certificate.id
48
+ }] : [];
49
+ });
50
+ return {
51
+ direct: [...r.entries()].map(([e, t]) => ({
52
+ workItem: e,
53
+ because: [...t].sort()
54
+ })).sort((e, t) => e.workItem < t.workItem ? -1 : 1),
55
+ transitive: [...l.entries()].map(([e, t]) => ({
56
+ workItem: e,
57
+ path: t
58
+ })).sort((e, t) => e.workItem < t.workItem ? -1 : 1),
59
+ plans: p,
60
+ certificates: m,
61
+ unknown: a
62
+ };
63
+ };
64
+ //#endregion
65
+ export { n as impactOf };