@mikeargento/bitgraph-player 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +98 -0
  3. package/SPEC.md +234 -0
  4. package/dist/__tests__/cast-order.test.d.ts +2 -0
  5. package/dist/__tests__/cast-order.test.d.ts.map +1 -0
  6. package/dist/__tests__/cast-order.test.js +434 -0
  7. package/dist/__tests__/cast-order.test.js.map +1 -0
  8. package/dist/__tests__/evaluate-verdict.test.d.ts +2 -0
  9. package/dist/__tests__/evaluate-verdict.test.d.ts.map +1 -0
  10. package/dist/__tests__/evaluate-verdict.test.js +228 -0
  11. package/dist/__tests__/evaluate-verdict.test.js.map +1 -0
  12. package/dist/__tests__/fixtures.d.ts +63 -0
  13. package/dist/__tests__/fixtures.d.ts.map +1 -0
  14. package/dist/__tests__/fixtures.js +150 -0
  15. package/dist/__tests__/fixtures.js.map +1 -0
  16. package/dist/__tests__/logic-rule.test.d.ts +2 -0
  17. package/dist/__tests__/logic-rule.test.d.ts.map +1 -0
  18. package/dist/__tests__/logic-rule.test.js +190 -0
  19. package/dist/__tests__/logic-rule.test.js.map +1 -0
  20. package/dist/cast.d.ts +29 -0
  21. package/dist/cast.d.ts.map +1 -0
  22. package/dist/cast.js +85 -0
  23. package/dist/cast.js.map +1 -0
  24. package/dist/cli.d.ts +3 -0
  25. package/dist/cli.d.ts.map +1 -0
  26. package/dist/cli.js +130 -0
  27. package/dist/cli.js.map +1 -0
  28. package/dist/evaluate.d.ts +30 -0
  29. package/dist/evaluate.d.ts.map +1 -0
  30. package/dist/evaluate.js +177 -0
  31. package/dist/evaluate.js.map +1 -0
  32. package/dist/index.d.ts +22 -0
  33. package/dist/index.d.ts.map +1 -0
  34. package/dist/index.js +9 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/logic.d.ts +16 -0
  37. package/dist/logic.d.ts.map +1 -0
  38. package/dist/logic.js +29 -0
  39. package/dist/logic.js.map +1 -0
  40. package/dist/order.d.ts +50 -0
  41. package/dist/order.d.ts.map +1 -0
  42. package/dist/order.js +290 -0
  43. package/dist/order.js.map +1 -0
  44. package/dist/rule.d.ts +40 -0
  45. package/dist/rule.d.ts.map +1 -0
  46. package/dist/rule.js +324 -0
  47. package/dist/rule.js.map +1 -0
  48. package/dist/types.d.ts +205 -0
  49. package/dist/types.d.ts.map +1 -0
  50. package/dist/types.js +16 -0
  51. package/dist/types.js.map +1 -0
  52. package/dist/verdict.d.ts +14 -0
  53. package/dist/verdict.d.ts.map +1 -0
  54. package/dist/verdict.js +146 -0
  55. package/dist/verdict.js.map +1 -0
  56. package/package.json +42 -0
  57. package/src/__tests__/cast-order.test.ts +473 -0
  58. package/src/__tests__/evaluate-verdict.test.ts +266 -0
  59. package/src/__tests__/fixtures.ts +206 -0
  60. package/src/__tests__/logic-rule.test.ts +221 -0
  61. package/src/cast.ts +120 -0
  62. package/src/cli.ts +143 -0
  63. package/src/evaluate.ts +238 -0
  64. package/src/index.ts +38 -0
  65. package/src/logic.ts +39 -0
  66. package/src/order.ts +380 -0
  67. package/src/rule.ts +340 -0
  68. package/src/types.ts +224 -0
  69. package/src/verdict.ts +159 -0
