@smthrs/journal 0.0.0-stage → 1.0.0-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +149 -0
- package/LICENSE +21 -0
- package/README.md +206 -2
- package/dist/cjs/CallFact.d.ts +129 -0
- package/dist/cjs/CallFact.d.ts.map +1 -0
- package/dist/cjs/CallFact.js +106 -0
- package/dist/cjs/CallFact.js.map +7 -0
- package/dist/cjs/Consensus.d.ts +440 -0
- package/dist/cjs/Consensus.d.ts.map +1 -0
- package/dist/cjs/Consensus.js +251 -0
- package/dist/cjs/Consensus.js.map +7 -0
- package/dist/cjs/EngineEvent.d.ts +890 -0
- package/dist/cjs/EngineEvent.d.ts.map +1 -0
- package/dist/cjs/EngineEvent.js +383 -0
- package/dist/cjs/EngineEvent.js.map +7 -0
- package/dist/cjs/ExecutionFact.d.ts +216 -0
- package/dist/cjs/ExecutionFact.d.ts.map +1 -0
- package/dist/cjs/ExecutionFact.js +303 -0
- package/dist/cjs/ExecutionFact.js.map +7 -0
- package/dist/cjs/Journal.d.ts +617 -0
- package/dist/cjs/Journal.d.ts.map +1 -0
- package/dist/cjs/Journal.js +190 -0
- package/dist/cjs/Journal.js.map +7 -0
- package/dist/cjs/JournalEvent.d.ts +421 -0
- package/dist/cjs/JournalEvent.d.ts.map +1 -0
- package/dist/cjs/JournalEvent.js +281 -0
- package/dist/cjs/JournalEvent.js.map +7 -0
- package/dist/cjs/JournalGeneration.d.ts +34 -0
- package/dist/cjs/JournalGeneration.d.ts.map +1 -0
- package/dist/cjs/JournalGeneration.js +72 -0
- package/dist/cjs/JournalGeneration.js.map +7 -0
- package/dist/cjs/JournalMetrics.d.ts +72 -0
- package/dist/cjs/JournalMetrics.d.ts.map +1 -0
- package/dist/cjs/JournalMetrics.js +55 -0
- package/dist/cjs/JournalMetrics.js.map +7 -0
- package/dist/cjs/Migrations.d.ts +42 -0
- package/dist/cjs/Migrations.d.ts.map +1 -0
- package/dist/cjs/Migrations.js +58 -0
- package/dist/cjs/Migrations.js.map +7 -0
- package/dist/cjs/OwnerId.d.ts +40 -0
- package/dist/cjs/OwnerId.d.ts.map +1 -0
- package/dist/cjs/OwnerId.js +40 -0
- package/dist/cjs/OwnerId.js.map +7 -0
- package/dist/cjs/Projection.d.ts +29 -0
- package/dist/cjs/Projection.d.ts.map +1 -0
- package/dist/cjs/Projection.js +25 -0
- package/dist/cjs/Projection.js.map +7 -0
- package/dist/cjs/RedactedLogger.d.ts +121 -0
- package/dist/cjs/RedactedLogger.d.ts.map +1 -0
- package/dist/cjs/RedactedLogger.js +235 -0
- package/dist/cjs/RedactedLogger.js.map +7 -0
- package/dist/cjs/Redaction.d.ts +350 -0
- package/dist/cjs/Redaction.d.ts.map +1 -0
- package/dist/cjs/Redaction.js +928 -0
- package/dist/cjs/Redaction.js.map +7 -0
- package/dist/cjs/SqlConsensus.d.ts +44 -0
- package/dist/cjs/SqlConsensus.d.ts.map +1 -0
- package/dist/cjs/SqlConsensus.js +243 -0
- package/dist/cjs/SqlConsensus.js.map +7 -0
- package/dist/cjs/SqlJournal.d.ts +173 -0
- package/dist/cjs/SqlJournal.d.ts.map +1 -0
- package/dist/cjs/SqlJournal.js +1568 -0
- package/dist/cjs/SqlJournal.js.map +7 -0
- package/dist/cjs/StepFact.d.ts +66 -0
- package/dist/cjs/StepFact.d.ts.map +1 -0
- package/dist/cjs/StepFact.js +68 -0
- package/dist/cjs/StepFact.js.map +7 -0
- package/dist/cjs/index.d.ts +95 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +63 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/internal/JournalInternalFault.d.ts +37 -0
- package/dist/cjs/internal/JournalInternalFault.d.ts.map +1 -0
- package/dist/cjs/internal/JournalInternalFault.js +43 -0
- package/dist/cjs/internal/JournalInternalFault.js.map +7 -0
- package/dist/cjs/migrations/0001_initial.d.ts +15 -0
- package/dist/cjs/migrations/0001_initial.d.ts.map +1 -0
- package/dist/cjs/migrations/0001_initial.js +54 -0
- package/dist/cjs/migrations/0001_initial.js.map +7 -0
- package/dist/cjs/migrations/0002_checkpoints.d.ts +27 -0
- package/dist/cjs/migrations/0002_checkpoints.d.ts.map +1 -0
- package/dist/cjs/migrations/0002_checkpoints.js +48 -0
- package/dist/cjs/migrations/0002_checkpoints.js.map +7 -0
- package/dist/cjs/migrations/0003_startup_index.d.ts +15 -0
- package/dist/cjs/migrations/0003_startup_index.d.ts.map +1 -0
- package/dist/cjs/migrations/0003_startup_index.js +40 -0
- package/dist/cjs/migrations/0003_startup_index.js.map +7 -0
- package/dist/cjs/migrations/0004_dedup.d.ts +15 -0
- package/dist/cjs/migrations/0004_dedup.d.ts.map +1 -0
- package/dist/cjs/migrations/0004_dedup.js +57 -0
- package/dist/cjs/migrations/0004_dedup.js.map +7 -0
- package/dist/cjs/migrations/0005_run_event_type.d.ts +15 -0
- package/dist/cjs/migrations/0005_run_event_type.d.ts.map +1 -0
- package/dist/cjs/migrations/0005_run_event_type.js +40 -0
- package/dist/cjs/migrations/0005_run_event_type.js.map +7 -0
- package/dist/cjs/migrations/0006_consensus.d.ts +22 -0
- package/dist/cjs/migrations/0006_consensus.d.ts.map +1 -0
- package/dist/cjs/migrations/0006_consensus.js +84 -0
- package/dist/cjs/migrations/0006_consensus.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/test/Notifying.d.ts +65 -0
- package/dist/cjs/test/Notifying.d.ts.map +1 -0
- package/dist/cjs/test/Notifying.js +62 -0
- package/dist/cjs/test/Notifying.js.map +7 -0
- package/dist/cjs/test/TestJournal.d.ts +43 -0
- package/dist/cjs/test/TestJournal.d.ts.map +1 -0
- package/dist/cjs/test/TestJournal.js +43 -0
- package/dist/cjs/test/TestJournal.js.map +7 -0
- package/dist/esm/CallFact.d.ts +129 -0
- package/dist/esm/CallFact.d.ts.map +1 -0
- package/dist/esm/CallFact.js +96 -0
- package/dist/esm/CallFact.js.map +1 -0
- package/dist/esm/Consensus.d.ts +440 -0
- package/dist/esm/Consensus.d.ts.map +1 -0
- package/dist/esm/Consensus.js +454 -0
- package/dist/esm/Consensus.js.map +1 -0
- package/dist/esm/EngineEvent.d.ts +890 -0
- package/dist/esm/EngineEvent.d.ts.map +1 -0
- package/dist/esm/EngineEvent.js +614 -0
- package/dist/esm/EngineEvent.js.map +1 -0
- package/dist/esm/ExecutionFact.d.ts +216 -0
- package/dist/esm/ExecutionFact.d.ts.map +1 -0
- package/dist/esm/ExecutionFact.js +374 -0
- package/dist/esm/ExecutionFact.js.map +1 -0
- package/dist/esm/Journal.d.ts +617 -0
- package/dist/esm/Journal.d.ts.map +1 -0
- package/dist/esm/Journal.js +323 -0
- package/dist/esm/Journal.js.map +1 -0
- package/dist/esm/JournalEvent.d.ts +421 -0
- package/dist/esm/JournalEvent.d.ts.map +1 -0
- package/dist/esm/JournalEvent.js +517 -0
- package/dist/esm/JournalEvent.js.map +1 -0
- package/dist/esm/JournalGeneration.d.ts +34 -0
- package/dist/esm/JournalGeneration.d.ts.map +1 -0
- package/dist/esm/JournalGeneration.js +65 -0
- package/dist/esm/JournalGeneration.js.map +1 -0
- package/dist/esm/JournalMetrics.d.ts +72 -0
- package/dist/esm/JournalMetrics.d.ts.map +1 -0
- package/dist/esm/JournalMetrics.js +79 -0
- package/dist/esm/JournalMetrics.js.map +1 -0
- package/dist/esm/Migrations.d.ts +42 -0
- package/dist/esm/Migrations.d.ts.map +1 -0
- package/dist/esm/Migrations.js +59 -0
- package/dist/esm/Migrations.js.map +1 -0
- package/dist/esm/OwnerId.d.ts +40 -0
- package/dist/esm/OwnerId.d.ts.map +1 -0
- package/dist/esm/OwnerId.js +33 -0
- package/dist/esm/OwnerId.js.map +1 -0
- package/dist/esm/Projection.d.ts +29 -0
- package/dist/esm/Projection.d.ts.map +1 -0
- package/dist/esm/Projection.js +13 -0
- package/dist/esm/Projection.js.map +1 -0
- package/dist/esm/RedactedLogger.d.ts +121 -0
- package/dist/esm/RedactedLogger.d.ts.map +1 -0
- package/dist/esm/RedactedLogger.js +445 -0
- package/dist/esm/RedactedLogger.js.map +1 -0
- package/dist/esm/Redaction.d.ts +350 -0
- package/dist/esm/Redaction.d.ts.map +1 -0
- package/dist/esm/Redaction.js +1584 -0
- package/dist/esm/Redaction.js.map +1 -0
- package/dist/esm/SqlConsensus.d.ts +44 -0
- package/dist/esm/SqlConsensus.d.ts.map +1 -0
- package/dist/esm/SqlConsensus.js +252 -0
- package/dist/esm/SqlConsensus.js.map +1 -0
- package/dist/esm/SqlJournal.d.ts +173 -0
- package/dist/esm/SqlJournal.d.ts.map +1 -0
- package/dist/esm/SqlJournal.js +1858 -0
- package/dist/esm/SqlJournal.js.map +1 -0
- package/dist/esm/StepFact.d.ts +66 -0
- package/dist/esm/StepFact.d.ts.map +1 -0
- package/dist/esm/StepFact.js +50 -0
- package/dist/esm/StepFact.js.map +1 -0
- package/dist/esm/index.d.ts +95 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +95 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal/JournalInternalFault.d.ts +37 -0
- package/dist/esm/internal/JournalInternalFault.d.ts.map +1 -0
- package/dist/esm/internal/JournalInternalFault.js +28 -0
- package/dist/esm/internal/JournalInternalFault.js.map +1 -0
- package/dist/esm/migrations/0001_initial.d.ts +15 -0
- package/dist/esm/migrations/0001_initial.d.ts.map +1 -0
- package/dist/esm/migrations/0001_initial.js +32 -0
- package/dist/esm/migrations/0001_initial.js.map +1 -0
- package/dist/esm/migrations/0002_checkpoints.d.ts +27 -0
- package/dist/esm/migrations/0002_checkpoints.d.ts.map +1 -0
- package/dist/esm/migrations/0002_checkpoints.js +38 -0
- package/dist/esm/migrations/0002_checkpoints.js.map +1 -0
- package/dist/esm/migrations/0003_startup_index.d.ts +15 -0
- package/dist/esm/migrations/0003_startup_index.d.ts.map +1 -0
- package/dist/esm/migrations/0003_startup_index.js +18 -0
- package/dist/esm/migrations/0003_startup_index.js.map +1 -0
- package/dist/esm/migrations/0004_dedup.d.ts +15 -0
- package/dist/esm/migrations/0004_dedup.d.ts.map +1 -0
- package/dist/esm/migrations/0004_dedup.js +38 -0
- package/dist/esm/migrations/0004_dedup.js.map +1 -0
- package/dist/esm/migrations/0005_run_event_type.d.ts +15 -0
- package/dist/esm/migrations/0005_run_event_type.d.ts.map +1 -0
- package/dist/esm/migrations/0005_run_event_type.js +18 -0
- package/dist/esm/migrations/0005_run_event_type.js.map +1 -0
- package/dist/esm/migrations/0006_consensus.d.ts +22 -0
- package/dist/esm/migrations/0006_consensus.d.ts.map +1 -0
- package/dist/esm/migrations/0006_consensus.js +69 -0
- package/dist/esm/migrations/0006_consensus.js.map +1 -0
- package/dist/esm/test/Notifying.d.ts +65 -0
- package/dist/esm/test/Notifying.d.ts.map +1 -0
- package/dist/esm/test/Notifying.js +62 -0
- package/dist/esm/test/Notifying.js.map +1 -0
- package/dist/esm/test/TestJournal.d.ts +43 -0
- package/dist/esm/test/TestJournal.d.ts.map +1 -0
- package/dist/esm/test/TestJournal.js +27 -0
- package/dist/esm/test/TestJournal.js.map +1 -0
- package/docs/README.md +164 -0
- package/docs/api.md +639 -0
- package/docs/concepts/compaction.md +157 -0
- package/docs/concepts/idempotency.md +127 -0
- package/docs/concepts/owner-fence.md +124 -0
- package/docs/concepts/redaction.md +218 -0
- package/docs/concepts/state-event-authority.md +159 -0
- package/docs/concepts/two-channels.md +167 -0
- package/docs/guides/commit-state-and-entry.md +114 -0
- package/docs/guides/compact-a-run.md +134 -0
- package/docs/guides/fold-a-projection.md +106 -0
- package/docs/guides/read-a-run.md +139 -0
- package/docs/guides/redact-log-output.md +94 -0
- package/docs/guides/testing.md +124 -0
- package/docs/guides/write-lifecycle-events.md +110 -0
- package/docs/installation.md +133 -0
- package/docs/quickstart.md +143 -0
- package/docs/troubleshooting.md +214 -0
- package/package.json +263 -3
- package/src/CallFact.ts +117 -0
- package/src/Consensus.ts +683 -0
- package/src/EngineEvent.ts +823 -0
- package/src/ExecutionFact.ts +433 -0
- package/src/Journal.ts +688 -0
- package/src/JournalEvent.ts +654 -0
- package/src/JournalGeneration.ts +77 -0
- package/src/JournalMetrics.ts +89 -0
- package/src/Migrations.ts +62 -0
- package/src/OwnerId.ts +42 -0
- package/src/Projection.ts +31 -0
- package/src/RedactedLogger.ts +483 -0
- package/src/Redaction.ts +1784 -0
- package/src/SqlConsensus.ts +344 -0
- package/src/SqlJournal.ts +2732 -0
- package/src/StepFact.ts +69 -0
- package/src/index.ts +109 -0
- package/src/internal/JournalInternalFault.ts +40 -0
- package/src/migrations/0001_initial.ts +41 -0
- package/src/migrations/0002_checkpoints.ts +46 -0
- package/src/migrations/0003_startup_index.ts +19 -0
- package/src/migrations/0004_dedup.ts +43 -0
- package/src/migrations/0005_run_event_type.ts +19 -0
- package/src/migrations/0006_consensus.ts +83 -0
- package/src/test/Notifying.ts +101 -0
- package/src/test/TestJournal.ts +52 -0
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native execution observations, independent of operational ownership leases.
|
|
3
|
+
* @since 1.0.0
|
|
4
|
+
*/
|
|
5
|
+
import * as Schema from "effect/Schema";
|
|
6
|
+
import * as Event from "./JournalEvent.js";
|
|
7
|
+
/** Native semantic lifecycle fields recorded by the owning writer.
|
|
8
|
+
* @category schemas
|
|
9
|
+
* @since 1.0.0
|
|
10
|
+
*/
|
|
11
|
+
export const Observation = Schema.Struct({
|
|
12
|
+
executionId: Event.RunId,
|
|
13
|
+
flowName: Schema.NonEmptyString,
|
|
14
|
+
status: Schema.Literals(["pending", "running", "suspended", "completed", "failed", "cancelled"]),
|
|
15
|
+
createdAtMs: Event.TimestampMs,
|
|
16
|
+
startedAtMs: Schema.NullOr(Event.TimestampMs),
|
|
17
|
+
finishedAtMs: Schema.NullOr(Event.TimestampMs),
|
|
18
|
+
parentRunId: Schema.NullOr(Event.RunId),
|
|
19
|
+
lineageId: Event.RunId,
|
|
20
|
+
roundOrdinal: Event.NonNegativeQuantity,
|
|
21
|
+
cancelRequestedAtMs: Schema.NullOr(Event.TimestampMs),
|
|
22
|
+
// Additive v1 extension: absent means the producer did not cover tree waits.
|
|
23
|
+
treeVersion: Schema.optional(Schema.Literal(1)),
|
|
24
|
+
parentPolicy: Schema.optional(Schema.Literals(["cancel", "detach"])),
|
|
25
|
+
waiting: Schema.NullOr(Schema.Struct({
|
|
26
|
+
reason: Schema.NonEmptyString,
|
|
27
|
+
wakeAtMs: Schema.NullOr(Event.TimestampMs),
|
|
28
|
+
tokenDigest: Schema.NullOr(Schema.NonEmptyString),
|
|
29
|
+
point: Schema.optional(Schema.NullOr(Schema.String)),
|
|
30
|
+
request: Schema.optional(Schema.NullOr(Schema.Json))
|
|
31
|
+
}))
|
|
32
|
+
});
|
|
33
|
+
/** A new observation baseline never invents the preceding history.
|
|
34
|
+
* @category schemas
|
|
35
|
+
* @since 1.0.0
|
|
36
|
+
*/
|
|
37
|
+
export const Fact = Schema.Struct({
|
|
38
|
+
version: Schema.Literal(1),
|
|
39
|
+
baseline: Schema.Literals(["created", "legacy"]),
|
|
40
|
+
observation: Observation
|
|
41
|
+
});
|
|
42
|
+
/** A corrupt/legacy row can still settle, but cannot establish a replay baseline.
|
|
43
|
+
* @category schemas
|
|
44
|
+
* @since 1.0.0
|
|
45
|
+
*/
|
|
46
|
+
export const UnavailableFact = Schema.Struct({
|
|
47
|
+
version: Schema.Literal(1),
|
|
48
|
+
unavailable: Schema.Literal("invalid-observation")
|
|
49
|
+
});
|
|
50
|
+
/** Root identity stays fixed while lifecycle follows its latest trampoline round.
|
|
51
|
+
* @category schemas
|
|
52
|
+
* @since 1.0.0
|
|
53
|
+
*/
|
|
54
|
+
export const View = Schema.Struct({
|
|
55
|
+
root: Observation,
|
|
56
|
+
current: Observation,
|
|
57
|
+
/** Redacted display observations; opaque wake tokens are never journal authority. */
|
|
58
|
+
humanWaits: Schema.optional(Schema.Array(Observation))
|
|
59
|
+
});
|
|
60
|
+
/** Honest replay coverage of the selected native root and current round.
|
|
61
|
+
* @category schemas
|
|
62
|
+
* @since 1.0.0
|
|
63
|
+
*/
|
|
64
|
+
export const Provenance = Schema.Struct({
|
|
65
|
+
source: Schema.Literals(["events", "legacy-observation", "unverified-observation"]),
|
|
66
|
+
rootExecutionId: Schema.String,
|
|
67
|
+
humanWaits: Schema.optional(Schema.Literals(["events", "legacy-observation", "unverified-observation"])),
|
|
68
|
+
/** Tree coverage starts independently in every native run-local stream. */
|
|
69
|
+
humanWaitSources: Schema.optional(Schema.Array(Schema.Struct({
|
|
70
|
+
executionId: Schema.String,
|
|
71
|
+
generation: Schema.Number,
|
|
72
|
+
baseline: Schema.Literals(["created", "legacy"]),
|
|
73
|
+
fromSequence: Schema.Number,
|
|
74
|
+
throughSequence: Schema.Number
|
|
75
|
+
}))),
|
|
76
|
+
currentExecutionId: Schema.optional(Schema.String),
|
|
77
|
+
generation: Schema.optional(Schema.Number),
|
|
78
|
+
baseline: Schema.optional(Schema.Literals(["created", "legacy"])),
|
|
79
|
+
fromSequence: Schema.optional(Schema.Number),
|
|
80
|
+
throughSequence: Schema.optional(Schema.Number)
|
|
81
|
+
});
|
|
82
|
+
const record = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
83
|
+
// The journal canonicalizes object key order. Display metadata compares JSON
|
|
84
|
+
// values, so a writer's insertion order cannot turn an equal question into a gap.
|
|
85
|
+
const equalJson = (left, right) => {
|
|
86
|
+
if (left === right)
|
|
87
|
+
return true;
|
|
88
|
+
if (left === null || right === null || typeof left !== "object" || typeof right !== "object")
|
|
89
|
+
return false;
|
|
90
|
+
if (Array.isArray(left) || Array.isArray(right)) {
|
|
91
|
+
return Array.isArray(left) && Array.isArray(right) &&
|
|
92
|
+
left.length === right.length && left.every((value, index) => equalJson(value, right[index]));
|
|
93
|
+
}
|
|
94
|
+
const keys = Object.keys(left).sort();
|
|
95
|
+
const other = Object.keys(right).sort();
|
|
96
|
+
return keys.length === other.length && keys.every((key, index) => key === other[index] &&
|
|
97
|
+
equalJson(left[key], right[key]));
|
|
98
|
+
};
|
|
99
|
+
/** Compare semantic state only; heartbeat and owner incarnation are operational.
|
|
100
|
+
* @category projections
|
|
101
|
+
* @since 1.0.0
|
|
102
|
+
*/
|
|
103
|
+
export const equal = (left, right) => left.executionId === right.executionId && left.flowName === right.flowName && left.status === right.status &&
|
|
104
|
+
left.createdAtMs === right.createdAtMs && left.startedAtMs === right.startedAtMs &&
|
|
105
|
+
left.finishedAtMs === right.finishedAtMs &&
|
|
106
|
+
left.parentRunId === right.parentRunId && left.lineageId === right.lineageId &&
|
|
107
|
+
left.roundOrdinal === right.roundOrdinal &&
|
|
108
|
+
left.cancelRequestedAtMs === right.cancelRequestedAtMs &&
|
|
109
|
+
left.treeVersion === right.treeVersion && left.parentPolicy === right.parentPolicy &&
|
|
110
|
+
(left.waiting === null ? right.waiting === null : right.waiting !== null &&
|
|
111
|
+
left.waiting.reason === right.waiting.reason && left.waiting.wakeAtMs === right.waiting.wakeAtMs &&
|
|
112
|
+
left.waiting.tokenDigest === right.waiting.tokenDigest && left.waiting.point === right.waiting.point &&
|
|
113
|
+
equalJson(left.waiting.request, right.waiting.request));
|
|
114
|
+
/**
|
|
115
|
+
* Fold native facts after a separately authenticated root binding. Sequence gaps
|
|
116
|
+
* alone are not loss: SQL journal rollbacks leave unused sequence reservations.
|
|
117
|
+
* A real omission/generation boundary invalidates coverage until a new complete
|
|
118
|
+
* baseline is recorded. Unknown producer versions never become successful replay.
|
|
119
|
+
* @category projections
|
|
120
|
+
* @since 1.0.0
|
|
121
|
+
*/
|
|
122
|
+
export const fold = (inputs, rootExecutionId, observed) => {
|
|
123
|
+
const states = new Map();
|
|
124
|
+
for (const input of inputs) {
|
|
125
|
+
let state = states.get(input.executionId);
|
|
126
|
+
if (input.generation !== null && state !== undefined && input.generation < state.generation)
|
|
127
|
+
continue;
|
|
128
|
+
if (input.gap) {
|
|
129
|
+
if (state === undefined) {
|
|
130
|
+
states.set(input.executionId, {
|
|
131
|
+
generation: input.generation ?? -1,
|
|
132
|
+
sequence: -1,
|
|
133
|
+
uncovered: true
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
if (input.generation !== null && input.generation > state.generation) {
|
|
138
|
+
state = { generation: input.generation, sequence: -1, uncovered: true };
|
|
139
|
+
states.set(input.executionId, state);
|
|
140
|
+
}
|
|
141
|
+
state.uncovered = true;
|
|
142
|
+
}
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (input.generation === null)
|
|
146
|
+
continue;
|
|
147
|
+
if (state === undefined || input.generation > state.generation) {
|
|
148
|
+
state = { generation: input.generation, sequence: -1, uncovered: state !== undefined || input.generation > 0 };
|
|
149
|
+
states.set(input.executionId, state);
|
|
150
|
+
}
|
|
151
|
+
if (input.sequence <= state.sequence)
|
|
152
|
+
continue;
|
|
153
|
+
state.sequence = input.sequence;
|
|
154
|
+
const payload = record(input.payload);
|
|
155
|
+
const candidate = payload.executionFact;
|
|
156
|
+
if (candidate === undefined) {
|
|
157
|
+
// Diagnostic decisions and wake requests are not lifecycle mutations.
|
|
158
|
+
if (state.observation !== undefined && input.eventType === "flows.engine.run-decision" &&
|
|
159
|
+
![
|
|
160
|
+
"wake-scheduled",
|
|
161
|
+
"claim-lost",
|
|
162
|
+
"activation-lost",
|
|
163
|
+
"steal-refused-owner-alive",
|
|
164
|
+
"child-policy-applied",
|
|
165
|
+
"lease-reconfirmed"
|
|
166
|
+
]
|
|
167
|
+
.includes(String(payload.decision))) {
|
|
168
|
+
state.uncovered = true;
|
|
169
|
+
}
|
|
170
|
+
if (state.observation !== undefined && input.eventType === "flows.engine.interrupted")
|
|
171
|
+
state.uncovered = true;
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
if ((input.eventType !== "flows.engine.run-decision" && input.eventType !== "flows.engine.interrupted") ||
|
|
175
|
+
!Schema.is(Fact)(candidate) || candidate.observation.executionId !== input.executionId) {
|
|
176
|
+
state.uncovered = true;
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
if (state.observation === undefined || state.uncovered) {
|
|
180
|
+
state.baseline = state.uncovered ? "legacy" : candidate.baseline;
|
|
181
|
+
state.fromSequence = input.sequence;
|
|
182
|
+
}
|
|
183
|
+
const completeTree = candidate.observation.treeVersion === 1 && candidate.observation.parentPolicy !== undefined &&
|
|
184
|
+
(candidate.observation.waiting === null || candidate.observation.waiting.point !== undefined &&
|
|
185
|
+
candidate.observation.waiting.request !== undefined);
|
|
186
|
+
if (completeTree && (state.treeFromSequence === undefined || state.uncovered)) {
|
|
187
|
+
state.treeFromSequence = input.sequence;
|
|
188
|
+
state.treeBaseline = state.uncovered || state.observation !== undefined ? "legacy" : candidate.baseline;
|
|
189
|
+
}
|
|
190
|
+
else if (!completeTree) {
|
|
191
|
+
delete state.treeFromSequence;
|
|
192
|
+
delete state.treeBaseline;
|
|
193
|
+
}
|
|
194
|
+
state.observation = candidate.observation;
|
|
195
|
+
state.uncovered = false;
|
|
196
|
+
}
|
|
197
|
+
const root = states.get(rootExecutionId);
|
|
198
|
+
let current = root;
|
|
199
|
+
if (root?.observation !== undefined) {
|
|
200
|
+
let ordinal = root.observation.roundOrdinal;
|
|
201
|
+
for (const state of states.values()) {
|
|
202
|
+
if (state.observation?.lineageId === root.observation.lineageId &&
|
|
203
|
+
state.observation.roundOrdinal > ordinal) {
|
|
204
|
+
current = state;
|
|
205
|
+
ordinal = state.observation.roundOrdinal;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
const treeApplicable = observed?.humanWaits !== undefined || current?.observation?.treeVersion === 1;
|
|
210
|
+
const reachable = new Map();
|
|
211
|
+
if (current?.observation !== undefined)
|
|
212
|
+
reachable.set(current.observation.executionId, 0);
|
|
213
|
+
for (let depth = 1; depth <= 64; depth++) {
|
|
214
|
+
let added = false;
|
|
215
|
+
for (const [id, state] of states) {
|
|
216
|
+
const observation = state.observation;
|
|
217
|
+
if (reachable.has(id) || observation === undefined || observation.parentRunId === null ||
|
|
218
|
+
observation.parentPolicy === "detach" || reachable.get(observation.parentRunId) !== depth - 1)
|
|
219
|
+
continue;
|
|
220
|
+
reachable.set(id, depth);
|
|
221
|
+
added = true;
|
|
222
|
+
}
|
|
223
|
+
if (!added)
|
|
224
|
+
break;
|
|
225
|
+
}
|
|
226
|
+
const tree = [...reachable].map(([id, depth]) => ({ state: states.get(id), depth }));
|
|
227
|
+
tree.sort((a, b) => a.depth - b.depth ||
|
|
228
|
+
a.state.observation.createdAtMs - b.state.observation.createdAtMs ||
|
|
229
|
+
// Execution ids are the reachable-map keys, so no two entries share one
|
|
230
|
+
// and the comparator never has to report a tie here.
|
|
231
|
+
(a.state.observation.executionId < b.state.observation.executionId ? -1 : 1));
|
|
232
|
+
const humanWaits = tree.flatMap(({ state }) => {
|
|
233
|
+
const observation = state.observation;
|
|
234
|
+
return !["completed", "failed", "cancelled"].includes(observation.status) &&
|
|
235
|
+
observation.waiting?.reason === "approval" && observation.waiting.tokenDigest !== null
|
|
236
|
+
? [observation] :
|
|
237
|
+
[];
|
|
238
|
+
});
|
|
239
|
+
// SQL and memory stores can enumerate an equal set of waits differently.
|
|
240
|
+
// Verify every identity and value without making store order semantic.
|
|
241
|
+
const observedHumanWaits = observed?.humanWaits;
|
|
242
|
+
const observedWaits = new Map((observedHumanWaits ?? []).map((wait) => [wait.executionId, wait]));
|
|
243
|
+
const treeCovered = treeApplicable && tree.length > 0 &&
|
|
244
|
+
// A missing/corrupt stream has unknown ancestry and cannot prove absence of a human wait.
|
|
245
|
+
[...states.values()].every((state) => state.observation !== undefined && !state.uncovered) &&
|
|
246
|
+
tree.every(({ state }) => state.observation?.treeVersion === 1 && state.observation.parentPolicy !== undefined &&
|
|
247
|
+
(state.observation.waiting === null || state.observation.waiting.point !== undefined &&
|
|
248
|
+
state.observation.waiting.request !== undefined)) &&
|
|
249
|
+
(observedHumanWaits === undefined || humanWaits.length === observedHumanWaits.length &&
|
|
250
|
+
observedWaits.size === humanWaits.length && humanWaits.every((wait) => {
|
|
251
|
+
const other = observedWaits.get(wait.executionId);
|
|
252
|
+
return other !== undefined && equal(wait, other);
|
|
253
|
+
}));
|
|
254
|
+
const view = root?.observation !== undefined && current?.observation !== undefined
|
|
255
|
+
? { root: root.observation, current: current.observation, ...(treeApplicable ? { humanWaits } : {}) } :
|
|
256
|
+
undefined;
|
|
257
|
+
const covered = view !== undefined && !root?.uncovered && !current?.uncovered &&
|
|
258
|
+
(!treeApplicable || treeCovered) &&
|
|
259
|
+
(observed === undefined || equal(view.root, observed.root) && equal(view.current, observed.current));
|
|
260
|
+
return {
|
|
261
|
+
view: covered ? view : observed,
|
|
262
|
+
provenance: {
|
|
263
|
+
source: covered
|
|
264
|
+
? "events"
|
|
265
|
+
: root?.observation === undefined && !root?.uncovered
|
|
266
|
+
? "legacy-observation"
|
|
267
|
+
: "unverified-observation",
|
|
268
|
+
rootExecutionId,
|
|
269
|
+
...(treeApplicable ?
|
|
270
|
+
{
|
|
271
|
+
humanWaits: treeCovered ?
|
|
272
|
+
"events" :
|
|
273
|
+
current?.observation?.treeVersion === 1
|
|
274
|
+
? "unverified-observation"
|
|
275
|
+
: "legacy-observation"
|
|
276
|
+
} :
|
|
277
|
+
{}),
|
|
278
|
+
...(treeCovered ?
|
|
279
|
+
{
|
|
280
|
+
humanWaitSources: tree.map(({ state }) => ({
|
|
281
|
+
executionId: state.observation.executionId,
|
|
282
|
+
generation: state.generation,
|
|
283
|
+
baseline: state.treeBaseline,
|
|
284
|
+
fromSequence: state.treeFromSequence,
|
|
285
|
+
throughSequence: state.sequence
|
|
286
|
+
}))
|
|
287
|
+
} :
|
|
288
|
+
{}),
|
|
289
|
+
...(current?.observation === undefined ? {} : { currentExecutionId: current.observation.executionId }),
|
|
290
|
+
...(current === undefined ? {} : { generation: current.generation }),
|
|
291
|
+
...(current?.baseline === undefined
|
|
292
|
+
? {}
|
|
293
|
+
: { baseline: root?.baseline === "legacy" ? "legacy" : current.baseline }),
|
|
294
|
+
...(current?.fromSequence === undefined ? {} : { fromSequence: current.fromSequence }),
|
|
295
|
+
...(current === undefined ? {} : { throughSequence: current.sequence })
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
};
|
|
299
|
+
/** Interpret only the host's explicit root binding, never an ID naming convention.
|
|
300
|
+
* @category projections
|
|
301
|
+
* @since 1.0.0
|
|
302
|
+
*/
|
|
303
|
+
export const foldControl = (events, controlRunId, observed) => {
|
|
304
|
+
let root;
|
|
305
|
+
let conflicting = false;
|
|
306
|
+
const inputs = [];
|
|
307
|
+
for (const event of events) {
|
|
308
|
+
if (event.runId !== controlRunId)
|
|
309
|
+
continue;
|
|
310
|
+
const payload = record(event.payload);
|
|
311
|
+
if (event.kind === "control.engine.bound") {
|
|
312
|
+
if (payload.version !== 1 || payload.controlRunId !== controlRunId || typeof payload.executionId !== "string" ||
|
|
313
|
+
payload.executionId.length === 0) {
|
|
314
|
+
conflicting = true;
|
|
315
|
+
}
|
|
316
|
+
else if (root !== undefined && root !== payload.executionId)
|
|
317
|
+
conflicting = true;
|
|
318
|
+
else
|
|
319
|
+
root = payload.executionId;
|
|
320
|
+
}
|
|
321
|
+
if (event.kind === "control.engine.event" && payload.version === 1 && typeof payload.executionId === "string" &&
|
|
322
|
+
typeof payload.generation === "number" && Number.isSafeInteger(payload.generation) && payload.generation >= 0 &&
|
|
323
|
+
typeof payload.sequence === "number" && Number.isSafeInteger(payload.sequence) && payload.sequence >= 0 &&
|
|
324
|
+
typeof payload.eventType === "string") {
|
|
325
|
+
inputs.push({
|
|
326
|
+
executionId: payload.executionId,
|
|
327
|
+
generation: payload.generation,
|
|
328
|
+
sequence: payload.sequence,
|
|
329
|
+
eventType: payload.eventType,
|
|
330
|
+
payload: payload.payload
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
if (event.kind === "control.engine.event" &&
|
|
334
|
+
!(payload.version === 1 && typeof payload.executionId === "string" &&
|
|
335
|
+
typeof payload.generation === "number" && Number.isSafeInteger(payload.generation) && payload.generation >= 0 &&
|
|
336
|
+
typeof payload.sequence === "number" && Number.isSafeInteger(payload.sequence) && payload.sequence >= 0 &&
|
|
337
|
+
typeof payload.eventType === "string")) {
|
|
338
|
+
if (typeof payload.executionId !== "string")
|
|
339
|
+
conflicting = true;
|
|
340
|
+
else {
|
|
341
|
+
inputs.push({
|
|
342
|
+
executionId: payload.executionId,
|
|
343
|
+
generation: null,
|
|
344
|
+
sequence: -1,
|
|
345
|
+
eventType: event.kind,
|
|
346
|
+
payload,
|
|
347
|
+
gap: true
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
if (event.kind === "control.engine.projection-gap" && typeof payload.executionId === "string") {
|
|
352
|
+
inputs.push({
|
|
353
|
+
executionId: payload.executionId,
|
|
354
|
+
generation: typeof payload.generation === "number" ? payload.generation : null,
|
|
355
|
+
sequence: -1,
|
|
356
|
+
eventType: event.kind,
|
|
357
|
+
payload,
|
|
358
|
+
gap: true
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
if (root === undefined || conflicting || observed !== undefined && observed.root.executionId !== root) {
|
|
363
|
+
return observed === undefined ? undefined : {
|
|
364
|
+
view: observed,
|
|
365
|
+
provenance: {
|
|
366
|
+
source: conflicting || root !== undefined ? "unverified-observation" : "legacy-observation",
|
|
367
|
+
rootExecutionId: observed.root.executionId,
|
|
368
|
+
currentExecutionId: observed.current.executionId
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
return fold(inputs, root, observed);
|
|
373
|
+
};
|
|
374
|
+
//# sourceMappingURL=ExecutionFact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExecutionFact.js","sourceRoot":"","sources":["../../src/ExecutionFact.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Native execution observations, independent of operational ownership leases.\n * @since 1.0.0\n */\n\nimport * as Schema from \"effect/Schema\"\nimport * as Event from \"./JournalEvent.ts\"\n\n/** Native semantic lifecycle fields recorded by the owning writer.\n * @category schemas\n * @since 1.0.0\n */\nexport const Observation = Schema.Struct({\n executionId: Event.RunId,\n flowName: Schema.NonEmptyString,\n status: Schema.Literals([\"pending\", \"running\", \"suspended\", \"completed\", \"failed\", \"cancelled\"]),\n createdAtMs: Event.TimestampMs,\n startedAtMs: Schema.NullOr(Event.TimestampMs),\n finishedAtMs: Schema.NullOr(Event.TimestampMs),\n parentRunId: Schema.NullOr(Event.RunId),\n lineageId: Event.RunId,\n roundOrdinal: Event.NonNegativeQuantity,\n cancelRequestedAtMs: Schema.NullOr(Event.TimestampMs),\n // Additive v1 extension: absent means the producer did not cover tree waits.\n treeVersion: Schema.optional(Schema.Literal(1)),\n parentPolicy: Schema.optional(Schema.Literals([\"cancel\", \"detach\"])),\n waiting: Schema.NullOr(Schema.Struct({\n reason: Schema.NonEmptyString,\n wakeAtMs: Schema.NullOr(Event.TimestampMs),\n tokenDigest: Schema.NullOr(Schema.NonEmptyString),\n point: Schema.optional(Schema.NullOr(Schema.String)),\n request: Schema.optional(Schema.NullOr(Schema.Json))\n }))\n})\n/** The value form of a native execution observation.\n * @category models\n * @since 1.0.0\n */\nexport type Observation = typeof Observation.Type\n\n/** A new observation baseline never invents the preceding history.\n * @category schemas\n * @since 1.0.0\n */\nexport const Fact = Schema.Struct({\n version: Schema.Literal(1),\n baseline: Schema.Literals([\"created\", \"legacy\"]),\n observation: Observation\n})\n\n/** A corrupt/legacy row can still settle, but cannot establish a replay baseline.\n * @category schemas\n * @since 1.0.0\n */\nexport const UnavailableFact = Schema.Struct({\n version: Schema.Literal(1),\n unavailable: Schema.Literal(\"invalid-observation\")\n})\n\n/** Root identity stays fixed while lifecycle follows its latest trampoline round.\n * @category schemas\n * @since 1.0.0\n */\nexport const View = Schema.Struct({\n root: Observation,\n current: Observation,\n /** Redacted display observations; opaque wake tokens are never journal authority. */\n humanWaits: Schema.optional(Schema.Array(Observation))\n})\n/** The value form of a logical execution view.\n * @category models\n * @since 1.0.0\n */\nexport type View = typeof View.Type\n\n/** Source positions are native run-local sequence plus native journal generation.\n * @category models\n * @since 1.0.0\n */\nexport interface Input {\n readonly executionId: string\n readonly generation: number | null\n readonly sequence: number\n readonly eventType: string\n readonly payload: unknown\n readonly gap?: boolean\n}\n/** Honest replay coverage of the selected native root and current round.\n * @category schemas\n * @since 1.0.0\n */\nexport const Provenance = Schema.Struct({\n source: Schema.Literals([\"events\", \"legacy-observation\", \"unverified-observation\"]),\n rootExecutionId: Schema.String,\n humanWaits: Schema.optional(Schema.Literals([\"events\", \"legacy-observation\", \"unverified-observation\"])),\n /** Tree coverage starts independently in every native run-local stream. */\n humanWaitSources: Schema.optional(Schema.Array(Schema.Struct({\n executionId: Schema.String,\n generation: Schema.Number,\n baseline: Schema.Literals([\"created\", \"legacy\"]),\n fromSequence: Schema.Number,\n throughSequence: Schema.Number\n }))),\n currentExecutionId: Schema.optional(Schema.String),\n generation: Schema.optional(Schema.Number),\n baseline: Schema.optional(Schema.Literals([\"created\", \"legacy\"])),\n fromSequence: Schema.optional(Schema.Number),\n throughSequence: Schema.optional(Schema.Number)\n})\n\nconst record = (value: unknown): Record<string, unknown> =>\n value !== null && typeof value === \"object\" && !Array.isArray(value) ? value as Record<string, unknown> : {}\n\n// The journal canonicalizes object key order. Display metadata compares JSON\n// values, so a writer's insertion order cannot turn an equal question into a gap.\nconst equalJson = (left: unknown, right: unknown): boolean => {\n if (left === right) return true\n if (left === null || right === null || typeof left !== \"object\" || typeof right !== \"object\") return false\n if (Array.isArray(left) || Array.isArray(right)) {\n return Array.isArray(left) && Array.isArray(right) &&\n left.length === right.length && left.every((value, index) => equalJson(value, right[index]))\n }\n const keys = Object.keys(left).sort()\n const other = Object.keys(right).sort()\n return keys.length === other.length && keys.every((key, index) =>\n key === other[index] &&\n equalJson((left as Record<string, unknown>)[key], (right as Record<string, unknown>)[key])\n )\n}\n\n/** Compare semantic state only; heartbeat and owner incarnation are operational.\n * @category projections\n * @since 1.0.0\n */\nexport const equal = (left: Observation, right: Observation): boolean =>\n left.executionId === right.executionId && left.flowName === right.flowName && left.status === right.status &&\n left.createdAtMs === right.createdAtMs && left.startedAtMs === right.startedAtMs &&\n left.finishedAtMs === right.finishedAtMs &&\n left.parentRunId === right.parentRunId && left.lineageId === right.lineageId &&\n left.roundOrdinal === right.roundOrdinal &&\n left.cancelRequestedAtMs === right.cancelRequestedAtMs &&\n left.treeVersion === right.treeVersion && left.parentPolicy === right.parentPolicy &&\n (left.waiting === null ? right.waiting === null : right.waiting !== null &&\n left.waiting.reason === right.waiting.reason && left.waiting.wakeAtMs === right.waiting.wakeAtMs &&\n left.waiting.tokenDigest === right.waiting.tokenDigest && left.waiting.point === right.waiting.point &&\n equalJson(left.waiting.request, right.waiting.request))\n\n/**\n * Fold native facts after a separately authenticated root binding. Sequence gaps\n * alone are not loss: SQL journal rollbacks leave unused sequence reservations.\n * A real omission/generation boundary invalidates coverage until a new complete\n * baseline is recorded. Unknown producer versions never become successful replay.\n * @category projections\n * @since 1.0.0\n */\nexport const fold = (inputs: ReadonlyArray<Input>, rootExecutionId: string, observed?: View): {\n readonly view: View | undefined\n readonly provenance: typeof Provenance.Type\n} => {\n interface State {\n generation: number\n sequence: number\n observation?: Observation\n baseline?: \"created\" | \"legacy\"\n fromSequence?: number\n treeFromSequence?: number\n treeBaseline?: \"created\" | \"legacy\"\n uncovered: boolean\n }\n const states = new Map<string, State>()\n for (const input of inputs) {\n let state = states.get(input.executionId)\n if (input.generation !== null && state !== undefined && input.generation < state.generation) continue\n if (input.gap) {\n if (state === undefined) {\n states.set(input.executionId, {\n generation: input.generation ?? -1,\n sequence: -1,\n uncovered: true\n })\n } else {\n if (input.generation !== null && input.generation > state.generation) {\n state = { generation: input.generation, sequence: -1, uncovered: true }\n states.set(input.executionId, state)\n }\n state.uncovered = true\n }\n continue\n }\n if (input.generation === null) continue\n if (state === undefined || input.generation > state.generation) {\n state = { generation: input.generation, sequence: -1, uncovered: state !== undefined || input.generation > 0 }\n states.set(input.executionId, state)\n }\n if (input.sequence <= state.sequence) continue\n state.sequence = input.sequence\n const payload = record(input.payload)\n const candidate = payload.executionFact\n if (candidate === undefined) {\n // Diagnostic decisions and wake requests are not lifecycle mutations.\n if (\n state.observation !== undefined && input.eventType === \"flows.engine.run-decision\" &&\n ![\n \"wake-scheduled\",\n \"claim-lost\",\n \"activation-lost\",\n \"steal-refused-owner-alive\",\n \"child-policy-applied\",\n \"lease-reconfirmed\"\n ]\n .includes(String(payload.decision))\n ) {\n state.uncovered = true\n }\n if (state.observation !== undefined && input.eventType === \"flows.engine.interrupted\") state.uncovered = true\n continue\n }\n if (\n (input.eventType !== \"flows.engine.run-decision\" && input.eventType !== \"flows.engine.interrupted\") ||\n !Schema.is(Fact)(candidate) || candidate.observation.executionId !== input.executionId\n ) {\n state.uncovered = true\n continue\n }\n if (state.observation === undefined || state.uncovered) {\n state.baseline = state.uncovered ? \"legacy\" : candidate.baseline\n state.fromSequence = input.sequence\n }\n const completeTree = candidate.observation.treeVersion === 1 && candidate.observation.parentPolicy !== undefined &&\n (candidate.observation.waiting === null || candidate.observation.waiting.point !== undefined &&\n candidate.observation.waiting.request !== undefined)\n if (completeTree && (state.treeFromSequence === undefined || state.uncovered)) {\n state.treeFromSequence = input.sequence\n state.treeBaseline = state.uncovered || state.observation !== undefined ? \"legacy\" : candidate.baseline\n } else if (!completeTree) {\n delete state.treeFromSequence\n delete state.treeBaseline\n }\n state.observation = candidate.observation\n state.uncovered = false\n }\n const root = states.get(rootExecutionId)\n let current = root\n if (root?.observation !== undefined) {\n let ordinal = root.observation.roundOrdinal\n for (const state of states.values()) {\n if (\n state.observation?.lineageId === root.observation.lineageId &&\n state.observation.roundOrdinal > ordinal\n ) {\n current = state\n ordinal = state.observation.roundOrdinal\n }\n }\n }\n const treeApplicable = observed?.humanWaits !== undefined || current?.observation?.treeVersion === 1\n const reachable = new Map<string, number>()\n if (current?.observation !== undefined) reachable.set(current.observation.executionId, 0)\n for (let depth = 1; depth <= 64; depth++) {\n let added = false\n for (const [id, state] of states) {\n const observation = state.observation\n if (\n reachable.has(id) || observation === undefined || observation.parentRunId === null ||\n observation.parentPolicy === \"detach\" || reachable.get(observation.parentRunId) !== depth - 1\n ) continue\n reachable.set(id, depth)\n added = true\n }\n if (!added) break\n }\n const tree = [...reachable].map(([id, depth]) => ({ state: states.get(id)!, depth }))\n tree.sort((a, b) =>\n a.depth - b.depth ||\n a.state.observation!.createdAtMs - b.state.observation!.createdAtMs ||\n // Execution ids are the reachable-map keys, so no two entries share one\n // and the comparator never has to report a tie here.\n (a.state.observation!.executionId < b.state.observation!.executionId ? -1 : 1)\n )\n const humanWaits = tree.flatMap(({ state }) => {\n const observation = state.observation!\n return ![\"completed\", \"failed\", \"cancelled\"].includes(observation.status) &&\n observation.waiting?.reason === \"approval\" && observation.waiting.tokenDigest !== null\n ? [observation] :\n []\n })\n // SQL and memory stores can enumerate an equal set of waits differently.\n // Verify every identity and value without making store order semantic.\n const observedHumanWaits = observed?.humanWaits\n const observedWaits = new Map((observedHumanWaits ?? []).map((wait) => [wait.executionId, wait]))\n const treeCovered = treeApplicable && tree.length > 0 &&\n // A missing/corrupt stream has unknown ancestry and cannot prove absence of a human wait.\n [...states.values()].every((state) => state.observation !== undefined && !state.uncovered) &&\n tree.every(({ state }) =>\n state.observation?.treeVersion === 1 && state.observation.parentPolicy !== undefined &&\n (state.observation.waiting === null || state.observation.waiting.point !== undefined &&\n state.observation.waiting.request !== undefined)\n ) &&\n (observedHumanWaits === undefined || humanWaits.length === observedHumanWaits.length &&\n observedWaits.size === humanWaits.length && humanWaits.every((wait) => {\n const other = observedWaits.get(wait.executionId)\n return other !== undefined && equal(wait, other)\n }))\n const view = root?.observation !== undefined && current?.observation !== undefined\n ? { root: root.observation, current: current.observation, ...(treeApplicable ? { humanWaits } : {}) } :\n undefined\n const covered = view !== undefined && !root?.uncovered && !current?.uncovered &&\n (!treeApplicable || treeCovered) &&\n (observed === undefined || equal(view.root, observed.root) && equal(view.current, observed.current))\n return {\n view: covered ? view : observed,\n provenance: {\n source: covered\n ? \"events\"\n : root?.observation === undefined && !root?.uncovered\n ? \"legacy-observation\"\n : \"unverified-observation\",\n rootExecutionId,\n ...(treeApplicable ?\n {\n humanWaits: treeCovered ?\n \"events\" as const :\n current?.observation?.treeVersion === 1\n ? \"unverified-observation\" as const\n : \"legacy-observation\" as const\n } :\n {}),\n ...(treeCovered ?\n {\n humanWaitSources: tree.map(({ state }) => ({\n executionId: state.observation!.executionId,\n generation: state.generation,\n baseline: state.treeBaseline!,\n fromSequence: state.treeFromSequence!,\n throughSequence: state.sequence\n }))\n } :\n {}),\n ...(current?.observation === undefined ? {} : { currentExecutionId: current.observation.executionId }),\n ...(current === undefined ? {} : { generation: current.generation }),\n ...(current?.baseline === undefined\n ? {}\n : { baseline: root?.baseline === \"legacy\" ? \"legacy\" : current.baseline }),\n ...(current?.fromSequence === undefined ? {} : { fromSequence: current.fromSequence }),\n ...(current === undefined ? {} : { throughSequence: current.sequence })\n }\n }\n}\n\n/** Control bridge inputs retain their native run-local positions and generation.\n * @category models\n * @since 1.0.0\n */\nexport interface BridgeEvent {\n readonly runId?: string | undefined\n readonly kind: string\n readonly payload: unknown\n}\n\n/** Interpret only the host's explicit root binding, never an ID naming convention.\n * @category projections\n * @since 1.0.0\n */\nexport const foldControl = (events: ReadonlyArray<BridgeEvent>, controlRunId: string, observed?: View) => {\n let root: string | undefined\n let conflicting = false\n const inputs: Array<Input> = []\n for (const event of events) {\n if (event.runId !== controlRunId) continue\n const payload = record(event.payload)\n if (event.kind === \"control.engine.bound\") {\n if (\n payload.version !== 1 || payload.controlRunId !== controlRunId || typeof payload.executionId !== \"string\" ||\n payload.executionId.length === 0\n ) {\n conflicting = true\n } else if (root !== undefined && root !== payload.executionId) conflicting = true\n else root = payload.executionId\n }\n if (\n event.kind === \"control.engine.event\" && payload.version === 1 && typeof payload.executionId === \"string\" &&\n typeof payload.generation === \"number\" && Number.isSafeInteger(payload.generation) && payload.generation >= 0 &&\n typeof payload.sequence === \"number\" && Number.isSafeInteger(payload.sequence) && payload.sequence >= 0 &&\n typeof payload.eventType === \"string\"\n ) {\n inputs.push({\n executionId: payload.executionId,\n generation: payload.generation,\n sequence: payload.sequence,\n eventType: payload.eventType,\n payload: payload.payload\n })\n }\n if (\n event.kind === \"control.engine.event\" &&\n !(payload.version === 1 && typeof payload.executionId === \"string\" &&\n typeof payload.generation === \"number\" && Number.isSafeInteger(payload.generation) && payload.generation >= 0 &&\n typeof payload.sequence === \"number\" && Number.isSafeInteger(payload.sequence) && payload.sequence >= 0 &&\n typeof payload.eventType === \"string\")\n ) {\n if (typeof payload.executionId !== \"string\") conflicting = true\n else {inputs.push({\n executionId: payload.executionId,\n generation: null,\n sequence: -1,\n eventType: event.kind,\n payload,\n gap: true\n })}\n }\n if (event.kind === \"control.engine.projection-gap\" && typeof payload.executionId === \"string\") {\n inputs.push({\n executionId: payload.executionId,\n generation: typeof payload.generation === \"number\" ? payload.generation : null,\n sequence: -1,\n eventType: event.kind,\n payload,\n gap: true\n })\n }\n }\n if (root === undefined || conflicting || observed !== undefined && observed.root.executionId !== root) {\n return observed === undefined ? undefined : {\n view: observed,\n provenance: {\n source: conflicting || root !== undefined ? \"unverified-observation\" as const : \"legacy-observation\" as const,\n rootExecutionId: observed.root.executionId,\n currentExecutionId: observed.current.executionId\n }\n }\n }\n return fold(inputs, root, observed)\n}\n"]}
|