Publish Tiny Hinglish Turn Detector development preview
Browse filesrelease inventory sha256: f381f906d00c3963b2975bf84b770ea4954880fdc834c2e981dcf4a25f914d8b
- MODEL_CARD.md +1 -1
- README.md +1 -1
- REPORT.md +2 -2
- SOURCE_README.md +1 -1
- export_manifest.json +5 -5
- release_provenance.json +17 -17
- scripts/build_release.py +59 -0
- space/requirements.txt +0 -1
- tests/test_release_guardrails.py +31 -0
MODEL_CARD.md
CHANGED
|
@@ -303,7 +303,7 @@ failure aggregates, silence perturbation report, exact environment files, CPU
|
|
| 303 |
benchmarks, and guarded release tooling. Per-example validation predictions and
|
| 304 |
the text-bearing split manifest remain in the private local workspace; the
|
| 305 |
public package contains aggregate reports and hashes, not those sensitive rows.
|
| 306 |
-
The quality gate completed with Ruff 0.15.16 passing and
|
| 307 |
passing via Python `unittest` discovery. The configured Hugging Face owner is
|
| 308 |
`suvradeepp`.
|
| 309 |
|
|
|
|
| 303 |
benchmarks, and guarded release tooling. Per-example validation predictions and
|
| 304 |
the text-bearing split manifest remain in the private local workspace; the
|
| 305 |
public package contains aggregate reports and hashes, not those sensitive rows.
|
| 306 |
+
The quality gate completed with Ruff 0.15.16 passing and 131/131 automated tests
|
| 307 |
passing via Python `unittest` discovery. The configured Hugging Face owner is
|
| 308 |
`suvradeepp`.
|
| 309 |
|
README.md
CHANGED
|
@@ -303,7 +303,7 @@ failure aggregates, silence perturbation report, exact environment files, CPU
|
|
| 303 |
benchmarks, and guarded release tooling. Per-example validation predictions and
|
| 304 |
the text-bearing split manifest remain in the private local workspace; the
|
| 305 |
public package contains aggregate reports and hashes, not those sensitive rows.
|
| 306 |
-
The quality gate completed with Ruff 0.15.16 passing and
|
| 307 |
passing via Python `unittest` discovery. The configured Hugging Face owner is
|
| 308 |
`suvradeepp`.
|
| 309 |
|
|
|
|
| 303 |
benchmarks, and guarded release tooling. Per-example validation predictions and
|
| 304 |
the text-bearing split manifest remain in the private local workspace; the
|
| 305 |
public package contains aggregate reports and hashes, not those sensitive rows.
|
| 306 |
+
The quality gate completed with Ruff 0.15.16 passing and 131/131 automated tests
|
| 307 |
passing via Python `unittest` discovery. The configured Hugging Face owner is
|
| 308 |
`suvradeepp`.
|
| 309 |
|
REPORT.md
CHANGED
|
@@ -525,8 +525,8 @@ calendar days or the missing external data collection occurred.
|
|
| 525 |
| 13 | Integrate controller and demo | replay, three-state controller, Gradio, Hinglish recording prompts | Preview model and synthetic controller integration complete; real sequence replay pending |
|
| 526 |
| 14 | Freeze test, package, publish | sealed-test guard, atomic release builder, exact-mirror publisher | Development packaging path ready; official-test/final gates not satisfied |
|
| 527 |
|
| 528 |
-
The repository quality gate passed Ruff 0.15.16 and all
|
| 529 |
-
(
|
| 530 |
the missing empirical datasets or rights review.
|
| 531 |
|
| 532 |
## 9. Decision log and next experiments
|
|
|
|
| 525 |
| 13 | Integrate controller and demo | replay, three-state controller, Gradio, Hinglish recording prompts | Preview model and synthetic controller integration complete; real sequence replay pending |
|
| 526 |
| 14 | Freeze test, package, publish | sealed-test guard, atomic release builder, exact-mirror publisher | Development packaging path ready; official-test/final gates not satisfied |
|
| 527 |
|
| 528 |
+
The repository quality gate passed Ruff 0.15.16 and all 131 automated tests
|
| 529 |
+
(131 passed via Python `unittest` discovery). That validates the implemented behavior under test; it does not fill
|
| 530 |
the missing empirical datasets or rights review.
|
| 531 |
|
| 532 |
## 9. Decision log and next experiments
|
SOURCE_README.md
CHANGED
|
@@ -26,7 +26,7 @@ engineering evidence, not a production-readiness claim.
|
|
| 26 |
| Domain-shift stress | Measured, confounded | Source-held-out AP 0.5500/0.5368 for TinyTCN/baseline; both near chance in ranking, with wide nine-source bootstrap intervals |
|
| 27 |
| Runtime/export | Measured | 611 KiB FP32 ONNX; exact PyTorch/ONNX parity; ONNX p95 0.956 ms neural-only and 1.629 ms waveform-to-probability |
|
| 28 |
| Controller integration | Synthetic only | Metadata-bound 8-checkpoint/3-turn fixture emits 3 response edges with 0 duplicates; not model or product-quality evidence |
|
| 29 |
-
| Code quality gate | Passed | Ruff 0.15.16;
|
| 30 |
| Accuracy/generalization | **Not established** | No full-corpus run, collected Hinglish recordings, real conversation replay, or official-test evaluation |
|
| 31 |
| Hugging Face publication | Not claimed here | Local guarded release/publisher path exists; verify any remote publication separately |
|
| 32 |
|
|
|
|
| 26 |
| Domain-shift stress | Measured, confounded | Source-held-out AP 0.5500/0.5368 for TinyTCN/baseline; both near chance in ranking, with wide nine-source bootstrap intervals |
|
| 27 |
| Runtime/export | Measured | 611 KiB FP32 ONNX; exact PyTorch/ONNX parity; ONNX p95 0.956 ms neural-only and 1.629 ms waveform-to-probability |
|
| 28 |
| Controller integration | Synthetic only | Metadata-bound 8-checkpoint/3-turn fixture emits 3 response edges with 0 duplicates; not model or product-quality evidence |
|
| 29 |
+
| Code quality gate | Passed | Ruff 0.15.16; 131/131 automated tests passed via `unittest` discovery |
|
| 30 |
| Accuracy/generalization | **Not established** | No full-corpus run, collected Hinglish recordings, real conversation replay, or official-test evaluation |
|
| 31 |
| Hugging Face publication | Not claimed here | Local guarded release/publisher path exists; verify any remote publication separately |
|
| 32 |
|
export_manifest.json
CHANGED
|
@@ -126,9 +126,9 @@
|
|
| 126 |
"sha256": "146763ebbe4d4ca0858c3fda2f56aa235aa9a4b6686b3216bcea58d148945d04"
|
| 127 |
},
|
| 128 |
{
|
| 129 |
-
"bytes":
|
| 130 |
"path": "scripts/build_release.py",
|
| 131 |
-
"sha256": "
|
| 132 |
},
|
| 133 |
{
|
| 134 |
"bytes": 10147,
|
|
@@ -196,9 +196,9 @@
|
|
| 196 |
"sha256": "40569f1e553f0cb340cf81414e072839ca734a7d303c5cb5f1e46c5035590804"
|
| 197 |
},
|
| 198 |
{
|
| 199 |
-
"bytes":
|
| 200 |
"path": "space/requirements.txt",
|
| 201 |
-
"sha256": "
|
| 202 |
},
|
| 203 |
{
|
| 204 |
"bytes": 160,
|
|
@@ -371,7 +371,7 @@
|
|
| 371 |
"sha256": "da0eac829fe43615f7bb149998c2f2762f148790fb0c14d4ba6db4d6b25298f4"
|
| 372 |
}
|
| 373 |
],
|
| 374 |
-
"source_inventory_sha256": "
|
| 375 |
"task": "audio-turn-end-detection",
|
| 376 |
"threshold": 0.741000771522522,
|
| 377 |
"training_data": {
|
|
|
|
| 126 |
"sha256": "146763ebbe4d4ca0858c3fda2f56aa235aa9a4b6686b3216bcea58d148945d04"
|
| 127 |
},
|
| 128 |
{
|
| 129 |
+
"bytes": 40091,
|
| 130 |
"path": "scripts/build_release.py",
|
| 131 |
+
"sha256": "07963aacb56af58add680f0a011dc58baefa24355e127b2dc0f10c018bde9525"
|
| 132 |
},
|
| 133 |
{
|
| 134 |
"bytes": 10147,
|
|
|
|
| 196 |
"sha256": "40569f1e553f0cb340cf81414e072839ca734a7d303c5cb5f1e46c5035590804"
|
| 197 |
},
|
| 198 |
{
|
| 199 |
+
"bytes": 51,
|
| 200 |
"path": "space/requirements.txt",
|
| 201 |
+
"sha256": "7b99ddd361d3626972bc819c85237ee929b6c579fa70b66d845ef88dd8bda7e7"
|
| 202 |
},
|
| 203 |
{
|
| 204 |
"bytes": 160,
|
|
|
|
| 371 |
"sha256": "da0eac829fe43615f7bb149998c2f2762f148790fb0c14d4ba6db4d6b25298f4"
|
| 372 |
}
|
| 373 |
],
|
| 374 |
+
"source_inventory_sha256": "e4f7592fd12f2fa89ff838df39dbb7ce487edf50ed439e8a17098e03cb71a6ab",
|
| 375 |
"task": "audio-turn-end-detection",
|
| 376 |
"threshold": 0.741000771522522,
|
| 377 |
"training_data": {
|
release_provenance.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
| 16 |
},
|
| 17 |
"MODEL_CARD.md": {
|
| 18 |
"bytes": 14805,
|
| 19 |
-
"sha256": "
|
| 20 |
},
|
| 21 |
"Makefile": {
|
| 22 |
"bytes": 777,
|
|
@@ -28,15 +28,15 @@
|
|
| 28 |
},
|
| 29 |
"README.md": {
|
| 30 |
"bytes": 14805,
|
| 31 |
-
"sha256": "
|
| 32 |
},
|
| 33 |
"REPORT.md": {
|
| 34 |
"bytes": 32272,
|
| 35 |
-
"sha256": "
|
| 36 |
},
|
| 37 |
"SOURCE_README.md": {
|
| 38 |
"bytes": 20535,
|
| 39 |
-
"sha256": "
|
| 40 |
},
|
| 41 |
"app.py": {
|
| 42 |
"bytes": 10381,
|
|
@@ -108,7 +108,7 @@
|
|
| 108 |
},
|
| 109 |
"export_manifest.json": {
|
| 110 |
"bytes": 12430,
|
| 111 |
-
"sha256": "
|
| 112 |
},
|
| 113 |
"model.onnx": {
|
| 114 |
"bytes": 625431,
|
|
@@ -247,8 +247,8 @@
|
|
| 247 |
"sha256": "146763ebbe4d4ca0858c3fda2f56aa235aa9a4b6686b3216bcea58d148945d04"
|
| 248 |
},
|
| 249 |
"scripts/build_release.py": {
|
| 250 |
-
"bytes":
|
| 251 |
-
"sha256": "
|
| 252 |
},
|
| 253 |
"scripts/compare_models.py": {
|
| 254 |
"bytes": 10147,
|
|
@@ -303,8 +303,8 @@
|
|
| 303 |
"sha256": "40569f1e553f0cb340cf81414e072839ca734a7d303c5cb5f1e46c5035590804"
|
| 304 |
},
|
| 305 |
"space/requirements.txt": {
|
| 306 |
-
"bytes":
|
| 307 |
-
"sha256": "
|
| 308 |
},
|
| 309 |
"src/turn_detection/__init__.py": {
|
| 310 |
"bytes": 160,
|
|
@@ -531,8 +531,8 @@
|
|
| 531 |
"sha256": "5af81ad7995b6bfd3816b7d97ee1226027659dc5b8a7cb4fe4376fa850dcd14e"
|
| 532 |
},
|
| 533 |
"tests/test_release_guardrails.py": {
|
| 534 |
-
"bytes":
|
| 535 |
-
"sha256": "
|
| 536 |
},
|
| 537 |
"tests/test_runtime_controller.py": {
|
| 538 |
"bytes": 3086,
|
|
@@ -566,15 +566,15 @@
|
|
| 566 |
},
|
| 567 |
"MODEL_CARD.md": {
|
| 568 |
"bytes": 14805,
|
| 569 |
-
"sha256": "
|
| 570 |
},
|
| 571 |
"NOTICE": {
|
| 572 |
"bytes": 563,
|
| 573 |
"sha256": "aee9451763081ff03b717ba3b821b52f0a57eac9e1c7689817b9d41e6317b36c"
|
| 574 |
},
|
| 575 |
"README.md": {
|
| 576 |
-
"bytes":
|
| 577 |
-
"sha256": "
|
| 578 |
},
|
| 579 |
"app.py": {
|
| 580 |
"bytes": 10381,
|
|
@@ -589,8 +589,8 @@
|
|
| 589 |
"sha256": "43636ad5efb642138c281a4582e85f19b5aae2f4f6cca69211169341ae4399b4"
|
| 590 |
},
|
| 591 |
"requirements.txt": {
|
| 592 |
-
"bytes":
|
| 593 |
-
"sha256": "
|
| 594 |
},
|
| 595 |
"src/turn_detection/__init__.py": {
|
| 596 |
"bytes": 160,
|
|
@@ -626,5 +626,5 @@
|
|
| 626 |
"metrics_file": "development_metrics.json",
|
| 627 |
"metrics_scope": "development",
|
| 628 |
"model_file": "model.onnx",
|
| 629 |
-
"source_and_artifact_inventory_sha256": "
|
| 630 |
}
|
|
|
|
| 16 |
},
|
| 17 |
"MODEL_CARD.md": {
|
| 18 |
"bytes": 14805,
|
| 19 |
+
"sha256": "05162a2792ee71d642605d87bef18089cf5f57b52e6a9b32e6d34cbd26789b29"
|
| 20 |
},
|
| 21 |
"Makefile": {
|
| 22 |
"bytes": 777,
|
|
|
|
| 28 |
},
|
| 29 |
"README.md": {
|
| 30 |
"bytes": 14805,
|
| 31 |
+
"sha256": "05162a2792ee71d642605d87bef18089cf5f57b52e6a9b32e6d34cbd26789b29"
|
| 32 |
},
|
| 33 |
"REPORT.md": {
|
| 34 |
"bytes": 32272,
|
| 35 |
+
"sha256": "40284013cd8d435f624464b5e9f7a3427f41a9a6410a5ae917ef34863a9a95b1"
|
| 36 |
},
|
| 37 |
"SOURCE_README.md": {
|
| 38 |
"bytes": 20535,
|
| 39 |
+
"sha256": "e74584ad5bc721c333d83346d9ee25e4f9a22c4c31f8efcf3ef30089dd3f8d0c"
|
| 40 |
},
|
| 41 |
"app.py": {
|
| 42 |
"bytes": 10381,
|
|
|
|
| 108 |
},
|
| 109 |
"export_manifest.json": {
|
| 110 |
"bytes": 12430,
|
| 111 |
+
"sha256": "7a5ec279128eeb68095467b00fd4c1ef5a644876f5a77867dcefbf81e20d99b8"
|
| 112 |
},
|
| 113 |
"model.onnx": {
|
| 114 |
"bytes": 625431,
|
|
|
|
| 247 |
"sha256": "146763ebbe4d4ca0858c3fda2f56aa235aa9a4b6686b3216bcea58d148945d04"
|
| 248 |
},
|
| 249 |
"scripts/build_release.py": {
|
| 250 |
+
"bytes": 40091,
|
| 251 |
+
"sha256": "07963aacb56af58add680f0a011dc58baefa24355e127b2dc0f10c018bde9525"
|
| 252 |
},
|
| 253 |
"scripts/compare_models.py": {
|
| 254 |
"bytes": 10147,
|
|
|
|
| 303 |
"sha256": "40569f1e553f0cb340cf81414e072839ca734a7d303c5cb5f1e46c5035590804"
|
| 304 |
},
|
| 305 |
"space/requirements.txt": {
|
| 306 |
+
"bytes": 51,
|
| 307 |
+
"sha256": "7b99ddd361d3626972bc819c85237ee929b6c579fa70b66d845ef88dd8bda7e7"
|
| 308 |
},
|
| 309 |
"src/turn_detection/__init__.py": {
|
| 310 |
"bytes": 160,
|
|
|
|
| 531 |
"sha256": "5af81ad7995b6bfd3816b7d97ee1226027659dc5b8a7cb4fe4376fa850dcd14e"
|
| 532 |
},
|
| 533 |
"tests/test_release_guardrails.py": {
|
| 534 |
+
"bytes": 18405,
|
| 535 |
+
"sha256": "bc94fd488aadb1859172e9cdd803f4b7cb828d8884e79b1899286019af28af19"
|
| 536 |
},
|
| 537 |
"tests/test_runtime_controller.py": {
|
| 538 |
"bytes": 3086,
|
|
|
|
| 566 |
},
|
| 567 |
"MODEL_CARD.md": {
|
| 568 |
"bytes": 14805,
|
| 569 |
+
"sha256": "05162a2792ee71d642605d87bef18089cf5f57b52e6a9b32e6d34cbd26789b29"
|
| 570 |
},
|
| 571 |
"NOTICE": {
|
| 572 |
"bytes": 563,
|
| 573 |
"sha256": "aee9451763081ff03b717ba3b821b52f0a57eac9e1c7689817b9d41e6317b36c"
|
| 574 |
},
|
| 575 |
"README.md": {
|
| 576 |
+
"bytes": 1314,
|
| 577 |
+
"sha256": "37e7617fceca4ee6196d2875b2cbda5e3211dd825f8c1b4a610a5a59fe2bf89c"
|
| 578 |
},
|
| 579 |
"app.py": {
|
| 580 |
"bytes": 10381,
|
|
|
|
| 589 |
"sha256": "43636ad5efb642138c281a4582e85f19b5aae2f4f6cca69211169341ae4399b4"
|
| 590 |
},
|
| 591 |
"requirements.txt": {
|
| 592 |
+
"bytes": 51,
|
| 593 |
+
"sha256": "7b99ddd361d3626972bc819c85237ee929b6c579fa70b66d845ef88dd8bda7e7"
|
| 594 |
},
|
| 595 |
"src/turn_detection/__init__.py": {
|
| 596 |
"bytes": 160,
|
|
|
|
| 626 |
"metrics_file": "development_metrics.json",
|
| 627 |
"metrics_scope": "development",
|
| 628 |
"model_file": "model.onnx",
|
| 629 |
+
"source_and_artifact_inventory_sha256": "1ef74a0b13c1cf68a4b96090911ca715e9bdfc2917bcfc4ac8483fc20d1d786a"
|
| 630 |
}
|
scripts/build_release.py
CHANGED
|
@@ -19,6 +19,11 @@ SOURCE_ROOT = ROOT / "src"
|
|
| 19 |
if str(SOURCE_ROOT) not in sys.path:
|
| 20 |
sys.path.insert(0, str(SOURCE_ROOT))
|
| 21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
|
| 23 |
def parse_args() -> argparse.Namespace:
|
| 24 |
parser = argparse.ArgumentParser(description=__doc__)
|
|
@@ -61,6 +66,59 @@ def _copy_file(source: Path, destination: Path) -> None:
|
|
| 61 |
shutil.copy2(source, destination)
|
| 62 |
|
| 63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
def _copy_runtime(destination: Path) -> None:
|
| 65 |
package_root = destination / "src" / "turn_detection"
|
| 66 |
package_root.mkdir(parents=True, exist_ok=True)
|
|
@@ -694,6 +752,7 @@ def main() -> int:
|
|
| 694 |
ROOT / "reports" / "controller_replay_integration.summary.json",
|
| 695 |
metadata.get("controller"),
|
| 696 |
)
|
|
|
|
| 697 |
|
| 698 |
frozen_manifest: dict | None = None
|
| 699 |
if not metadata_is_development:
|
|
|
|
| 19 |
if str(SOURCE_ROOT) not in sys.path:
|
| 20 |
sys.path.insert(0, str(SOURCE_ROOT))
|
| 21 |
|
| 22 |
+
_SPACE_CARD_COLORS = frozenset(
|
| 23 |
+
{"red", "yellow", "green", "blue", "indigo", "purple", "pink", "gray"}
|
| 24 |
+
)
|
| 25 |
+
_SPACE_SHORT_DESCRIPTION_MAX_LENGTH = 60
|
| 26 |
+
|
| 27 |
|
| 28 |
def parse_args() -> argparse.Namespace:
|
| 29 |
parser = argparse.ArgumentParser(description=__doc__)
|
|
|
|
| 66 |
shutil.copy2(source, destination)
|
| 67 |
|
| 68 |
|
| 69 |
+
def _space_card_frontmatter(path: Path) -> dict[str, str]:
|
| 70 |
+
"""Parse the scalar fields used by the packaged Hugging Face Space card."""
|
| 71 |
+
|
| 72 |
+
try:
|
| 73 |
+
lines = path.read_text(encoding="utf-8").splitlines()
|
| 74 |
+
except OSError as exc:
|
| 75 |
+
raise SystemExit(f"Space README is unreadable: {path}") from exc
|
| 76 |
+
if not lines or lines[0].strip() != "---":
|
| 77 |
+
raise SystemExit("Space README must start with YAML frontmatter")
|
| 78 |
+
try:
|
| 79 |
+
closing_index = next(
|
| 80 |
+
index for index, line in enumerate(lines[1:], start=1) if line.strip() == "---"
|
| 81 |
+
)
|
| 82 |
+
except StopIteration as exc:
|
| 83 |
+
raise SystemExit("Space README frontmatter is not closed") from exc
|
| 84 |
+
|
| 85 |
+
metadata: dict[str, str] = {}
|
| 86 |
+
for line in lines[1:closing_index]:
|
| 87 |
+
stripped = line.strip()
|
| 88 |
+
if not stripped or stripped.startswith("#"):
|
| 89 |
+
continue
|
| 90 |
+
if ":" not in stripped:
|
| 91 |
+
raise SystemExit("Space README frontmatter must contain scalar key/value pairs")
|
| 92 |
+
key, value = stripped.split(":", 1)
|
| 93 |
+
key = key.strip()
|
| 94 |
+
value = value.strip().strip("'\"")
|
| 95 |
+
if not key or key in metadata:
|
| 96 |
+
raise SystemExit(f"Space README has an invalid or duplicate metadata key: {key!r}")
|
| 97 |
+
metadata[key] = value
|
| 98 |
+
return metadata
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
def _validate_space_card(path: Path) -> None:
|
| 102 |
+
metadata = _space_card_frontmatter(path)
|
| 103 |
+
if metadata.get("sdk") != "gradio":
|
| 104 |
+
raise SystemExit("Space README sdk must be 'gradio'")
|
| 105 |
+
if metadata.get("app_file") != "app.py":
|
| 106 |
+
raise SystemExit("Space README app_file must be 'app.py'")
|
| 107 |
+
for field in ("colorFrom", "colorTo"):
|
| 108 |
+
color = metadata.get(field)
|
| 109 |
+
if color not in _SPACE_CARD_COLORS:
|
| 110 |
+
allowed = ", ".join(sorted(_SPACE_CARD_COLORS))
|
| 111 |
+
raise SystemExit(f"Space README {field} must be one of: {allowed}")
|
| 112 |
+
short_description = metadata.get("short_description", "")
|
| 113 |
+
if not short_description:
|
| 114 |
+
raise SystemExit("Space README short_description must be non-empty")
|
| 115 |
+
if len(short_description) > _SPACE_SHORT_DESCRIPTION_MAX_LENGTH:
|
| 116 |
+
raise SystemExit(
|
| 117 |
+
"Space README short_description must be at most "
|
| 118 |
+
f"{_SPACE_SHORT_DESCRIPTION_MAX_LENGTH} characters"
|
| 119 |
+
)
|
| 120 |
+
|
| 121 |
+
|
| 122 |
def _copy_runtime(destination: Path) -> None:
|
| 123 |
package_root = destination / "src" / "turn_detection"
|
| 124 |
package_root.mkdir(parents=True, exist_ok=True)
|
|
|
|
| 752 |
ROOT / "reports" / "controller_replay_integration.summary.json",
|
| 753 |
metadata.get("controller"),
|
| 754 |
)
|
| 755 |
+
_validate_space_card(ROOT / "space" / "README.md")
|
| 756 |
|
| 757 |
frozen_manifest: dict | None = None
|
| 758 |
if not metadata_is_development:
|
space/requirements.txt
CHANGED
|
@@ -1,4 +1,3 @@
|
|
| 1 |
-
gradio==5.49.1
|
| 2 |
numpy==2.3.5
|
| 3 |
onnxruntime==1.26.0
|
| 4 |
soundfile==0.14.0
|
|
|
|
|
|
|
| 1 |
numpy==2.3.5
|
| 2 |
onnxruntime==1.26.0
|
| 3 |
soundfile==0.14.0
|
tests/test_release_guardrails.py
CHANGED
|
@@ -85,6 +85,37 @@ class ReleaseGuardrailTest(unittest.TestCase):
|
|
| 85 |
self.assertTrue((destination / "new.txt").is_file())
|
| 86 |
self.assertFalse((destination / "old.txt").exists())
|
| 87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
def test_synthetic_replay_must_be_labelled_and_hash_bound(self) -> None:
|
| 89 |
from scripts.build_release import _validate_synthetic_replay
|
| 90 |
|
|
|
|
| 85 |
self.assertTrue((destination / "new.txt").is_file())
|
| 86 |
self.assertFalse((destination / "old.txt").exists())
|
| 87 |
|
| 88 |
+
def test_space_card_rejects_server_invalid_frontmatter(self) -> None:
|
| 89 |
+
from scripts.build_release import _validate_space_card
|
| 90 |
+
|
| 91 |
+
valid = """---
|
| 92 |
+
title: Test Space
|
| 93 |
+
colorFrom: yellow
|
| 94 |
+
colorTo: indigo
|
| 95 |
+
sdk: gradio
|
| 96 |
+
app_file: app.py
|
| 97 |
+
short_description: Tiny endpoint detector
|
| 98 |
+
---
|
| 99 |
+
"""
|
| 100 |
+
with tempfile.TemporaryDirectory() as directory:
|
| 101 |
+
card = Path(directory) / "README.md"
|
| 102 |
+
card.write_text(valid, encoding="utf-8")
|
| 103 |
+
_validate_space_card(card)
|
| 104 |
+
|
| 105 |
+
card.write_text(
|
| 106 |
+
valid.replace("colorFrom: yellow", "colorFrom: orange"),
|
| 107 |
+
encoding="utf-8",
|
| 108 |
+
)
|
| 109 |
+
with self.assertRaisesRegex(SystemExit, "colorFrom"):
|
| 110 |
+
_validate_space_card(card)
|
| 111 |
+
|
| 112 |
+
card.write_text(
|
| 113 |
+
valid.replace("Tiny endpoint detector", "x" * 61),
|
| 114 |
+
encoding="utf-8",
|
| 115 |
+
)
|
| 116 |
+
with self.assertRaisesRegex(SystemExit, "at most 60"):
|
| 117 |
+
_validate_space_card(card)
|
| 118 |
+
|
| 119 |
def test_synthetic_replay_must_be_labelled_and_hash_bound(self) -> None:
|
| 120 |
from scripts.build_release import _validate_synthetic_replay
|
| 121 |
|