instar 1.3.552 → 1.3.554

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 (50) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +71 -2
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/config/ConfigDefaults.d.ts.map +1 -1
  5. package/dist/config/ConfigDefaults.js +35 -0
  6. package/dist/config/ConfigDefaults.js.map +1 -1
  7. package/dist/core/PostUpdateMigrator.d.ts +10 -0
  8. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  9. package/dist/core/PostUpdateMigrator.js +60 -0
  10. package/dist/core/PostUpdateMigrator.js.map +1 -1
  11. package/dist/core/devGatedFeatures.d.ts.map +1 -1
  12. package/dist/core/devGatedFeatures.js +6 -0
  13. package/dist/core/devGatedFeatures.js.map +1 -1
  14. package/dist/core/types.d.ts +50 -0
  15. package/dist/core/types.d.ts.map +1 -1
  16. package/dist/core/types.js.map +1 -1
  17. package/dist/scaffold/templates.d.ts.map +1 -1
  18. package/dist/scaffold/templates.js +4 -0
  19. package/dist/scaffold/templates.js.map +1 -1
  20. package/dist/scheduler/JobLeaseClaimStore.d.ts +105 -0
  21. package/dist/scheduler/JobLeaseClaimStore.d.ts.map +1 -0
  22. package/dist/scheduler/JobLeaseClaimStore.js +165 -0
  23. package/dist/scheduler/JobLeaseClaimStore.js.map +1 -0
  24. package/dist/scheduler/JobLeaseCutoverGate.d.ts +73 -0
  25. package/dist/scheduler/JobLeaseCutoverGate.d.ts.map +1 -0
  26. package/dist/scheduler/JobLeaseCutoverGate.js +66 -0
  27. package/dist/scheduler/JobLeaseCutoverGate.js.map +1 -0
  28. package/dist/scheduler/JobScheduler.d.ts +53 -0
  29. package/dist/scheduler/JobScheduler.d.ts.map +1 -1
  30. package/dist/scheduler/JobScheduler.js +136 -20
  31. package/dist/scheduler/JobScheduler.js.map +1 -1
  32. package/dist/server/AgentServer.d.ts +3 -0
  33. package/dist/server/AgentServer.d.ts.map +1 -1
  34. package/dist/server/AgentServer.js +3 -0
  35. package/dist/server/AgentServer.js.map +1 -1
  36. package/dist/server/PoolPollCache.d.ts +136 -0
  37. package/dist/server/PoolPollCache.d.ts.map +1 -0
  38. package/dist/server/PoolPollCache.js +163 -0
  39. package/dist/server/PoolPollCache.js.map +1 -0
  40. package/dist/server/routes.d.ts +9 -0
  41. package/dist/server/routes.d.ts.map +1 -1
  42. package/dist/server/routes.js +51 -8
  43. package/dist/server/routes.js.map +1 -1
  44. package/package.json +1 -1
  45. package/src/data/builtin-manifest.json +65 -65
  46. package/src/scaffold/templates.ts +4 -0
  47. package/upgrades/1.3.553.md +63 -0
  48. package/upgrades/1.3.554.md +79 -0
  49. package/upgrades/side-effects/multi-machine-seamlessness-ws44-pool-cache.md +115 -0
  50. package/upgrades/side-effects/ws43-journal-lease-cutover.md +132 -0
