hanzo-memory: real BLAKE3 + fix render_vtt trailing newline

Two byte-equivalence bugs caught by cross-runtime parity check:

1. _blake3() was falling back to BLAKE2b when hashlib lacked BLAKE3 (it
   always does on stock CPython). Wallet addresses depend on the SAME
   hash across all five brain runtimes. Required the `blake3` pip
   package; no fallback. Python addresses now match the TS canonical
   (@noble/hashes/blake3): encode_address(32x0x00) → "hanzo:UFC8qCW8...".

2. render_vtt joined lines with "\n" and appended one "" at the end,
   producing a single trailing newline. Every other runtime emits "\n\n"
   after each segment so cues are separated by a blank line per WebVTT
   spec. Switched to explicit f-string append; render_srt fixed the same
   way.

53 tests still pass.
This commit is contained in:
2026-05-11 12:27:11 -07:00
parent 25d195929b
commit b74c5ce6f1
2 changed files with 29 additions and 16 deletions
+1
View File
@@ -31,6 +31,7 @@ dependencies = [
"rich>=13.7.1",
"numpy>=1.26.0",
"sqlite-vec>=0.1.0", # SQLite with vector search capabilities
"blake3>=0.4.0", # Wallet-style content-addressable ids (byte-equivalent across all 5 brain runtimes)
]
[project.optional-dependencies]
+28 -16
View File
@@ -470,23 +470,27 @@ class CaptionSegment:
def render_vtt(segs: list[CaptionSegment]) -> str:
lines = ["WEBVTT", ""]
out = "WEBVTT\n\n"
for i, s in enumerate(segs):
lines.append(str(i + 1))
lines.append(f"{_vtt_time(s.start_secs)} --> {_vtt_time(s.end_secs)}")
lines.append(f"<v {s.speaker}>{s.text}</v>" if s.speaker else s.text)
lines.append("")
return "\n".join(lines)
out += f"{i + 1}\n"
out += f"{_vtt_time(s.start_secs)} --> {_vtt_time(s.end_secs)}\n"
if s.speaker:
out += f"<v {s.speaker}>{s.text}</v>\n\n"
else:
out += f"{s.text}\n\n"
return out
def render_srt(segs: list[CaptionSegment]) -> str:
lines: list[str] = []
out = ""
for i, s in enumerate(segs):
lines.append(str(i + 1))
lines.append(f"{_srt_time(s.start_secs)} --> {_srt_time(s.end_secs)}")
lines.append(f"{s.speaker}: {s.text}" if s.speaker else s.text)
lines.append("")
return "\n".join(lines)
out += f"{i + 1}\n"
out += f"{_srt_time(s.start_secs)} --> {_srt_time(s.end_secs)}\n"
if s.speaker:
out += f"{s.speaker}: {s.text}\n\n"
else:
out += f"{s.text}\n\n"
return out
def render_rttm(segs: list[CaptionSegment], uri: str = "audio") -> str:
@@ -683,11 +687,19 @@ _VERSION_V1 = 0x01
def _blake3(data: bytes) -> bytes:
"""BLAKE3 via hashlib if available; falls back to blake2b for portability."""
"""BLAKE3 — required. Wallet addresses depend on byte-equivalence across
every Hanzo runtime (TS @noble/hashes/blake3, Rust blake3 crate, Go
lukechampine.com/blake3, C++ vendored reference impl). The `blake3` pip
package is the only path here; do not fall back to anything else."""
try:
return hashlib.blake2b(data, digest_size=32).digest() if not hasattr(hashlib, "blake3") else hashlib.blake3(data).digest() # type: ignore[attr-defined]
except Exception:
return hashlib.blake2b(data, digest_size=32).digest()
from blake3 import blake3 as _blake3_impl # type: ignore[import-not-found]
except ImportError as exc: # pragma: no cover
raise RuntimeError(
"hanzo_memory.algorithms requires the `blake3` package "
"(pip install blake3). Wallet addresses are content-addressable; "
"no other hash is acceptable."
) from exc
return _blake3_impl(data).digest()
def encode_address(public_key: bytes, prefix: str = "hanzo") -> str: