[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M78FW32CY4FMBYWN0PF5ADSC":3,"skill-same:01M78FW32CY4FMBYWN0PF5ADSC":51},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":18,"linkOnly":19,"markdownContent":20,"markdownBody":21,"frontMatter":22,"refName":23,"commitSha":24,"skillDirectory":25,"forksCount":13,"repositoryHtmlUrl":26,"repositoryHomepageUrl":6,"ownerHtmlUrl":27,"ownerBlogUrl":28,"ownerDescription":29,"updatedAt":30,"install":31,"resources":44},"01M78FW32CY4FMBYWN0PF5ADSC","voice-post-call",null,"Cody-Lange\u002Fgbrain","Cody-Lange","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F50972659?v=4","01M78FVPSYY5SH1PSK0RS0WZ2G","Cody Brant Lange","01M78FVPTN6JKMV5NP7K7C5ANG",0,"MIT","https:\u002F\u002Fgithub.com\u002FCody-Lange\u002Fgbrain\u002Fblob\u002Fmaster\u002Frecipes\u002Fagent-voice\u002Fskills\u002Fvoice-post-call\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: voice-post-call\nversion: 0.1.0\ndescription: Post-call handling for a voice session — turn the transcript into a brain page, post the summary to the operator's messaging surface, archive the audio. Belt-and-suspenders: fires both from a tool the voice persona can call mid-call AND from the automatic call-end handler in server.mjs.\ntriggers:\n  - \"after the call\"\n  - \"call ended\"\n  - \"summarize the call\"\n  - \"call transcript\"\n  - \"voice call summary\"\n  - \"post call summary\"\nmutating: true\nwrites_pages: true\nwrites_to:\n  - meetings\u002F\n  - voice-calls\u002F\n---\n\n# voice-post-call — Post-session transcript + summary handling\n\n> **Convention:** see [conventions\u002Fquality.md](..\u002Fconventions\u002Fquality.md) for citation rules + back-link enforcement.\n>\n> **Convention:** see [_brain-filing-rules.md](..\u002F_brain-filing-rules.md) for filing decision protocol.\n\n## Iron Law\n\n**Every call gets processed, even on tool-call failure.** The voice persona MAY call a `log_call_summary` tool mid-session, OR the call may end without that tool firing (model forgot, WebRTC dropped, browser crashed). The automatic call-end handler in `services\u002Fvoice-agent\u002Fcode\u002Fserver.mjs` posts a structured signal regardless so the brain still gets the transcript + audio reference.\n\nIf both paths fire (the tool call AND the call-end handler), the second one is idempotent — it sees the brain page already exists and updates instead of duplicating.\n\n## The pipeline\n\n```\n1. CAPTURE  → MediaRecorder on the host repo's voice-agent service captures\n              the full call audio (webm\u002Fopus) to \u002Ftmp\u002Fcalls\u002F\u003Cts>-\u003Cpersona>.webm.\n              The browser client at \u002Fcall?test=1 also captures via WebAudio-tee\n              for E2E asserts; production \u002Fcall uses server-side capture only.\n2. TRANSCRIBE → Whisper (via gbrain transcription) processes the audio. Output:\n              full transcript (timestamped) + speaker labels where possible.\n3. SUMMARIZE  → A separate LLM call produces a 3-5 sentence summary covering\n              key topics, decisions, and unresolved items.\n4. WRITE      → Create or update meetings\u002FYYYY-MM-DD-call-\u003Cpersona>.md with:\n              - frontmatter (date, persona, duration, ratings)\n              - full transcript in a \"Transcript\" block-quote section\n              - summary in a \"Summary\" section\n              - audio link (file:\u002F\u002F, or signed URL if uploaded to storage)\n              - any entity cross-links (people, companies mentioned)\n5. CROSS-LINK → For each entity in the transcript (person, company), append a\n              timeline entry to people\u002F\u003Cslug>.md or companies\u002F\u003Cslug>.md pointing\n              back to this call page. Iron Law: per conventions\u002Fquality.md.\n6. POST       → Send the summary to the operator's messaging surface (Telegram,\n              Slack, Discord — whichever is wired in $TARGET_REPO\u002F.env).\n```\n\n## Two firing paths (belt + suspenders)\n\n**Path A — Persona-initiated mid-call:**\nThe voice persona calls `log_call_summary` via the WebRTC data channel. The host-repo `\u002Ftool` endpoint dispatches to `tools.mjs`. Note: `log_call_summary` is in `OPTIONAL_OPS`, not `READ_ONLY_OPS`, so this only works if the operator's `tools-allowlist.local.json` opts in.\n\n**Path B — Automatic call-end (default):**\nWhen the WebSocket \u002F WebRTC connection closes, `server.mjs` fires a `call_end` event. The host repo's post-call handler (operator-implemented; the recipe ships a stub) reads the captured audio + transcript, runs the pipeline above. This path requires NO operator opt-in to work — the call-end handler is part of the shipped server.\n\n## Brain page format\n\n```markdown\n---\ntype: meeting\nsubtype: voice-call\npersona: venus\ndate: 2026-05-17\nduration_sec: 124\ncaller: operator\nrating: 7\nissues: []\naudio_url: \"file:\u002F\u002F\u002Ftmp\u002Fcalls\u002F2026-05-17-1029-venus.webm\"\ncreated: 2026-05-17\n---\n\n# Voice call: 2026-05-17 with Venus\n\n> Brief 3-5 sentence summary of what was discussed and any decisions made.\n\n## Summary\n[Agent-authored 3-5 sentence summary covering topics, decisions, action items.]\n\n## Transcript\n\n> [Verbatim per-turn transcript with speaker labels and timestamps. Pure quote\n> — do not paraphrase. Block-quoted because the exact wording matters more\n> than a cleaned-up version.]\n\n🔊 [Audio](file:\u002F\u002F\u002Ftmp\u002Fcalls\u002F2026-05-17-1029-venus.webm)\n\n## Entities mentioned\n- [Person](people\u002F\u003Cslug>.md)\n- [Company](companies\u002F\u003Cslug>.md)\n\n## Timeline\n\n- **2026-05-17 10:29 PT** | voice call with Venus, 124s, rating 7 — [topic]\n```\n\n## Citation format\n\n```\n[Source: voice call with \u003Cpersona>, YYYY-MM-DD HH:MM PT]\n```\n\n## Anti-patterns\n\n- ❌ Paraphrasing the transcript. The verbatim text IS the signal; the summary is the agent's interpretation.\n- ❌ Skipping the audio archive step. Every call has a recoverable audio file.\n- ❌ Skipping entity cross-links when people\u002Fcompanies are mentioned. Iron Law fail.\n- ❌ Posting to messaging WITHOUT writing the brain page first. The messaging summary is a notification, not the canonical record.\n- ❌ Letting Path A's success suppress Path B. They MAY both fire; the second one is idempotent and serves as a redundant safety net.\n\n## Related skills\n\n- [voice-persona-mars](..\u002Fvoice-persona-mars\u002FSKILL.md) — the persona that may invoke this\n- [voice-persona-venus](..\u002Fvoice-persona-venus\u002FSKILL.md) — the other persona that may invoke this\n- [meeting-ingestion](..\u002Fmeeting-ingestion\u002FSKILL.md) — analogous flow for multi-party meeting transcripts (different in that voice-call is typically 1:1)\n- [voice-note-ingest](..\u002Fvoice-note-ingest\u002FSKILL.md) — for recorded one-way voice memos (different from live voice calls)\n\n## Contract\n\nThis skill guarantees:\n\n- Routing matches the canonical triggers in the frontmatter.\n- The post-call pipeline runs idempotently — second invocations update rather than duplicate.\n- Output written under `meetings\u002F` or `voice-calls\u002F` (consistent with `_brain-filing-rules.md`).\n- Conventions referenced (`quality.md`, `_brain-filing-rules.md`) are followed.\n- Privacy contract preserved: no real names in any committed sample; the operator's actual call transcripts contain whatever they say, which is the operator's data and not gbrain's concern.\n\n## Output Format\n\n```markdown\n---\ntype: meeting\nsubtype: voice-call\npersona: \u003Cmars|venus>\ndate: YYYY-MM-DD\nduration_sec: N\ncaller: \u003Cidentity>\nrating: 0-10\naudio_url: \"\u003Cfile:\u002F\u002F or signed URL>\"\n---\n\n# Voice call: \u003Cdate> with \u003Cpersona>\n\n> \u003CSummary>\n\n## Summary\n\u003Cbody>\n\n## Transcript\n\n> \u003Cverbatim>\n\n🔊 [Audio](\u003Curl>)\n\n## Timeline\n\n- **\u003Cdate> \u003Ctime> \u003Ctz>** | voice call with \u003Cpersona>, \u003Cduration>s — \u003Ctopic>\n```\n","# voice-post-call — Post-session transcript + summary handling\n\n> **Convention:** see [conventions\u002Fquality.md](..\u002Fconventions\u002Fquality.md) for citation rules + back-link enforcement.\n>\n> **Convention:** see [_brain-filing-rules.md](..\u002F_brain-filing-rules.md) for filing decision protocol.\n\n## Iron Law\n\n**Every call gets processed, even on tool-call failure.** The voice persona MAY call a `log_call_summary` tool mid-session, OR the call may end without that tool firing (model forgot, WebRTC dropped, browser crashed). The automatic call-end handler in `services\u002Fvoice-agent\u002Fcode\u002Fserver.mjs` posts a structured signal regardless so the brain still gets the transcript + audio reference.\n\nIf both paths fire (the tool call AND the call-end handler), the second one is idempotent — it sees the brain page already exists and updates instead of duplicating.\n\n## The pipeline\n\n```\n1. CAPTURE  → MediaRecorder on the host repo's voice-agent service captures\n              the full call audio (webm\u002Fopus) to \u002Ftmp\u002Fcalls\u002F\u003Cts>-\u003Cpersona>.webm.\n              The browser client at \u002Fcall?test=1 also captures via WebAudio-tee\n              for E2E asserts; production \u002Fcall uses server-side capture only.\n2. TRANSCRIBE → Whisper (via gbrain transcription) processes the audio. Output:\n              full transcript (timestamped) + speaker labels where possible.\n3. SUMMARIZE  → A separate LLM call produces a 3-5 sentence summary covering\n              key topics, decisions, and unresolved items.\n4. WRITE      → Create or update meetings\u002FYYYY-MM-DD-call-\u003Cpersona>.md with:\n              - frontmatter (date, persona, duration, ratings)\n              - full transcript in a \"Transcript\" block-quote section\n              - summary in a \"Summary\" section\n              - audio link (file:\u002F\u002F, or signed URL if uploaded to storage)\n              - any entity cross-links (people, companies mentioned)\n5. CROSS-LINK → For each entity in the transcript (person, company), append a\n              timeline entry to people\u002F\u003Cslug>.md or companies\u002F\u003Cslug>.md pointing\n              back to this call page. Iron Law: per conventions\u002Fquality.md.\n6. POST       → Send the summary to the operator's messaging surface (Telegram,\n              Slack, Discord — whichever is wired in $TARGET_REPO\u002F.env).\n```\n\n## Two firing paths (belt + suspenders)\n\n**Path A — Persona-initiated mid-call:**\nThe voice persona calls `log_call_summary` via the WebRTC data channel. The host-repo `\u002Ftool` endpoint dispatches to `tools.mjs`. Note: `log_call_summary` is in `OPTIONAL_OPS`, not `READ_ONLY_OPS`, so this only works if the operator's `tools-allowlist.local.json` opts in.\n\n**Path B — Automatic call-end (default):**\nWhen the WebSocket \u002F WebRTC connection closes, `server.mjs` fires a `call_end` event. The host repo's post-call handler (operator-implemented; the recipe ships a stub) reads the captured audio + transcript, runs the pipeline above. This path requires NO operator opt-in to work — the call-end handler is part of the shipped server.\n\n## Brain page format\n\n```markdown\n---\ntype: meeting\nsubtype: voice-call\npersona: venus\ndate: 2026-05-17\nduration_sec: 124\ncaller: operator\nrating: 7\nissues: []\naudio_url: \"file:\u002F\u002F\u002Ftmp\u002Fcalls\u002F2026-05-17-1029-venus.webm\"\ncreated: 2026-05-17\n---\n\n# Voice call: 2026-05-17 with Venus\n\n> Brief 3-5 sentence summary of what was discussed and any decisions made.\n\n## Summary\n[Agent-authored 3-5 sentence summary covering topics, decisions, action items.]\n\n## Transcript\n\n> [Verbatim per-turn transcript with speaker labels and timestamps. Pure quote\n> — do not paraphrase. Block-quoted because the exact wording matters more\n> than a cleaned-up version.]\n\n🔊 [Audio](file:\u002F\u002F\u002Ftmp\u002Fcalls\u002F2026-05-17-1029-venus.webm)\n\n## Entities mentioned\n- [Person](people\u002F\u003Cslug>.md)\n- [Company](companies\u002F\u003Cslug>.md)\n\n## Timeline\n\n- **2026-05-17 10:29 PT** | voice call with Venus, 124s, rating 7 — [topic]\n```\n\n## Citation format\n\n```\n[Source: voice call with \u003Cpersona>, YYYY-MM-DD HH:MM PT]\n```\n\n## Anti-patterns\n\n- ❌ Paraphrasing the transcript. The verbatim text IS the signal; the summary is the agent's interpretation.\n- ❌ Skipping the audio archive step. Every call has a recoverable audio file.\n- ❌ Skipping entity cross-links when people\u002Fcompanies are mentioned. Iron Law fail.\n- ❌ Posting to messaging WITHOUT writing the brain page first. The messaging summary is a notification, not the canonical record.\n- ❌ Letting Path A's success suppress Path B. They MAY both fire; the second one is idempotent and serves as a redundant safety net.\n\n## Related skills\n\n- [voice-persona-mars](..\u002Fvoice-persona-mars\u002FSKILL.md) — the persona that may invoke this\n- [voice-persona-venus](..\u002Fvoice-persona-venus\u002FSKILL.md) — the other persona that may invoke this\n- [meeting-ingestion](..\u002Fmeeting-ingestion\u002FSKILL.md) — analogous flow for multi-party meeting transcripts (different in that voice-call is typically 1:1)\n- [voice-note-ingest](..\u002Fvoice-note-ingest\u002FSKILL.md) — for recorded one-way voice memos (different from live voice calls)\n\n## Contract\n\nThis skill guarantees:\n\n- Routing matches the canonical triggers in the frontmatter.\n- The post-call pipeline runs idempotently — second invocations update rather than duplicate.\n- Output written under `meetings\u002F` or `voice-calls\u002F` (consistent with `_brain-filing-rules.md`).\n- Conventions referenced (`quality.md`, `_brain-filing-rules.md`) are followed.\n- Privacy contract preserved: no real names in any committed sample; the operator's actual call transcripts contain whatever they say, which is the operator's data and not gbrain's concern.\n\n## Output Format\n\n```markdown\n---\ntype: meeting\nsubtype: voice-call\npersona: \u003Cmars|venus>\ndate: YYYY-MM-DD\nduration_sec: N\ncaller: \u003Cidentity>\nrating: 0-10\naudio_url: \"\u003Cfile:\u002F\u002F or signed URL>\"\n---\n\n# Voice call: \u003Cdate> with \u003Cpersona>\n\n> \u003CSummary>\n\n## Summary\n\u003Cbody>\n\n## Transcript\n\n> \u003Cverbatim>\n\n🔊 [Audio](\u003Curl>)\n\n## Timeline\n\n- **\u003Cdate> \u003Ctime> \u003Ctz>** | voice call with \u003Cpersona>, \u003Cduration>s — \u003Ctopic>\n```\n",{},"master","0a12c636317068e0cf0a946d4d05ccaf86cf1f1b","recipes\u002Fagent-voice\u002Fskills\u002Fvoice-post-call","https:\u002F\u002Fgithub.com\u002FCody-Lange\u002Fgbrain","https:\u002F\u002Fgithub.com\u002FCody-Lange","https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Fcody-lange-bab430b6\u002F","Michigan State University Mechanical Engineering '17,\r\nUniversity of Michigan Applied Data Science '21\r\n","2026-07-13 12:38:53",{"source":7,"skillName":5,"commands":32,"prompt":42,"zipAvailable":43},[33,36,39],{"tool":34,"command":35},"npx","npx skills add Cody-Lange\u002Fgbrain --skill voice-post-call",{"tool":37,"command":38},"bunx","bunx skills add Cody-Lange\u002Fgbrain --skill voice-post-call",{"tool":40,"command":41},"pnpm","pnpm dlx skills add Cody-Lange\u002Fgbrain --skill voice-post-call","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FCody-Lange\u002Fgbrain\u002Fblob\u002Fmaster\u002Frecipes\u002Fagent-voice\u002Fskills\u002Fvoice-post-call\u002FSKILL.md",true,[45],{"path":46,"resourceType":47,"resourceTypeDesc":48,"sizeBytes":49,"sourceHtmlUrl":50},"routing-eval.jsonl","OTHER","其他",591,"https:\u002F\u002Fgithub.com\u002FCody-Lange\u002Fgbrain\u002Fblob\u002Fmaster\u002Frecipes\u002Fagent-voice\u002Fskills\u002Fvoice-post-call\u002Frouting-eval.jsonl",[52,58,64,71,78,85],{"skillNo":53,"name":54,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":55,"categories":56,"keywords":57,"publishedAt":18},"01M78G5K078E75VN0ZZ26KYR5S","query-helper","https:\u002F\u002Fgithub.com\u002FCody-Lange\u002Fgbrain\u002Fblob\u002Fmaster\u002Ftest\u002Ffixtures\u002Fskill-catalog\u002Fskills\u002Fquery-helper\u002FSKILL.md",[],[],{"skillNo":59,"name":60,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":61,"categories":62,"keywords":63,"publishedAt":18},"01M78G5J3TSEXBJH7M0F2MXKCZ","broken","https:\u002F\u002Fgithub.com\u002FCody-Lange\u002Fgbrain\u002Fblob\u002Fmaster\u002Ftest\u002Ffixtures\u002Fskill-catalog\u002Fskills\u002Fbroken\u002FSKILL.md",[],[],{"skillNo":65,"name":66,"nameZh":6,"description":67,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":68,"categories":69,"keywords":70,"publishedAt":18},"01M78G5GB3M0K6376M62TV8Y43","brain-ops","Read, enrich, and write brain pages with source attribution.","https:\u002F\u002Fgithub.com\u002FCody-Lange\u002Fgbrain\u002Fblob\u002Fmaster\u002Ftest\u002Ffixtures\u002Fskill-catalog\u002Fskills\u002Fbrain-ops\u002FSKILL.md",[],[],{"skillNo":72,"name":73,"nameZh":6,"description":74,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":75,"categories":76,"keywords":77,"publishedAt":18},"01M78G5ETFR36WB9VCSK1C7WBD","signal-detector","Always-on ambient signal capture for the OpenClaw reference fixture.","https:\u002F\u002Fgithub.com\u002FCody-Lange\u002Fgbrain\u002Fblob\u002Fmaster\u002Ftest\u002Ffixtures\u002Fopenclaw-reference-minimal\u002Fskills\u002Fsignal-detector\u002FSKILL.md",[],[],{"skillNo":79,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":18},"01M78G5DD4R21BZHCAT51WGKM1","query","Look up brain pages in the OpenClaw reference fixture.","https:\u002F\u002Fgithub.com\u002FCody-Lange\u002Fgbrain\u002Fblob\u002Fmaster\u002Ftest\u002Ffixtures\u002Fopenclaw-reference-minimal\u002Fskills\u002Fquery\u002FSKILL.md",[],[],{"skillNo":86,"name":87,"nameZh":6,"description":88,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":89,"categories":90,"keywords":91,"publishedAt":18},"01M78G5BYJPCGJ3WC270Y3DGNX","context-now","ALWAYS-ON time-sensitivity discipline for the OpenClaw reference fixture.","https:\u002F\u002Fgithub.com\u002FCody-Lange\u002Fgbrain\u002Fblob\u002Fmaster\u002Ftest\u002Ffixtures\u002Fopenclaw-reference-minimal\u002Fskills\u002Fcontext-now\u002FSKILL.md",[],[]]