mirror of
https://github.com/block/buzz.git
synced 2026-10-31 22:41:12 +00:00
🤖 I’m Larry, updating this description on Logan’s behalf. ## Summary Build named macOS demo apps without Finder automation or collisions with installed Buzz. `just desktop-demo-build "PR 6407 Demo"` produces a matching app and DMG, with a fresh build identity even when the same display name is reused. - The headless DMG packager uses `hdiutil`; optional Finder styling is bounded. The existing production release recipe is unchanged. - Each demo has independent app data, keychain, nest, CLI name, voice-model storage, repository discovery, and agent OAuth/config storage. Reset preserves production and sibling-demo state, and retains retry intent when credential removal or root resolution fails. - Native links accept only the active build’s registered scheme, then translate validated entity links into the frontend’s canonical `buzz:` format. - The recipe builds all six executable sidecars. Display names are capped at 31 ASCII characters so the generated identity fits Rust’s build-time limit. **Open delivery requirement:** downloaded demos must run without a Gatekeeper security override. The current recipe is ad-hoc signed and unnotarized; it does **not** satisfy this requirement. Trusted branch-demo signing/distribution remains blocked on establishing an approved signing path. This PR is not being presented as complete download-and-run delivery. ### Related issue N/A — reported in the Buzz DMG-packaging workstream. ### Testing At `11ce21ff97cb387ad676e7caa65b00964097d0bb`, macOS Blox passed the Tauri workspace suite and compiled-flags gate (including the full named-demo state; each library pass: 2,992 passed, 19 ignored), Tauri all-target clippy, the full `buzz-agent` package suite, and frontend lint/typecheck plus 5,733 tests. Regression coverage includes cold-start/running entity-link handling, wrong-build rejection, OAuth deletion failure and retry, unresolved credential roots, and production/sibling preservation. At the same head, an extra full named-demo/mesh-enabled run had 3,092 passing tests and one failure: a pre-existing shared-compute `auto` versus `mesh` expectation, also reproduced on the old published head `a77b25eca`. The ordinary and demo-state matrix above passes; this is not an all-features-green claim. Live macOS Launch Services delivery remains unverified. GitHub CI completed with 30 successful checks and 9 skipped. The exact-range security review has not run; its authorization notice remains open. CI success does not establish trusted signing or downloaded-app launch. Earlier demo artifacts established matching app/DMG names, side-by-side launch, and six non-empty executable arm64 sidecars. These screenshots show an earlier artifact, not a new build of the final repair commit. Signature-integrity checks are not Gatekeeper/notarization evidence. <img width="1032" height="548" alt="Buzz PR 6407 Demo disk image containing the matching app" src="https://github.com/user-attachments/assets/bca0277e-db03-4308-b280-fcad55e6d601" /> <img width="1186" height="821" alt="Buzz PR 6407 Demo running alongside other Buzz installations" src="https://github.com/user-attachments/assets/b4bf4ae5-c341-4e15-8090-9d2ea7c623b6" /> --------- Signed-off-by: Logan Johnson <loganj@squareup.com> Signed-off-by: Larry <8cf5a83f590ec0955b11647d1c88f796a98e088c30a492c58e0e46c3026ae7a4@buzz.block.builderlab.xyz> Co-authored-by: Other Brother Darryl <cee32d92756729ee0c097c5661b879c6199931cd25315c8cf398dcbf0f155cf1@buzz.block.builderlab.xyz> Co-authored-by: Larry <loganj+sandbox-larry@squareup.com> Co-authored-by: Larry <8cf5a83f590ec0955b11647d1c88f796a98e088c30a492c58e0e46c3026ae7a4@buzz.block.builderlab.xyz>
160 lines
5.4 KiB
Rust
160 lines
5.4 KiB
Rust
use super::*;
|
|
|
|
#[test]
|
|
fn voice_models_follow_the_selected_build_nest() {
|
|
let home = PathBuf::from("/Users/example");
|
|
for nest_name in [
|
|
".buzz",
|
|
".buzz-demo-workstream-board",
|
|
".buzz-demo-second-demo",
|
|
] {
|
|
let nest = home.join(nest_name);
|
|
assert_eq!(models_dir(nest.clone()), nest.join("models"));
|
|
}
|
|
}
|
|
|
|
fn create_ready_model_dir(root: &Path) -> PathBuf {
|
|
let model_dir = root.join(TTS_MODEL_DIR_NAME);
|
|
std::fs::create_dir_all(&model_dir).expect("create model dir");
|
|
for file in TTS_EXPECTED_FILES {
|
|
let path = model_dir.join(file);
|
|
let handle = std::fs::File::create(path).expect("create expected file");
|
|
if let Some(size) = tts_expected_size(file) {
|
|
handle.set_len(size).expect("size expected file");
|
|
} else {
|
|
std::fs::write(model_dir.join(file), b"test").expect("write expected file");
|
|
}
|
|
}
|
|
std::fs::write(model_dir.join(MANIFEST_FILENAME), TTS_MODEL_VERSION).expect("manifest");
|
|
model_dir
|
|
}
|
|
|
|
#[test]
|
|
fn expected_files_match_april_int8_metadata() {
|
|
let mut expected = april_model_info()
|
|
.artifacts
|
|
.iter()
|
|
.map(|artifact| artifact.filename)
|
|
.chain([TTS_LICENSE_ARTIFACT.filename, TTS_LICENSE_FILE_NAME])
|
|
.chain(POCKET_VOICES.iter().map(|voice| voice.reference_file))
|
|
.collect::<Vec<_>>();
|
|
expected.sort_unstable();
|
|
let mut actual = TTS_EXPECTED_FILES.to_vec();
|
|
actual.sort_unstable();
|
|
|
|
assert_eq!(actual, expected);
|
|
assert!(!actual.contains(&"flow_lm_main.onnx"));
|
|
assert!(!actual.contains(&"flow_lm_flow.onnx"));
|
|
assert!(!actual.contains(&"mimi_decoder.onnx"));
|
|
assert!(!actual.contains(&"marius.wav"));
|
|
}
|
|
|
|
#[test]
|
|
fn tts_readiness_requires_license_sidecar() {
|
|
let temp = tempfile::tempdir().expect("tempdir");
|
|
let slot = tts_model_slot();
|
|
let model_dir = create_ready_model_dir(temp.path());
|
|
|
|
assert!(slot.is_ready(temp.path()));
|
|
|
|
std::fs::remove_file(model_dir.join(TTS_LICENSE_FILE_NAME)).expect("remove sidecar");
|
|
assert!(!slot.is_ready(temp.path()));
|
|
}
|
|
|
|
#[test]
|
|
fn tts_readiness_rejects_truncated_pinned_artifact() {
|
|
let temp = tempfile::tempdir().expect("tempdir");
|
|
let slot = tts_model_slot();
|
|
let model_dir = create_ready_model_dir(temp.path());
|
|
let artifact = april_model_info().artifacts[0];
|
|
|
|
std::fs::OpenOptions::new()
|
|
.write(true)
|
|
.open(model_dir.join(artifact.filename))
|
|
.expect("open artifact")
|
|
.set_len(artifact.size_bytes - 1)
|
|
.expect("truncate artifact");
|
|
|
|
assert!(!slot.is_ready(temp.path()));
|
|
}
|
|
|
|
#[test]
|
|
fn january_cache_is_not_ready_for_april_int8() {
|
|
let temp = tempfile::tempdir().expect("tempdir");
|
|
let slot = tts_model_slot();
|
|
let model_dir = temp.path().join(TTS_MODEL_DIR_NAME);
|
|
std::fs::create_dir_all(&model_dir).expect("create model dir");
|
|
for file in [
|
|
"decoder.onnx",
|
|
"encoder.onnx",
|
|
"lm_flow.onnx",
|
|
"lm_main.onnx",
|
|
"text_conditioner.onnx",
|
|
"vocab.json",
|
|
"token_scores.json",
|
|
"LICENSE",
|
|
"reference_sample.wav",
|
|
TTS_LICENSE_FILE_NAME,
|
|
] {
|
|
std::fs::write(model_dir.join(file), b"january").expect("write January file");
|
|
}
|
|
std::fs::write(model_dir.join(MANIFEST_FILENAME), "3").expect("manifest");
|
|
|
|
assert!(!slot.is_ready(temp.path()));
|
|
}
|
|
|
|
#[test]
|
|
fn interrupted_install_restores_backup_when_destination_is_missing() {
|
|
let temp = tempfile::tempdir().expect("tempdir");
|
|
let slot = tts_model_slot();
|
|
let backup_dir = temp.path().join("pocket-tts.old");
|
|
std::fs::create_dir_all(&backup_dir).expect("create backup");
|
|
std::fs::write(backup_dir.join("sentinel"), b"previous").expect("write sentinel");
|
|
|
|
slot.recover_interrupted_install(temp.path());
|
|
|
|
assert_eq!(
|
|
std::fs::read(temp.path().join(TTS_MODEL_DIR_NAME).join("sentinel"))
|
|
.expect("restored sentinel"),
|
|
b"previous"
|
|
);
|
|
assert!(!backup_dir.exists());
|
|
}
|
|
|
|
#[test]
|
|
fn interrupted_install_replaces_incomplete_destination_with_backup() {
|
|
let temp = tempfile::tempdir().expect("tempdir");
|
|
let slot = tts_model_slot();
|
|
let model_dir = temp.path().join(TTS_MODEL_DIR_NAME);
|
|
let backup_dir = temp.path().join("pocket-tts.old");
|
|
std::fs::create_dir_all(&model_dir).expect("create incomplete destination");
|
|
std::fs::write(model_dir.join("incomplete"), b"april").expect("write incomplete file");
|
|
std::fs::create_dir_all(&backup_dir).expect("create backup");
|
|
std::fs::write(backup_dir.join("sentinel"), b"previous").expect("write sentinel");
|
|
|
|
slot.recover_interrupted_install(temp.path());
|
|
|
|
assert_eq!(
|
|
std::fs::read(model_dir.join("sentinel")).expect("restored sentinel"),
|
|
b"previous"
|
|
);
|
|
assert!(!model_dir.join("incomplete").exists());
|
|
assert!(!backup_dir.exists());
|
|
}
|
|
|
|
#[test]
|
|
fn ready_destination_removes_stale_backup() {
|
|
let temp = tempfile::tempdir().expect("tempdir");
|
|
let slot = tts_model_slot();
|
|
let model_dir = create_ready_model_dir(temp.path());
|
|
let backup_dir = temp.path().join("pocket-tts.old");
|
|
std::fs::create_dir_all(&backup_dir).expect("create backup");
|
|
std::fs::write(backup_dir.join("sentinel"), b"previous").expect("write sentinel");
|
|
|
|
slot.recover_interrupted_install(temp.path());
|
|
|
|
assert!(slot.is_ready(temp.path()));
|
|
assert!(model_dir.exists());
|
|
assert!(!backup_dir.exists());
|
|
}
|