[WORKER] Voice+Models — vocal stack, low-power inference and CI hardening loop #54
Open
opened 2026-09-08 02:02:52 +00:00 by nsaspy
·
21 comments
No Branch/Tag specified
main
feat/p0-prolog-python-nim-product-packages
fix/860-lisp-evidence-type-fence-20260921
feat/strange-loop-experts
companion/805-android-animations-20260917
feat/star-kb-agent
fix/860-lisp-apply-input-schema-20260921
agentic15/lane3-closed-output-contracts
feature/doordash-commerce
feat/860-lisp-symbolic-conversation-20260921
feat/mara-emacs-todo-roam-928
feat/zara-symbolic-memory
fix/860-lisp-apply-verification-lineage
expert-builder-2/nix-bash-current-core-20260920
fix/860-core-lisp-composition
fix/860-lisp-composition-argument-authority
feat/864-nix-bash-style-sources
fix/859-language-handler-verdict
fix/859-language-handler-failed-verdict
fix/859-expert-stop-unregister
feat/863-js-ts-java-kotlin-host
fix/860-lisp-delegation-status
feat/expert-composition-864
feat/862-language-expert-adapters-v2
chore/dotfiles-expert-ownership-20260919
feat/zara-emacs-deep-20260919
feat/862-language-expert-adapters
feature/866-wiki-gates-search
codex/emacs-kb-857-20260919
feat/851-zara-ssh-files
feat/844-zara-music-prolog-tools
feat/emacs-workflows-20260919
feat/org-roam-shared-memory-2026-09-19
feat/844-zara-music
feat/calendar-caldav-824
feature/zara-activity-android-826
feat/zara-home-ha-transport
feat/prolog-policy-plugin-20260917
feat/812-prolog-policy-default-kb
feat/zara-home-ha-events
feat/839-zara-pi-bash-tmux
feat/zara-cota-static-gtfs-830
feature/zara-mobility-829-20260917
docs/agents-working-model-20260917
codex/808-stock-expert-2026-09-17
feat/linux-context-hooks
feat/811-prolog-policy-advice
fix/zara-coding-criteria-provenance-v2
plugin-d/local-recall-transactional-install
plugin-b/pipewire-player-506
plugin-d/508-discord-transactional-install
fix/zara-discord-startup-fail-closed
fix/browser-list-tabs-primary-error
fix/zara-coding-evidence-provenance
feat/zara-browser-webdriver-backend
rage/503-files-root-shape
rage/500-calendar-mutation-proof
rage/495-contacts-create-proof
rage/497-calendar-write-evidence
rage/495-contacts-create-evidence
rage/489-comms-send-evidence-replay
rage/485-calendar-free-busy-evidence
rage/489-comms-send-evidence
rage/485-calendar-free-busy-evidence-replay
rage/489-comms-send-payload-proof
rage/487-calendar-event-temporal-order
rage/483-timers-persisted-numeric-types
rage/481-github-pr-provider-metadata
rage/479-media-numeric-metadata
rage/477-media-accepted-bool
rage/475-comms-attachment-size-type
rage/471-sysadmin-provider-booleans
rage/473-comms-provider-booleans
rage/469-home-scene-verified-bool
rage/467-contacts-accepted-bool
rage/465-calendar-accepted-bool
rage/463-media-provider-booleans
rage/461-discord-boolean-policy
rage/459-expert-host-policy
rage/457-discord-chance-policy
rage/455-timers-numeric-descriptors
rage/453-discord-history-bounds
rage/451-browser-session-bounds
rage/449-avatar-renderer-command-config
rage/447-avatar-directory-policy
rage/407-avatar-renderer-policy-replay
rage/444-discord-context-bound-types
rage/444-discord-context-bound-types-replay
fix/443-avatar-idle-cpu
rage/439-discord-audit-bound-types
rage/439-discord-audit-red-proof
rage/435-healthcheck-numeric-types-replay
rage/435-healthcheck-numeric-types
rage/434-files-numeric-types
rage/432-contacts-numeric-types
rage/429-sysadmin-numeric-types
rage/427-calendar-numeric-types
rage/425-comms-policy-types
rage/423-media-constructor-limit-types
rage/421-media-queue-search-types
rage/419-media-playback-types
rage/417-local-recall-selector-type
rage/415-local-recall-bool-limits
rage/413-context-plugin-ttl-type
rage/411-context-freshness-types
rage/409-knowledge-config-types
rage/407-avatar-renderer-policy
rage/403-agent-zero-config-types-v2
rage/403-agent-zero-config-types
rage/403-agent-zero-config-red
rage/399-starintel-numeric-types-v2
rage/399-starintel-numeric-types
rage/399-starintel-numeric-red
rage/395-emacs-config-types-v2
rage/395-emacs-config-types
rage/395-emacs-config-red
rage/392-brave-config-types-v2
rage/392-brave-config-types
rage/377-coding-prolog-policy-v2
rage/377-red-proof-v2
rage/387-github-integer-limits
rage/385-github-numeric-config
rage/377-coding-prolog-policy-descriptors
rage/382-memory-duplicate-projections
rage/379-shell-runtime-limit-type
rage/374-memory-duplicate-recall
rage/369-coding-inspector-descriptors
rage/368-memory-projection-evidence
rage/370-shell-policy-collections
rage/366-memory-backend-fact-bound
rage/364-shell-policy-descriptors
rage/362-memory-recall-bound
rage/360-expert-bool-bounds
rage/358-github-config-bools
rage/356-github-number-types
rage/354-shell-runtime-bool
rage/352-memory-jsonrpc-id-type
rage/350-memory-mcp-result-status
rage/348-memory-mcp-oserror
rage/345-memory-schema-registration-type-v2
rage/345-memory-schema-registration-type
rage/340-memory-schema-types-v2
rage/340-memory-schema-types
rage/336-coding-task-state-executable-v2
rage/338-memory-bounded-facts
rage/336-coding-task-state-executable
rage/334-memory-type-selector-validation
rage/332-coding-canonical-changed-paths
rage/330-shell-invalid-subprocess-strings
rage/328-memory-provenance-alias
rage/326-memory-write-evidence
rage/324-memory-fact-term
rage/322-memory-scope-type
rage/320-shell-cwd-type
rage/318-memory-provenance
rage/316-memory-query-type
rage/314-shell-argv-container
rage/312-shell-env-mapping
rage/310-current-zara-pin
rage/308-shell-typed-stdin
rage/306-memory-schema-fact-isolation
rage/303-github-strict-result-limits
rage/301-shell-strict-runtime-config
rage/298-shell-environment-allowlist
rage/296-memory-mcp-finite-deadline
rage/294-memory-mcp-response-identity
rage/292-memory-type-isolation
rage/290-shell-byte-limits
rage/288-task-dependencies
rage/286-current-verifier-failures
rage/284-shell-finite-runtime
rage/280-latest-verifier-result
rage/282-shell-typed-config
rage/1-verifier-owned-evidence
rage/registry-timeout-abort
rage/registry-module-import-timeout
rage/registry-bound-module-entrypoints
rage/registry-bound-contract-attributes
rage/registry-service-factory-timeout
rage/registry-legacy-entrypoint-timeout
rage/coding-task-repository-context
rage/registry-sync-timeout-bounds
rage/registry-real-sync-timeouts
rage/coding-task-state-protocol-fence
rage/registry-installed-import-isolation
rage/coding-task-state-response-timeout
rage/coding-task-state-crash-fence
rage/coding-task-state-status-contract
rage/registry-dependency-env-construction
rage/248-document-task-completion
docs/248-task-state-contract
rage/246-freeze-completed-task
rage/244-evidence-status
rage/242-passing-verification
rage/240-task-state-bounds
rage/242-passing-evidence
rage/238-prolog-task-state
rage/236-verifier-duplicate-evidence
rage/234-canonical-verification-object-ids
rage/232-service-plugin-type-agreement
rage/230-deduplicate-worktree-evidence
rage/228-deduplicate-changed-path-evidence
rage/226-isolate-agent-zero-env
rage/224-isolate-avatar-renderer
rage/222-isolate-starintel-live-env
rage/220-strip-live-provider-secrets
rage/215-module-level-factory
rage/217-canonical-evidence-paths
rage/213-commit-tree-object-id
rage/211-diff-head-object-id
rage/209-inspect-head-object-id
rage/207-worktree-head-object-id
rage/205-service-api-version
rage/199-branch-object-id
rage/202-worktree-lock-proof
rage/200-worktree-add-proof
rage/199-branch-object-ids
rage/197-log-object-ids
rage/195-numstat-errors
rage/193-diff-snapshot
rage/191-inspect-dirty-snapshot
rage/189-atomic-branch-create
rage/187-branch-inventory-snapshot
rage/185-fence-branch-create
rage/183-confine-installers
rage/181-confine-plugin-roots
rage/179-strict-service-metadata
rage/177-compat-lifecycle-timeout
rage/175-canonical-install-command
rage/173-python-dependency-metadata
rage/171-canonical-search-paths
rage/169-registry-updated-date
rage/167-canonical-registry-strings
rage/registry-installer-layout-agreement
rage/registry-install-command-grammar
rage/registry-source-urls
rage/registry-search-path-metadata
rage/registry-install-target-metadata
rage/registry-flake-source-metadata
rage/registry-license-metadata
rage/compat-runtime-advice-contract
rage/compat-runtime-worker-sync
rage/compat-runtime-worker-signature
rage/compat-runtime-worker-identity
rage/coding-worktree-remove
rage/compat-runtime-advice-shutdown
rage/compat-runtime-dispatch-contract
rage/registry-nix-metadata-agreement
rage/registry-runtime-readonly-config
rage/registry-require-docs
rage/registry-runtime-closed-workers
rage/registry-confine-metadata-paths
rage/registry-runtime-subscription-lifecycle
rage/registry-runtime-worker-contract
rage/registry-runtime-subscribe-contract
rage/registry-lifecycle-call-semantics
rage/registry-service-tools-call-semantics
rage/registry-async-tools
rage/registry-async-lifecycle
rage/registry-enabled-default-contract
rage/registry-legacy-precedence
rage/registry-legacy-entrypoint-proof
rage/registry-canonical-tool-names
rage/registry-tool-metadata-quality
rage/registry-description-metadata
rage/registry-search-path-discovery
rage/registry-isolate-plugin-imports
rage/registry-tool-name-collisions
rage/1-zara-coding-evidence-branch-shape
rage/1-zara-coding-verify-branch-shape
rage/1-zara-coding-evidence-root-shape
rage/1-zara-coding-verify-root-shape
rage/1-zara-coding-worktree-evidence-path-shape
rage/1-zara-coding-verify-worktree-path-shape
rage/1-zara-coding-verify-path-boundary
rage/1-zara-coding-repository-text-evidence
rage/1-zara-coding-verify-evidence-shape
rage/1-zara-coding-snapshot-evidence-shape
rage/1-zara-coding-worktree-evidence-shape
rage/1-zara-coding-branch-inventory-bound
rage/1-zara-coding-verify-head-shape
rage/1-zara-coding-diff-snapshot
rage/1-zara-coding-rollback-proof
rage/1-zara-coding-inspect-bound
rage/1-zara-coding-dirty-path-coherence
rage/1-zara-coding-doc-current-surface
rage/1-zara-coding-add-lock-rollback
rage/1-zara-coding-changed-path-verify
rage/1-zara-coding-worktree-absent
rage/1-zara-coding-worktree-verify
rage/1-zara-coding-worktree-add-locked
rage/1-zara-coding-worktree-remove
rage/1-zara-coding-branch-assertion
rage/1-zara-coding-check-repository
rage/1-zara-coding-verify-tool
rage/1-zara-coding-spec-verify
rage/1-zara-coding-repository-evidence
rage/1-zara-coding-spec-compile
rage/1-zara-coding-worktree-add
rage/1-zara-coding-branch-create-cas
rage/1-zara-coding-commit
rage/1-zara-coding-branch-delete
rage/1-zara-coding-branch-create
rage/1-zara-coding-worktree-inventory
rage/1-worktree-list
rage/1-repo-list-status
rage/1-spec-language-catalog
rage/1-git-diff-summary
rage/1-git-log-adapter
rage/1-zara-coding-spec-normalize
rage/7-symbolic-memory-native-remember-get
rage/1-zara-coding-task-state
rage/5-zara-shell
rage/8-home-assistant-adapter
rage/7-zara-memory
rage/13-zara-voice-lab
rage/12-zara-voice
rage/8-zara-home-rules
rage/8-zara-home
rage/2-zara-expert
rage/32-discord-scoped-moderation
rage/31-discord-moderation-ack
rage/28-discord-moderation-audit
rage/35-discord-ci-preset
rage/33-discord-channel-commands
rage/33-discord-channel-inspection-policy
rage/27-discord-opt-in-message-content
rage/34-discord-content-diagnostics
rage/30-discord-public-output-privacy
rage/29-discord-user-isolation
rage/12-voice-runtime
rage/53-installed-runtime-smoke
rage/53-lifecycle-compat
rage/12-voice
rage/19-healthcheck-clean
rage/19-healthcheck
rage/16-timers
rage/11-comms
rage/17-contacts
rage/10-calendar
rage/14-media
rage/6-sysadmin
rage/15-files
rage/9-browser
rage/4-context
rage/3-desktop
rage/3-desktop-red
rage/52-emacs-red
rage/18-51-knowledge-brave
rage/50-github-red
fix/agent-zero-native-api
rage/53-zara-compat-red
feat/zara-starintel-server-47
fix/discord-recent-context
feat/agent-zero-bridge-40
fix/discord-tool-execution
feat/zara-persona-37
feat/declarative-runtime-layout
feat/discord-inspection-moderation
fix/discord-manager-permissions
feat/zara-org-todos
codex/zara-plugins-ci-push
feat/zara-discord
No results found.
Labels
Clear labels
accessibility
Barrier affecting people with disabilities
bug
Something isn't working
documentation
Improvements or additions to documentation
duplicate
This issue or pull request already exists
enhancement
New feature or request
good first issue
Good for newcomers
help wanted
Extra attention is needed
invalid
This doesn't seem right
question
Further information is requested
security
wontfix
This will not be worked on
No labels
accessibility
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
security
wontfix
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
No due date set.
Dependencies
No dependencies set.
Reference
nsaspy/zara-plugins#54
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Mission
Own Zara's voice/model productionization across the plugin/runtime boundary with two equal goals: better real voice behavior and real low-power model coverage that can run in CI.
This worker may touch
zara-pluginsdirectly and file/consume narrowly scoped Zara Core issues/PRs where the canonical voice/runtime seam lives. It must not fork a second voice stack.Stagger slot
Start after Core+Android (+30m). Preserve the relative offset if cadence changes.
Primary queue
zara-voiceconcrete TTS/player adapters, streaming/cancellation and observed playback evidence;zara-voice-labreal local STT/TTS/wake/normalization backends and benchmark harnesses;Real-model CI contract
Mocks/fakes remain mandatory for deterministic failure/race tests, but they are not enough. Build a separately labeled CPU-only tiny-model CI lane using pinned, redistributable artifacts whenever licensing permits.
Research and freeze the actual model set before pinning it. The target coverage is:
For every real model record: source/revision, license, hash, artifact size, quantization/precision, runtime, architecture, RAM/peak RSS, CPU count, cold/warm startup, cancellation behavior and test corpus.
Default model CI must be network-independent after artifacts are provisioned/cached and must never silently substitute a fake backend when the job is labeled real-model.
Low-power profile
Create a constrained profile approximating weak hardware, initially CPU-only and deliberately thread-limited. Measure before freezing numeric budgets. Track at least:
Prefer a small model that reliably catches integration regressions over a larger impressive model that makes CI unusable.
Voice test ladder
Cover accents/noise/silence where fixtures permit, VAD boundaries, partial/final ordering, false starts/corrections, stale output, interruption, model unload/reload and backend failure.
Feature expansion
Research/implement one bounded slice at a time: natural TTS, better local STT, wake detection, transcript normalization, streaming, model routing, offline voice or media/desktop integration only when it materially supports the voice experience and respects existing owners.
Hardening requirements
State loop
Current handoff: PR #510 exists and must receive its planned adversarial exact-head review before this worker moves to a new target.
Output contract
Guardrails
main/master.WORKER_STATE
worker: plugin-b
mode_used: IMPLEMENT
result: Added the first production zara-browser backend: bounded loopback W3C WebDriver attachment with native window/navigation/element/text/click/type/screenshot operations and explicit unsupported download/select states.
issue_or_pr: #510
head:
74effc9948tests: TDD test file added first (
test_webdriver.py) covering loopback-only endpoint policy, active-tab restoration, real tab navigation, no execute/JS path, observed click/type evidence, explicit download unavailability, and screenshot decode. GitHub exact-head status currently has no reported checks yet; full unittest/registry/Nix gates remain pending CI.blockers: No implementation blocker. Exact-head CI/check evidence is not available yet, so merge is not justified this run.
next_mode: REVIEW
next_target: Adversarially review PR #510 at exact head for false-success semantics, WebDriver protocol correctness, stale/active-window restoration, response/resource bounds, and CI gate results; fix concrete findings before considering merge.
WORKER_STATE
worker: plugin-b
mode_used: REVIEW
result: Adversarial review of PR #510 found two merge-blocking correctness gaps: click/type falsely report observed success based only on an active window, and tab enumeration fails to restore the prior active window on mid-enumeration errors; also flagged unbounded per-handle enumeration work.
refs: #510 review comment https://github.com/lost-rob0t/zara-plugins/pull/510#issuecomment-5567523658
head:
74effc9948tests: Exact-head GitHub checks
testandzara-avatar idle CPU budgetare both green. Existingtest_webdriver.pycovers happy-path active-window restoration, loopback endpoint policy, native no-JS operations, explicit unavailable download, and screenshot decode, but does not cover the blocking failure semantics found in review.blockers: PR #510 must not merge until false-success action evidence is removed/replaced with real postcondition evidence and active-window restoration is guaranteed on failure; bound returned handle enumeration work in the same repair if practical.
next_mode: IMPLEMENT
next_target: Repair PR #510 tests-first: add RED cases for command acknowledgement-without-observed-effect and mid-list failure restoration, then minimally fix WebDriver backend semantics and add a bounded handle-count guard; rerun focused suite plus registry/Nix/exact-head gates.
WORKER_STATE
worker: plugin-b
mode_used: IMPLEMENT
result: Repaired and merged #510. WebDriver click now separates acknowledgement from effect observation; typing requires concrete before/after element value readback; tab enumeration is bounded to 32 unique handles and restores the original active window through failure paths.
refs: #510 merged as
265f106ccfhead:
72a7131458(verified PR head); merge265f106ccftests: Tests were committed before the implementation repair for acknowledgement-vs-observation semantics, failed-enumeration restoration, bounded handle sets, verified value readback, and unavailable readback. Exact-head CI run 34100574068 passed compatibility gates, registry/plugin tests, plugin package builds, and zara-avatar idle CPU budget.
blockers: none for this slice
next_mode: REVIEW
next_target: Adversarially review the merged zara-browser WebDriver backend at main for residual false-success semantics, restoration masking, stale-session behavior, response/resource bounds, and credential leakage; if clean, advance to the next dependency-ready browser/media/voice/desktop production gap.
WORKER_STATE
worker: plugin-b
mode_used: REVIEW
result: Adversarial review of the merged zara-browser WebDriver backend at current main found one concrete residual correctness blocker:
list_tabs()restores the original window infinally, but a restoration failure can mask the primary enumeration/provider error and destroy the evidence needed to diagnose stale-session failures. The prior false-success fixes remain intact: click separates acknowledgement from observation, type requires before/after element-value evidence, tab handles are bounded/unique, transport errors do not expose endpoint/session credentials, and no generic JS/eval/shell path is present.refs: merged #510; main
plugins/zara-browser/lib/zara_browser/webdriver.py; #506 durable mailboxhead:
265f106ccftests: #510 exact-head CI run 34100574068 passed compatibility gates, registry/plugin tests, plugin package builds, and zara-avatar idle CPU budget at verified PR head
72a7131458. No separate pull-request workflow run is associated with the merge commit because the workflow lookup is PR-trigger scoped. Current tests cover failed enumeration restoration, but not the double-failure case where enumeration and restoration both fail.blockers: restoration-error masking remains. Add a regression where enumeration fails on a secondary handle and restoration to the original handle also fails; preserve/raise the primary enumeration error while retaining restoration failure as chained/secondary evidence. No new unsafe generic execution, credential leakage, or unbounded response issue found in this slice.
next_mode: IMPLEMENT
next_target: Tests-first repair on a focused branch/PR: add the double-failure restoration regression, minimally change
list_tabs()so restoration cannot overwrite the primary failure, then run zara-browser focused tests plus registry/Nix/exact-head gates before merge.WORKER_STATE
worker: plugin-b
mode_used: IMPLEMENT
result: Opened tests-first PR #516 fixing zara-browser
list_tabs()double-failure semantics so active-window restoration can no longer overwrite the primary enumeration/provider error; restoration failure is retained as chained secondary evidence.refs: #516; test-first commit
0c40cef7f6; implementation commitc612d7e979; CI run 34110579627head:
c612d7e979tests: Added RED regression for enumeration failure on a secondary handle plus simultaneous restoration failure; asserts the caller still receives
synthetic title failure, withsynthetic restoration failureretained as__cause__. Existing focused WebDriver coverage remains in place. Exact-head CI has started: compatibility gate/whitespace steps are green, while registry/plugin/package and zara-avatar idle CPU jobs are still in progress at this handoff.blockers: Exact-head CI run 34110579627 is still in progress, so merge is not justified yet. No code blocker found.
evidence: PR diff is limited to
plugins/zara-browser/lib/zara_browser/webdriver.pyandplugins/zara-browser/test/test_webdriver.py; no new generic execution path, credential/raw-media surface, session expansion, or response-bound relaxation was introduced. Existing 32-handle and transport byte limits are unchanged.next_mode: REVIEW
next_target: Adversarially review PR #516 at exact head after CI settles: verify primary-vs-restoration exception ordering, stale-session/error chaining, no credential leakage through chained errors, and exact-head registry/plugin/Nix/idle-CPU gates; merge only if all remain green.
WORKER_STATE
worker: plugin-b
mode_used: REVIEW
result: Adversarial exact-head review of PR #516 passed. The repair preserves the primary
list_tabs()enumeration/provider failure when restoration also fails, retains restoration failure as chained secondary evidence, introduces no generic execution surface or response-bound relaxation, and exact-head CI is fully green. Merged #516.refs: #516; CI run 34110579627; merge
c9d8252affhead:
c612d7e979(reviewed exact PR head); main after mergec9d8252afftests: Exact-head workflow 34110579627 completed success.
testpassed whitespace, compatibility contract, source/installed compatibility diagnostics, registry/plugin tests, and plugin package builds.zara-avatar idle CPU budgetpassed the real Electron idle-CPU gate. Regression verifies secondary-handle enumeration failure remains the raised error while simultaneous restoration failure is retained as__cause__.blockers: none for #516. Review found no new false-success path, unsafe JS/eval/shell execution, stale-session masking regression, unbounded handle growth, credential/raw-media surface, or missing gate evidence in this bounded diff.
evidence: PR diff is limited to
plugins/zara-browser/lib/zara_browser/webdriver.pyandplugins/zara-browser/test/test_webdriver.py; existing 32-handle and 1 MiB transport response limits remain; loopback-only endpoint and bounded/safe session-id validation remain; transport-facing BrowserError messages do not echo endpoint/session values. Merge used expected head SHA and main now points atc9d8252aff.next_mode: RESEARCH
next_target: Audit current maintained
zara-voiceTTS/player backend APIs and current source, then choose one minimal production adapter slice with observed playback evidence, bounded cancellation/resource behavior, and no raw-audio/transcript diagnostic leakage.WORKER_STATE
worker: plugin-b
mode_used: RESEARCH
result: Audited current
zara-voiceseams plus maintained local TTS/playback APIs and selected a minimal production-first slice: a Linux PipeWirepw-playplayer adapter, ahead of Piper synthesis, because the existing service already has a concrete player injection seam and bounded in-memory artifacts while the maintained Piper line adds model/package/license/resource questions that deserve a separate slice.refs: current
plugins/zara-voice/lib/zara_voice/domain.py,plugin.py, README; PipeWirepw-cat/pw-playdocs https://pipewire.pages.freedesktop.org/pipewire/page_man_pw-cat_1.html ; maintained Piper https://github.com/OHF-Voice/piper1-gpl and Python API https://github.com/OHF-Voice/piper1-gpl/blob/main/docs/API_PYTHON.mdhead:
eaef813695model_matrix: research only; no model executed. Maintained Piper (
piper-tts, GPL-3.0) exposesPiperVoice.synthesize_wavand streamingPiperVoice.synthesize; current public repo shows v1.4.2 as the latest surfaced release. Deferred model pinning/license/artifact benchmarking to a later dedicated TTS slice.voice_tests: none executed in RESEARCH. Current zara-voice tests are fake-only; selected next slice must add deterministic process/player contract tests first and a separately gated real PipeWire smoke where an audio server is available.
resource_results: research only. PipeWire 1.6.8 docs show
pw-play [options] [FILE|-]; stdin playback is supported, encoded PCM formats are handled through libsndfile where streamable, and raw mode has explicit rate/format/channel controls. Proposed adapter must keep one child process per playback, fixed argv only, bounded stdin inherited from existingmax_audio_bytes, and explicit process termination/wait bounds for cancellation.blockers: none for the player slice. Do not claim audible-device success from subprocess spawn/exit alone; observed evidence should distinguish
started, process exit status, cancellation/termination outcome, and hardware/device verification. Piper productionization remains intentionally separate because packaging GPL-3 code/models, pinned voice provenance/license/hash, warm model lifetime, CPU/RSS/thread limits, and synthesis cancellation need their own review.next_mode: IMPLEMENT
next_target: Tests-first
zara-voicePipeWire player adapter: fixedpw-playexecutable/argv (no shell), accept only supported bounded artifact formats, generate opaque playback IDs, retain process handles, reject stale/unknown IDs, make cancel terminate+wait with bounded escalation, never log/return raw audio, report unavailable whenpw-play/PipeWire is absent, and return playback evidence that cannot be confused with confirmed audible output. Keep default plugin behavior unavailable unless explicitly configured; focused zara-voice tests + registry/Nix/exact-head gates before any merge.WORKER_STATE
worker: plugin-b
mode_used: IMPLEMENT
result: Opened tests-first PR #517 adding a bounded production
zara-voicePipeWirepw-playadapter with fixed argv/no shell, WAV-only bounded input, opaque playback IDs, stale/unknown-ID rejection, bounded terminate→wait→kill cancellation, explicit unavailable behavior, bounded active playback count, and playback evidence that explicitly does not claim audible-device success.refs: #517; #12; test-first commit
576467d753; implementation commit172ef7053c; CI run 34126731108head:
172ef7053cmodel_matrix: none; this slice is player-only and does not relabel fake/process coverage as a real TTS-model test.
tests: Added deterministic PipeWire player contract tests first for unavailable binary fail-closed behavior, fixed
pw-play -argv with shell disabled, non-audible process-start evidence, raw-audio omission, unsupported/oversized input rejection, stale/finished playback-ID rejection, bounded terminate/wait/kill escalation, and active-playback capacity. Exact-head CI is running at172ef7053c: whitespace + compatibility contract + Nix install are green; registry/plugin/package gates and the real Electron idle-CPU gate are still in progress.blockers: Exact-head CI run 34126731108 has not finished, so merge is not justified. This bounded slice also does not claim real audible PipeWire/device coverage; a separately gated real PipeWire smoke remains required before calling hardware playback verified.
evidence: PR #517 changes only
plugins/zara-voice/test/test_pipewire_player.pyandplugins/zara-voice/lib/zara_voice/player.py. Production spawn uses only resolvedpw-playwith argv[pw-play, "-"],shell=False, DEVNULL stdout/stderr, and no model-controlled command surface. Playback result contains only opaque ID/state/backend plusaudible_confirmed: false; raw audio is never returned/logged. Input is capped, active processes are capped, and cancellation has explicit terminate/kill wait bounds.next_mode: REVIEW
next_target: Adversarial exact-head review of PR #517 after CI settles: attack writer-thread/process lifetime, cancellation races, finished/stale ID cleanup, false-success wording, binary/path trust, raw-audio leakage, active-process/resource bounds, and absence of a real PipeWire smoke; merge only if exact-head registry/plugin/Nix/idle-CPU gates are green and no blocker remains.
WORKER_STATE
worker: plugin-b
mode_used: REVIEW
result: Adversarial exact-head review of PR #517 found merge-blocking lifetime/cleanup defects plus a failed exact-head CI gate. The PipeWire adapter keeps its fixed/no-shell bounded execution and non-audible evidence semantics, but it can leak an untracked child if playback-ID allocation fails after spawn; cancellation does not bound writer-thread/raw-audio lifetime; and ZaraVoicePlugin.stop() does not close an injected production player.
refs: #517; review comment https://github.com/lost-rob0t/zara-plugins/pull/517#issuecomment-5571915487; #12; CI run 34126731108
head:
172ef7053cmodel_matrix: none; player-only review, no TTS model exercised and no fake/process result relabeled as real-model coverage.
tests: Exact-head CI run 34126731108 completed failure.
zara-avatar idle CPU budgetpassed, buttestfailed atRun registry and plugin tests; package builds were skipped. Existing PipeWire contract tests cover unavailable binary, fixed argv/no shell, non-audible process-start evidence, input bounds, stale IDs, terminate/wait/kill escalation, and active-playback capacity. Missing regressions: ID-allocation failure after spawn cleanup, blocked writer teardown on cancel, and plugin stop closing active player resources.blockers: 1) spawned process/stdin can remain live and untracked if
_new_playback_id_locked()exhausts attempts; 2) cancel returns after child wait without closing/joining writer, so a writer may outlive cancellation and retain raw audio; 3)ZaraVoicePlugin.stop()is a no-op, so injected PipeWire children are not lifecycle-bound to plugin shutdown; 4) registry/plugin exact-head gate is red and package gate never ran; 5) no real PipeWire/device smoke exists, so audible hardware playback remains explicitly unverified.evidence:
player.pyspawns before allocating the opaque ID, stores the raw audio in the writer target, and never joins that writer during cancel; currentplugin.pystop() returns None without invoking player.close(). Fixed[pw-play, "-"],shell=False, DEVNULL output, byte/active-process bounds, opaque IDs, andaudible_confirmed: falseremain intact; no generic JS/eval/shell surface or returned raw-media body was found.next_mode: IMPLEMENT
next_target: Tests-first repair on PR #517/focused branch: add RED cases for post-spawn ID-allocation cleanup, blocked-writer cancellation teardown, and plugin-stop player cleanup; minimally bound/close/join writer/process resources, preserve fail-closed/non-audible semantics, diagnose the current registry/plugin failure, then rerun focused zara-voice tests plus registry/Nix/package/idle-CPU exact-head gates. Do not merge until green.
WORKER_STATE
worker: plugin-b
mode_used: IMPLEMENT
result: Repaired PR #517 tests-first for the review-blocking PipeWire lifetime issues: playback IDs are now allocated before spawn, cancellation closes stdin and requires bounded writer-thread teardown before reporting success, and plugin shutdown closes the injected player.
refs: #517; #12; test-first commits
69f0475ee8and7f12c63712; implementation commits45afb6a60dande1ba5c31ba; PR comment #issuecomment-5572678466; CI run 34137456255head:
e1ba5c31bamodel_matrix: none; player-only repair, no TTS model exercised and no fake/process coverage relabeled as real-model coverage.
tests: Added RED coverage before implementation for ID-allocation exhaustion without process spawn, blocked-writer cancellation cleanup, and ZaraVoicePlugin.stop() closing an injected player. Exact-head CI run 34137456255 has started at
e1ba5c31ba; whitespace and compatibility-contract steps are green, while Nix/registry/plugin/package and real Electron idle-CPU gates are still running at handoff.blockers: Exact-head CI has not completed, so merge is not justified. Real audible PipeWire/device playback remains explicitly unverified and is not claimed by this slice. Prior registry/plugin failure is being re-exercised by the new exact-head run; no direct job-log text was available through the connector this run.
evidence: Current source now allocates the opaque ID before Popen, retains stdin/writer/process together, closes stdin before termination to unblock the writer, joins the writer under writer_timeout, and refuses successful cancellation if writer cleanup exceeds the bound; timed-out resources remain tracked. ZaraVoicePlugin.stop() invokes player.close() when present. Fixed [pw-play, "-"], shell=False, DEVNULL output, WAV/input/active-process bounds, opaque IDs, and audible_confirmed:false remain unchanged; no generic execution path or raw-audio return/log surface was introduced.
next_mode: REVIEW
next_target: Adversarially review PR #517 at exact head
e1ba5c31baafter CI settles. Verify cancellation cannot falsely succeed with a live writer, close() does not silently abandon timed-out resources, finished/stale cleanup remains bounded, plugin stop lifecycle is correct, no credential/raw-media leakage or unsafe execution was added, and registry/plugin/package/Nix/idle-CPU exact-head gates are green before merge.WORKER_STATE
worker: plugin-b
mode_used: REVIEW
result: Adversarial review of PR #517 at exact head found the previous lifetime fixes valid, but merge remains blocked by a repeated red registry/plugin gate plus two residual shutdown/raw-audio lifetime failure semantics: double process-timeout exits before writer teardown is checked, and player.close()/plugin.stop() silently swallow cleanup failure while leaving live resources tracked.
refs: #517; PR review comment https://github.com/lost-rob0t/zara-plugins/pull/517#issuecomment-5573296194; #12; CI run 34137456255
head:
e1ba5c31bamodel_matrix: none; player-only adversarial review, no TTS model or audible-device result exercised.
tests: Existing tests prove ID allocation before spawn, normal blocked-writer cancellation teardown, plugin stop invoking player.close(), fixed argv/no shell, input/active-process bounds, stale IDs, and terminate→kill escalation. Missing RED coverage for terminate timeout + kill timeout while writer teardown is still required, and for close()/plugin-stop surfacing incomplete cleanup. Exact-head CI run 34137456255 completed failure: compatibility/Nix diagnostics passed,
zara-avatar idle CPU budgetpassed,testfailed again atRun registry and plugin tests, and package builds were skipped.blockers: 1) on second process wait timeout, cancel raises before bounded writer join/check, so raw-audio-holding writer lifetime is not proven on the worst stuck-process path; 2) close() catches every VoiceError and returns normally, so ZaraVoicePlugin.stop() can appear successful while a timed-out child/writer remains live and tracked; 3) exact-head registry/plugin gate remains red and package gate did not run; 4) real PipeWire/device audibility remains explicitly unverified, correctly not claimed.
evidence: Current source retains failed resources in
_playbacks, closes stdin before termination, and joins the writer on normal cancellation; fixed[pw-play, "-"],shell=False, DEVNULL output, opaque IDs, WAV/max-byte/max-active bounds, andaudible_confirmed:falseremain intact. No generic execution, credential leakage, or returned raw-media body found. Review comment records the residual failure paths.next_mode: IMPLEMENT
next_target: Repair PR #517 tests-first: add RED cases for terminate-timeout + kill-timeout requiring writer cleanup before error return, and for close()/plugin-stop surfacing incomplete cleanup instead of swallowing it; minimally fix lifecycle semantics while retaining failed resources for retry, diagnose/fix the current registry/plugin failure, then rerun focused zara-voice plus registry/package/Nix/idle-CPU exact-head gates. Do not merge until green.
WORKER_STATE
worker: plugin-b
mode_used: IMPLEMENT
result: Repaired PR #517 tests-first for the residual PipeWire shutdown/cancellation false-success paths: double process timeout now still performs bounded writer teardown checks, close()/plugin stop surface incomplete cleanup, failed resources stay tracked for retry, and finished playback IDs are reaped/rejected as stale instead of returning cancellation success.
refs: #517; #12; test-first commits
6ba116dd16and5a0549332c; implementation commit577ccbf8c7; PR comment #issuecomment-5573858906; CI run 34146937921head:
577ccbf8c7model_matrix: none; player-only lifecycle repair, no TTS model or fake/process result relabeled as real-model/audio-device coverage.
tests: Added RED coverage before implementation for terminate-timeout + kill-timeout with required writer teardown, close() surfacing incomplete cleanup while retaining the failed playback, and plugin.stop() propagating player cleanup failure. Existing stale/finished-ID test exposed a deterministic branch mismatch; implementation now reaps a finished playback and rejects its ID as stale. Exact-head CI 34146937921 is running:
testis in progress and the real Electron idle-CPU job is queued at handoff. Direct Actions job logs for the prior registry failure were unavailable through the connector, so the stale-ID mismatch is evidence-backed but not claimed as the sole prior CI cause.blockers: Exact-head registry/plugin/package/Nix and idle-CPU gates have not completed, so merge is not justified. Real PipeWire/device audibility remains explicitly unverified and is not claimed.
evidence:
cancel()no longer raises on the second process wait timeout before writer cleanup; it records the process failure, performs bounded writer join/check, returns True only when both resources are cleaned, and otherwise retains the playback for retry.close()counts failed cancellations and raisesVoiceErrorinstead of swallowing them, so ZaraVoicePlugin.stop() propagates incomplete shutdown. Fixed[pw-play, "-"], shell=False, DEVNULL output, WAV/max-byte/max-active limits, opaque IDs, andaudible_confirmed:falseremain unchanged; no generic execution, credential leakage, or returned raw-media body was introduced.next_mode: REVIEW
next_target: Adversarial exact-head review of PR #517 at
577ccbf8c7after CI settles. Verify double-timeout exception ordering and retry tracking, finished/stale cleanup, close()/plugin-stop failure propagation, no writer/raw-audio lifetime leak, no unsafe execution or credential/media leakage, and require green registry/plugin/package/Nix/idle-CPU exact-head gates before merge.WORKER_STATE
worker: plugin-b
mode_used: REVIEW
result: Adversarial exact-head review of PR #517 found two remaining merge-blocking lifecycle/state defects and a red exact-head registry/plugin gate: a no-stdin spawn can leave a stubborn pw-play child live and untracked after bounded terminate+kill failure, and a finished process with a still-live writer is incorrectly reported as a stale playback ID while the resource remains tracked.
refs: #517; review comment https://github.com/lost-rob0t/zara-plugins/pull/517#issuecomment-5574295280; #12; CI run 34146937921
head:
577ccbf8c7model_matrix: none; player-only review, no TTS model or audible-device result exercised and no fake/process result relabeled as real-model coverage.
tests: No code was changed in REVIEW. Existing tests cover fixed argv/no shell, unavailable binary, byte/format/active-playback bounds, ID allocation before spawn, normal and double-timeout cancellation, blocked-writer teardown, close()/plugin-stop failure propagation, and stale finished IDs. Missing RED regressions are: (1) Popen returns no stdin and the child survives terminate+kill, which currently becomes untracked; (2) process is finished but writer survives the configured join bound, which currently raises
unknown or stale playback iddespite a live tracked resource. Exact-head CI run 34146937921 completed failure: compatibility/Nix diagnostics and real Electron idle-CPU passed;Run registry and plugin testsfailed again; package builds were skipped.blockers: 1)
_terminate_untracked()silently abandons a stuck child in the missing-stdin path, leaving no retry/close handle; 2) finished-process/live-writer cancellation misstates live tracked state as stale and hides cleanup-timeout semantics; 3) exact-head registry/plugin gate is red and package gate did not run; 4) real PipeWire/device audibility remains explicitly unverified.evidence: Current
player.pyat exact head still uses fixed[pw-play, "-"],shell=False, DEVNULL output, WAV/max-byte/max-active bounds, opaque IDs, andaudible_confirmed:false. The previous double process-timeout repair correctly performs writer cleanup before returning an error, retains failed tracked playbacks, andclose()now raises on incomplete cleanup;plugin.stop()propagates player close failure. No generic JS/eval/shell execution, credential leakage, or returned raw-media body was found in the bounded diff.next_mode: IMPLEMENT
next_target: Repair PR #517 tests-first: add RED coverage for missing-stdin + unkillable child so no process can be silently abandoned, and for finished process + writer cleanup timeout so it reports an explicit cleanup failure rather than stale; minimally fix lifecycle tracking/teardown semantics, diagnose/fix the repeated registry/plugin failure, then rerun focused zara-voice plus registry/package/Nix/idle-CPU exact-head gates. Do not merge until green.
WORKER_STATE
worker: plugin-b
mode_used: IMPLEMENT
result: Repaired PR #517 tests-first for the two remaining PipeWire lifecycle/state blockers: a missing-stdin child that survives bounded terminate+kill is now retained under its opaque playback ID for retry/close, and a finished process with a still-live writer now reports explicit writer-cleanup timeout instead of falsely reporting stale state.
refs: #517; #12; test-first commit
c828cf2c78; implementation commit0693ba0b3e; PR comment #issuecomment-5574798826; CI run 34154901121head:
0693ba0b3emodel_matrix: none; player-only lifecycle repair, no TTS model or fake/process result relabeled as real-model/audible-device coverage.
tests: Added RED regressions before implementation for missing-stdin + unkillable child retention and finished-process + live-writer cleanup-timeout semantics. Existing coverage still exercises fixed argv/no shell, unavailable binary, WAV/byte/active-playback bounds, ID allocation before spawn, terminate→kill cancellation bounds, blocked-writer teardown, double process timeout, close()/plugin-stop failure propagation, and stale finished IDs. Exact-head CI run 34154901121 is pending at handoff; no jobs had started when last checked.
blockers: Exact-head registry/plugin/package/Nix and idle-CPU gates are not yet green, so merge is not justified. The repeated registry/plugin failure from prior heads remains to be re-exercised by this run. Real PipeWire/device audibility remains explicitly unverified and is not claimed.
evidence: Current source registers the no-stdin child in
_playbacksbefore cleanup, removes it only after bounded process teardown succeeds, and retains it on cleanup timeout so later close/cancel has a handle. Finished-process cancellation closes stdin, performs bounded writer join, retains the resource and raisesplayback writer cleanup exceeded configured time boundwhile the writer is live, and only removes/reports stale once writer teardown is complete. Fixed[pw-play, "-"],shell=False, DEVNULL output, opaque IDs, input/active-process bounds, andaudible_confirmed:falseremain unchanged; no generic execution, credential leakage, or raw-media return/log surface was introduced.next_mode: REVIEW
next_target: Adversarially review PR #517 at exact head
0693ba0b3eafter CI settles. Attack missing-stdin retry/close behavior, finished/live-writer cleanup ordering, process OSError semantics, stale-state fencing, cancellation/resource bounds, raw-audio lifetime/leakage, unsafe execution, and require green registry/plugin/package/Nix/idle-CPU exact-head gates before merge.WORKER_STATE
worker: plugin-b
mode_used: REVIEW
result: Adversarial exact-head review of PR #517 confirmed the prior tracked-state repairs but found one remaining production cancellation-bound/raw-audio-lifetime blocker:
_close_input()performs an unbounded real pipe close before process termination/bounded writer join, so cancel/reap can hang before configured timeouts while the writer retains raw audio. Exact-head registry/plugin CI is also red again.refs: #517; review comment https://github.com/lost-rob0t/zara-plugins/pull/517#issuecomment-5575240862; #12; CI run 34154901121
head:
0693ba0b3emodel_matrix: none; player-only review, no TTS model or audible-device result exercised and no fake/process result relabeled as real-model coverage.
tests: No code changed in REVIEW. Existing tests cover fixed argv/no shell, unavailable binary, WAV/byte/active-playback bounds, ID allocation before spawn, missing-stdin stubborn-child retention, terminate→kill bounds, blocked-writer teardown, double process timeout, close()/plugin-stop failure propagation, finished/live-writer cleanup timeout, and stale finished IDs. Missing RED regression: stdin.close() itself blocks while the writer owns/blocks on the real pipe stream, proving cancellation remains bounded. Exact-head CI run 34154901121 completed failure: whitespace/compatibility/Nix diagnostics passed, real Electron idle CPU passed,
Run registry and plugin testsfailed, and package builds were skipped.blockers: 1)
_close_input()directly invokes potentially blockingPopen.stdin.close()before child termination and before the configured writer timeout, so cancellation/reaping is not actually end-to-end bounded and raw-audio writer lifetime can exceed policy; current fakeBlockingStdin.close()artificially releases the writer and does not cover real buffered-pipe lock/backpressure behavior; 2) exact-head registry/plugin gate remains red and package gate did not run; 3) real PipeWire/device audibility remains explicitly unverified.evidence: Current exact-head source retains missing-stdin stubborn children under opaque IDs, retains finished/live-writer resources on writer timeout, surfaces incomplete close/plugin stop, uses fixed
[pw-play, "-"],shell=False, DEVNULL output, bounded input/active counts, andaudible_confirmed:false. No generic JS/eval/shell surface, credential leakage, or raw-media return/log surface found. Review comment records the unbounded close-before-terminate path.next_mode: IMPLEMENT
next_target: Repair PR #517 tests-first: add a RED concurrent-pipe regression where
stdin.close()blocks whilewrite()owns the stream and assert cancel/reap still terminate within policy; minimally reorder or otherwise bound stream/process teardown so no unbounded close occurs before terminate/kill + writer timeout while failed resources remain tracked. Also diagnose/fix the repeated registry/plugin failure, then rerun focused zara-voice plus registry/package/Nix/idle-CPU exact-head gates. Do not merge until green.WORKER_STATE
worker: plugin-b
mode_used: IMPLEMENT
result: Repaired PR #517 tests-first for the remaining cancellation-bound/raw-audio lifetime bug: cancellation/reaping no longer calls potentially blocking
stdin.close()before configured timeouts; teardown is now bounded process-first followed by bounded writer join, with writer-owned final stream close.refs: #517; #12; test-first commits
65ddde0d92and91df046fa4; implementation commit11ec6bd55e; PR comment #issuecomment-5575677861; exact-head CI run 34162266962head:
11ec6bd55emodel_matrix: none; player-only lifecycle repair, no TTS model, real audio device, or fake/process result relabeled as real-model/audible coverage.
tests: Added RED concurrent-pipe coverage where
stdin.close()blocks behind an in-flight writer lock and cancellation must still complete inside the configured process/writer budget. Updated deterministic teardown fakes before implementation so process termination/kill models reader disappearance and writer release. Existing coverage remains for fixed argv/no shell, unavailable binary, WAV/byte/active limits, ID allocation before spawn, missing-stdin stubborn-child tracking, terminate→kill bounds, double-timeout cleanup, finished/live-writer state, close/plugin-stop failure propagation, stale IDs, and raw-audio omission. Exact-head CI 34162266962 is currently in progress.blockers: Exact-head registry/plugin/package/Nix/idle-CPU gates are not yet all green, so merge is not justified. Prior heads repeatedly failed
Run registry and plugin tests; job metadata confirms the failing step but the connector does not expose the failing log text, so this exact-head run must re-exercise it. Real PipeWire/device audibility remains explicitly unverified and is not claimed.evidence: Tests were committed before implementation. Current source no longer performs caller-side stream close in cancel/reap; active cancellation executes bounded terminate→wait→kill→wait first, then joins the writer with
writer_timeout. The writer closes stdin in its ownfinally, avoiding an unbounded concurrent BufferedWriter close lock. Failed process or writer cleanup still leaves the playback tracked for retry/close. Fixed[pw-play, "-"],shell=False, DEVNULL output, opaque IDs, input/active bounds, andaudible_confirmed:falseremain intact; no generic execution, credential leakage, or raw-media return/log surface was introduced.next_mode: REVIEW
next_target: Adversarial exact-head review of PR #517 at
11ec6bd55eafter CI settles. Attack process-first teardown ordering, writer release assumptions on real pipes, double-timeout tracking, finished-process/live-writer state, close/plugin-stop propagation, cancellation wall-clock bounds, raw-audio lifetime/leakage, unsafe execution, and the repeated registry/plugin failure. Merge only with green exact-head registry/plugin/package/Nix/idle-CPU gates and no lifecycle blocker.WORKER_STATE
worker: plugin-b
mode_used: REVIEW
result: Reviewed PR #517 at exact head
11ec6bd55e. Process-first cancellation fixes survive adversarial source review, but exact-head CI is still red at the repeated registry/plugin gate, so merge remains blocked.refs: #517 review comment https://github.com/lost-rob0t/zara-plugins/pull/517#issuecomment-5576105327 ; CI run 34162266962
head:
11ec6bd55emodel_matrix: none; player-only review, no TTS model or fake/process result relabeled as real-model/audible-device coverage.
tests: Exact-head run 34162266962 completed with
zara-avatar idle CPU budgetgreen and the maintestjob red specifically atRun registry and plugin tests; compatibility/Nix diagnostic steps passed and package builds were skipped. Existing deterministic player tests cover fixed argv/no shell, unavailable backend, WAV/byte/active bounds, opaque/stale IDs, blocked writer, process terminate→kill bounds, double-timeout retention, missing-stdin stubborn child, finished/live-writer state, close/plugin-stop failure propagation, and concurrent buffered-stream close ordering.blockers: Required registry/plugin/package exact-head gate is not green; #517 must not merge. Real
pw-play/PipeWire device audibility remains unverified and is correctly not claimed byaudible_confirmed:false.evidence: Source at exact head performs bounded process-first cancellation then bounded writer join, reports success only after both resources are cleaned, retains failed resources for retry/close, propagates shutdown cleanup failure, uses fixed
[pw-play, "-"]withshell=Falseand DEVNULL output, and exposes no generic execution, credential echo, or raw-audio return/log path found in this review.next_mode: IMPLEMENT
next_target: On #517, reproduce and diagnose the repeated
Run registry and plugin testsfailure at exact head; if branch-caused, add the narrow RED regression first and minimally repair it, then rerun focused zara-voice tests plus exact-head registry/plugin/package/Nix and idle-CPU gates. Do not merge until all required gates are green.WORKER_STATE
worker: plugin-b
mode_used: IMPLEMENT
result: Diagnosed the repeated #517 registry/plugin gate as branch-specific and added tests-first fail-closed CI diagnostics so the exact failing
nix flake checkderivation/test will be preserved as an artifact instead of remaining opaque.refs: #517; PR comment https://github.com/lost-rob0t/zara-plugins/pull/517#issuecomment-5576558436; test-first commit
8950e62f20; implementation commit727887e695; prior failing CI 34162266962; green base CI 34117803590; green current-main CI 34160158788head:
727887e695model_matrix: none; CI diagnosis only, no TTS model or fake/process result relabeled as real-model/audible-device coverage.
tests: Added the RED contract first requiring
flake-check.logpreservation, an always-uploadedflake-check-diagnosticsartifact, and nocontinue-on-errorweakening of the flake gate. Then changed the workflow to runset -o pipefail; nix flake check --print-build-logs 2>&1 | tee flake-check.logand upload the log withif: always(). Previous exact head11ec6bd55ehad compatibility/Nix diagnostics and real Electron idle CPU green but failedRun registry and plugin tests; package builds skipped. New exact-head checks were not yet reported at handoff.blockers: Root failing derivation/test is not yet visible because the existing connector cannot read Actions job log bodies and the execution sandbox cannot resolve github.com. #517 remains unmergeable until the new exact-head run produces
flake-check-diagnostics, the actual branch-caused failure is repaired tests-first, and registry/plugin/package/Nix + idle-CPU gates are green. Realpw-play/PipeWire device audibility also remains explicitly unverified.evidence: Original PR base
eaef813695and current maindbcc7a763cboth have green fulltestchecks, while #517 repeatedly fails insidenix flake check; branch diff before this diagnostic slice was confined to zara-voice files. The new logging usespipefail, so capture cannot convert a failing flake check into success.next_mode: IMPLEMENT
next_target: Read the
flake-check-diagnosticsartifact from the exact-head727887e695run, identify the precise failing check/test, add the narrow RED regression first if not already covered, minimally repair the branch-caused failure, and rerun focused zara-voice plus exact-head registry/plugin/package/Nix and idle-CPU gates. Do not merge until green.WORKER_STATE
worker: plugin-b
mode_used: IMPLEMENT
result: Consumed the exact-head flake diagnostic artifact for #517, identified the repeated registry/plugin failure as a test-fixture validation-order bug, and repaired that existing RED regression without changing production PipeWire behavior.
refs: #517; #12; CI run 34169356018; flake-check-diagnostics artifact 10035211194; repair commit
b90cf39ee6; PR comment #issuecomment-5577078057head:
b90cf39ee6model_matrix: none; CI/test repair only, no TTS model or fake/process result relabeled as real-model/audible-device coverage.
tests: The artifact showed
zara-check-zara-voice-testsfailingtest_rejects_unsupported_format_and_oversized_audio_before_spawn:max_audio_bytes=8combined with the defaultb"RIFFsafe-audio"payload caused the byte-limit guard to fire before the expected format error. The existing RED test was repaired to isolate contracts: unsupported-format now usesaudio=b"RIFF"(under the byte bound), while the oversize assertion still usesb"RIFF" * 3. Productionplayer.pyis unchanged. Prior exact-head run 34169356018 had idle CPU green and failed only atRun registry and plugin tests; the new exact head had no reported workflow run yet at handoff.blockers: #517 remains unmergeable until exact-head CI for
b90cf39ee6proves registry/plugin/package/Nix and idle-CPU gates green. Real pw-play/PipeWire audibility remains explicitly unverified and is not claimed.evidence:
flake-check.lognames the exact failing derivationchecks.x86_64-linux.zara-voice-testsand assertion mismatch ("format"vsaudio exceeds configured player byte limit). The repair changes only the test input so format and size validation are exercised independently; fixed argv/no shell, cancellation/resource bounds, stale-state fencing, shutdown failure propagation, opaque IDs,audible_confirmed:false, and raw-media omission remain untouched.next_mode: REVIEW
next_target: Adversarially review #517 at exact head
b90cf39ee6after CI settles. Verify the registry/plugin/package/Nix and idle-CPU gates are green, confirm the test-only repair did not mask a production validation defect, recheck lifecycle/cancellation/resource/raw-audio/unsafe-exec semantics, and merge only if no blocker remains.WORKER_STATE
worker: plugin-b
mode_used: REVIEW
result: Adversarial exact-head review of #517 is clean; all required CI gates passed and the bounded PipeWire production player was merged with expected-head protection.
refs: #517; #12; CI run 34172537463; review comment #issuecomment-5577558661; merge
89f0e938fbexact head:
b90cf39ee6tests: Exact-head CI 34172537463 completed success. Compatibility gate contract tests passed; registry/plugin
nix flake checkpassed; flake diagnostics upload passed; plugin package builds passed; real Electron idle-CPU budget passed. Final source review rechecked fixed argv/no shell, WAV+byte bounds, active playback cap, pre-spawn ID allocation, bounded terminate/wait/kill plus writer join, retained failed resources, explicit finished-process/live-writer failure, shutdown error propagation, opaque IDs,audible_confirmed:false, and raw-media omission. Final test-only validation-order repair does not weaken production guards.blockers: none for #517. Real PipeWire/device audibility remains explicitly unverified and is not claimed as CI evidence.
evidence: PR head was mergeable and unchanged at
b90cf39ee6; CI run 34172537463 had both jobs green, including registry/plugin/package/Nix and the real Electron idle CPU gate. Review found no remaining false-success, unsafe generic execution, stale state, cancellation, resource-bound, credential/raw-media leakage, or missing adapter-contract blocker for this slice. Merge used expected_head_sha and produced89f0e938fb.next_mode: RESEARCH
next_target: Audit the next dependency-ready browser/media/voice/voice-lab/desktop production-backend gap against current maintained upstream APIs, prioritizing a minimal real voice/backend slice that adds observed production capability without duplicating Zara Core or claiming fake coverage as real-device evidence.
WORKER_STATE
worker: plugin-b
mode_used: RESEARCH
result: Audited current zara-voice/voice-lab production seams and current maintained local TTS upstreams; selected one dependency-satisfied next slice: an explicitly configured local Piper 1.8.0 synthesis backend for zara-voice using the maintained Python API, leaving voice-lab cloning/training and streaming for later.
refs: #506; closed scope issue #12; main zara-voice domain/player/plugin; OHF-Voice/piper1-gpl v1.8.0 (published 2026-09-04), README and Python API docs
exact head:
89f0e938fbhead:
89f0e938fbmodel_matrix: research only; no model executed. Upstream Piper is current at v1.8.0 and ships manylinux x86_64/aarch64 wheels. Its supported Python seam is
PiperVoice.load(...)plussynthesize_wav(...), with chunkedsynthesize(...)available but intentionally deferred from the first slice.voice_tests: none executed in RESEARCH. Current zara-voice already enforces text/audio/duration/cache bounds, locality policy, backend/profile provenance, raw-audio omission from public artifacts, and the newly merged bounded PipeWire player. The first Piper slice must add deterministic fake-Piper contract tests plus an optional separately labeled real-model smoke; it must not call a fake a real-model test.
resource_results: research only. First slice should load one configured voice lazily, CPU-only by default, synthesize to an in-memory bounded WAV, derive duration/sample-rate/format from the produced WAV, and report explicit backend/model identity. No download at runtime, no shell/CLI wrapper, no network fallback, and no GPU unless explicitly configured.
blockers: No architectural blocker for a basic local synthesis adapter:
VoiceService.synthesize()already accepts a provider-neutral backend returning audio bytes/format/sample_rate/duration/request_id. Do not bundle or auto-download a voice yet: the worker contract requires pinning voice source/revision/license/hash/artifact size and measuring CPU/RSS/startup before freezing a real-model CI artifact. Upstream Piper is GPL-3.0 and its README currently asks for maintainers, so packaging/license review must remain explicit. Streaming/cancellation of in-process Piper synthesis is not proven by the basicsynthesize_wavAPI and is out of this bounded first slice.evidence: Zara main is exactly the #517 merge commit. Current zara-voice source has a clean backend injection seam and bounded artifact validation; current zara-voice-lab source is oriented to clone/create/preview/export rather than runtime STT, so adding Whisper STT there now would require a new domain seam and is not the smallest dependency-satisfied production move. Piper upstream v1.8.0 was released 2026-09-04; maintained docs expose direct Python synthesis and streaming APIs, avoiding arbitrary subprocess execution.
next_mode: IMPLEMENT
next_target: Tests-first focused PR for
zara-voicelocal Piper backend only: explicit configured model/config paths,PiperVoice.loadCPU-only by default,synthesize_wavinto bounded in-memory WAV, validate/return WAV metadata and opaque request/backend provenance, fail closed for missing package/model/config/load/synthesis errors, never auto-download or expose text/audio/model paths in errors, retain current max text/audio/duration bounds, keep default backend unavailable unless configured, and add an optional real Piper smoke only after pinning one redistributable voice with source/revision/license/hash/size. Run focused zara-voice tests plus registry/package/Nix/exact-head gates; no direct main commit.