@@ -0,0 +1,105 @@
1
+ /**
2
+ * JobLeaseClaimStore — WS4.3 durable, epoch-fenced job-claim leases.
3
+ *
4
+ * (MULTI-MACHINE-SEAMLESSNESS-SPEC §WS4.3, "Cutover discipline".)
5
+ *
6
+ * The journal-backed upgrade of the best-effort `JobClaimManager` bus
7
+ * broadcast. A claim is a LEASE with a fenced ownership epoch: a receiver
8
+ * rejects a stale-epoch claim (invariant-4 epoch fencing), so a demoted
9
+ * machine's late claim cannot steal a job from the current lease-holder, and a
10
+ * partition double-run is structurally prevented when the journal is reachable.
11
+ *
12
+ * Claim records store METADATA ONLY — machine id, job slug, epoch, timestamps —
13
+ * never job payloads (the spec's explicit privacy bound). The store is the
14
+ * local materialized view of the replicated claim kind; the journal carries
15
+ * each record to peers and feeds them back through `applyRemote`.
16
+ *
17
+ * This store does NOT decide WHEN to use the journal path — that is the
18
+ * `JobLeaseCutoverGate`. The store only manages the leases once the gate has
19
+ * selected the journal path.
20
+ */
21
+ /** A durable, epoch-fenced job-claim lease. Metadata only. */
22
+ export interface JobLeaseClaim {
23
+ /** Unique claim id (idempotency key). */
24
+ claimId: string;
25
+ /** Job slug being leased. */
26
+ jobSlug: string;
27
+ /** Machine id that holds the lease. */
28
+ machineId: string;
29
+ /** The ownership epoch under which the lease was taken (fencing token). A
30
+ * claim with an epoch older than the latest seen for the slug is stale. */
31
+ epoch: number;
32
+ /** When the lease was taken (ISO 8601). */
33
+ claimedAt: string;
34
+ /** When the lease expires if no completion arrives (ISO 8601). */
35
+ expiresAt: string;
36
+ /** Whether the job completed under this lease. */
37
+ completed: boolean;
38
+ /** Completion result (set on complete). */
39
+ result?: 'success' | 'failure';
40
+ /** When the job completed (ISO 8601). */
41
+ completedAt?: string;
42
+ }
43
+ export interface JobLeaseClaimStoreConfig {
44
+ /** This machine's id. */
45
+ machineId: string;
46
+ /** State directory (.instar) for persisting the lease ledger. */
47
+ stateDir: string;
48
+ /** Default lease timeout in ms (default: 30 min). */
49
+ defaultLeaseTimeoutMs?: number;
50
+ /** Injectable clock (tests). */
51
+ now?: () => number;
52
+ }
53
+ /** The verdict of a local claim attempt. */
54
+ export type ClaimAttempt = {
55
+ ok: true;
56
+ claim: JobLeaseClaim;
57
+ }
58
+ /** Another machine holds a live, non-stale lease on this slug. */
59
+ | {
60
+ ok: false;
61
+ reason: 'held-by-peer';
62
+ heldBy: string;
63
+ }
64
+ /** We already hold a live lease (idempotent re-claim). */
65
+ | {
66
+ ok: false;
67
+ reason: 'already-own';
68
+ claim: JobLeaseClaim;
69
+ };
70
+ export declare class JobLeaseClaimStore {
71
+ private machineId;
72
+ private claimsDir;
73
+ private defaultLeaseTimeoutMs;
74
+ private now;
75
+ private claims;
76
+ constructor(config: JobLeaseClaimStoreConfig);
77
+ /**
78
+ * Attempt to take a lease on a job at the given ownership epoch.
79
+ *
80
+ * Returns the new lease on success, or a rejection when a peer holds a live,
81
+ * non-stale lease. Idempotent: re-claiming a slug this machine already leases
82
+ * (at the same-or-newer epoch) returns the existing lease.
83
+ */
84
+ tryClaim(jobSlug: string, epoch: number, timeoutMs?: number): ClaimAttempt;
85
+ /** Mark our lease on a slug complete (releases it for the next tick). */
86
+ completeClaim(jobSlug: string, result: 'success' | 'failure'): void;
87
+ /**
88
+ * Apply a claim record received from a peer over the journal. Epoch fencing:
89
+ * a record whose epoch is OLDER than the one we already hold for the slug is
90
+ * rejected (returns false) — a demoted machine's stale claim never overwrites
91
+ * a fresher lease. Returns true if the record was applied.
92
+ */
93
+ applyRemote(record: JobLeaseClaim): boolean;
94
+ /** True if a peer holds a live, non-stale lease on the slug. */
95
+ hasRemoteClaim(jobSlug: string): boolean;
96
+ getClaim(jobSlug: string): JobLeaseClaim | undefined;
97
+ getActiveClaims(): JobLeaseClaim[];
98
+ getAllClaims(): JobLeaseClaim[];
99
+ /** Remove expired (uncompleted past expiry) + old completed records. */
100
+ pruneExpired(): number;
101
+ private isExpired;
102
+ private load;
103
+ private save;
104
+ }
105
+ //# sourceMappingURL=JobLeaseClaimStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JobLeaseClaimStore.d.ts","sourceRoot":"","sources":["../../src/scheduler/JobLeaseClaimStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH,8DAA8D;AAC9D,MAAM,WAAW,aAAa;IAC5B,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB;gFAC4E;IAC5E,KAAK,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,SAAS,EAAE,OAAO,CAAC;IACnB,2CAA2C;IAC3C,MAAM,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;IAC/B,yCAAyC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,gCAAgC;IAChC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAKD,4CAA4C;AAC5C,MAAM,MAAM,YAAY,GACpB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,aAAa,CAAA;CAAE;AACpC,kEAAkE;GAChE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AACvD,0DAA0D;GACxD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,aAAa,CAAA;CAAE,CAAC;AAE/D,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,qBAAqB,CAAS;IACtC,OAAO,CAAC,GAAG,CAAe;IAC1B,OAAO,CAAC,MAAM,CAAyC;gBAE3C,MAAM,EAAE,wBAAwB;IAW5C;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY;IA8B1E,yEAAyE;IACzE,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,IAAI;IASnE;;;;;OAKG;IACH,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO;IAc3C,gEAAgE;IAChE,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOxC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAKpD,eAAe,IAAI,aAAa,EAAE;IAKlC,YAAY,IAAI,aAAa,EAAE;IAI/B,wEAAwE;IACxE,YAAY,IAAI,MAAM;IAmBtB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,IAAI;IAYZ,OAAO,CAAC,IAAI;CAMb"}
@@ -0,0 +1,165 @@
1
+ /**
2
+ * JobLeaseClaimStore — WS4.3 durable, epoch-fenced job-claim leases.
3
+ *
4
+ * (MULTI-MACHINE-SEAMLESSNESS-SPEC §WS4.3, "Cutover discipline".)
5
+ *
6
+ * The journal-backed upgrade of the best-effort `JobClaimManager` bus
7
+ * broadcast. A claim is a LEASE with a fenced ownership epoch: a receiver
8
+ * rejects a stale-epoch claim (invariant-4 epoch fencing), so a demoted
9
+ * machine's late claim cannot steal a job from the current lease-holder, and a
10
+ * partition double-run is structurally prevented when the journal is reachable.
11
+ *
12
+ * Claim records store METADATA ONLY — machine id, job slug, epoch, timestamps —
13
+ * never job payloads (the spec's explicit privacy bound). The store is the
14
+ * local materialized view of the replicated claim kind; the journal carries
15
+ * each record to peers and feeds them back through `applyRemote`.
16
+ *
17
+ * This store does NOT decide WHEN to use the journal path — that is the
18
+ * `JobLeaseCutoverGate`. The store only manages the leases once the gate has
19
+ * selected the journal path.
20
+ */
21
+ import crypto from 'node:crypto';
22
+ import fs from 'node:fs';
23
+ import path from 'node:path';
24
+ const DEFAULT_LEASE_TIMEOUT_MS = 30 * 60_000;
25
+ const CLAIMS_FILE = 'job-lease-claims.json';
26
+ export class JobLeaseClaimStore {
27
+ machineId;
28
+ claimsDir;
29
+ defaultLeaseTimeoutMs;
30
+ now;
31
+ claims = new Map(); // keyed by jobSlug
32
+ constructor(config) {
33
+ this.machineId = config.machineId;
34
+ this.defaultLeaseTimeoutMs = config.defaultLeaseTimeoutMs ?? DEFAULT_LEASE_TIMEOUT_MS;
35
+ this.now = config.now ?? (() => Date.now());
36
+ this.claimsDir = path.join(config.stateDir, 'state');
37
+ if (!fs.existsSync(this.claimsDir)) {
38
+ fs.mkdirSync(this.claimsDir, { recursive: true });
39
+ }
40
+ this.load();
41
+ }
42
+ /**
43
+ * Attempt to take a lease on a job at the given ownership epoch.
44
+ *
45
+ * Returns the new lease on success, or a rejection when a peer holds a live,
46
+ * non-stale lease. Idempotent: re-claiming a slug this machine already leases
47
+ * (at the same-or-newer epoch) returns the existing lease.
48
+ */
49
+ tryClaim(jobSlug, epoch, timeoutMs) {
50
+ this.pruneExpired();
51
+ const existing = this.claims.get(jobSlug);
52
+ if (existing && !existing.completed && !this.isExpired(existing)) {
53
+ if (existing.machineId === this.machineId) {
54
+ return { ok: false, reason: 'already-own', claim: existing };
55
+ }
56
+ // A peer holds a live lease. We may only supersede it with a STRICTLY
57
+ // newer epoch (the peer was demoted; our epoch advanced). A same/older
58
+ // epoch is fenced out — never steal from a current lease-holder.
59
+ if (epoch <= existing.epoch) {
60
+ return { ok: false, reason: 'held-by-peer', heldBy: existing.machineId };
61
+ }
62
+ }
63
+ const claim = {
64
+ claimId: `lease_${crypto.randomBytes(8).toString('hex')}`,
65
+ jobSlug,
66
+ machineId: this.machineId,
67
+ epoch,
68
+ claimedAt: new Date(this.now()).toISOString(),
69
+ expiresAt: new Date(this.now() + (timeoutMs ?? this.defaultLeaseTimeoutMs)).toISOString(),
70
+ completed: false,
71
+ };
72
+ this.claims.set(jobSlug, claim);
73
+ this.save();
74
+ return { ok: true, claim };
75
+ }
76
+ /** Mark our lease on a slug complete (releases it for the next tick). */
77
+ completeClaim(jobSlug, result) {
78
+ const claim = this.claims.get(jobSlug);
79
+ if (!claim || claim.machineId !== this.machineId)
80
+ return;
81
+ claim.completed = true;
82
+ claim.result = result;
83
+ claim.completedAt = new Date(this.now()).toISOString();
84
+ this.save();
85
+ }
86
+ /**
87
+ * Apply a claim record received from a peer over the journal. Epoch fencing:
88
+ * a record whose epoch is OLDER than the one we already hold for the slug is
89
+ * rejected (returns false) — a demoted machine's stale claim never overwrites
90
+ * a fresher lease. Returns true if the record was applied.
91
+ */
92
+ applyRemote(record) {
93
+ // Never let a remote record masquerade as our own machine's authority.
94
+ if (record.machineId === this.machineId)
95
+ return false;
96
+ const existing = this.claims.get(record.jobSlug);
97
+ if (existing && !existing.completed && !this.isExpired(existing)) {
98
+ // Strict epoch fence — equal epoch keeps the incumbent (first-writer-wins
99
+ // is resolved upstream by the journal's ordering; we never flip on a tie).
100
+ if (record.epoch <= existing.epoch)
101
+ return false;
102
+ }
103
+ this.claims.set(record.jobSlug, { ...record });
104
+ this.save();
105
+ return true;
106
+ }
107
+ /** True if a peer holds a live, non-stale lease on the slug. */
108
+ hasRemoteClaim(jobSlug) {
109
+ this.pruneExpired();
110
+ const claim = this.claims.get(jobSlug);
111
+ if (!claim || claim.completed || claim.machineId === this.machineId)
112
+ return false;
113
+ return !this.isExpired(claim);
114
+ }
115
+ getClaim(jobSlug) {
116
+ this.pruneExpired();
117
+ return this.claims.get(jobSlug);
118
+ }
119
+ getActiveClaims() {
120
+ this.pruneExpired();
121
+ return Array.from(this.claims.values()).filter((c) => !c.completed);
122
+ }
123
+ getAllClaims() {
124
+ return Array.from(this.claims.values());
125
+ }
126
+ /** Remove expired (uncompleted past expiry) + old completed records. */
127
+ pruneExpired() {
128
+ const now = this.now();
129
+ let pruned = 0;
130
+ for (const [slug, claim] of this.claims) {
131
+ if (claim.completed) {
132
+ const completedAt = claim.completedAt ? new Date(claim.completedAt).getTime() : now;
133
+ if (now - completedAt > 60 * 60_000) {
134
+ this.claims.delete(slug);
135
+ pruned++;
136
+ }
137
+ }
138
+ else if (this.isExpired(claim)) {
139
+ this.claims.delete(slug);
140
+ pruned++;
141
+ }
142
+ }
143
+ if (pruned > 0)
144
+ this.save();
145
+ return pruned;
146
+ }
147
+ isExpired(claim) {
148
+ return this.now() > new Date(claim.expiresAt).getTime();
149
+ }
150
+ load() {
151
+ try {
152
+ const data = JSON.parse(fs.readFileSync(path.join(this.claimsDir, CLAIMS_FILE), 'utf-8'));
153
+ this.claims.clear();
154
+ for (const c of data)
155
+ this.claims.set(c.jobSlug, c);
156
+ }
157
+ catch {
158
+ /* @silent-fallback-ok — no ledger yet; start empty */
159
+ }
160
+ }
161
+ save() {
162
+ fs.writeFileSync(path.join(this.claimsDir, CLAIMS_FILE), JSON.stringify(Array.from(this.claims.values()), null, 2) + '\n');
163
+ }
164
+ }
165
+ //# sourceMappingURL=JobLeaseClaimStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JobLeaseClaimStore.js","sourceRoot":"","sources":["../../src/scheduler/JobLeaseClaimStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * JobLeaseCutoverGate — WS4.3 journal-lease cutover discipline.
3
+ *
4
+ * (MULTI-MACHINE-SEAMLESSNESS-SPEC §WS4.3, "Cutover discipline".)
5
+ *
6
+ * Job claims upgrade from the legacy best-effort AgentBus broadcast
7
+ * (`JobClaimManager`) to a durable, epoch-fenced lease carried over the
8
+ * replicated journal. The named migration hazard the spec closes is two
9
+ * NON-INTEROPERATING claim mechanisms running at once: one machine leasing
10
+ * via the journal while a peer broadcasts via the bus for the SAME job set.
11
+ * There must never be a window where both are live for a job.
12
+ *
13
+ * This gate is the SINGLE decision point that resolves which path a job uses.
14
+ * It engages the journal-lease path ONLY when invariant-5 flag coherence holds:
15
+ * 1. the dark flag `multiMachine.seamlessness.ws43JournalLease` is on;
16
+ * 2. the pool has at least one peer (single-machine = strict no-op, the
17
+ * legacy path is byte-for-byte today's behavior);
18
+ * 3. EVERY online peer advertises the `ws43JournalLease` capability in its
19
+ * `seamlessnessFlags` heartbeat — a peer that does not advertise it (an
20
+ * older version, or the flag off there) keeps the WHOLE pool on the bus.
21
+ *
22
+ * A peer with NO seamlessnessFlags field is an older version → treated as NOT
23
+ * advertising (the conservative side). Absent = non-participant, per the
24
+ * spec's invariant-5 ("absent = the peer predates this spec = flag-state-off").
25
+ *
26
+ * Pure + deterministic: the gate holds no state and performs no IO, so it is
27
+ * trivially testable and can be re-read live at every spawn boundary (a
28
+ * mid-run flag flip or a peer going dark cuts the pool back to the bus
29
+ * immediately, never stranding a half-migrated job set).
30
+ */
31
+ /** A peer's advertised seamlessness capability, read from its heartbeat. */
32
+ export interface CutoverPeerAdvert {
33
+ machineId: string;
34
+ /** Whether the peer is currently online. An offline peer is not a participant
35
+ * in coherence (it cannot lease or broadcast right now) and is excluded. */
36
+ online?: boolean;
37
+ /** The peer's advertised WS4.3 journal-lease capability. ABSENT/false = the
38
+ * peer does not advertise it (older version or flag off there). */
39
+ ws43JournalLease?: boolean;
40
+ }
41
+ /** Inputs to the cutover decision, all read LIVE at each evaluation. */
42
+ export interface CutoverGateInput {
43
+ /** `multiMachine.seamlessness.ws43JournalLease` resolved live. */
44
+ enabled: boolean;
45
+ /** `multiMachine.seamlessness.ws43JournalLeaseDryRun` resolved live. When
46
+ * true AND the gate would otherwise select 'journal', the journal claim is
47
+ * LOGGED as intended but the legacy bus path still runs (the WS-wide dry-run
48
+ * posture: "log intended refusals/claims"). */
49
+ dryRun: boolean;
50
+ /** Every KNOWN peer (excluding self) with its advertised capability. An empty
51
+ * list means single-machine (no peers) → strict no-op. */
52
+ peers: ReadonlyArray<CutoverPeerAdvert>;
53
+ }
54
+ /** Which claim mechanism a job must use this evaluation. */
55
+ export type ClaimPath = 'journal' | 'bus';
56
+ export interface CutoverDecision {
57
+ /** The claim path the scheduler must use. Exactly one — never both. */
58
+ path: ClaimPath;
59
+ /** When true, the journal claim should be LOGGED as intended but the bus path
60
+ * actually runs (dry-run). Only ever true alongside `path: 'bus'`. */
61
+ journalDryRun: boolean;
62
+ /** Machine-readable reason, for audit + the status surface. */
63
+ reason: 'flag-off' | 'single-machine' | 'peers-incoherent' | 'dry-run' | 'journal-coherent';
64
+ /** Online peers that do NOT advertise the capability (empty ⇒ coherent). The
65
+ * reason a coherent-pool cutover was withheld, surfaced for the operator. */
66
+ incoherentPeers: string[];
67
+ }
68
+ /**
69
+ * Resolve the claim path for the current pool state. Pure: same input ⇒ same
70
+ * output, no IO, no clock.
71
+ */
72
+ export declare function decideClaimPath(input: CutoverGateInput): CutoverDecision;
73
+ //# sourceMappingURL=JobLeaseCutoverGate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JobLeaseCutoverGate.d.ts","sourceRoot":"","sources":["../../src/scheduler/JobLeaseCutoverGate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,4EAA4E;AAC5E,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB;iFAC6E;IAC7E,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;wEACoE;IACpE,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,wEAAwE;AACxE,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,OAAO,EAAE,OAAO,CAAC;IACjB;;;oDAGgD;IAChD,MAAM,EAAE,OAAO,CAAC;IAChB;+DAC2D;IAC3D,KAAK,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;CACzC;AAED,4DAA4D;AAC5D,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,KAAK,CAAC;AAE1C,MAAM,WAAW,eAAe;IAC9B,uEAAuE;IACvE,IAAI,EAAE,SAAS,CAAC;IAChB;2EACuE;IACvE,aAAa,EAAE,OAAO,CAAC;IACvB,+DAA+D;IAC/D,MAAM,EACF,UAAU,GACV,gBAAgB,GAChB,kBAAkB,GAClB,SAAS,GACT,kBAAkB,CAAC;IACvB;kFAC8E;IAC9E,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,gBAAgB,GAAG,eAAe,CAoCxE"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * JobLeaseCutoverGate — WS4.3 journal-lease cutover discipline.
3
+ *
4
+ * (MULTI-MACHINE-SEAMLESSNESS-SPEC §WS4.3, "Cutover discipline".)
5
+ *
6
+ * Job claims upgrade from the legacy best-effort AgentBus broadcast
7
+ * (`JobClaimManager`) to a durable, epoch-fenced lease carried over the
8
+ * replicated journal. The named migration hazard the spec closes is two
9
+ * NON-INTEROPERATING claim mechanisms running at once: one machine leasing
10
+ * via the journal while a peer broadcasts via the bus for the SAME job set.
11
+ * There must never be a window where both are live for a job.
12
+ *
13
+ * This gate is the SINGLE decision point that resolves which path a job uses.
14
+ * It engages the journal-lease path ONLY when invariant-5 flag coherence holds:
15
+ * 1. the dark flag `multiMachine.seamlessness.ws43JournalLease` is on;
16
+ * 2. the pool has at least one peer (single-machine = strict no-op, the
17
+ * legacy path is byte-for-byte today's behavior);
18
+ * 3. EVERY online peer advertises the `ws43JournalLease` capability in its
19
+ * `seamlessnessFlags` heartbeat — a peer that does not advertise it (an
20
+ * older version, or the flag off there) keeps the WHOLE pool on the bus.
21
+ *
22
+ * A peer with NO seamlessnessFlags field is an older version → treated as NOT
23
+ * advertising (the conservative side). Absent = non-participant, per the
24
+ * spec's invariant-5 ("absent = the peer predates this spec = flag-state-off").
25
+ *
26
+ * Pure + deterministic: the gate holds no state and performs no IO, so it is
27
+ * trivially testable and can be re-read live at every spawn boundary (a
28
+ * mid-run flag flip or a peer going dark cuts the pool back to the bus
29
+ * immediately, never stranding a half-migrated job set).
30
+ */
31
+ /**
32
+ * Resolve the claim path for the current pool state. Pure: same input ⇒ same
33
+ * output, no IO, no clock.
34
+ */
35
+ export function decideClaimPath(input) {
36
+ // (1) Flag off → legacy bus, byte-for-byte today's behavior.
37
+ if (!input.enabled) {
38
+ return { path: 'bus', journalDryRun: false, reason: 'flag-off', incoherentPeers: [] };
39
+ }
40
+ // Consider only ONLINE peers — an offline peer cannot claim/broadcast right
41
+ // now, so it neither blocks coherence nor participates in it (it will be
42
+ // re-evaluated when it returns and re-advertises).
43
+ const onlinePeers = input.peers.filter((p) => p.online !== false);
44
+ // (2) No online peers → single-machine (or all-peers-dark) strict no-op. The
45
+ // legacy path is the no-op baseline; with no peers there is no one to
46
+ // double-run against, so the cutover is irrelevant.
47
+ if (onlinePeers.length === 0) {
48
+ return { path: 'bus', journalDryRun: false, reason: 'single-machine', incoherentPeers: [] };
49
+ }
50
+ // (3) Flag coherence: EVERY online peer must advertise ws43JournalLease.
51
+ // Absent/false = does not advertise (the conservative side — invariant-5).
52
+ const incoherentPeers = onlinePeers
53
+ .filter((p) => p.ws43JournalLease !== true)
54
+ .map((p) => p.machineId);
55
+ if (incoherentPeers.length > 0) {
56
+ // Mixed pool → stay on the bus for the WHOLE job set. Never lease while a
57
+ // peer broadcasts: the named migration hazard. Degrade conservatively.
58
+ return { path: 'bus', journalDryRun: false, reason: 'peers-incoherent', incoherentPeers };
59
+ }
60
+ // Coherent pool. Dry-run still runs the bus path but logs the intended claim.
61
+ if (input.dryRun) {
62
+ return { path: 'bus', journalDryRun: true, reason: 'dry-run', incoherentPeers: [] };
63
+ }
64
+ return { path: 'journal', journalDryRun: false, reason: 'journal-coherent', incoherentPeers: [] };
65
+ }
66
+ //# sourceMappingURL=JobLeaseCutoverGate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JobLeaseCutoverGate.js","sourceRoot":"","sources":["../../src/scheduler/JobLeaseCutoverGate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAgDH;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,KAAuB;IACrD,6DAA6D;IAC7D,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC;IACxF,CAAC;IAED,4EAA4E;IAC5E,yEAAyE;IACzE,mDAAmD;IACnD,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC;IAElE,6EAA6E;IAC7E,sEAAsE;IACtE,oDAAoD;IACpD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC;IAC9F,CAAC;IAED,yEAAyE;IACzE,2EAA2E;IAC3E,MAAM,eAAe,GAAG,WAAW;SAChC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,KAAK,IAAI,CAAC;SAC1C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAE3B,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,0EAA0E;QAC1E,uEAAuE;QACvE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,eAAe,EAAE,CAAC;IAC5F,CAAC;IAED,8EAA8E;IAC9E,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC;IACtF,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC;AACpG,CAAC"}
@@ -17,6 +17,8 @@ import type { CanRunJobResult, IntelligenceProvider, MessagingAdapter } from '..
17
17
  import type { JobDefinition, JobSchedulerConfig, JobPriority } from '../core/types.js';
18
18
  import type { TelegramAdapter } from '../messaging/TelegramAdapter.js';
19
19
  import type { JobClaimManager } from './JobClaimManager.js';
20
+ import type { JobLeaseClaimStore } from './JobLeaseClaimStore.js';
21
+ import { type CutoverGateInput, type CutoverDecision } from './JobLeaseCutoverGate.js';
20
22
  import type { TopicMemory } from '../memory/TopicMemory.js';
21
23
  interface QueuedJob {
22
24
  slug: string;
@@ -66,6 +68,26 @@ export declare class JobScheduler {
66
68
  private quotaTracker;
67
69
  /** Optional job claim manager for multi-machine deduplication (Phase 4C) */
68
70
  private claimManager;
71
+ /**
72
+ * MULTI-MACHINE-SEAMLESSNESS-SPEC §WS4.3 journal-lease cutover. The durable,
73
+ * epoch-fenced lease store — the journal-backed UPGRADE of the best-effort
74
+ * AgentBus broadcast in `claimManager`. It is consulted for a job ONLY when
75
+ * `journalLeaseGate` selects the 'journal' path (flag on + pool coherent). The
76
+ * gate guarantees the two mechanisms are never both live for a job set (the
77
+ * named migration hazard). When unset, the scheduler stays on the legacy bus
78
+ * path (byte-for-byte today's behavior).
79
+ */
80
+ private leaseClaimStore;
81
+ /**
82
+ * Live provider for the cutover-gate input (flag + dry-run + the pool peers'
83
+ * advertised ws43JournalLease capability + this machine's lease epoch). Read
84
+ * LIVE at each claim boundary so a flag flip / a peer going dark cuts the pool
85
+ * back to the bus immediately. When unset, the gate is never consulted and the
86
+ * legacy bus path runs (strict no-op).
87
+ */
88
+ private journalLeaseGate;
89
+ /** Optional sink for the most-recent cutover decision (status/audit surface). */
90
+ private onCutoverDecision;
69
91
  /**
70
92
  * UNIFIED-SESSION-LIFECYCLE §P0 #9 (SE-8): function returning cumulative
71
93
  * wall-time-asleep in milliseconds during a half-open window [startMs, endMs).
@@ -130,6 +152,37 @@ export declare class JobScheduler {
130
152
  * and skip jobs already claimed by other machines.
131
153
  */
132
154
  setJobClaimManager(manager: JobClaimManager): void;
155
+ /**
156
+ * MULTI-MACHINE-SEAMLESSNESS-SPEC §WS4.3 — inject the journal-lease cutover.
157
+ *
158
+ * `store` is the durable epoch-fenced lease store; `gateInput` returns the
159
+ * LIVE cutover-gate input (flag, dry-run, pool peers' advertised capability,
160
+ * and this machine's current lease epoch) — read fresh at each claim boundary,
161
+ * never cached. `onDecision` (optional) receives the resolved decision per job
162
+ * for the status/audit surface.
163
+ *
164
+ * When omitted, the scheduler never consults the journal path — the legacy
165
+ * AgentBus `claimManager` runs unchanged (single-machine / flag-off no-op).
166
+ */
167
+ setJournalLeaseCutover(store: JobLeaseClaimStore, gateInput: () => CutoverGateInput & {
168
+ epoch: number;
169
+ }, onDecision?: (slug: string, decision: CutoverDecision) => void): void;
170
+ /**
171
+ * Resolve which claim mechanism a job uses RIGHT NOW. Pure read of the live
172
+ * gate input. Returns null when the cutover is not wired (legacy bus only).
173
+ * Exposed for the scheduler's claim seams (check + claim + complete) so a
174
+ * single evaluation drives all three — never two mechanisms for one job.
175
+ */
176
+ private resolveClaimPath;
177
+ /**
178
+ * Release a claim for a completed job across BOTH mechanisms. The path that
179
+ * actually took the claim may differ from the path the gate would pick at
180
+ * completion time (a mid-run flag flip), so we release both — each store's
181
+ * completeClaim is a strict no-op when this machine does not own the slug's
182
+ * live record, so releasing the unused store is harmless. The journal release
183
+ * is synchronous (durable); the bus release is best-effort async.
184
+ */
185
+ private releaseClaim;
133
186
  /**
134
187
  * Set local machine identity for machine-scoped job filtering.
135
188
  * Jobs with a `machines` field will only run on machines whose ID or name matches.
@@ -1 +1 @@
1
- {"version":3,"file":"JobScheduler.d.ts","sourceRoot":"","sources":["../../src/scheduler/JobScheduler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"JobScheduler.d.ts","sourceRoot":"","sources":["../../src/scheduler/JobScheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,gBAAgB,EAAc,MAAM,kBAAkB,CAAC;AAE5G,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAY,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACjG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAmB,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACxG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAS5D,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AASD,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,IAAI,CAAuB;IACnC,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;IAEvB,2DAA2D;IAC3D,OAAO,CAAC,YAAY,CAAkC;IAEtD,2EAA2E;IAC3E,OAAO,CAAC,UAAU,CAAqF;IAEvG,2DAA2D;IAC3D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAOrC;IAEF,qEAAqE;IACrE,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,WAAW,CAAuB;IAE1C;;;;OAIG;IACH,SAAS,EAAE,CAAC,QAAQ,EAAE,WAAW,KAAK,OAAO,GAAG,eAAe,CAAc;IAE7E,uDAAuD;IACvD,OAAO,CAAC,SAAS,CAAiC;IAElD,uDAAuD;IACvD,OAAO,CAAC,QAAQ,CAAgC;IAEhD,sEAAsE;IACtE,OAAO,CAAC,YAAY,CAA6B;IAEjD,4EAA4E;IAC5E,OAAO,CAAC,YAAY,CAAgC;IAEpD;;;;;;;;OAQG;IACH,OAAO,CAAC,eAAe,CAAmC;IAC1D;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB,CAA6D;IACrF,iFAAiF;IACjF,OAAO,CAAC,iBAAiB,CAAoE;IAC7F;;;;;;OAMG;IACH,OAAO,CAAC,uBAAuB,CAA6D;IAE5F,2EAA2E;IAC3E,OAAO,CAAC,YAAY,CAAqC;IAEzD,0EAA0E;IAC1E,OAAO,CAAC,eAAe,CAAgC;IAEvD,wDAAwD;IACxD,OAAO,CAAC,WAAW,CAA4B;IAE/C;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,iBAAiB,CAAkE;IAE3F;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB,CAAmE;gBAG3F,MAAM,EAAE,kBAAkB,EAC1B,cAAc,EAAE,cAAc,EAC9B,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,MAAM;IAUlB;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI;IAI7C;;;;OAIG;IACH,0BAA0B,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI;IAIhF;;;OAGG;IACH,WAAW,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAa3C;;;;OAIG;IACH,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAI5C;;;;OAIG;IACH,kBAAkB,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAIlD;;;;;;;;;;;OAWG;IACH,sBAAsB,CACpB,KAAK,EAAE,kBAAkB,EACzB,SAAS,EAAE,MAAM,gBAAgB,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,EACrD,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,KAAK,IAAI,GAC7D,IAAI;IAMP;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAexB;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY;IAWpB;;;OAGG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAMhE;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI;IAIrD;;;;OAIG;IACH,kBAAkB,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI;IAI/C;;;OAGG;IACH,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;IAI9C;;;;;;OAMG;IACH,YAAY,CACV,QAAQ,EAAE,MAAM;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,EACzD,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAC3D,IAAI;IAKP;;OAEG;IACH,KAAK,IAAI,IAAI;IA8Db;;OAEG;IACH,IAAI,IAAI,IAAI;IAsBZ;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;IAsM3F;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IAahC;;OAEG;IACH,YAAY,IAAI,IAAI;IAuBpB;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,UAAU,IAAI,IAAI;IAIlB;;OAEG;IACH,MAAM,IAAI,IAAI;IAKd;;OAEG;IACH,SAAS,IAAI,eAAe;IAY5B;;OAEG;IACH,OAAO,IAAI,aAAa,EAAE;IAI1B;;OAEG;IACH,QAAQ,IAAI,SAAS,EAAE;IAIvB;;;;OAIG;IACH,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAQrD;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAKjC;;OAEG;IACH,aAAa,IAAI,UAAU;IAI3B;;OAEG;IACH,aAAa,IAAI,aAAa;IAI9B;;;;;;;;;;;;;;;;OAgBG;IACG,aAAa,CAAC,UAAU,EAAE;QAAE,oBAAoB,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAoGjH,OAAO,CAAC,OAAO;IAoBf;;;;;;OAMG;IACH,OAAO,CAAC,YAAY;IA2FpB,OAAO,CAAC,eAAe;IA4IvB;;;;;;;;OAQG;IACH,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,WAAW;IAsGnB;;;OAGG;IACH,OAAO,CAAC,aAAa;IAOrB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAI1B;;;;OAIG;IACH,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKpD,OAAO,CAAC,sBAAsB;IAI9B,OAAO,CAAC,UAAU;IAOlB;;OAEG;IACG,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2O9E;;;;OAIG;YACW,eAAe;IAsE7B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;;;;;;;OAQG;YACW,YAAY;IAwD1B;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAK7B;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAkCrB;;OAEG;IACH,OAAO,CAAC,eAAe;IAQvB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,0BAA0B;IA0BlC;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;YA4ClB,eAAe;IAmD7B;;;;OAIG;YACW,gBAAgB;IAyD9B;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,mBAAmB;IA4FhE;;;8EAG0E;IAC1E,MAAM,CAAC,qBAAqB,CAAC,SAAS,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,OAAO;IAQ5E;;;;OAIG;IACH,MAAM,CAAC,uBAAuB,CAC5B,GAAG,EAAE,aAAa,EAClB,UAAU,EAAE,mBAAmB,GAC9B,gBAAgB;IAqCnB;;;;;OAKG;IACH,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM;IAc3C;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,oBAAoB;IA8D5B;;;;wCAIoC;IACpC,WAAW,IAAI;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE;CAO9E;AAED,4EAA4E;AAC5E,MAAM,WAAW,mBAAmB;IAClC,IAAI,EACA,QAAQ,GACR,OAAO,GACP,cAAc,GACd,SAAS,GACT,cAAc,GACd,qBAAqB,GACrB,wBAAwB,CAAC;IAC7B;;;2FAGuF;IACvF,SAAS,EAAE,MAAM,EAAE,GAAG,GAAG,GAAG,IAAI,CAAC;IACjC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,gBAAgB,EAAE,OAAO,CAAC;IAC1B;;;;mEAI+D;IAC/D,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,iDAAiD;AACjD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;IACrC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,aAAa,EAAE,MAAM,EAAE,GAAG,GAAG,GAAG,IAAI,CAAC;IACrC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,gBAAgB,EAAE,OAAO,CAAC;CAC3B"}