untracked files on main: dceb101 feat(#63): IMP-34 R1 donor capacity measured bound (u1+u2)

This commit is contained in:
2026-05-21 22:07:41 +09:00
commit 8f085a28d3
3220 changed files with 985495 additions and 0 deletions
+91
View File
@@ -0,0 +1,91 @@
"""IMP-46 u1 — Frame transformation cache signature builder.
Deterministic SHA256 over the 8 declared structural axes:
frame_id, v4_label, cardinality, source_shape,
h3_count, char_count_bucket, layout_preset, zone_position
Guardrails:
* No sample/section identifiers in the signature surface (no-hardcoding lock).
* source_shape constrained to the bullet/paragraph/table/mixed enum.
* char_count_bucket is the *bucket label*; numeric counts must be projected
via :func:`bucket_char_count` before being fed to :func:`build_signature`.
* Schema version is embedded in the hashed payload so a future axis change
breaks the digest by design (cache invalidation on schema bump).
"""
from __future__ import annotations
import hashlib
import json
from enum import Enum
SCHEMA_VERSION = 1
class SourceShape(str, Enum):
BULLET = "bullet"
PARAGRAPH = "paragraph"
TABLE = "table"
MIXED = "mixed"
_CHAR_COUNT_BUCKETS: tuple[tuple[int, str], ...] = (
(50, "0-50"),
(150, "51-150"),
(400, "151-400"),
(1000, "401-1000"),
)
_CHAR_COUNT_BUCKET_OVERFLOW = "1001+"
CHAR_COUNT_BUCKET_LABELS: tuple[str, ...] = tuple(
label for _, label in _CHAR_COUNT_BUCKETS
) + (_CHAR_COUNT_BUCKET_OVERFLOW,)
def bucket_char_count(char_count: int) -> str:
"""Project a non-negative character count to its fixed bucket label."""
if isinstance(char_count, bool) or not isinstance(char_count, int):
raise TypeError("char_count must be a non-negative int")
if char_count < 0:
raise ValueError("char_count must be non-negative")
for upper, label in _CHAR_COUNT_BUCKETS:
if char_count <= upper:
return label
return _CHAR_COUNT_BUCKET_OVERFLOW
def build_signature(
*,
frame_id: str,
v4_label: str,
cardinality: int | None,
source_shape: SourceShape | str,
h3_count: int,
char_count_bucket: str,
layout_preset: str,
zone_position: str,
) -> str:
"""Return a deterministic SHA256 hex digest over the 8 declared axes."""
if isinstance(source_shape, SourceShape):
source_shape_value = source_shape.value
elif isinstance(source_shape, str):
source_shape_value = SourceShape(source_shape).value
else:
raise TypeError("source_shape must be SourceShape or str")
if char_count_bucket not in CHAR_COUNT_BUCKET_LABELS:
raise ValueError(
f"char_count_bucket={char_count_bucket!r} is not a known bucket "
f"label (expected one of {CHAR_COUNT_BUCKET_LABELS})"
)
payload = {
"schema_version": SCHEMA_VERSION,
"frame_id": frame_id,
"v4_label": v4_label,
"cardinality": cardinality,
"source_shape": source_shape_value,
"h3_count": h3_count,
"char_count_bucket": char_count_bucket,
"layout_preset": layout_preset,
"zone_position": zone_position,
}
encoded = json.dumps(payload, sort_keys=True, ensure_ascii=False).encode("utf-8")
return hashlib.sha256(encoded).hexdigest()