@bli-cockpit/telemetry-core 0.1.15 → 0.1.16
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.
|
@@ -26,10 +26,24 @@ export declare function normalizeActorLabel(rawLabel: string): string;
|
|
|
26
26
|
export declare function unresolvedActorId(rawLabel: string): string;
|
|
27
27
|
export interface DecisionEventIdInput {
|
|
28
28
|
captureSource: string;
|
|
29
|
-
/**
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Hash of exactly the bytes that make up this one decision; null for a live
|
|
31
|
+
* hook firing, which has no artifact at all.
|
|
32
|
+
*
|
|
33
|
+
* "This one decision" and not "the file it arrived in", which is the whole
|
|
34
|
+
* point. A verdict JSON holds one decision, so its record is the file and the
|
|
35
|
+
* two hashes coincide. `merge-log.jsonl` holds thousands and gains another
|
|
36
|
+
* every time somebody merges, so its record is the single line — hashing the
|
|
37
|
+
* file there would change every id in it on the next append, and a re-import
|
|
38
|
+
* would write a second copy of the ledger instead of updating the rows it
|
|
39
|
+
* already has.
|
|
40
|
+
*
|
|
41
|
+
* Which snapshot of which file the record came out of is still worth knowing;
|
|
42
|
+
* it is kept as `source_artifact_hash_sha256`, beside `source_line_number`, as
|
|
43
|
+
* provenance. Neither is an identity input. Conflating the two jobs in one
|
|
44
|
+
* field is what made a growing ledger un-re-importable.
|
|
45
|
+
*/
|
|
46
|
+
sourceRecordHashSha256: string | null;
|
|
33
47
|
kind: string;
|
|
34
48
|
/**
|
|
35
49
|
* Only for a live firing, which has no artifact to hash and no line to point
|
|
@@ -43,10 +57,19 @@ export interface DecisionEventIdInput {
|
|
|
43
57
|
/**
|
|
44
58
|
* The id of one decision event.
|
|
45
59
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* never
|
|
60
|
+
* Three consequences worth stating. Re-running the backfill is idempotent,
|
|
61
|
+
* because the same record always yields the same id no matter how much the file
|
|
62
|
+
* around it has grown or how far down it has been pushed. An *edited* record
|
|
63
|
+
* produces a new id rather than mutating an old one, which keeps the store
|
|
64
|
+
* append-only in the same way jarvis_corrections is — history is added to, never
|
|
65
|
+
* rewritten. And two byte-identical records collapse onto one row, which is the
|
|
66
|
+
* intended reading: in a ledger, identical bytes mean a hook wrote the same
|
|
67
|
+
* decision twice. If that is ever false the ledger format is underspecified, and
|
|
68
|
+
* the fix belongs there rather than in a tiebreaker here.
|
|
69
|
+
*
|
|
70
|
+
* The line number is deliberately absent. It is the one part of a record's
|
|
71
|
+
* position that a rotation or a compaction can change without the decision
|
|
72
|
+
* itself changing at all, and an id that moves when a file is renumbered is
|
|
73
|
+
* worse than a duplicate: it silently lands on some other decision's row.
|
|
51
74
|
*/
|
|
52
75
|
export declare function decisionEventId(input: DecisionEventIdInput): string;
|
|
@@ -52,19 +52,25 @@ export function unresolvedActorId(rawLabel) {
|
|
|
52
52
|
/**
|
|
53
53
|
* The id of one decision event.
|
|
54
54
|
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* never
|
|
55
|
+
* Three consequences worth stating. Re-running the backfill is idempotent,
|
|
56
|
+
* because the same record always yields the same id no matter how much the file
|
|
57
|
+
* around it has grown or how far down it has been pushed. An *edited* record
|
|
58
|
+
* produces a new id rather than mutating an old one, which keeps the store
|
|
59
|
+
* append-only in the same way jarvis_corrections is — history is added to, never
|
|
60
|
+
* rewritten. And two byte-identical records collapse onto one row, which is the
|
|
61
|
+
* intended reading: in a ledger, identical bytes mean a hook wrote the same
|
|
62
|
+
* decision twice. If that is ever false the ledger format is underspecified, and
|
|
63
|
+
* the fix belongs there rather than in a tiebreaker here.
|
|
64
|
+
*
|
|
65
|
+
* The line number is deliberately absent. It is the one part of a record's
|
|
66
|
+
* position that a rotation or a compaction can change without the decision
|
|
67
|
+
* itself changing at all, and an id that moves when a file is renumbered is
|
|
68
|
+
* worse than a duplicate: it silently lands on some other decision's row.
|
|
60
69
|
*/
|
|
61
70
|
export function decisionEventId(input) {
|
|
62
71
|
const parts = [
|
|
63
72
|
input.captureSource,
|
|
64
|
-
input.
|
|
65
|
-
input.sourceLineNumber === null || input.sourceLineNumber === undefined
|
|
66
|
-
? ""
|
|
67
|
-
: String(input.sourceLineNumber),
|
|
73
|
+
input.sourceRecordHashSha256 ?? "",
|
|
68
74
|
input.kind,
|
|
69
75
|
input.occurredAt ?? "",
|
|
70
76
|
input.subjectDiscriminator ?? "",
|
package/dist/decision-event.d.ts
CHANGED
|
@@ -411,6 +411,7 @@ export declare const DecisionEventSchema: z.ZodObject<{
|
|
|
411
411
|
source_line_number: z.ZodNullable<z.ZodNumber>;
|
|
412
412
|
rule_id: z.ZodNullable<z.ZodString>;
|
|
413
413
|
rulebook_version: z.ZodNullable<z.ZodString>;
|
|
414
|
+
host: z.ZodNullable<z.ZodString>;
|
|
414
415
|
evidence_pointers: z.ZodArray<z.ZodObject<{
|
|
415
416
|
kind: z.ZodEnum<{
|
|
416
417
|
claude_state_path: "claude_state_path";
|
|
@@ -593,6 +594,7 @@ export declare const DecisionEventEnvelopeSchema: z.ZodObject<{
|
|
|
593
594
|
source_line_number: z.ZodNullable<z.ZodNumber>;
|
|
594
595
|
rule_id: z.ZodNullable<z.ZodString>;
|
|
595
596
|
rulebook_version: z.ZodNullable<z.ZodString>;
|
|
597
|
+
host: z.ZodNullable<z.ZodString>;
|
|
596
598
|
evidence_pointers: z.ZodArray<z.ZodObject<{
|
|
597
599
|
kind: z.ZodEnum<{
|
|
598
600
|
claude_state_path: "claude_state_path";
|
package/dist/decision-event.js
CHANGED
|
@@ -330,7 +330,8 @@ export const DecisionEventSchema = z
|
|
|
330
330
|
.object({
|
|
331
331
|
/**
|
|
332
332
|
* Deterministic, so re-running the backfill is idempotent and an edited
|
|
333
|
-
*
|
|
333
|
+
* record produces a new id rather than mutating an old one. Derived from the
|
|
334
|
+
* record's own bytes, never from the file around them — see
|
|
334
335
|
* `decisionEventId`.
|
|
335
336
|
*/
|
|
336
337
|
decision_event_id: NonEmptyStringSchema.max(64),
|
|
@@ -340,7 +341,13 @@ export const DecisionEventSchema = z
|
|
|
340
341
|
subject: DecisionSubjectSchema,
|
|
341
342
|
outcome: DecisionOutcomeSchema,
|
|
342
343
|
capture_source: DecisionCaptureSourceSchema,
|
|
343
|
-
/**
|
|
344
|
+
/**
|
|
345
|
+
* Which snapshot of which file this was read out of, and where in it. Both
|
|
346
|
+
* are provenance, not identity: a re-import of a ledger that has grown since
|
|
347
|
+
* refreshes them on the existing row. Identity comes from the record's own
|
|
348
|
+
* bytes instead, which is what lets that re-import update rather than
|
|
349
|
+
* duplicate — see `decisionEventId`.
|
|
350
|
+
*/
|
|
344
351
|
source_artifact_hash_sha256: Sha256Schema.nullable(),
|
|
345
352
|
source_line_number: z.number().int().nonnegative().nullable(),
|
|
346
353
|
/**
|
|
@@ -350,6 +357,20 @@ export const DecisionEventSchema = z
|
|
|
350
357
|
*/
|
|
351
358
|
rule_id: NonEmptyStringSchema.max(40).nullable(),
|
|
352
359
|
rulebook_version: VersionStringSchema.nullable(),
|
|
360
|
+
/**
|
|
361
|
+
* Which machine the decision was made on, straight from the ledger line.
|
|
362
|
+
*
|
|
363
|
+
* A column rather than an `attributes` key, and deliberately beside
|
|
364
|
+
* `rulebook_version`: both are provenance about the *decision* rather than
|
|
365
|
+
* about the actor, and "did the laptop behave differently from the desktop"
|
|
366
|
+
* is a group-by question. A jsonb key would answer it by digging.
|
|
367
|
+
*
|
|
368
|
+
* Nullable because both ledgers only started stamping `host` on 2026-08-04
|
|
369
|
+
* (BLI-2435). Every line before that legitimately has none, so absence is
|
|
370
|
+
* history rather than an error, and a record without one must ingest
|
|
371
|
+
* cleanly.
|
|
372
|
+
*/
|
|
373
|
+
host: NonEmptyStringSchema.max(253).nullable(),
|
|
353
374
|
evidence_pointers: z.array(DecisionEvidencePointerSchema).max(20),
|
|
354
375
|
/**
|
|
355
376
|
* Small, flat, non-narrative extras. Enforced as scalar-or-scalar-array by
|