@bli-cockpit/telemetry-core 0.1.26 → 0.1.28
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.
|
@@ -56,6 +56,8 @@ export declare const CollectorHeartbeatSchema: z.ZodObject<{
|
|
|
56
56
|
last_sync_reason: z.ZodOptional<z.ZodString>;
|
|
57
57
|
sessions_observed: z.ZodOptional<z.ZodNumber>;
|
|
58
58
|
sessions_outside_root: z.ZodOptional<z.ZodNumber>;
|
|
59
|
+
sessions_new_this_tick: z.ZodOptional<z.ZodNumber>;
|
|
60
|
+
sessions_pending_upload: z.ZodOptional<z.ZodNumber>;
|
|
59
61
|
}, z.core.$strict>;
|
|
60
62
|
export type CollectorHeartbeat = z.infer<typeof CollectorHeartbeatSchema>;
|
|
61
63
|
/**
|
|
@@ -89,6 +89,29 @@ export const CollectorHeartbeatSchema = z
|
|
|
89
89
|
.nonnegative()
|
|
90
90
|
.max(1_000_000)
|
|
91
91
|
.optional(),
|
|
92
|
+
/**
|
|
93
|
+
* BLI-3645. Two honest counters beside the raw scan count above, both
|
|
94
|
+
* optional so a collector too old to compute them keeps posting:
|
|
95
|
+
*
|
|
96
|
+
* - `sessions_new_this_tick` — sessions first seen since this source's
|
|
97
|
+
* cursor as it stood before this tick, a FLOW, not the re-scanned
|
|
98
|
+
* STOCK `sessions_observed` is.
|
|
99
|
+
* - `sessions_pending_upload` — sessions inside an approved root with
|
|
100
|
+
* no durable pointer yet, i.e. the "only copy" set. A FLOOR at the
|
|
101
|
+
* moment this tick observed it, same as every other counter here.
|
|
102
|
+
*/
|
|
103
|
+
sessions_new_this_tick: z
|
|
104
|
+
.number()
|
|
105
|
+
.int()
|
|
106
|
+
.nonnegative()
|
|
107
|
+
.max(1_000_000)
|
|
108
|
+
.optional(),
|
|
109
|
+
sessions_pending_upload: z
|
|
110
|
+
.number()
|
|
111
|
+
.int()
|
|
112
|
+
.nonnegative()
|
|
113
|
+
.max(1_000_000)
|
|
114
|
+
.optional(),
|
|
92
115
|
})
|
|
93
116
|
.strict();
|
|
94
117
|
/**
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Is this pack the server has no record of actually durable, or did it just
|
|
3
|
+
* fall out of this laptop's own memory?" — the wire contract for asking.
|
|
4
|
+
*
|
|
5
|
+
* BLI-3619. The local upload ledger (`cursors/raw-evidence.json` `objects`) is
|
|
6
|
+
* capped at 5,000 rows, so a pack staged before the ledger's own memory begins
|
|
7
|
+
* reads `unknown` locally — not because it was never delivered, but because the
|
|
8
|
+
* ledger that would say so has forgotten. `unknown` is never deleted, but on a
|
|
9
|
+
* machine running for months it grows without bound. This is the one door that
|
|
10
|
+
* resolves it: ask the dashboard's own upload ledger
|
|
11
|
+
* (`ambient_raw_evidence_upload_ledger`), by content hash, whether THIS
|
|
12
|
+
* device's copy of those bytes ever landed.
|
|
13
|
+
*
|
|
14
|
+
* Deliberately keyed on `content_hash_sha256` alone, never `pack_id` — a pack
|
|
15
|
+
* id is a local directory name the server has never seen and has no column
|
|
16
|
+
* for. The collector may ask about the same hash on behalf of several packs
|
|
17
|
+
* (duplicate content is not impossible); the answer applies to the hash, and
|
|
18
|
+
* the collector applies it to every local object that hash matches.
|
|
19
|
+
*
|
|
20
|
+
* Three verdicts, not two, because collapsing them would erase the difference
|
|
21
|
+
* the doctor row needs to report honestly:
|
|
22
|
+
* committed a ledger row for this device, this hash, is
|
|
23
|
+
* `status = "committed"`. Durable. Prunable under the
|
|
24
|
+
* normal retention rule from here on.
|
|
25
|
+
* not_committed a ledger row exists for this device and this hash, but
|
|
26
|
+
* it never reached `committed` (pending/aborted/failed).
|
|
27
|
+
* The server started a transaction and it did not finish.
|
|
28
|
+
* unknown_to_server no ledger row at all for this device, this hash. The
|
|
29
|
+
* server has never heard of these bytes.
|
|
30
|
+
* Both `not_committed` and `unknown_to_server` become the collector's ordinary
|
|
31
|
+
* `uncommitted` state — never deleted — the label only changes what a person is
|
|
32
|
+
* told about why.
|
|
33
|
+
*/
|
|
34
|
+
import { z } from "zod";
|
|
35
|
+
export declare const EVIDENCE_RECONCILE_SCHEMA_VERSION = "evidence-reconcile.v1";
|
|
36
|
+
/** One request may ask about at most this many hashes. */
|
|
37
|
+
export declare const EVIDENCE_RECONCILE_MAX_BATCH = 500;
|
|
38
|
+
export declare const EvidenceReconcileRequestItemSchema: z.ZodObject<{
|
|
39
|
+
content_hash_sha256: z.ZodString;
|
|
40
|
+
}, z.core.$strict>;
|
|
41
|
+
export type EvidenceReconcileRequestItem = z.infer<typeof EvidenceReconcileRequestItemSchema>;
|
|
42
|
+
export declare const EvidenceReconcileRequestSchema: z.ZodObject<{
|
|
43
|
+
schema_version: z.ZodLiteral<"evidence-reconcile.v1">;
|
|
44
|
+
items: z.ZodArray<z.ZodObject<{
|
|
45
|
+
content_hash_sha256: z.ZodString;
|
|
46
|
+
}, z.core.$strict>>;
|
|
47
|
+
}, z.core.$strict>;
|
|
48
|
+
export type EvidenceReconcileRequest = z.infer<typeof EvidenceReconcileRequestSchema>;
|
|
49
|
+
export declare const EvidenceReconcileVerdictSchema: z.ZodEnum<{
|
|
50
|
+
committed: "committed";
|
|
51
|
+
not_committed: "not_committed";
|
|
52
|
+
unknown_to_server: "unknown_to_server";
|
|
53
|
+
}>;
|
|
54
|
+
export type EvidenceReconcileVerdict = z.infer<typeof EvidenceReconcileVerdictSchema>;
|
|
55
|
+
export declare const EvidenceReconcileResultSchema: z.ZodObject<{
|
|
56
|
+
content_hash_sha256: z.ZodString;
|
|
57
|
+
verdict: z.ZodEnum<{
|
|
58
|
+
committed: "committed";
|
|
59
|
+
not_committed: "not_committed";
|
|
60
|
+
unknown_to_server: "unknown_to_server";
|
|
61
|
+
}>;
|
|
62
|
+
committed_at: z.ZodNullable<z.ZodString>;
|
|
63
|
+
}, z.core.$strict>;
|
|
64
|
+
export type EvidenceReconcileResult = z.infer<typeof EvidenceReconcileResultSchema>;
|
|
65
|
+
export declare const EvidenceReconcileCountsSchema: z.ZodObject<{
|
|
66
|
+
committed: z.ZodNumber;
|
|
67
|
+
not_committed: z.ZodNumber;
|
|
68
|
+
unknown_to_server: z.ZodNumber;
|
|
69
|
+
}, z.core.$strict>;
|
|
70
|
+
export type EvidenceReconcileCounts = z.infer<typeof EvidenceReconcileCountsSchema>;
|
|
71
|
+
export declare const EvidenceReconcileResponseSchema: z.ZodObject<{
|
|
72
|
+
schema_version: z.ZodLiteral<"evidence-reconcile.v1">;
|
|
73
|
+
results: z.ZodArray<z.ZodObject<{
|
|
74
|
+
content_hash_sha256: z.ZodString;
|
|
75
|
+
verdict: z.ZodEnum<{
|
|
76
|
+
committed: "committed";
|
|
77
|
+
not_committed: "not_committed";
|
|
78
|
+
unknown_to_server: "unknown_to_server";
|
|
79
|
+
}>;
|
|
80
|
+
committed_at: z.ZodNullable<z.ZodString>;
|
|
81
|
+
}, z.core.$strict>>;
|
|
82
|
+
counts: z.ZodObject<{
|
|
83
|
+
committed: z.ZodNumber;
|
|
84
|
+
not_committed: z.ZodNumber;
|
|
85
|
+
unknown_to_server: z.ZodNumber;
|
|
86
|
+
}, z.core.$strict>;
|
|
87
|
+
}, z.core.$strict>;
|
|
88
|
+
export type EvidenceReconcileResponse = z.infer<typeof EvidenceReconcileResponseSchema>;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Is this pack the server has no record of actually durable, or did it just
|
|
3
|
+
* fall out of this laptop's own memory?" — the wire contract for asking.
|
|
4
|
+
*
|
|
5
|
+
* BLI-3619. The local upload ledger (`cursors/raw-evidence.json` `objects`) is
|
|
6
|
+
* capped at 5,000 rows, so a pack staged before the ledger's own memory begins
|
|
7
|
+
* reads `unknown` locally — not because it was never delivered, but because the
|
|
8
|
+
* ledger that would say so has forgotten. `unknown` is never deleted, but on a
|
|
9
|
+
* machine running for months it grows without bound. This is the one door that
|
|
10
|
+
* resolves it: ask the dashboard's own upload ledger
|
|
11
|
+
* (`ambient_raw_evidence_upload_ledger`), by content hash, whether THIS
|
|
12
|
+
* device's copy of those bytes ever landed.
|
|
13
|
+
*
|
|
14
|
+
* Deliberately keyed on `content_hash_sha256` alone, never `pack_id` — a pack
|
|
15
|
+
* id is a local directory name the server has never seen and has no column
|
|
16
|
+
* for. The collector may ask about the same hash on behalf of several packs
|
|
17
|
+
* (duplicate content is not impossible); the answer applies to the hash, and
|
|
18
|
+
* the collector applies it to every local object that hash matches.
|
|
19
|
+
*
|
|
20
|
+
* Three verdicts, not two, because collapsing them would erase the difference
|
|
21
|
+
* the doctor row needs to report honestly:
|
|
22
|
+
* committed a ledger row for this device, this hash, is
|
|
23
|
+
* `status = "committed"`. Durable. Prunable under the
|
|
24
|
+
* normal retention rule from here on.
|
|
25
|
+
* not_committed a ledger row exists for this device and this hash, but
|
|
26
|
+
* it never reached `committed` (pending/aborted/failed).
|
|
27
|
+
* The server started a transaction and it did not finish.
|
|
28
|
+
* unknown_to_server no ledger row at all for this device, this hash. The
|
|
29
|
+
* server has never heard of these bytes.
|
|
30
|
+
* Both `not_committed` and `unknown_to_server` become the collector's ordinary
|
|
31
|
+
* `uncommitted` state — never deleted — the label only changes what a person is
|
|
32
|
+
* told about why.
|
|
33
|
+
*/
|
|
34
|
+
import { z } from "zod";
|
|
35
|
+
import { IsoDateTimeSchema, Sha256Schema } from "./common.js";
|
|
36
|
+
export const EVIDENCE_RECONCILE_SCHEMA_VERSION = "evidence-reconcile.v1";
|
|
37
|
+
/** One request may ask about at most this many hashes. */
|
|
38
|
+
export const EVIDENCE_RECONCILE_MAX_BATCH = 500;
|
|
39
|
+
export const EvidenceReconcileRequestItemSchema = z
|
|
40
|
+
.object({
|
|
41
|
+
content_hash_sha256: Sha256Schema,
|
|
42
|
+
})
|
|
43
|
+
.strict();
|
|
44
|
+
export const EvidenceReconcileRequestSchema = z
|
|
45
|
+
.object({
|
|
46
|
+
schema_version: z.literal(EVIDENCE_RECONCILE_SCHEMA_VERSION),
|
|
47
|
+
items: z
|
|
48
|
+
.array(EvidenceReconcileRequestItemSchema)
|
|
49
|
+
.min(1)
|
|
50
|
+
.max(EVIDENCE_RECONCILE_MAX_BATCH),
|
|
51
|
+
})
|
|
52
|
+
.strict();
|
|
53
|
+
export const EvidenceReconcileVerdictSchema = z.enum([
|
|
54
|
+
"committed",
|
|
55
|
+
"not_committed",
|
|
56
|
+
"unknown_to_server",
|
|
57
|
+
]);
|
|
58
|
+
export const EvidenceReconcileResultSchema = z
|
|
59
|
+
.object({
|
|
60
|
+
content_hash_sha256: Sha256Schema,
|
|
61
|
+
verdict: EvidenceReconcileVerdictSchema,
|
|
62
|
+
/** Present only when `verdict === "committed"`. */
|
|
63
|
+
committed_at: IsoDateTimeSchema.nullable(),
|
|
64
|
+
})
|
|
65
|
+
.strict();
|
|
66
|
+
export const EvidenceReconcileCountsSchema = z
|
|
67
|
+
.object({
|
|
68
|
+
committed: z.number().int().nonnegative(),
|
|
69
|
+
not_committed: z.number().int().nonnegative(),
|
|
70
|
+
unknown_to_server: z.number().int().nonnegative(),
|
|
71
|
+
})
|
|
72
|
+
.strict();
|
|
73
|
+
export const EvidenceReconcileResponseSchema = z
|
|
74
|
+
.object({
|
|
75
|
+
schema_version: z.literal(EVIDENCE_RECONCILE_SCHEMA_VERSION),
|
|
76
|
+
results: z.array(EvidenceReconcileResultSchema),
|
|
77
|
+
counts: EvidenceReconcileCountsSchema,
|
|
78
|
+
})
|
|
79
|
+
.strict();
|
|
@@ -354,8 +354,8 @@ export type RawEvidenceUploadCommitRequest = z.infer<typeof RawEvidenceUploadCom
|
|
|
354
354
|
export declare const RawEvidenceUploadCommitResponseSchema: z.ZodObject<{
|
|
355
355
|
ok: z.ZodLiteral<true>;
|
|
356
356
|
status: z.ZodEnum<{
|
|
357
|
-
already_committed: "already_committed";
|
|
358
357
|
committed: "committed";
|
|
358
|
+
already_committed: "already_committed";
|
|
359
359
|
}>;
|
|
360
360
|
object_key: z.ZodString;
|
|
361
361
|
content_hash_sha256: z.ZodString;
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from "./common.js";
|
|
|
4
4
|
export * from "./decision-event.js";
|
|
5
5
|
export * from "./decision-event-id.js";
|
|
6
6
|
export * from "./evidence-completeness.js";
|
|
7
|
+
export * from "./evidence-reconcile.js";
|
|
7
8
|
export * from "./evidence-upload.js";
|
|
8
9
|
export * from "./ingest-dto.js";
|
|
9
10
|
export * from "./local-config.js";
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ export * from "./common.js";
|
|
|
4
4
|
export * from "./decision-event.js";
|
|
5
5
|
export * from "./decision-event-id.js";
|
|
6
6
|
export * from "./evidence-completeness.js";
|
|
7
|
+
export * from "./evidence-reconcile.js";
|
|
7
8
|
export * from "./evidence-upload.js";
|
|
8
9
|
export * from "./ingest-dto.js";
|
|
9
10
|
export * from "./local-config.js";
|