Codex commited on
Commit
ca45ff1
·
1 Parent(s): 0382000

Bind release evidence to verified text variants

Browse files
app.py CHANGED
@@ -154,6 +154,8 @@ MAX_TEXT_CHARS = 360
154
  QUALITY_MAX_GENERATED_CHUNKS = 32
155
  QUALITY_MAX_GENERATED_TEXT_UNITS = 800
156
  EMAIL_MAIL_FALLBACK_CANDIDATE_ORDINALS = frozenset((2, 5, 6))
 
 
157
  QUALITY_FINAL_ASR_MAX_NEW_TOKENS = 440
158
  QUALITY_MAX_CER = 0.20
159
  QUALITY_MAX_PACE_CPS = 4.30
@@ -1327,7 +1329,26 @@ def _verify_sequence_trajectory_audio(
1327
  f"chunk_candidates={sequence_result.chunk_candidate_indices} "
1328
  f"{_verification_metric_log_fields(assembled_verification)}"
1329
  )
1330
- return assembled_verification
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1331
 
1332
 
1333
  def _synthesize(
@@ -1451,6 +1472,48 @@ def _synthesize(
1451
  )
1452
  return tuple(transformed)
1453
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1454
  def generation_chunk_specs(
1455
  seed: int,
1456
  candidate_chunks: tuple[str, ...],
@@ -1615,6 +1678,17 @@ def _synthesize(
1615
  candidate_chunks,
1616
  generation_context=generation_context,
1617
  )
 
 
 
 
 
 
 
 
 
 
 
1618
  rows = tuple(
1619
  chunk_cfg_evidence(
1620
  chunk,
@@ -1637,6 +1711,7 @@ def _synthesize(
1637
  floor_reasons=tuple(row[1] for row in rows),
1638
  chunk_candidate_ordinals=candidate_ordinals,
1639
  network_conditioned=network_flags,
 
1640
  )
1641
 
1642
  try:
 
154
  QUALITY_MAX_GENERATED_CHUNKS = 32
155
  QUALITY_MAX_GENERATED_TEXT_UNITS = 800
156
  EMAIL_MAIL_FALLBACK_CANDIDATE_ORDINALS = frozenset((2, 5, 6))
157
+ BASE_CHUNK_TEXT_VARIANT = "base"
158
+ EMAIL_DOMAIN_MAIL_CHUNK_TEXT_VARIANT = "email_domain_mail_v1"
159
  QUALITY_FINAL_ASR_MAX_NEW_TOKENS = 440
160
  QUALITY_MAX_CER = 0.20
161
  QUALITY_MAX_PACE_CPS = 4.30
 
1329
  f"chunk_candidates={sequence_result.chunk_candidate_indices} "
1330
  f"{_verification_metric_log_fields(assembled_verification)}"
1331
  )
1332
+ if not assembled_verification.passed:
1333
+ return assembled_verification
1334
+ independent_verification = _verify_independent_whole_audio(
1335
+ waveform,
1336
+ whole_target_text,
1337
+ anchor,
1338
+ independent_cache,
1339
+ )
1340
+ intersected = qualify_trajectory_with_joined_output(
1341
+ assembled_verification,
1342
+ independent_verification,
1343
+ )
1344
+ independent_status = "verified" if independent_verification.passed else "rejected"
1345
+ print(
1346
+ f"[BlueMagpie] sequence path independent large-v3 {independent_status} "
1347
+ f"rank={sequence_result.sequence_path_rank} "
1348
+ f"chunk_candidates={sequence_result.chunk_candidate_indices} "
1349
+ f"{_verification_metric_log_fields(independent_verification)}"
1350
+ )
1351
+ return intersected
1352
 
1353
 
1354
  def _synthesize(
 
1472
  )
1473
  return tuple(transformed)
1474
 
1475
+ def candidate_generation_text_variants(
1476
+ canonical_chunks: tuple[str, ...],
1477
+ generation_context: CandidateGenerationContext,
1478
+ ) -> tuple[str, ...]:
1479
+ expected_canonical = canonical_chunks_for_context(generation_context)
1480
+ if canonical_chunks != expected_canonical:
1481
+ raise ValueError("candidate text variant lacks canonical provenance")
1482
+ generated_chunks = candidate_generation_text_transform(
1483
+ canonical_chunks,
1484
+ generation_context,
1485
+ )
1486
+ variants: list[str] = []
1487
+ for chunk_index, canonical, generated, candidate_ordinal in zip(
1488
+ generation_context.chunk_indices,
1489
+ canonical_chunks,
1490
+ generated_chunks,
1491
+ generation_context.chunk_candidate_ordinals,
1492
+ strict=True,
1493
+ ):
1494
+ if generated == canonical:
1495
+ variants.append(BASE_CHUNK_TEXT_VARIANT)
1496
+ continue
1497
+ if chunk_specs is None:
1498
+ raise ValueError("candidate text variant lacks network proof")
1499
+ spec = chunk_specs[chunk_index]
1500
+ expected_variant = email_domain_mail_generation_variant(
1501
+ canonical,
1502
+ spec.network_fragment_proofs,
1503
+ )
1504
+ if (
1505
+ candidate_ordinal not in EMAIL_MAIL_FALLBACK_CANDIDATE_ORDINALS
1506
+ or generated != expected_variant
1507
+ or generated == canonical
1508
+ or not any(
1509
+ proof.identifier_kind == "email"
1510
+ for proof in spec.network_fragment_proofs
1511
+ )
1512
+ ):
1513
+ raise ValueError("candidate text variant is not proof-bound")
1514
+ variants.append(EMAIL_DOMAIN_MAIL_CHUNK_TEXT_VARIANT)
1515
+ return tuple(variants)
1516
+
1517
  def generation_chunk_specs(
1518
  seed: int,
1519
  candidate_chunks: tuple[str, ...],
 
1678
  candidate_chunks,
1679
  generation_context=generation_context,
1680
  )
1681
+ canonical_chunks = canonical_chunks_for_context(generation_context)
1682
+ expected_generation_chunks = candidate_generation_text_transform(
1683
+ canonical_chunks,
1684
+ generation_context,
1685
+ )
1686
+ if candidate_chunks != expected_generation_chunks:
1687
+ raise ValueError("generation evidence text disagrees with its schedule")
1688
+ text_variants = candidate_generation_text_variants(
1689
+ canonical_chunks,
1690
+ generation_context,
1691
+ )
1692
  rows = tuple(
1693
  chunk_cfg_evidence(
1694
  chunk,
 
1711
  floor_reasons=tuple(row[1] for row in rows),
1712
  chunk_candidate_ordinals=candidate_ordinals,
1713
  network_conditioned=network_flags,
1714
+ chunk_text_variants=text_variants,
1715
  )
1716
 
1717
  try:
quality_runtime.py CHANGED
@@ -61,7 +61,7 @@ RELEASE_SPEAKER_TRIGGER_SECONDS = 1.48
61
  SEQUENCE_FALLBACK_MAX_LOCAL_BOUNDARY_SPEAKER_DROP = 0.15
62
  SEQUENCE_FALLBACK_SPEAKER_WEIGHT = 0.05
63
  SEQUENCE_FALLBACK_BOUNDARY_WEIGHT = 0.10
64
- CASCADE_EVIDENCE_SCHEMA_VERSION = 4
65
  CASCADE_EVIDENCE_LOG_PREFIX = "[BlueMagpie] cascade evidence "
66
  CASCADE_EVIDENCE_MAX_ATTEMPTS = ADAPTIVE_CASCADE_STAGE_LIMITS[-1]
67
  CASCADE_EVIDENCE_MAX_LOCAL_RESULTS = ADAPTIVE_CASCADE_STAGE_LIMITS[-1]
@@ -1583,6 +1583,7 @@ class CandidateGenerationEvidence:
1583
  floor_reasons: tuple[tuple[str, ...], ...]
1584
  chunk_candidate_ordinals: tuple[int, ...] = ()
1585
  network_conditioned: tuple[bool, ...] = ()
 
1586
 
1587
 
1588
  @dataclass(frozen=True)
@@ -1600,6 +1601,7 @@ class CandidateAttemptEvidence:
1600
  chunk_text_units: tuple[int, ...]
1601
  chunk_candidate_ordinals: tuple[int, ...]
1602
  network_conditioned: tuple[bool, ...]
 
1603
  scheduled_cfg: float | None
1604
  effective_cfgs: tuple[float, ...]
1605
  floor_reasons: tuple[tuple[str, ...], ...]
@@ -2526,6 +2528,7 @@ def _candidate_attempt_evidence_payload(
2526
  "chunk_text_units": list(evidence.chunk_text_units),
2527
  "chunk_candidate_ordinals": list(candidate_ordinals),
2528
  "chunk_policies": chunk_policies,
 
2529
  "network_conditioned": list(evidence.network_conditioned),
2530
  "scheduled_cfg": evidence.scheduled_cfg,
2531
  "effective_cfgs": list(evidence.effective_cfgs),
@@ -2615,6 +2618,7 @@ def _selected_generation_evidence_payload(
2615
  candidate_ordinals: list[int | None] = []
2616
  policies: list[str | None] = []
2617
  network_conditioned: list[bool | None] = []
 
2618
  complete = True
2619
  for chunk_index, candidate_index in enumerate(
2620
  selection.chunk_candidate_indices
@@ -2628,6 +2632,7 @@ def _selected_generation_evidence_payload(
2628
  candidate_ordinals.append(None)
2629
  policies.append(None)
2630
  network_conditioned.append(None)
 
2631
  continue
2632
  try:
2633
  local_index = attempt.chunk_indices.index(chunk_index)
@@ -2641,6 +2646,7 @@ def _selected_generation_evidence_payload(
2641
  candidate_ordinals.append(None)
2642
  policies.append(None)
2643
  network_conditioned.append(None)
 
2644
  continue
2645
  try:
2646
  ordinal = attempt.chunk_candidate_ordinals[local_index]
@@ -2661,6 +2667,11 @@ def _selected_generation_evidence_payload(
2661
  except IndexError:
2662
  complete = False
2663
  network_conditioned.append(None)
 
 
 
 
 
2664
  return {
2665
  "complete": complete,
2666
  "chunk_scheduled_cfgs": scheduled_cfgs,
@@ -2669,6 +2680,7 @@ def _selected_generation_evidence_payload(
2669
  "chunk_candidate_ordinals": candidate_ordinals,
2670
  "chunk_policies": policies,
2671
  "network_conditioned": network_conditioned,
 
2672
  }
2673
 
2674
 
@@ -2753,6 +2765,7 @@ def format_cascade_evidence_log(
2753
  and len(attempt.chunk_indices) == len(attempt.chunk_text_units)
2754
  == len(attempt.chunk_candidate_ordinals)
2755
  == len(attempt.network_conditioned)
 
2756
  == len(attempt.effective_cfgs)
2757
  == len(attempt.floor_reasons)
2758
  and bool(attempt.chunk_indices)
@@ -3298,6 +3311,21 @@ def _validated_candidate_generation_evidence(
3298
  network_conditioned = value.network_conditioned
3299
  else:
3300
  network_conditioned = (False,) * len(chunks)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3301
  raw_ordinals = value.chunk_candidate_ordinals
3302
  if not raw_ordinals:
3303
  if require_explicit_candidate_ordinals:
@@ -3377,6 +3405,7 @@ def _validated_candidate_generation_evidence(
3377
  floor_reasons=tuple(floor_reasons),
3378
  chunk_candidate_ordinals=candidate_ordinals,
3379
  network_conditioned=network_conditioned,
 
3380
  )
3381
 
3382
 
@@ -3415,6 +3444,9 @@ def _candidate_attempt_evidence(
3415
  network_conditioned=(
3416
  generation.network_conditioned if generation is not None else ()
3417
  ),
 
 
 
3418
  scheduled_cfg=(generation.scheduled_cfg if generation is not None else None),
3419
  effective_cfgs=(generation.effective_cfgs if generation is not None else ()),
3420
  floor_reasons=(generation.floor_reasons if generation is not None else ()),
 
61
  SEQUENCE_FALLBACK_MAX_LOCAL_BOUNDARY_SPEAKER_DROP = 0.15
62
  SEQUENCE_FALLBACK_SPEAKER_WEIGHT = 0.05
63
  SEQUENCE_FALLBACK_BOUNDARY_WEIGHT = 0.10
64
+ CASCADE_EVIDENCE_SCHEMA_VERSION = 5
65
  CASCADE_EVIDENCE_LOG_PREFIX = "[BlueMagpie] cascade evidence "
66
  CASCADE_EVIDENCE_MAX_ATTEMPTS = ADAPTIVE_CASCADE_STAGE_LIMITS[-1]
67
  CASCADE_EVIDENCE_MAX_LOCAL_RESULTS = ADAPTIVE_CASCADE_STAGE_LIMITS[-1]
 
1583
  floor_reasons: tuple[tuple[str, ...], ...]
1584
  chunk_candidate_ordinals: tuple[int, ...] = ()
1585
  network_conditioned: tuple[bool, ...] = ()
1586
+ chunk_text_variants: tuple[str, ...] = ()
1587
 
1588
 
1589
  @dataclass(frozen=True)
 
1601
  chunk_text_units: tuple[int, ...]
1602
  chunk_candidate_ordinals: tuple[int, ...]
1603
  network_conditioned: tuple[bool, ...]
1604
+ chunk_text_variants: tuple[str, ...]
1605
  scheduled_cfg: float | None
1606
  effective_cfgs: tuple[float, ...]
1607
  floor_reasons: tuple[tuple[str, ...], ...]
 
2528
  "chunk_text_units": list(evidence.chunk_text_units),
2529
  "chunk_candidate_ordinals": list(candidate_ordinals),
2530
  "chunk_policies": chunk_policies,
2531
+ "chunk_text_variants": list(evidence.chunk_text_variants),
2532
  "network_conditioned": list(evidence.network_conditioned),
2533
  "scheduled_cfg": evidence.scheduled_cfg,
2534
  "effective_cfgs": list(evidence.effective_cfgs),
 
2618
  candidate_ordinals: list[int | None] = []
2619
  policies: list[str | None] = []
2620
  network_conditioned: list[bool | None] = []
2621
+ chunk_text_variants: list[str | None] = []
2622
  complete = True
2623
  for chunk_index, candidate_index in enumerate(
2624
  selection.chunk_candidate_indices
 
2632
  candidate_ordinals.append(None)
2633
  policies.append(None)
2634
  network_conditioned.append(None)
2635
+ chunk_text_variants.append(None)
2636
  continue
2637
  try:
2638
  local_index = attempt.chunk_indices.index(chunk_index)
 
2646
  candidate_ordinals.append(None)
2647
  policies.append(None)
2648
  network_conditioned.append(None)
2649
+ chunk_text_variants.append(None)
2650
  continue
2651
  try:
2652
  ordinal = attempt.chunk_candidate_ordinals[local_index]
 
2667
  except IndexError:
2668
  complete = False
2669
  network_conditioned.append(None)
2670
+ try:
2671
+ chunk_text_variants.append(attempt.chunk_text_variants[local_index])
2672
+ except IndexError:
2673
+ complete = False
2674
+ chunk_text_variants.append(None)
2675
  return {
2676
  "complete": complete,
2677
  "chunk_scheduled_cfgs": scheduled_cfgs,
 
2680
  "chunk_candidate_ordinals": candidate_ordinals,
2681
  "chunk_policies": policies,
2682
  "network_conditioned": network_conditioned,
2683
+ "chunk_text_variants": chunk_text_variants,
2684
  }
2685
 
2686
 
 
2765
  and len(attempt.chunk_indices) == len(attempt.chunk_text_units)
2766
  == len(attempt.chunk_candidate_ordinals)
2767
  == len(attempt.network_conditioned)
2768
+ == len(attempt.chunk_text_variants)
2769
  == len(attempt.effective_cfgs)
2770
  == len(attempt.floor_reasons)
2771
  and bool(attempt.chunk_indices)
 
3311
  network_conditioned = value.network_conditioned
3312
  else:
3313
  network_conditioned = (False,) * len(chunks)
3314
+ if value.chunk_text_variants:
3315
+ if (
3316
+ not isinstance(value.chunk_text_variants, tuple)
3317
+ or len(value.chunk_text_variants) != len(chunks)
3318
+ or any(
3319
+ variant not in {"base", "email_domain_mail_v1"}
3320
+ for variant in value.chunk_text_variants
3321
+ )
3322
+ ):
3323
+ raise ValueError(
3324
+ "generation evidence text variants do not match the attempt"
3325
+ )
3326
+ chunk_text_variants = value.chunk_text_variants
3327
+ else:
3328
+ chunk_text_variants = ("base",) * len(chunks)
3329
  raw_ordinals = value.chunk_candidate_ordinals
3330
  if not raw_ordinals:
3331
  if require_explicit_candidate_ordinals:
 
3405
  floor_reasons=tuple(floor_reasons),
3406
  chunk_candidate_ordinals=candidate_ordinals,
3407
  network_conditioned=network_conditioned,
3408
+ chunk_text_variants=chunk_text_variants,
3409
  )
3410
 
3411
 
 
3444
  network_conditioned=(
3445
  generation.network_conditioned if generation is not None else ()
3446
  ),
3447
+ chunk_text_variants=(
3448
+ generation.chunk_text_variants if generation is not None else ()
3449
+ ),
3450
  scheduled_cfg=(generation.scheduled_cfg if generation is not None else None),
3451
  effective_cfgs=(generation.effective_cfgs if generation is not None else ()),
3452
  floor_reasons=(generation.floor_reasons if generation is not None else ()),
tests/test_coverage_adaptive.py CHANGED
@@ -567,7 +567,7 @@ def test_refill_budget_accounts_exact_generated_chunks_and_text_units():
567
  selection=result,
568
  )
569
  payload = json.loads(line.removeprefix(CASCADE_EVIDENCE_LOG_PREFIX))
570
- assert payload["schema_version"] == 4
571
  assert payload["generation_evidence_complete"] is True
572
  assert payload["request_chunk_count"] == 2
573
  assert payload["generated_chunk_count"] == 3
@@ -589,6 +589,7 @@ def test_refill_budget_accounts_exact_generated_chunks_and_text_units():
589
  "chunk_candidate_ordinals": [1, 0],
590
  "chunk_policies": ["safe_duration", "base"],
591
  "network_conditioned": [False, False],
 
592
  }
593
 
594
 
@@ -1221,6 +1222,91 @@ def test_remaining_budget_prioritizes_request_endpoints_after_full_coverage():
1221
  assert result.chunk_candidate_counts == (1, 1, 2)
1222
 
1223
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1224
  def test_ragged_dp_accepts_unequal_row_widths_and_stable_cost_order():
1225
  ranked = select_culprit_diverse_candidate_sequences(
1226
  [[0.0], [0.3, 0.1, 0.2], [0.4, 0.0]],
 
567
  selection=result,
568
  )
569
  payload = json.loads(line.removeprefix(CASCADE_EVIDENCE_LOG_PREFIX))
570
+ assert payload["schema_version"] == 5
571
  assert payload["generation_evidence_complete"] is True
572
  assert payload["request_chunk_count"] == 2
573
  assert payload["generated_chunk_count"] == 3
 
589
  "chunk_candidate_ordinals": [1, 0],
590
  "chunk_policies": ["safe_duration", "base"],
591
  "network_conditioned": [False, False],
592
+ "chunk_text_variants": ["base", "base"],
593
  }
594
 
595
 
 
1222
  assert result.chunk_candidate_counts == (1, 1, 2)
1223
 
1224
 
1225
+ def test_exact_asr_speaker_near_miss_gets_priority_then_latest_result_reorders():
1226
+ chunks = ("第一段", "第二段")
1227
+ generated = []
1228
+
1229
+ def verification(candidate_chunks, states):
1230
+ observations = []
1231
+ artifacts = []
1232
+ for chunk, state in zip(candidate_chunks, states, strict=True):
1233
+ semantic_passed = state != "semantic_failure"
1234
+ speaker_similarity = 0.05 if state == "speaker_near_miss" else 0.80
1235
+ observations.append(
1236
+ CandidateObservation(
1237
+ target_text=chunk,
1238
+ transcript_text=chunk if semantic_passed else "完全錯誤",
1239
+ audio_duration_seconds=2.0,
1240
+ speaker_similarity=speaker_similarity,
1241
+ begin_speaker_similarity=speaker_similarity,
1242
+ end_speaker_similarity=speaker_similarity,
1243
+ pace_cps=2.0,
1244
+ )
1245
+ )
1246
+ artifacts.append(
1247
+ ChunkCandidateArtifact(
1248
+ speaker_embedding=np.array([1.0, 0.0], dtype=np.float32),
1249
+ rms_db=-20.0,
1250
+ )
1251
+ )
1252
+ return verify_trajectory(
1253
+ observations,
1254
+ chunk_artifacts=artifacts,
1255
+ max_pace_cps=4.3,
1256
+ min_speaker_similarity=0.10,
1257
+ )
1258
+
1259
+ initial_local = verification(
1260
+ chunks,
1261
+ ("semantic_failure", "speaker_near_miss"),
1262
+ )
1263
+ assert initial_local.candidate_results[0].comparison.passed is False
1264
+ assert initial_local.candidate_results[1].comparison.passed is True
1265
+ assert "speaker_similarity" in initial_local.candidate_results[
1266
+ 1
1267
+ ].rejection_reasons
1268
+
1269
+ def generator(candidate_chunks, seed):
1270
+ generated.append((candidate_chunks, seed))
1271
+ return tuple(f"{seed}:{chunk}" for chunk in candidate_chunks)
1272
+
1273
+ def refill_verifier(trajectory, candidate_chunks, seed):
1274
+ state = (
1275
+ "semantic_failure"
1276
+ if candidate_chunks == ("第二段",) and seed == 101
1277
+ else "passed"
1278
+ )
1279
+ return verification(candidate_chunks, (state,))
1280
+
1281
+ result = run_coverage_adaptive_cascade(
1282
+ chunks,
1283
+ 100,
1284
+ generator,
1285
+ lambda trajectory, candidate_chunks, seed: TrajectoryGateResult(
1286
+ passed=False,
1287
+ candidate_results=initial_local.candidate_results,
1288
+ score=math.inf,
1289
+ rejection_reasons=("joined_output:semantic_gate",),
1290
+ chunk_artifacts=initial_local.chunk_artifacts,
1291
+ ),
1292
+ refill_verifier,
1293
+ sequence_final_verifier=lambda result, candidate_chunks: _exact_final(
1294
+ candidate_chunks
1295
+ ),
1296
+ max_generated_chunks=5,
1297
+ max_generated_text_units=100,
1298
+ max_sequence_paths=1,
1299
+ )
1300
+
1301
+ assert generated[1:] == [
1302
+ (("第二段",), 101),
1303
+ (("第一段",), 102),
1304
+ (("第二段",), 103),
1305
+ ]
1306
+ assert result.chunk_candidate_indices == (2, 3)
1307
+ assert result.chunk_candidate_counts == (1, 1)
1308
+
1309
+
1310
  def test_ragged_dp_accepts_unequal_row_widths_and_stable_cost_order():
1311
  ranked = select_culprit_diverse_candidate_sequences(
1312
  [[0.0], [0.3, 0.1, 0.2], [0.4, 0.0]],
tests/test_production.py CHANGED
@@ -1054,6 +1054,37 @@ def test_network_request_bounded_ordinary_envelope_splits_long_final_clause():
1054
  assert "".join(spec.text for spec in specs) == target
1055
 
1056
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1057
  def test_generation_network_planner_prefers_context_before_identifier_start():
1058
  raw = (
1059
  "途中若發現落石或樹枝阻斷通行,請拍照並寄到 "
 
1054
  assert "".join(spec.text for spec in specs) == target
1055
 
1056
 
1057
+ @pytest.mark.parametrize(
1058
+ ("terminal_units", "expected_units"),
1059
+ (
1060
+ (36, (14, 36)),
1061
+ (37, (14, 25, 12)),
1062
+ ),
1063
+ )
1064
+ def test_network_request_terminal_ordinary_clause_splits_only_above_36_units(
1065
+ terminal_units,
1066
+ expected_units,
1067
+ ):
1068
+ raw = "請寄到 patrol@forestmail.tw。" + "甲" * terminal_units + "。"
1069
+ target = normalize_spoken_forms(raw)
1070
+
1071
+ specs = plan_generation_chunks(raw, target, ordinary_max_units=36)
1072
+
1073
+ assert tuple(count_speech_units(spec.text) for spec in specs) == expected_units
1074
+ assert specs[0].network_conditioned
1075
+ assert all(not spec.network_conditioned for spec in specs[1:])
1076
+ assert all(
1077
+ left.source_end == right.source_start
1078
+ for left, right in zip(specs, specs[1:], strict=False)
1079
+ )
1080
+ assert specs[0].source_start == 0
1081
+ assert specs[-1].source_end == len(target)
1082
+ assert all(spec.boundary_after == "semantic" for spec in specs[:-1])
1083
+ assert specs[-1].boundary_after == "none"
1084
+ assert max(count_speech_units(spec.text) for spec in specs) <= 36
1085
+ assert "".join(spec.text for spec in specs) == target
1086
+
1087
+
1088
  def test_generation_network_planner_prefers_context_before_identifier_start():
1089
  raw = (
1090
  "途中若發現落石或樹枝阻斷通行,請拍照並寄到 "
tests/test_quality_runtime.py CHANGED
@@ -1675,7 +1675,7 @@ def test_canonical_attempt_evidence_distinguishes_local_v3_pass_and_not_run():
1675
  )
1676
  attempt = payload["attempts"][0]
1677
 
1678
- assert payload["schema_version"] == 4
1679
  assert attempt["independent_local_evidence_complete"] is True
1680
  assert attempt["independent_local_results"] == [
1681
  {
 
1675
  )
1676
  attempt = payload["attempts"][0]
1677
 
1678
+ assert payload["schema_version"] == 5
1679
  assert attempt["independent_local_evidence_complete"] is True
1680
  assert attempt["independent_local_results"] == [
1681
  {
tests/test_release_pins.py CHANGED
@@ -3,6 +3,16 @@ import hashlib
3
  from pathlib import Path
4
  from types import SimpleNamespace
5
 
 
 
 
 
 
 
 
 
 
 
6
  from quality_runtime import LocalIndependentGateEvidence
7
 
8
 
@@ -51,6 +61,59 @@ def _literal_constants(path: Path) -> dict[str, object]:
51
  return values
52
 
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  def _isolated_load_speakers(*, metadata: dict, speaker_ids: tuple[str, ...]):
55
  """Execute only ``_load_speakers`` without importing the GPU application."""
56
 
@@ -522,7 +585,8 @@ def test_network_local_dual_asr_capability_is_range_bound_for_initial_and_refill
522
  assert "chunk_artifacts=primary_verification.chunk_artifacts" in (
523
  intersection_source
524
  )
525
- assert "CASCADE_EVIDENCE_SCHEMA_VERSION = 4" in quality_source
 
526
  assert "local_candidate_has_coverage_eligibility(" in helper_source
527
  assert "independent_local_results=" in initial_source
528
  assert "independent_local_results=" in refill_source
@@ -1023,8 +1087,19 @@ def test_space_hard_intersects_dual_asr_on_whole_and_proven_network_locals():
1023
  sequence_large_v3_transcriber = sequence_source.index(
1024
  "transcriber=transcribe_verification_whisper"
1025
  )
1026
- assert sequence_assemble < sequence_large_v3 < sequence_large_v3_transcriber
1027
- assert "_verify_independent_whole_audio(" not in sequence_source
 
 
 
 
 
 
 
 
 
 
 
1028
 
1029
  cache_create = synthesize_source.index(
1030
  "independent_cache = WholeWaveformVerificationCache()"
@@ -1306,6 +1381,88 @@ def test_space_locks_validated_nfe_and_bounds_total_generation_work():
1306
  assert "boundary-only relaxation" in readme
1307
 
1308
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1309
  def test_space_locks_waveform_only_bounded_whisper_segmentation():
1310
  source = (ROOT / "quality_runtime.py").read_text(encoding="utf-8")
1311
  readme = (ROOT / "README.md").read_text(encoding="utf-8")
 
3
  from pathlib import Path
4
  from types import SimpleNamespace
5
 
6
+ import numpy as np
7
+
8
+ from production import (
9
+ GenerationChunkSpec,
10
+ count_speech_units,
11
+ fade_variable_internal_edges,
12
+ join_audio_chunks_variable,
13
+ match_chunk_rms,
14
+ punctuation_pause_seconds,
15
+ )
16
  from quality_runtime import LocalIndependentGateEvidence
17
 
18
 
 
61
  return values
62
 
63
 
64
+ def _isolated_assemble_trajectory_audio():
65
+ """Execute only the production assembly function without loading the model."""
66
+
67
+ app_path = ROOT / "app.py"
68
+ tree = ast.parse(app_path.read_text(encoding="utf-8"))
69
+ function = next(
70
+ node
71
+ for node in tree.body
72
+ if isinstance(node, ast.FunctionDef)
73
+ and node.name == "_assemble_trajectory_audio"
74
+ )
75
+ module = ast.Module(
76
+ body=[
77
+ ast.ImportFrom(
78
+ module="__future__",
79
+ names=[ast.alias(name="annotations")],
80
+ level=0,
81
+ ),
82
+ function,
83
+ ],
84
+ type_ignores=[],
85
+ )
86
+ ast.fix_missing_locations(module)
87
+
88
+ constants = _literal_constants(app_path)
89
+ namespace = {
90
+ "np": np,
91
+ "GenerationChunkSpec": GenerationChunkSpec,
92
+ "SR": 1_000,
93
+ "CHUNK_RMS_MATCH_DB": constants["CHUNK_RMS_MATCH_DB"],
94
+ "SEMANTIC_CHUNK_MIN_SILENCE_MS": constants[
95
+ "SEMANTIC_CHUNK_MIN_SILENCE_MS"
96
+ ],
97
+ "NETWORK_REQUEST_SEMANTIC_CHUNK_MIN_SILENCE_MS": constants[
98
+ "NETWORK_REQUEST_SEMANTIC_CHUNK_MIN_SILENCE_MS"
99
+ ],
100
+ "NETWORK_INTERNAL_SILENCE_MS": constants["NETWORK_INTERNAL_SILENCE_MS"],
101
+ "NETWORK_INTERNAL_FADE_MS": constants["NETWORK_INTERNAL_FADE_MS"],
102
+ "CHUNK_EDGE_FADE_MS": constants["CHUNK_EDGE_FADE_MS"],
103
+ "CROSSFADE_MS": constants["CROSSFADE_MS"],
104
+ "match_chunk_rms": match_chunk_rms,
105
+ "punctuation_pause_seconds": punctuation_pause_seconds,
106
+ "fade_variable_internal_edges": fade_variable_internal_edges,
107
+ "join_audio_chunks_variable": join_audio_chunks_variable,
108
+ "apply_loudness_floor": lambda waveform, **_kwargs: waveform,
109
+ "_apply_speed": lambda waveform, _speed: waveform,
110
+ "count_speech_units": count_speech_units,
111
+ "finish_audio": lambda waveform, _sample_rate, **_kwargs: waveform,
112
+ }
113
+ exec(compile(module, str(app_path), "exec"), namespace)
114
+ return namespace["_assemble_trajectory_audio"]
115
+
116
+
117
  def _isolated_load_speakers(*, metadata: dict, speaker_ids: tuple[str, ...]):
118
  """Execute only ``_load_speakers`` without importing the GPU application."""
119
 
 
585
  assert "chunk_artifacts=primary_verification.chunk_artifacts" in (
586
  intersection_source
587
  )
588
+ assert "CASCADE_EVIDENCE_SCHEMA_VERSION = 5" in quality_source
589
+ assert '"chunk_text_variants"' in quality_source
590
  assert "local_candidate_has_coverage_eligibility(" in helper_source
591
  assert "independent_local_results=" in initial_source
592
  assert "independent_local_results=" in refill_source
 
1087
  sequence_large_v3_transcriber = sequence_source.index(
1088
  "transcriber=transcribe_verification_whisper"
1089
  )
1090
+ sequence_independent = sequence_source.index(
1091
+ "independent_verification = _verify_independent_whole_audio("
1092
+ )
1093
+ sequence_intersection = sequence_source.index(
1094
+ "intersected = qualify_trajectory_with_joined_output("
1095
+ )
1096
+ assert (
1097
+ sequence_assemble
1098
+ < sequence_large_v3
1099
+ < sequence_large_v3_transcriber
1100
+ < sequence_independent
1101
+ < sequence_intersection
1102
+ )
1103
 
1104
  cache_create = synthesize_source.index(
1105
  "independent_cache = WholeWaveformVerificationCache()"
 
1381
  assert "boundary-only relaxation" in readme
1382
 
1383
 
1384
+ def test_pace_only_fallback_guard_starts_at_30_ordinary_units_not_29():
1385
+ app_path = ROOT / "app.py"
1386
+ constants = _literal_constants(app_path)
1387
+ tree = ast.parse(app_path.read_text(encoding="utf-8"))
1388
+ generate_chunk = next(
1389
+ node
1390
+ for node in tree.body
1391
+ if isinstance(node, ast.FunctionDef) and node.name == "_generate_chunk"
1392
+ )
1393
+ guarded_ifs = [
1394
+ node
1395
+ for node in ast.walk(generate_chunk)
1396
+ if isinstance(node, ast.If)
1397
+ and any(
1398
+ isinstance(name, ast.Name)
1399
+ and name.id == "PACE_ONLY_FALLBACK_MIN_UNITS"
1400
+ for name in ast.walk(node.test)
1401
+ )
1402
+ ]
1403
+
1404
+ assert constants["PACE_ONLY_FALLBACK_MIN_UNITS"] == 30
1405
+ assert len(guarded_ifs) == 1
1406
+ expression = ast.Expression(body=guarded_ifs[0].test)
1407
+ ast.fix_missing_locations(expression)
1408
+ guard = compile(expression, str(app_path), "eval")
1409
+
1410
+ def eligible(units, *, network_conditioned=False):
1411
+ return eval(
1412
+ guard,
1413
+ {
1414
+ "PACE_ONLY_FALLBACK_MIN_UNITS": constants[
1415
+ "PACE_ONLY_FALLBACK_MIN_UNITS"
1416
+ ],
1417
+ "count_speech_units": lambda _text: units,
1418
+ "network_conditioned": network_conditioned,
1419
+ "text": "測試",
1420
+ },
1421
+ )
1422
+
1423
+ assert eligible(29) is False
1424
+ assert eligible(30) is True
1425
+ assert eligible(30, network_conditioned=True) is False
1426
+
1427
+
1428
+ def test_assembled_waveform_uses_250ms_ordinary_and_350ms_network_request_pause():
1429
+ assemble = _isolated_assemble_trajectory_audio()
1430
+ chunks = ("第一段,", "第二段")
1431
+ trajectory = (
1432
+ np.ones(100, dtype=np.float32),
1433
+ np.ones(100, dtype=np.float32),
1434
+ )
1435
+
1436
+ ordinary = assemble(trajectory, chunks, 1.0)
1437
+
1438
+ assert ordinary.shape == (450,)
1439
+ np.testing.assert_array_equal(ordinary[100:350], np.zeros(250, dtype=np.float32))
1440
+
1441
+ first_end = len(chunks[0])
1442
+ network_specs = (
1443
+ GenerationChunkSpec(
1444
+ text=chunks[0],
1445
+ source_start=0,
1446
+ source_end=first_end,
1447
+ boundary_after="semantic",
1448
+ ),
1449
+ GenerationChunkSpec(
1450
+ text=chunks[1],
1451
+ source_start=first_end,
1452
+ source_end=first_end + len(chunks[1]),
1453
+ network_span_indices=(0,),
1454
+ boundary_after="none",
1455
+ ),
1456
+ )
1457
+ network_request = assemble(trajectory, chunks, 1.0, network_specs)
1458
+
1459
+ assert network_request.shape == (550,)
1460
+ np.testing.assert_array_equal(
1461
+ network_request[100:450],
1462
+ np.zeros(350, dtype=np.float32),
1463
+ )
1464
+
1465
+
1466
  def test_space_locks_waveform_only_bounded_whisper_segmentation():
1467
  source = (ROOT / "quality_runtime.py").read_text(encoding="utf-8")
1468
  readme = (ROOT / "README.md").read_text(encoding="utf-8")