@gotcos/glasses-server 6.21.25 → 6.21.26

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 CHANGED
@@ -1,3 +1,22 @@
1
+ ## 6.21.26
2
+
3
+ - `assertedSegments` added to the speaker review: how many segments belong to
4
+ voices the panel actually shows WITH A NAME. `attributed` is a boolean that
5
+ only goes false at 100% unidentified, so a meeting where 295 of 299 chunks
6
+ matched nobody reported `true` and rendered as though normally attributed.
7
+ Measured unidentified share across 14 retained sessions ran 24% to 100%, all
8
+ of it collapsing onto that one boolean.
9
+
10
+ It counts asserted voices (`nameAsserted`), NOT chunks carrying a
11
+ person-shaped label. Those diverge sharply: on session 0i1xv3 the label-based
12
+ count is 287 of 379 segments while only 177 are displayed as names, so a
13
+ header built on labels would claim three quarters of the meeting identified
14
+ above a list of rows reading "Unidentified voice".
15
+
16
+ Purely additive — the route already spreads the review object and no client
17
+ decodes this payload strictly. COS Control 0.5.5+ renders it, and omits the
18
+ line against an older server rather than showing a zero.
19
+
1
20
  ## 6.21.25
2
21
 
3
22
  - `POST /meeting/:sessionId/confirm` — record that a human vouched for a label
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gotcos/glasses-server",
3
- "version": "6.21.25",
3
+ "version": "6.21.26",
4
4
  "description": "COS Glasses — self-hosted AI heads-up-display server for Even G2 smart glasses, powered by Claude Code, Codex, or Cursor Agent CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -227,6 +227,23 @@ export interface MeetingSpeakerReview {
227
227
  segments: number
228
228
  /** False when no chunk carries a real speaker — a recovered capture. */
229
229
  attributed: boolean
230
+ /**
231
+ * Segments belonging to voices this review asserts a NAME for.
232
+ *
233
+ * `attributed` is a boolean that only goes false at 100% unidentified, so a
234
+ * meeting where 295 of 299 chunks matched nobody still reports `true` and
235
+ * renders as though it were normally attributed. This is the graded version:
236
+ * measured Ext share across 14 retained sessions ran from 24% to 100%.
237
+ *
238
+ * Counts SEGMENTS OF ASSERTED VOICES, not chunks carrying a person-shaped
239
+ * label — see the derivation for why those differ. Denominator is `segments`
240
+ * (every chunk, including unlabelled ones), so `assertedSegments / segments`
241
+ * is the ratio every client should compute.
242
+ *
243
+ * Not named "coverage": `coverageRatio` in batch-transcript-quality.ts is an
244
+ * unrelated word-overlap measure and the two must not read as siblings.
245
+ */
246
+ assertedSegments: number
230
247
  durationMs: number
231
248
  voices: VoiceReview[]
232
249
  /** Chronological spans, so a ribbon can be a timeline instead of a share bar. */
@@ -500,6 +517,14 @@ export function reviewMeetingSpeakers(
500
517
  return {
501
518
  segments: chunks.length,
502
519
  attributed: named.length > 0,
520
+ // Derived from `nameAsserted`, NOT from `isUnattributed`. Those two answer
521
+ // different questions and diverge badly: measured on session 0i1xv3, the
522
+ // label-based count is 287 of 379 segments while only 177 belong to voices
523
+ // the panel actually shows with a name — a 29-point gap. A header built on
524
+ // labels would claim three quarters of the meeting was identified above a
525
+ // list of rows reading "Unidentified voice", which is the confusion this
526
+ // number exists to remove.
527
+ assertedSegments: voices.reduce((n, v) => (v.nameAsserted ? n + v.segments : n), 0),
503
528
  durationMs,
504
529
  voices,
505
530
  timeline: speakerTimeline(chunks, durationMs),