Skip to content

Remove VoiceServer + Notification system from PAI (#112, closes #83)#138

Merged
virtualian merged 6 commits intomainfrom
fix/112-remove-voice-server-notification-system
Apr 15, 2026
Merged

Remove VoiceServer + Notification system from PAI (#112, closes #83)#138
virtualian merged 6 commits intomainfrom
fix/112-remove-voice-server-notification-system

Conversation

@virtualian
Copy link
Copy Markdown
Owner

Summary

Closes #112. Closes #83.

Surgical ripout of the entire voice notification stack per #112's 8-part scope. Six logical commits, 31 files changed (75+/1125-). Supersedes the never-landed #83 hook-side gate fix — the subsystem is gone, so the bug can no longer occur.

Commits

SHA Scope
58e2c9b Part 2 — VoiceCompletion hook + VoiceNotification handler + Stop hook registration
329c6f7 Part 3 — voice aphorisms from settings.json (Q1 gated)
4c1973f Part 4 — Voice announcements from Algorithm v3.7.0
fdc0dc4 Part 5 — NATIVE MODE inline curl + 12 agent voice curls
27238bb Part 6 — THENOTIFICATIONSYSTEM.md + cross-refs (9 docs/data files)
b64ad51 Part 7 — Notify.ts invocations from Learning skill

Part 1 (Notify.ts CLI deletion) yielded no repo diff — the CLI lived only at ~/.pai/PAI/Tools/Notify.ts and never shipped in the release template. Releases/v4.0.3+/.claude/**/Notify.ts glob returns nothing. Runtime file was deleted in the same pass for behavioural parity.

Open Questions (from #112's Q1/Q2/Q3 review)

Q1 — Non-TTS consumers of daidentity.voices.* / voiceId / voiceClone

Verdict: LEAVE the data in settings.json. A grep of `hooks/lib/identity.ts` and its callers found multiple non-voice consumers:

  • `hooks/RatingCapture.hook.ts`, `RelationshipMemory.hook.ts`, `KittyEnvPersist.hook.ts`, `handlers/TabState.ts` — use `getDAName()` / `getIdentity().name`
  • `lib/migration/validator.ts` + `extractor.ts` — read `daidentity.mainDAVoiceID` for migration state
  • `skills/Telos/Tools/UpdateTelos.ts` — uses `getPrincipal()`
  • `PAI/Tools/TranscriptParser.ts` — uses `getIdentity()` for the 🗣️ line regex

Removing `daidentity.voices.*` / `mainDAVoiceID` / `voiceClone` would cascade into refactors of `identity.ts` plus every caller. Out of surgical scope.

Only removed from settings.json:

  • Top-level `voiceEnabled` field (runtime only — release template didn't have it; Remove VoiceServer + Notification system from PAI #112's line numbers 265/385 were matching the runtime file, not the release)
  • `notifications.voice` block (runtime only — release didn't have it)
  • The two voice-related aphorism strings in the release settings.json aphorisms array

Q2 — Notify.ts live invocations in skill markdown

Verdict: 4 live hits in the Learning skill, all removed.

File Line Hit
`skills/Learning/SKILL.md` 20 bun Notify.ts template
`skills/Learning/Workflows/Review.md` 4 bun Notify.ts invocation
`skills/Learning/Workflows/Check.md` 4 bun Notify.ts invocation
`skills/Learning/Workflows/Apply.md` 4 bun Notify.ts invocation

Null findings (grep of full Packs + skills tree): no hits in Research, Security/Recon, Security/WorldThreatModelHarness, Security/AnnualReports, or PAIUpgrade — despite #112's speculative list. Those references have already migrated to other patterns or never existed.

Q3 — LaunchAgent / systemd / shell unit for port 8888

Verdict: None ship with this repo. No launchd plist, no systemd unit, no shell startup snippet found. The closest thing is `PAI-Install/engine/actions.ts` which calls `/health`, `/shutdown`, and tests `/notify` during installation — those are installer-time probes, not startup units.

Users who ran the voice server: stop the localhost:8888 process manually. The ElevenLabs API key env var (`ELEVENLABS_API_KEY`) is no longer needed by PAI itself. No plists/units to clean up.

Scope discrepancies found

These were documented but not touched — they expand beyond #112's explicit 8-part scope and would widen this PR into a refactor:

  • `VoiceServer/server.ts` lives inside this repo, contrary to Remove VoiceServer + Notification system from PAI #112's "outside this repo" wording. It's at `Releases/v4.0.3+/.claude/VoiceServer/server.ts` (950+ lines). Not deleted — follow-up issue recommended.
  • `hooks/UpdateTabTitle.hook.ts` still POSTs to `localhost:8888/notify` on prompt submit (line 226). The hook is protected by an in-file "DO NOT REMOVE voice from this hook" constitutional comment referencing `MEMORY/LEARNING/SYSTEM/2026-01/...voice-on-prompt-submit-architecture.md`. Left intact; only stripped the now-stale "Task completion voice is separate (VoiceCompletion.hook.ts → VoiceNotification handler)" cross-reference comment from the header block.
  • `hooks/handlers/DocCrossRefIntegrity.ts:370` POSTs to `localhost:8888/notify` — independent voice path.
  • `PAI/Tools/pai.ts` (lines 35, 91) — separate voice server client code.
  • `PAI/Tools/algorithm.ts` (lines 53, 641) — separate voice server client code.
  • `PAI/Tools/IntegrityMaintenance.ts` (lines 787, 973) — `sendVoiceNotification()` function.
  • `PAI/SKILL.md` — 7 per-phase inline voice curls at lines 237-336. Not touched; user scope listed Algorithm v3.7.0.md but not PAI/SKILL.md.
  • `PAI/Algorithm/v3.5.0.md` — legacy Algorithm with its own voice curls (lines 26, 116). Not touched; scope said v3.7.0 only.
  • `skills/Media/Art/Workflows/*.md` — 9 art workflow markdown files each with a voice curl at line 8. Not touched; not in scope.
  • `hooks/lib/output-validators.ts` still exports `isValidVoiceCompletion` / `getVoiceFallback` — used only by the deleted `VoiceNotification.ts`. Dead code after this PR but left per the surgical rule.
  • `PAI/Tools/TranscriptParser.ts` still exports `extractVoiceCompletion`. Dead code after this PR.
  • `PAI-Install/engine/{types,validate,actions}.ts` + `public/app.js` track a `voiceEnabled` installer state and write it to settings.json during install. The installer will re-introduce `voiceEnabled` on a fresh install unless those are updated too.

Recommend follow-up issue(s) for the above — together they'd fully detach PAI from the voice server.

Preserved intentionally

  • `MEMORY/VOICE/voice-events.jsonl` — frozen archive, NOT deleted
  • `🗣️ Viki` / `🗣️ {DAIDENTITY.NAME}` lines in NATIVE/ALGORITHM/MINIMAL output formats — text summary signal, just no longer triggers TTS
  • `━━━ 👁️ OBSERVE ━━━ 1/7` phase headers and PRD frontmatter edit instructions in Algorithm v3.7.0 — only the "Voice announce" prefix was stripped
  • `daidentity.voices.*`, `voiceClone`, `mainDAVoiceID`, `voiceId` in settings.json — per Q1
  • Intentional release↔runtime path divergences in THEHOOKSYSTEM.md, TOOLS.md, agent files (release uses `/.pai/`, runtime uses `/.claude/`)
  • PR Bundle upstream cherries: statusline spacing + AlgorithmTab dead docs (#91 partial, #83 verified) #137's recent AlgorithmTab.hook.ts dead doc removals — did not conflict
  • `hooks/UpdateTabTitle.hook.ts`'s own voice announcement code (sticky constraint)

Release note

Removed: voice notification system. The localhost:8888 voice server is no longer used by PAI. If you ran the server process for PAI, stop it manually — the ElevenLabs API key env var is no longer needed by PAI itself. The `🗣️ Viki` line in NATIVE/ALGORITHM response formats is preserved as a text summary signal; it just no longer triggers TTS playback.

Test plan

  • `bun -e 'JSON.parse(...)'` on all 4 touched JSON files (2× settings.json, 2× doc-dependencies.json)
  • `bun build --target=bun --no-bundle` on `hooks/UpdateTabTitle.hook.ts` + `hooks/lib/change-detection.ts` (the two .ts files that kept orphan-risk after deletions)
  • Grep sweep for `VoiceCompletion` / `VoiceNotification` / `localhost:8888` / `Notify.ts` / `THENOTIFICATIONSYSTEM` — zero residuals in release tree except `VoiceServer/server.ts` (server source itself, out of scope)
  • Grep sweep in runtime `~/.pai` — zero residuals in live code, only historical memory logs remain
  • `MEMORY/VOICE/voice-events.jsonl` archive preserved
  • Maintainer smoke: start a fresh session and confirm the Algorithm enters without voice errors
  • Maintainer smoke: run a `/loop` or any skill and confirm Stop hook no longer crashes on missing VoiceCompletion

🤖 Generated with Claude Code

virtualian and others added 6 commits April 15, 2026 21:56
Delete VoiceCompletion.hook.ts and handlers/VoiceNotification.ts,
drop the VoiceCompletion entry from the settings.json Stop hook
block, and strip the now-stale "Task completion voice is separate"
cross-reference comment from UpdateTabTitle.hook.ts.

Part 2 of the #112 ripout bundle. Runtime mirror (~/.pai) was
updated in the same pass but is not tracked by this repo.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Drop the two voice-related aphorism strings from the settings.json
aphorisms array that describe a system that no longer exists:
"Voice announcements at Algorithm entry..." and "Only the primary
agent makes voice curls...".

The release template did not contain top-level voiceEnabled nor a
notifications.voice block (#112's line references 265 / 385 were
matching the runtime ~/.claude/settings.json, not the release). The
runtime copy had both and has been cleaned in the same pass.

daidentity.voices.*, voiceClone, mainDAVoiceID, and voiceId remain
in settings.json: non-TTS consumers (hooks/lib/identity.ts ->
RatingCapture, RelationshipMemory, KittyEnvPersist, TabState,
TranscriptParser, migration/{validator,extractor}, Telos/UpdateTelos,
pai.ts) still read them. Q1 gate verdict: leave the data.

Part 3 of the #112 ripout bundle.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Strip from Algorithm v3.7.0.md:
- Entire "### Voice Announcements" section (9 lines)
- The "Voice (FIRST action after loading this file)" line before
  the PRD stub instructions
- The "Voice announce ..., then" prefix from all 7 phase FIRST
  ACTIONs (OBSERVE, THINK, PLAN, BUILD, EXECUTE, VERIFY, LEARN)
- The "before voice announcement and PRD edit" wording in the
  console output gate

Phase headers, PRD frontmatter edit instructions, and all other
Algorithm content are preserved. The runtime mirror at
~/.pai/PAI/Algorithm/v3.7.0.md was updated in the same pass.

Part 4 of the #112 ripout bundle.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CLAUDE.md.template: strip the NATIVE MODE 'Voice:' curl invocation
line. The shipped CLAUDE.md was already cleaned by PR #111; only
the fresh-install template still had the curl.

Agent files (12 files): for each of the 11 "standard-shape" agents
(ClaudeResearcher, PerplexityResearcher, GeminiResearcher,
CodexResearcher, GrokResearcher, Engineer, Designer, Architect,
Algorithm, Artist, QATester), strip:
- the "Send voice notification that you're loading context" bullet
  from the MANDATORY STARTUP SEQUENCE list (renumbering the rest)
- the entire "MANDATORY VOICE NOTIFICATION SYSTEM" section with
  its bash curl block + trailing separator
- the "Send voice notifications" bullet from the closing Remember
  list (renumbering the rest)

Pentester.md uses a different embedded structure — stripped the
"CRITICAL: VOICE NOTIFICATION IS MANDATORY" section plus the
"SEND VOICE NOTIFICATION FIRST" bullet from CRITICAL OUTPUT RULES.

Runtime mirror (~/.pai/agents/*.md, 13 files including Intern)
updated in the same pass. Intern follows the same embedded
Pentester-style shape.

Part 5 of the #112 ripout bundle.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Delete PAI/THENOTIFICATIONSYSTEM.md entirely (305 lines). Strip
the cross-references that pointed at it and at the voice system
from the surrounding docs and data files:

- PAI/CONTEXT_ROUTING.md: drop the "Notification system" row
- PAI/DOCUMENTATIONINDEX.md: drop "execute voice notifications,"
  from the skill execution prose
- PAI/README.md: drop the THENOTIFICATIONSYSTEM filename ref and
  the ElevenLabs/localhost:8888 sentence from the Notifications
  section; the ntfy/Discord/Twilio description stays
- PAI/TOOLS.md: drop the entire "Voice Server API" section
- PAI/THEHOOKSYSTEM.md: drop the VoiceCompletion entry from the
  Stop hook JSON + handler list, the "Voice Notifications" common
  pattern section + code example, the "Voice Notifications Not
  Working" troubleshooting block, the STOP (4 hooks) -> (3 hooks)
  listing update, the VOICE SERVER ASCII block, VoiceNotification
  from the identity.ts consumers list, and the `voice.*` event
  table row
- hooks/README.md: drop VoiceCompletion from the Stop diagram,
  the VoiceCompletion.hook.ts table row, the second Stop diagram
  (ResponseTabReset -> brand color becomes the sole tail), and
  VoiceNotification from the output-validators consumers list
- PAI/doc-dependencies.json: drop the notification-system section
  from SYSTEMARCHITECTURE dependents and the THENOTIFICATIONSYSTEM
  top-level entry
- hooks/lib/change-detection.ts: drop THENOTIFICATIONSYSTEM.md
  from HIGH_PRIORITY_PATHS

Runtime mirror (~/.pai) updated in the same pass, preserving the
intentional release<->runtime path divergences in THEHOOKSYSTEM.md.
Intentional divergences: release uses ~/.pai/skills/..., runtime
uses ~/.claude/skills/... - neither form was normalized.

Out-of-scope voice refs left intact (documented for PR body):
SKILLSYSTEM.md, PAI/SKILL.md 7-phase curls, Algorithm/v3.5.0.md
legacy, PAI/Tools/{pai,algorithm,IntegrityMaintenance}.ts,
PAI/Tools/TranscriptParser.ts (extractVoiceCompletion),
hooks/handlers/DocCrossRefIntegrity.ts, hooks/UpdateTabTitle.hook.ts,
hooks/lib/output-validators.ts (isValidVoiceCompletion,
getVoiceFallback), VoiceServer/server.ts (the server source lives
inside this repo, contrary to #112's 'outside this repo' note).

Part 6 of the #112 ripout bundle.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Strip the four live 'bun Notify.ts' shell blocks from the
Learning skill:
- skills/Learning/SKILL.md: drop the entire "Voice Notification"
  section; rename the remaining "Workflow Announcement" to keep
  just the text-announcement guidance
- skills/Learning/Workflows/Review.md: drop the bun Notify.ts
  code block at the top; the text announcement remains
- skills/Learning/Workflows/Check.md: same
- skills/Learning/Workflows/Apply.md: same

These were the only live Notify.ts invocations in release skill
markdown per a full grep (Q2 verdict: 4 Learning hits, no hits
in Packs, Research, Security/Recon, PAIUpgrade despite #112's
speculative list).

Runtime mirror (~/.pai/skills/Learning) updated in the same pass,
preserving the ~/.pai/ vs ~/.claude/ intentional path divergence.

Part 7 of the #112 ripout bundle.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@virtualian virtualian merged commit 37de81c into main Apr 15, 2026
1 check passed
@virtualian virtualian deleted the fix/112-remove-voice-server-notification-system branch April 15, 2026 21:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remove VoiceServer + Notification system from PAI Voice plays despite settings.json voice.enabled: false

1 participant