feat(voice): voice-sampler foundations — OmniVoice catalog live, diarization stack repaired - #2471
Conversation
…ization stack repaired, sampler spec - OmniVoice: enable the ref-voice catalog bind (/voices, ro) with an empty catalog dir + README encoding set-not-preset; health now reports catalog:true. - media-audio: PyTorch retired the cu124 wheel channel, killing the build. Regenerated requirements.lock via uv for cu128 on the DOCUMENTED pyannote stack (pyannote 3.4 + huggingface-hub 0.36 + torch 2.7.1+cu128 + transformers 4.57). transformers<5 is load-bearing: 5.x forces hub>=1.0 which breaks pyannote 3.x, and pyannote 4.x hard-requires torchcodec>=0.7 which aborts on import (std::length_error) — 202-restart crash loop, reproduced in isolation. - media-audio compose: env.shared blanks SSL_CERT_FILE/SSL_CERT_DIR/*_CA_BUNDLE (Windows host-leak guard) but empty means trust-nothing for Python/OpenSSL — HF downloads failed TLS verify. Re-point at the container CA store. - docs: VOICE_SAMPLER_SPEC.md — media→diarize→audition→pub-gate→publish flow, Voice Vault room app, owner-only gates. - submodule: promote PMOVES-Creator → ae174f7f (H3 blueprints PR #10, merged). Verified: service boots healthy on GPU (RTX 5090), stt+emotion loaded, no crashes; diarization reaches authenticated download (final step gated on the operator's HF token rotation). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Docker Hardening ValidationHardening Validation ReportValidated: Fri Aug 7 15:28:24 UTC 2026Services CheckedPMOVES.AI Docker Hardening Validation[INFO] Checking: pmoves/docker-compose.hardened.yml [INFO] Validating: hi-rag-gateway-v2 [INFO] Validating: extract-worker [INFO] Validating: langextract [INFO] Validating: presign [INFO] Validating: render-webhook [INFO] Validating: retrieval-eval [INFO] Validating: pdf-ingest [INFO] Validating: jellyfin-bridge [INFO] Validating: invidious-companion-proxy [INFO] Validating: ffmpeg-whisper [INFO] Validating: media-video [INFO] Validating: media-audio [INFO] Validating: hi-rag-gateway-v2-gpu [INFO] Validating: hi-rag-gateway-gpu [INFO] Validating: deepresearch [INFO] Validating: supaserch [INFO] Validating: publisher-discord [INFO] Validating: mesh-agent [INFO] Validating: nats-echo-req [INFO] Validating: nats-echo-res [INFO] Validating: comfy-watcher [INFO] Validating: grayjay-plugin-host [INFO] Validating: agent-zero [INFO] Validating: p7-room-orchestrator [INFO] Validating: archon [INFO] Validating: channel-monitor [INFO] Validating: pmoves-yt [INFO] Validating: notebook-sync [INFO] Validating: supabase_service_role_key [INFO] Validating: supabase_jwt_secret [INFO] Validating: p7_control_token ====================================== |
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
📝 WalkthroughWalkthroughThe change defines voice-reference publication events and safe catalog identifiers. It updates voice-sampler documentation, constrains ChangesVoice sampler publication contract
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Docker Hardening ValidationHardening Validation ReportValidated: Fri Aug 7 15:30:39 UTC 2026Services CheckedPMOVES.AI Docker Hardening Validation[INFO] Checking: pmoves/docker-compose.hardened.yml [INFO] Validating: hi-rag-gateway-v2 [INFO] Validating: extract-worker [INFO] Validating: langextract [INFO] Validating: presign [INFO] Validating: render-webhook [INFO] Validating: retrieval-eval [INFO] Validating: pdf-ingest [INFO] Validating: jellyfin-bridge [INFO] Validating: invidious-companion-proxy [INFO] Validating: ffmpeg-whisper [INFO] Validating: media-video [INFO] Validating: media-audio [INFO] Validating: hi-rag-gateway-v2-gpu [INFO] Validating: hi-rag-gateway-gpu [INFO] Validating: deepresearch [INFO] Validating: supaserch [INFO] Validating: publisher-discord [INFO] Validating: mesh-agent [INFO] Validating: nats-echo-req [INFO] Validating: nats-echo-res [INFO] Validating: comfy-watcher [INFO] Validating: grayjay-plugin-host [INFO] Validating: agent-zero [INFO] Validating: p7-room-orchestrator [INFO] Validating: archon [INFO] Validating: channel-monitor [INFO] Validating: pmoves-yt [INFO] Validating: notebook-sync [INFO] Validating: supabase_service_role_key [INFO] Validating: supabase_jwt_secret [INFO] Validating: p7_control_token ====================================== |
…6 weights-only load With a valid HF_TOKEN the gated segmentation-3.0 checkpoint downloads but fails torch 2.6+'s weights_only=True unpickling (TorchVersion / Specifications / Problem / Resolution are not default-safe globals). Allowlist exactly those four so TORCH_FORCE_WEIGHTS_ONLY_LOAD=1 keeps guarding every other model load. Verified live: healthz now reports models_loaded=[stt, emotion, diarization], diarization_enabled=true on the 5090. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Docker Hardening ValidationHardening Validation ReportValidated: Fri Aug 7 18:03:05 UTC 2026Services CheckedPMOVES.AI Docker Hardening Validation[INFO] Checking: pmoves/docker-compose.hardened.yml [INFO] Validating: hi-rag-gateway-v2 [INFO] Validating: extract-worker [INFO] Validating: langextract [INFO] Validating: presign [INFO] Validating: render-webhook [INFO] Validating: retrieval-eval [INFO] Validating: pdf-ingest [INFO] Validating: jellyfin-bridge [INFO] Validating: invidious-companion-proxy [INFO] Validating: ffmpeg-whisper [INFO] Validating: media-video [INFO] Validating: media-audio [INFO] Validating: hi-rag-gateway-v2-gpu [INFO] Validating: hi-rag-gateway-gpu [INFO] Validating: deepresearch [INFO] Validating: supaserch [INFO] Validating: publisher-discord [INFO] Validating: mesh-agent [INFO] Validating: nats-echo-req [INFO] Validating: nats-echo-res [INFO] Validating: comfy-watcher [INFO] Validating: grayjay-plugin-host [INFO] Validating: agent-zero [INFO] Validating: p7-room-orchestrator [INFO] Validating: archon [INFO] Validating: channel-monitor [INFO] Validating: pmoves-yt [INFO] Validating: notebook-sync [INFO] Validating: supabase_service_role_key [INFO] Validating: supabase_jwt_secret [INFO] Validating: p7_control_token ====================================== |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (1)
pmoves/services/media-audio/server.py (1)
167-177: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winScope the pyannote safe-global allowlist to the load.
torch.serialization.add_safe_globals(...)keepsTorchVersion,Specifications,Problem, andResolutiontrusted for the rest of the process. These classes are only needed forPyannotePipeline.from_pretrained, so wrap the load withtorch.serialization.safe_globals(...)and remove the process-wide registration.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pmoves/services/media-audio/server.py` around lines 167 - 177, Replace the process-wide torch.serialization.add_safe_globals call in the pyannote loading flow with a torch.serialization.safe_globals context covering only PyannotePipeline.from_pretrained. Keep the existing four classes in the scoped allowlist and ensure the context exits immediately after the load.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@pmoves/docs/AGENTS/AGNOTE4482PHI.t1.md`:
- Around line 1629-1631: The AGNOTE4482PHI claims-register entry incorrectly
combines claimed, released, gated, and unrelated work. Split it into append-only
lane-specific CLAIM/REVIEW and RELEASE rows: keep voice-sampler and PR `#2471` in
CLAIM/REVIEW until merge plus reproducible operator validation, then add a
separate RELEASE row containing branch/PR, validation commands and results,
operator follow-up, and a signed ACK block; separate JuiceFS, Pinokio, SEAP,
Open Notebook, DARKXSIDE, Veo, and cross-node work, isolating runtime changes
from operator-only follow-ups.
In `@pmoves/docs/creator/VOICE_SAMPLER_SPEC.md`:
- Line 29: Update the post-publication announcement near the existing
voice.reference.approved.v1 emission to use a distinct
voice.reference.published.v1 subject, reserving voice.reference.approved.v1 for
the room-to-sampler approval input. Document the resulting event topology,
including idempotency and replay behavior, while preserving the
domain.entity.action.v{n} subject format.
- Line 20: Update the ASCII flow code fence in VOICE_SAMPLER_SPEC.md to specify
the text language, changing the opening fence to use text and preserving the
existing flow content unchanged.
- Around line 25-29: Define the publication-boundary catalog identity contract
in pmoves/docs/creator/VOICE_SAMPLER_SPEC.md (lines 25-29) and
pmoves/services/creator-operator/voices/README.md (lines 3-5): validate
pmoves_core.voice_profiles.name against ^[A-Za-z0-9_-]{3,64}$, normalize or
reject local filenames, and document how room/persona/clip JuiceFS paths and
OmniVoice’s ref_audio filenames map to name and ref_audio_path; keep the mapping
consistent in both files.
In `@pmoves/services/media-audio/requirements.txt`:
- Around line 28-33: Bound pyannote.audio to the intended 3.x stack by adding an
upper constraint below version 4 in the dependency declaration and the Docker
runtime installation line. Keep the existing loader and Torch/torchaudio
compatibility path unchanged, and ensure requirements.txt and Docker install
constraints match.
---
Nitpick comments:
In `@pmoves/services/media-audio/server.py`:
- Around line 167-177: Replace the process-wide
torch.serialization.add_safe_globals call in the pyannote loading flow with a
torch.serialization.safe_globals context covering only
PyannotePipeline.from_pretrained. Keep the existing four classes in the scoped
allowlist and ensure the context exits immediately after the load.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: d377518c-2eaf-4b55-8629-620943274334
⛔ Files ignored due to path filters (1)
pmoves/services/media-audio/requirements.lockis excluded by!**/*.lock
📒 Files selected for processing (9)
PMOVES-Creatorpmoves/docker-compose.media.ymlpmoves/docker-compose.ymlpmoves/docs/AGENTS/AGNOTE4482PHI.t1.mdpmoves/docs/creator/VOICE_SAMPLER_SPEC.mdpmoves/services/creator-operator/omnivoice.compose.ymlpmoves/services/creator-operator/voices/README.mdpmoves/services/media-audio/requirements.txtpmoves/services/media-audio/server.py
New pmoves/services/voice-sampler (port 8124, workers/voice profiles): SOURCE -> ANALYZE -> AUDITION -> APPROVE -> PUBLISH -> ANNOUNCE per VOICE_SAMPLER_SPEC.md. POST /sample diarizes a MinIO media object via media-audio (transcoding to 16k mono WAV first — pyannote's soundfile backend can't read m4a/AAC and torchcodec is deliberately absent), cuts per-speaker candidate clips with pydub, stages them in JuiceFS rooms/<room>/creator/references/voice-candidates/, and publishes voice.sample.candidates.v1. A NATS subscriber on voice.reference.approved.v1 executes the owner-gated PUBLISH step (JuiceFS references path + OmniVoice catalog dir + optional flute clone register, off by default while the flute routes are TODO) and announces voice.reference.published.v1. Owner gate fails closed when VOICE_SAMPLER_OWNER_ID is unset. Subjects registered in .claude/context/nats-subjects.md; voice-sampler mapped to the media split in split_compose.py. Smoke (5090, live): two-voice deep-dive m4a -> 2 speakers, 5 clips each, 10 objects staged in JuiceFS, batch 8995f0d90a67. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Docker Hardening ValidationHardening Validation ReportValidated: Fri Aug 7 20:46:42 UTC 2026Services CheckedPMOVES.AI Docker Hardening Validation[INFO] Checking: pmoves/docker-compose.hardened.yml [INFO] Validating: hi-rag-gateway-v2 [INFO] Validating: extract-worker [INFO] Validating: langextract [INFO] Validating: presign [INFO] Validating: render-webhook [INFO] Validating: retrieval-eval [INFO] Validating: pdf-ingest [INFO] Validating: jellyfin-bridge [INFO] Validating: invidious-companion-proxy [INFO] Validating: ffmpeg-whisper [INFO] Validating: media-video [INFO] Validating: media-audio [INFO] Validating: hi-rag-gateway-v2-gpu [INFO] Validating: hi-rag-gateway-gpu [INFO] Validating: deepresearch [INFO] Validating: supaserch [INFO] Validating: publisher-discord [INFO] Validating: mesh-agent [INFO] Validating: nats-echo-req [INFO] Validating: nats-echo-res [INFO] Validating: comfy-watcher [INFO] Validating: grayjay-plugin-host [INFO] Validating: agent-zero [INFO] Validating: p7-room-orchestrator [INFO] Validating: archon [INFO] Validating: channel-monitor [INFO] Validating: pmoves-yt [INFO] Validating: notebook-sync [INFO] Validating: supabase_service_role_key [INFO] Validating: supabase_jwt_secret [INFO] Validating: p7_control_token ====================================== |
The revive recreate ran from this main-based branch, which lacks #2471's CA block — media-audio came up with SSL_CERT_FILE='' and the HF xet downloader died with 'No CA certificates were loaded from the system' (models_loaded empty, degraded). Identical text to #2471's hunk so the merge dedupes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…undations # Conflicts: # pmoves/docs/AGENTS/AGNOTE4482PHI.t1.md
…ubject split doc'd, pyannote <4 bound - _handle_approval now rejects room/persona/catalog_id containing path separators or '..' (the NATS payload path skipped the /sample validator while feeding a host-bind filename) - spec: step 6 announces voice.reference.published.v1 (matches the worker); approved vs published subjects split documented with replay/idempotency semantics; identifier contract section added; MD040 fence language - voices/README: naming contract for catalog ids (reject, don't sanitize) - pyannote.audio bounded <4 in requirements.txt + Dockerfile — 4.x pulls torchcodec which aborts on import (reproduced 202-restart crash loop) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Docker Hardening ValidationHardening Validation ReportValidated: Sun Aug 9 14:07:12 UTC 2026Services CheckedPMOVES.AI Docker Hardening Validation[INFO] Checking: pmoves/docker-compose.hardened.yml [INFO] Validating: hi-rag-gateway-v2 [INFO] Validating: extract-worker [INFO] Validating: langextract [INFO] Validating: presign [INFO] Validating: render-webhook [INFO] Validating: retrieval-eval [INFO] Validating: pdf-ingest [INFO] Validating: jellyfin-bridge [INFO] Validating: invidious-companion-proxy [INFO] Validating: ffmpeg-whisper [INFO] Validating: media-video [INFO] Validating: media-audio [INFO] Validating: hi-rag-gateway-v2-gpu [INFO] Validating: hi-rag-gateway-gpu [INFO] Validating: deepresearch [INFO] Validating: supaserch [INFO] Validating: publisher-discord [INFO] Validating: mesh-agent [INFO] Validating: nats-echo-req [INFO] Validating: nats-echo-res [INFO] Validating: comfy-watcher [INFO] Validating: grayjay-plugin-host [INFO] Validating: agent-zero [INFO] Validating: p7-room-orchestrator [INFO] Validating: archon [INFO] Validating: channel-monitor [INFO] Validating: pmoves-yt [INFO] Validating: notebook-sync [INFO] Validating: supabase_service_role_key [INFO] Validating: supabase_jwt_secret [INFO] Validating: p7_control_token ====================================== |
Docker Hardening ValidationHardening Validation ReportValidated: Sun Aug 9 18:08:51 UTC 2026Services CheckedPMOVES.AI Docker Hardening Validation[INFO] Checking: pmoves/docker-compose.hardened.yml [INFO] Validating: hi-rag-gateway-v2 [INFO] Validating: extract-worker [INFO] Validating: langextract [INFO] Validating: presign [INFO] Validating: render-webhook [INFO] Validating: retrieval-eval [INFO] Validating: pdf-ingest [INFO] Validating: jellyfin-bridge [INFO] Validating: invidious-companion-proxy [INFO] Validating: ffmpeg-whisper [INFO] Validating: media-video [INFO] Validating: media-audio [INFO] Validating: hi-rag-gateway-v2-gpu [INFO] Validating: hi-rag-gateway-gpu [INFO] Validating: deepresearch [INFO] Validating: supaserch [INFO] Validating: publisher-discord [INFO] Validating: mesh-agent [INFO] Validating: nats-echo-req [INFO] Validating: nats-echo-res [INFO] Validating: comfy-watcher [INFO] Validating: grayjay-plugin-host [INFO] Validating: agent-zero [INFO] Validating: p7-room-orchestrator [INFO] Validating: archon [INFO] Validating: channel-monitor [INFO] Validating: pmoves-yt [INFO] Validating: notebook-sync [INFO] Validating: supabase_service_role_key [INFO] Validating: supabase_jwt_secret [INFO] Validating: p7_control_token ====================================== |
Docker Hardening ValidationHardening Validation ReportValidated: Sun Aug 9 20:33:30 UTC 2026Services CheckedPMOVES.AI Docker Hardening Validation[INFO] Checking: pmoves/docker-compose.hardened.yml [INFO] Validating: hi-rag-gateway-v2 [INFO] Validating: extract-worker [INFO] Validating: langextract [INFO] Validating: presign [INFO] Validating: render-webhook [INFO] Validating: retrieval-eval [INFO] Validating: pdf-ingest [INFO] Validating: jellyfin-bridge [INFO] Validating: invidious-companion-proxy [INFO] Validating: ffmpeg-whisper [INFO] Validating: media-video [INFO] Validating: media-audio [INFO] Validating: hi-rag-gateway-v2-gpu [INFO] Validating: hi-rag-gateway-gpu [INFO] Validating: deepresearch [INFO] Validating: supaserch [INFO] Validating: publisher-discord [INFO] Validating: mesh-agent [INFO] Validating: nats-echo-req [INFO] Validating: nats-echo-res [INFO] Validating: comfy-watcher [INFO] Validating: grayjay-plugin-host [INFO] Validating: agent-zero [INFO] Validating: p7-room-orchestrator [INFO] Validating: archon [INFO] Validating: channel-monitor [INFO] Validating: pmoves-yt [INFO] Validating: notebook-sync [INFO] Validating: supabase_service_role_key [INFO] Validating: supabase_jwt_secret [INFO] Validating: p7_control_token ====================================== |
…e mount, UTS wiring (#2491) * feat(room): DARKXSIDE room voice loading — manifest repair, MCP bridge mount, UTS port fix - darkxsides.room.json: remove the 3 skill-binding objects duplicated into apps[] (15 schema errors), fold out-of-contract skills/default_services into service_refs/launcher_refs, add tts-studio + voice-vault app entries (5090-voice room shapes). Manifest now validates. - catalog.json: darkxsides.room stage archive -> rehearsal (archive suppressed every window; rehearsal renders PREVIEW per stage discipline). - flute-gateway: mount mcp_bridge router — the written-but-orphaned 6-tool MCP surface over all 14 TTS engines. Verified live: :8055/sse 200. Fulfills vei.contract.mcp-bridge. - compose: ULTIMATE_TTS_URL default 7860 -> 7861 (compose publishes UTS on 7861; 7860 was the silent-unhealthy-provider trap). Splits regenerated. - docs: three lane views for operator review — governance stress-test design (mechanisms x whale scenarios -> Wealth settlement), school-psych economics model design (replaces fabricated SEAP unit economics with modeled+settled numbers), Dirichlet-drop CHIT living-docs update plan (6 overclaim corrections + belief-envelope additions + tour beat-3 plan). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(voice): flute->UTS direct container route + UTS egress network - ULTIMATE_TTS_URL default -> http://ultimate-tts-studio:7860 (shared pmoves_app network; host.docker.internal publishing is unreliable on Docker Desktop Windows — the 7861 host bind wedged in the daemon's port ledger and only a Desktop restart clears it). Verified: flute healthz reports ultimate_tts: true. - UTS overlay joins pmoves_external: engines lazy-download weights from HuggingFace on first load; without egress every handle_load_* returns 'Failed to load'. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(voice): UTS routing is NATIVE-first — the GHCR image is an engine-less UI shell Live probing the hardened container: kittentts/f5_tts/omegaconf are NOT installed (every handle_load_* returns 'Failed to load' even with egress + CA fixed). The real 13-engine studio is the Pinokio-native UTS on host 7860 (feedback_tts_native_not_docker) — restore host.docker.internal:7860 as flute's default and document the container override for a future engine-baked image. Keeps the UTS overlay fixes (pmoves_external egress + CA re-point) so the shell is one image-fix away from working. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(media-audio): re-apply container CA store env on this branch The revive recreate ran from this main-based branch, which lacks #2471's CA block — media-audio came up with SSL_CERT_FILE='' and the HF xet downloader died with 'No CA certificates were loaded from the system' (models_loaded empty, degraded). Identical text to #2471's hunk so the merge dedupes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(flute-mcp): address review P1s — auth on MCP router, full base64 payload, event-API load/unload, configs baked into image - include_router now carries verify_api_key (no-op when FLUTE_API_KEY unset) - tts_synthesize returns the complete base64 WAV instead of a truncated stub - tts_load/unload_engine go through provider._call_gradio (/gradio_api/call); the old synchronous /api/ path 404s on current Ultimate-TTS builds - Dockerfile ships tts-engine-{capabilities,expressions}.yaml at the bridge's /app/pmoves/configs/ resolution path so tools/list isn't empty in-container Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Mavis <Mavis@pmoves.local> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Summary
/voices, ro) enabled with an intentionally-empty catalog + README encoding the set-not-preset rule. Health now reportscatalog: true.transformers<5is load-bearing (see requirements.txt comment): 5.x forces hub≥1.0 → breaks pyannote 3.x; pyannote 4.x requires torchcodec≥0.7 which aborts on import (std::length_error, reproduced in isolation on jammy AND noble/FFmpeg 6.1) — caused a 202-restart crash loop.SSL_CERT_FILE/SSL_CERT_DIR/*_CA_BUNDLEas a Windows host-leak guard, but empty = trust-nothing for Python/OpenSSL → HF downloads failed verify. media-audio env re-points them at the container CA store (same anti-leak intent, working chain). Split composes regenerated.ae174f7f(H3 blueprints, PMOVES-Creator#10 merged; clean fast-forward verified).Test plan
make build-svc SVC=media-audioclean (0 errors);recreate-svcboots healthy on RTX 5090:models_loaded: [stt, emotion], no crashes.catalog: true,/voicesmounted ro.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes
Documentation