@@ -0,0 +1,177 @@
1
+ // Copyright (c) 2024-2026 Mike Argento. Licensed under the MIT License. See LICENSE.
2
+ import { kleeneAll, kleeneAny, kleeneNot } from "./logic.js";
3
+ import { compare } from "./order.js";
4
+ import { basisTier, meetsFloor } from "./types.js";
5
+ function positionOf(proof) {
6
+ const out = { proofHash: proof.proofHash };
7
+ if (proof.epochId !== undefined)
8
+ out["epochId"] = proof.epochId;
9
+ out["chainId"] = proof.chainId;
10
+ if (proof.counter !== undefined)
11
+ out["counter"] = proof.counter;
12
+ if (proof.slotCounter !== undefined)
13
+ out["slotCounter"] = proof.slotCounter;
14
+ return out;
15
+ }
16
+ /**
17
+ * Classify a role for predicate purposes.
18
+ * resolved -> use the recording
19
+ * definitely-absent -> optional and absent: closed-world FALSE material
20
+ * undetermined -> everything else, with the reason
21
+ */
22
+ function classify(ctx, role) {
23
+ const res = ctx.resolutions.get(role);
24
+ if (res === undefined) {
25
+ return { kind: "undetermined", reason: `role "${role}" is not declared in the cast` };
26
+ }
27
+ switch (res.kind) {
28
+ case "resolved":
29
+ return { kind: "resolved", proof: res.proof };
30
+ case "absent":
31
+ return res.optional
32
+ ? { kind: "definitely-absent" }
33
+ : {
34
+ kind: "undetermined",
35
+ reason: `required role "${role}" has no verified recording in the bundle`,
36
+ };
37
+ case "ambiguous":
38
+ return {
39
+ kind: "undetermined",
40
+ reason: `role "${role}" matches ${res.matchCount} recordings and no "at" pin selects one`,
41
+ };
42
+ case "invalid":
43
+ return { kind: "undetermined", reason: `role "${role}": ${res.reason}` };
44
+ }
45
+ }
46
+ function record(ctx, step) {
47
+ ctx.steps.push(step);
48
+ return step.result;
49
+ }
50
+ function evalExists(ctx, role) {
51
+ const c = classify(ctx, role);
52
+ const claim = `exists(${role})`;
53
+ if (c.kind === "resolved") {
54
+ return record(ctx, {
55
+ claim,
56
+ result: "TRUE",
57
+ because: { recording: positionOf(c.proof) },
58
+ });
59
+ }
60
+ if (c.kind === "definitely-absent") {
61
+ return record(ctx, {
62
+ claim,
63
+ result: "FALSE",
64
+ because: {
65
+ reason: `no verified recording of the declared digest is in the bundle; definite absence within the declared closed world`,
66
+ },
67
+ });
68
+ }
69
+ return record(ctx, { claim, result: "UNDETERMINED", because: { reason: c.reason } });
70
+ }
71
+ /** Shared body of before/after: asks whether `x` precedes `y`. */
72
+ function evalPrecedes(ctx, claim, x, y) {
73
+ const cx = classify(ctx, x);
74
+ const cy = classify(ctx, y);
75
+ for (const [role, c] of [
76
+ [x, cx],
77
+ [y, cy],
78
+ ]) {
79
+ if (c.kind === "undetermined") {
80
+ return record(ctx, {
81
+ claim,
82
+ result: "UNDETERMINED",
83
+ because: { reason: c.reason, role },
84
+ });
85
+ }
86
+ }
87
+ if (cx.kind === "definitely-absent" || cy.kind === "definitely-absent") {
88
+ const absent = cx.kind === "definitely-absent" ? x : y;
89
+ return record(ctx, {
90
+ claim,
91
+ result: "FALSE",
92
+ because: {
93
+ reason: `role "${absent}" is definitely absent within the declared closed world; no ordering claim about it can hold`,
94
+ },
95
+ });
96
+ }
97
+ const a = cx.proof;
98
+ const b = cy.proof;
99
+ const order = compare(a, b, ctx.audit);
100
+ const because = {
101
+ a: positionOf(a),
102
+ b: positionOf(b),
103
+ relation: order.relation,
104
+ detail: order.detail,
105
+ };
106
+ if (order.relation === "same") {
107
+ return record(ctx, { claim, result: "FALSE", because });
108
+ }
109
+ if (order.relation === "unordered") {
110
+ return record(ctx, { claim, result: "UNDETERMINED", because });
111
+ }
112
+ const basis = order.basis;
113
+ // The tier the specific answer rests on — carried by the adapter, not
114
+ // recomputed from the basis family (lineage coverage can downgrade it).
115
+ const tier = order.tier ?? basisTier(basis);
116
+ because["weaker"] = order.weaker;
117
+ because["assumptionDependent"] = order.assumptionDependent;
118
+ if (!meetsFloor(tier, ctx.rule.requires.ordering)) {
119
+ because["floor"] = ctx.rule.requires.ordering;
120
+ return record(ctx, {
121
+ claim,
122
+ result: "UNDETERMINED",
123
+ basis,
124
+ evidenceTier: tier,
125
+ because: {
126
+ ...because,
127
+ reason: `ordering evidence ("${basis}", tier "${tier}") is below the rule's declared floor ("${ctx.rule.requires.ordering}")`,
128
+ },
129
+ });
130
+ }
131
+ ctx.usedTiers.add(tier);
132
+ return record(ctx, {
133
+ claim,
134
+ result: order.relation === "before" ? "TRUE" : "FALSE",
135
+ basis,
136
+ evidenceTier: tier,
137
+ because,
138
+ });
139
+ }
140
+ function evalClaim(ctx, claim) {
141
+ if ("exists" in claim)
142
+ return evalExists(ctx, claim.exists);
143
+ if ("before" in claim) {
144
+ const [x, y] = claim.before;
145
+ return evalPrecedes(ctx, `before(${x}, ${y})`, x, y);
146
+ }
147
+ if ("after" in claim) {
148
+ const [x, y] = claim.after;
149
+ // after(x, y) holds exactly when y precedes x.
150
+ return evalPrecedes(ctx, `after(${x}, ${y})`, y, x);
151
+ }
152
+ if ("between" in claim) {
153
+ const [subject, lower, upper] = claim.between;
154
+ // between(x, a, b) := after(x, a) AND before(x, b), recorded as two steps.
155
+ const afterPart = evalPrecedes(ctx, `between(${subject}, ${lower}, ${upper}): after(${subject}, ${lower})`, lower, subject);
156
+ const beforePart = evalPrecedes(ctx, `between(${subject}, ${lower}, ${upper}): before(${subject}, ${upper})`, subject, upper);
157
+ return kleeneAll([afterPart, beforePart]);
158
+ }
159
+ if ("all" in claim)
160
+ return kleeneAll(claim.all.map((c) => evalClaim(ctx, c)));
161
+ if ("any" in claim)
162
+ return kleeneAny(claim.any.map((c) => evalClaim(ctx, c)));
163
+ return kleeneNot(evalClaim(ctx, claim.not));
164
+ }
165
+ export function evaluate(rule, resolutions, audit) {
166
+ const ctx = { rule, resolutions, audit, steps: [], usedTiers: new Set() };
167
+ const result = evalClaim(ctx, rule.claim);
168
+ const evaluation = { result, steps: ctx.steps };
169
+ if (ctx.usedTiers.has("assumption-dependent")) {
170
+ evaluation.weakestEvidence = "assumption-dependent";
171
+ }
172
+ else if (ctx.usedTiers.has("hash-linked")) {
173
+ evaluation.weakestEvidence = "hash-linked";
174
+ }
175
+ return evaluation;
176
+ }
177
+ //# sourceMappingURL=evaluate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../src/evaluate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @mikeargento/bitgraph-player
3
+ *
4
+ * Deterministic evaluation of causal rules over BitGraph proof bundles.
5
+ *
6
+ * BitGraph records. Player executes.
7
+ *
8
+ * Player is a pure function over `runAudit()`'s output: same rule, same
9
+ * bundle, same verdict, on anyone's machine, with no network access at
10
+ * evaluation time. It decides; it does not enforce — no field in the rule
11
+ * format is capable of causing an action.
12
+ */
13
+ export type { CastEntry, CastPin, Claim, DeclaredEntry, DerivedStep, EvidenceTier, OrderBasis, OrderResult, Resolution, Rule, ThreeValued, Verdict, } from "./types.js";
14
+ export { basisTier, meetsFloor } from "./types.js";
15
+ export { parseRule, normalizeDigest, RuleError } from "./rule.js";
16
+ export { resolveCast, resolveRole } from "./cast.js";
17
+ export { compare } from "./order.js";
18
+ export { kleeneAll, kleeneAny, kleeneNot } from "./logic.js";
19
+ export { evaluate } from "./evaluate.js";
20
+ export type { Evaluation } from "./evaluate.js";
21
+ export { buildVerdict, serializeVerdict, playerVersion } from "./verdict.js";
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AAEH,YAAY,EACV,SAAS,EACT,OAAO,EACP,KAAK,EACL,aAAa,EACb,WAAW,EACX,YAAY,EACZ,UAAU,EACV,WAAW,EACX,UAAU,EACV,IAAI,EACJ,WAAW,EACX,OAAO,GACR,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ // Copyright (c) 2024-2026 Mike Argento. Licensed under the MIT License. See LICENSE.
2
+ export { basisTier, meetsFloor } from "./types.js";
3
+ export { parseRule, normalizeDigest, RuleError } from "./rule.js";
4
+ export { resolveCast, resolveRole } from "./cast.js";
5
+ export { compare } from "./order.js";
6
+ export { kleeneAll, kleeneAny, kleeneNot } from "./logic.js";
7
+ export { evaluate } from "./evaluate.js";
8
+ export { buildVerdict, serializeVerdict, playerVersion } from "./verdict.js";
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qFAAqF;AA6BrF,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Strong Kleene three-valued connectives.
3
+ *
4
+ * all: FALSE if any FALSE; else UNDETERMINED if any UNDETERMINED; else TRUE
5
+ * any: TRUE if any TRUE; else UNDETERMINED if any UNDETERMINED; else FALSE
6
+ * not: TRUE <-> FALSE; UNDETERMINED stays UNDETERMINED
7
+ *
8
+ * UNDETERMINED is not a nuisance value: it is the honest answer wherever
9
+ * the evidence does not decide, and these tables are what keep it from
10
+ * being laundered into FALSE by composition.
11
+ */
12
+ import type { ThreeValued } from "./types.js";
13
+ export declare function kleeneNot(v: ThreeValued): ThreeValued;
14
+ export declare function kleeneAll(values: readonly ThreeValued[]): ThreeValued;
15
+ export declare function kleeneAny(values: readonly ThreeValued[]): ThreeValued;
16
+ //# sourceMappingURL=logic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logic.d.ts","sourceRoot":"","sources":["../src/logic.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,wBAAgB,SAAS,CAAC,CAAC,EAAE,WAAW,GAAG,WAAW,CAIrD;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,WAAW,CAOrE;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,WAAW,CAOrE"}
package/dist/logic.js ADDED
@@ -0,0 +1,29 @@
1
+ // Copyright (c) 2024-2026 Mike Argento. Licensed under the MIT License. See LICENSE.
2
+ export function kleeneNot(v) {
3
+ if (v === "TRUE")
4
+ return "FALSE";
5
+ if (v === "FALSE")
6
+ return "TRUE";
7
+ return "UNDETERMINED";
8
+ }
9
+ export function kleeneAll(values) {
10
+ let sawUndetermined = false;
11
+ for (const v of values) {
12
+ if (v === "FALSE")
13
+ return "FALSE";
14
+ if (v === "UNDETERMINED")
15
+ sawUndetermined = true;
16
+ }
17
+ return sawUndetermined ? "UNDETERMINED" : "TRUE";
18
+ }
19
+ export function kleeneAny(values) {
20
+ let sawUndetermined = false;
21
+ for (const v of values) {
22
+ if (v === "TRUE")
23
+ return "TRUE";
24
+ if (v === "UNDETERMINED")
25
+ sawUndetermined = true;
26
+ }
27
+ return sawUndetermined ? "UNDETERMINED" : "FALSE";
28
+ }
29
+ //# sourceMappingURL=logic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logic.js","sourceRoot":"","sources":["../src/logic.ts"],"names":[],"mappings":"AAAA,qFAAqF;AAgBrF,MAAM,UAAU,SAAS,CAAC,CAAc;IACtC,IAAI,CAAC,KAAK,MAAM;QAAE,OAAO,OAAO,CAAC;IACjC,IAAI,CAAC,KAAK,OAAO;QAAE,OAAO,MAAM,CAAC;IACjC,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAA8B;IACtD,IAAI,eAAe,GAAG,KAAK,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,KAAK,OAAO;YAAE,OAAO,OAAO,CAAC;QAClC,IAAI,CAAC,KAAK,cAAc;YAAE,eAAe,GAAG,IAAI,CAAC;IACnD,CAAC;IACD,OAAO,eAAe,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAA8B;IACtD,IAAI,eAAe,GAAG,KAAK,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,KAAK,MAAM;YAAE,OAAO,MAAM,CAAC;QAChC,IAAI,CAAC,KAAK,cAAc;YAAE,eAAe,GAAG,IAAI,CAAC;IACnD,CAAC;IACD,OAAO,eAAe,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC;AACpD,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * The ordering adapter. Player does not reimplement causal reconstruction —
3
+ * `bitgraph-audit` already computes it — this module carries audit's
4
+ * answers into a single compare(a, b) without flattening their evidence
5
+ * classes, and without asserting anything the specific pair of recordings
6
+ * is not actually covered by.
7
+ *
8
+ * An artifact's position is its COMMIT position. At the slot the digest is
9
+ * not bound yet, so the slot cannot be the position of the artifact.
10
+ *
11
+ * Within a partition (signer key, epochId, chainId):
12
+ * - "chain-link": a DIRECTED prevB64 path connects the two recordings
13
+ * through observed proofs. The path itself decides the direction; a
14
+ * path contradicting the counters is an anomaly and answers nothing.
15
+ * Undirected co-membership in a component is NOT chain-link evidence:
16
+ * two fork branches share a component without any path between them.
17
+ * - "counter-order": no path, but both commit counters parse under the
18
+ * canonical strict-decimal grammar. Rests on counter discipline.
19
+ *
20
+ * Across epochs:
21
+ * - "epoch-lineage": a chain of hard epochLink edges whose observed
22
+ * predecessor/via proofs cover THIS pair. Successor-side coverage is
23
+ * by signer key: a proof signed by the successor key cannot predate
24
+ * that key's creation at epoch init, which the link proves happened
25
+ * after the referenced predecessor existed. Predecessor-side coverage
26
+ * is a directed path to (or identity with) the referenced predecessor
27
+ * — hash-linked — or a strictly smaller parseable counter, which
28
+ * downgrades the whole answer to the assumption-dependent tier.
29
+ * - "anchor-bounds": strict block separation between verified segment
30
+ * bounds; always assumption-dependent (anchor freshness). If BOTH
31
+ * directions satisfy strict separation the evidence is contradictory
32
+ * and answers nothing.
33
+ * Epoch pairs supported by neither are concurrent-or-unordered, and the
34
+ * honest answer is "unordered", never a coin flip.
35
+ */
36
+ import type { AuditResult, ObservedProof } from "@mikeargento/bitgraph-audit";
37
+ import type { OrderResult } from "./types.js";
38
+ /**
39
+ * Canonical strict-decimal counter grammar, mirroring audit's own
40
+ * parseCounter. Every other spelling BigInt would accept ("", "0x10",
41
+ * "-3", " 7 ") is NO counter evidence, exactly as audit treats it.
42
+ */
43
+ export declare function parseCounter(value: string | undefined): bigint | undefined;
44
+ /**
45
+ * Compare two resolved recordings. Pure over the AuditResult; no network,
46
+ * no clock. The returned tier is what the answer actually rests on and is
47
+ * what the evidence floor gates.
48
+ */
49
+ export declare function compare(a: ObservedProof, b: ObservedProof, audit: AuditResult): OrderResult;
50
+ //# sourceMappingURL=order.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"order.d.ts","sourceRoot":"","sources":["../src/order.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,KAAK,EACV,WAAW,EAEX,aAAa,EAGd,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,YAAY,CAAC;AAE5D;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAG1E;AA2LD;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,WAAW,GAAG,WAAW,CAoI3F"}
package/dist/order.js ADDED
@@ -0,0 +1,290 @@
1
+ // Copyright (c) 2024-2026 Mike Argento. Licensed under the MIT License. See LICENSE.
2
+ /**
3
+ * Canonical strict-decimal counter grammar, mirroring audit's own
4
+ * parseCounter. Every other spelling BigInt would accept ("", "0x10",
5
+ * "-3", " 7 ") is NO counter evidence, exactly as audit treats it.
6
+ */
7
+ export function parseCounter(value) {
8
+ if (value === undefined || value.length === 0 || !/^[0-9]+$/.test(value))
9
+ return undefined;
10
+ return BigInt(value);
11
+ }
12
+ function unordered(detail) {
13
+ return { relation: "unordered", assumptionDependent: false, weaker: false, detail };
14
+ }
15
+ function partitionOf(audit, proofHash) {
16
+ return audit.reconstruction.partitions.find((p) => p.memberProofHashes.includes(proofHash));
17
+ }
18
+ function segmentOf(audit, proofHash) {
19
+ return audit.temporal.segments.find((s) => s.memberProofHashes.includes(proofHash));
20
+ }
21
+ function proofsByHash(audit) {
22
+ return new Map(audit.ingest.proofs.map((p) => [p.proofHash, p]));
23
+ }
24
+ /**
25
+ * True when `ancestor` lies on the directed prevB64 chain above
26
+ * `descendant`, walking only proofs observed in the bundle and confined to
27
+ * one partition. Identity does not count.
28
+ */
29
+ function isDirectedAncestor(ancestor, descendant, partition, byChainHash) {
30
+ const members = new Set(partition.memberProofHashes);
31
+ const visited = new Set();
32
+ let current = descendant;
33
+ while (current !== undefined) {
34
+ const prev = current.prevB64;
35
+ if (prev === undefined)
36
+ return false;
37
+ const parent = byChainHash.get(prev);
38
+ if (parent === undefined || !members.has(parent.proofHash))
39
+ return false;
40
+ if (visited.has(parent.proofHash))
41
+ return false; // cycle guard
42
+ visited.add(parent.proofHash);
43
+ if (parent.proofHash === ancestor.proofHash)
44
+ return true;
45
+ current = parent;
46
+ }
47
+ return false;
48
+ }
49
+ function chainHashIndex(audit, partition) {
50
+ const byHash = proofsByHash(audit);
51
+ const index = new Map();
52
+ for (const memberHash of partition.memberProofHashes) {
53
+ const proof = byHash.get(memberHash);
54
+ if (proof !== undefined)
55
+ index.set(proof.chainHash, proof);
56
+ }
57
+ return index;
58
+ }
59
+ // ---------------------------------------------------------------------------
60
+ // Epoch lineage at recording granularity
61
+ // ---------------------------------------------------------------------------
62
+ /**
63
+ * Try to prove `a` precedes `b` through a chain of hard epochLink edges.
64
+ *
65
+ * A usable first edge references an observed predecessor proof P in a's
66
+ * own partition, with a covering P (identity, directed path, or strictly
67
+ * smaller parseable counter — the last downgrades the tier). Every
68
+ * subsequent edge must be anchored in the partition the previous edge's
69
+ * via proof belongs to; reaching b's partition completes the proof, since
70
+ * any proof of that partition postdates its key's creation at init.
71
+ */
72
+ function lineagePrecedes(a, partA, b, partB, audit) {
73
+ const byHash = proofsByHash(audit);
74
+ const edges = audit.reconstruction.epochRelationships.edges.filter((e) => e.hardEdge && e.predecessorProofHash !== undefined);
75
+ const partitionKeyOf = (p) => JSON.stringify(p.key);
76
+ const partitionByProofHash = (hash) => partitionOf(audit, hash);
77
+ const queue = [];
78
+ const chainIndexA = chainHashIndex(audit, partA);
79
+ const ca = parseCounter(a.counter);
80
+ for (const edge of edges) {
81
+ const pred = byHash.get(edge.predecessorProofHash);
82
+ if (pred === undefined)
83
+ continue;
84
+ const predPartition = partitionByProofHash(pred.proofHash);
85
+ if (predPartition !== partA)
86
+ continue;
87
+ let hopTier;
88
+ if (pred.proofHash === a.proofHash || isDirectedAncestor(a, pred, partA, chainIndexA)) {
89
+ hopTier = "hash-linked";
90
+ }
91
+ else {
92
+ const cp = parseCounter(pred.counter);
93
+ if (ca !== undefined && cp !== undefined && ca < cp)
94
+ hopTier = "assumption-dependent";
95
+ }
96
+ if (hopTier === undefined)
97
+ continue;
98
+ const viaPartition = partitionByProofHash(edge.viaProofHash);
99
+ if (viaPartition === undefined)
100
+ continue;
101
+ queue.push({ partitionKey: partitionKeyOf(viaPartition), tier: hopTier });
102
+ }
103
+ // BFS over subsequent hops. Later hops are free of counter assumptions:
104
+ // the next edge's predecessor proof is signed by the current partition's
105
+ // key, so it postdates that key's creation.
106
+ const bestTierByPartition = new Map();
107
+ const targetKey = partitionKeyOf(partB);
108
+ let best;
109
+ while (queue.length > 0) {
110
+ const state = queue.shift();
111
+ const seen = bestTierByPartition.get(state.partitionKey);
112
+ if (seen === "hash-linked" || seen === state.tier)
113
+ continue;
114
+ if (seen === undefined || state.tier === "hash-linked") {
115
+ bestTierByPartition.set(state.partitionKey, state.tier);
116
+ }
117
+ if (state.partitionKey === targetKey) {
118
+ if (best === undefined || state.tier === "hash-linked")
119
+ best = state.tier;
120
+ if (best === "hash-linked")
121
+ break;
122
+ continue;
123
+ }
124
+ for (const edge of edges) {
125
+ const pred = byHash.get(edge.predecessorProofHash);
126
+ if (pred === undefined)
127
+ continue;
128
+ const predPartition = partitionByProofHash(pred.proofHash);
129
+ if (predPartition === undefined || partitionKeyOf(predPartition) !== state.partitionKey) {
130
+ continue;
131
+ }
132
+ const viaPartition = partitionByProofHash(edge.viaProofHash);
133
+ if (viaPartition === undefined)
134
+ continue;
135
+ queue.push({ partitionKey: partitionKeyOf(viaPartition), tier: state.tier });
136
+ }
137
+ }
138
+ return best === undefined ? undefined : { tier: best };
139
+ }
140
+ // ---------------------------------------------------------------------------
141
+ // Anchor bounds
142
+ // ---------------------------------------------------------------------------
143
+ /**
144
+ * Strict precedence between two one-sided anchor bounds. Equality proves
145
+ * nothing: A precedes the anchor COMMIT that consumed block N, B follows
146
+ * the MINING of block N, and the gap between mining and commit is exactly
147
+ * where the two could swap.
148
+ */
149
+ function boundsStrictlyOrdered(upper, lower) {
150
+ if (upper.blockNumber !== undefined && lower.blockNumber !== undefined) {
151
+ return BigInt(upper.blockNumber) < BigInt(lower.blockNumber);
152
+ }
153
+ // Verified witness timestamps; Ethereum block timestamps are strictly
154
+ // increasing, so strict timestamp inequality is strict block inequality.
155
+ return upper.timestamp < lower.timestamp;
156
+ }
157
+ function anchorPrecedes(firstSegment, secondSegment) {
158
+ let best;
159
+ for (const upper of firstSegment.upperBounds) {
160
+ for (const lower of secondSegment.lowerBounds) {
161
+ if (!boundsStrictlyOrdered(upper, lower))
162
+ continue;
163
+ const weaker = upper.weaker || lower.weaker;
164
+ if (best === undefined || (best.weaker && !weaker)) {
165
+ best = { weaker, upper, lower };
166
+ }
167
+ }
168
+ }
169
+ return best;
170
+ }
171
+ function describeBound(bound) {
172
+ return bound.blockNumber !== undefined ? `block ${bound.blockNumber}` : `t=${bound.timestamp}`;
173
+ }
174
+ // ---------------------------------------------------------------------------
175
+ // compare
176
+ // ---------------------------------------------------------------------------
177
+ /**
178
+ * Compare two resolved recordings. Pure over the AuditResult; no network,
179
+ * no clock. The returned tier is what the answer actually rests on and is
180
+ * what the evidence floor gates.
181
+ */
182
+ export function compare(a, b, audit) {
183
+ if (a.proofHash === b.proofHash) {
184
+ return {
185
+ relation: "same",
186
+ assumptionDependent: false,
187
+ weaker: false,
188
+ detail: "both roles resolved to the identical recording",
189
+ };
190
+ }
191
+ const partA = partitionOf(audit, a.proofHash);
192
+ const partB = partitionOf(audit, b.proofHash);
193
+ if (partA === undefined || partB === undefined) {
194
+ return unordered("at least one recording is observed-but-unchained (no counter or epochId): it holds no causal position to compare");
195
+ }
196
+ // -------------------------------------------------------------------
197
+ // Same partition: a directed prevB64 path decides; counters corroborate
198
+ // or, absent a path, carry the answer at the weaker tier.
199
+ // -------------------------------------------------------------------
200
+ if (partA === partB) {
201
+ const chainIndex = chainHashIndex(audit, partA);
202
+ const aBeforeB = isDirectedAncestor(a, b, partA, chainIndex);
203
+ const bBeforeA = isDirectedAncestor(b, a, partA, chainIndex);
204
+ const ca = parseCounter(a.counter);
205
+ const cb = parseCounter(b.counter);
206
+ if (aBeforeB && bBeforeA) {
207
+ return unordered("prevB64 links form a cycle between these recordings: an anomaly, not an order");
208
+ }
209
+ if (aBeforeB || bBeforeA) {
210
+ const relation = aBeforeB ? "before" : "after";
211
+ // A verified path contradicted by the counters is an anomaly:
212
+ // both cannot be honest, so neither answers.
213
+ if (ca !== undefined && cb !== undefined && (aBeforeB ? ca >= cb : cb >= ca)) {
214
+ return unordered("a verified prevB64 path contradicts the commit counters: an anomaly, not an order");
215
+ }
216
+ return {
217
+ relation,
218
+ basis: "chain-link",
219
+ tier: "hash-linked",
220
+ assumptionDependent: false,
221
+ weaker: false,
222
+ detail: `a directed prevB64 path through observed proofs connects the recordings; the path decides the direction`,
223
+ };
224
+ }
225
+ if (ca === undefined || cb === undefined) {
226
+ return unordered("no prevB64 path connects the recordings and at least one carries no parseable strict-decimal commit counter");
227
+ }
228
+ if (ca === cb) {
229
+ return unordered("two distinct recordings claim the same commit counter in one partition: an anomaly, not an order");
230
+ }
231
+ return {
232
+ relation: ca < cb ? "before" : "after",
233
+ basis: "counter-order",
234
+ tier: "assumption-dependent",
235
+ assumptionDependent: true,
236
+ weaker: true,
237
+ detail: `no prevB64 path in the bundle connects the recordings; commit counters ${a.counter} vs ${b.counter} rest on the authority's counter discipline`,
238
+ };
239
+ }
240
+ // -------------------------------------------------------------------
241
+ // Different partitions. Counters are never comparable across
242
+ // partitions; order can only come through covered epoch lineage or
243
+ // anchor bounds.
244
+ // -------------------------------------------------------------------
245
+ if (a.epochId !== undefined && b.epochId !== undefined && a.epochId === b.epochId) {
246
+ return unordered("same epochId under a different signer key or chain: counters are not comparable and no cross-partition evidence orders them");
247
+ }
248
+ const lineageForward = lineagePrecedes(a, partA, b, partB, audit);
249
+ const lineageBackward = lineagePrecedes(b, partB, a, partA, audit);
250
+ if (lineageForward !== undefined && lineageBackward !== undefined) {
251
+ return unordered("epochLink lineage evidence runs in both directions between these recordings: contradictory, an anomaly, not an order");
252
+ }
253
+ const lineage = lineageForward ?? lineageBackward;
254
+ if (lineage !== undefined) {
255
+ const relation = lineageForward !== undefined ? "before" : "after";
256
+ const assumptionDependent = lineage.tier === "assumption-dependent";
257
+ return {
258
+ relation,
259
+ basis: "epoch-lineage",
260
+ tier: lineage.tier,
261
+ assumptionDependent,
262
+ weaker: assumptionDependent,
263
+ detail: assumptionDependent
264
+ ? "hard epochLink succession covers this pair, with the predecessor-side coverage resting on counter discipline"
265
+ : "hard epochLink succession covers this pair: the earlier recording precedes the referenced predecessor by hash links, and the later one is signed by a key created after it",
266
+ };
267
+ }
268
+ const segA = segmentOf(audit, a.proofHash);
269
+ const segB = segmentOf(audit, b.proofHash);
270
+ if (segA !== undefined && segB !== undefined) {
271
+ const forward = anchorPrecedes(segA, segB);
272
+ const backward = anchorPrecedes(segB, segA);
273
+ if (forward !== undefined && backward !== undefined) {
274
+ return unordered("anchor bounds satisfy strict precedence in both directions: contradictory evidence, an anomaly, not an order");
275
+ }
276
+ const hit = forward ?? backward;
277
+ if (hit !== undefined) {
278
+ return {
279
+ relation: forward !== undefined ? "before" : "after",
280
+ basis: "anchor-bounds",
281
+ tier: "assumption-dependent",
282
+ assumptionDependent: true,
283
+ weaker: hit.weaker,
284
+ detail: `not-after anchor ${describeBound(hit.upper)} strictly precedes not-before anchor ${describeBound(hit.lower)}; rests on the anchor-freshness assumption`,
285
+ };
286
+ }
287
+ }
288
+ return unordered(`epochs ${a.epochId ?? "(none)"} and ${b.epochId ?? "(none)"} are concurrent-or-unordered for this pair: no covering lineage and no strict anchor-bound separation`);
289
+ }
290
+ //# sourceMappingURL=order.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"order.js","sourceRoot":"","sources":["../src/order.ts"],"names":[],"mappings":"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"}