Skip to content

OVOS-PERSONA-1: Persona Pipeline Plugin Specification#37

Draft
JarbasAl wants to merge 7 commits into
devfrom
spec/persona
Draft

OVOS-PERSONA-1: Persona Pipeline Plugin Specification#37
JarbasAl wants to merge 7 commits into
devfrom
spec/persona

Conversation

@JarbasAl
Copy link
Copy Markdown
Member

@JarbasAl JarbasAl commented May 27, 2026

Companion issue: #50

Summary

Defines the persona pipeline plugin — a complete conversational agent that, when active for a session, claims every utterance that reaches its pipeline stage and generates natural-language responses.

What the spec covers

  • §3persona_id session field: absent = no-persona mode (deterministic pipeline); present = named persona active
  • §4 — No-persona mode: persona stages MUST decline except for embedded commands
  • §5–§6 — Summon (self-summon via Match.updated_session, or external via session field) and dismiss
  • §7 — Match contract: two routes — embedded persona command detection (always active) and utterance claim when persona is active
  • §8 — Handler contract: standard PIPELINE-1 dispatch; multi-turn via CONVERSE-1; session.fallback_pipeline_id for per-persona fallback chains; conversation history via SESSION-2 MAY-internal pathway
  • §8.5 — Out-of-band query: ovos.persona.query / ovos.persona.answer — direct text-in/text-out bypassing the pipeline; session for history from context.session.session_id
  • §9 — Multiple persona coexistence: each plugin declares supported persona_ids; at most one active per session
  • §10 — Pipeline positioning: after deterministic intents and converse, before fallback
  • §11 — Bus surface
  • §12 — Conformance

Bus surface

Topic Purpose
ovos.persona.query Out-of-band query to a persona
ovos.persona.answer Persona's generated response
ovos.persona.list Enumerate supported persona identities
ovos.persona.list.response Supported-identity listing
ovos.persona.register Runtime persona registration
ovos.persona.deregister Runtime persona deregistration

Conceptual definition of a persona as a complete conversational agent, with summon/dismiss interaction rules, no-persona mode, pipeline-positioning constraints, and an out-of-band query interface.

- §2: conceptual definition (identity, personality, capabilities)
- §3: persona_id session field (matching existing Session.persona_id)
- §4: no-persona mode (deterministic pipeline without persona)
- §5: summon rules (activating a persona by setting persona_id)
- §6: dismiss rules (deactivating via stop cascade or mutation)
- §7: simplified match contract (check persona_id, consume all)
- §8: handler contract, multi-turn via converse, out-of-band query
- §9: multiple persona coexistence (identity namespace, selection)
- §10: pipeline positioning (skills and stop before persona)
- §11: bus surface
- §12: conformance

Co-Authored-By: big-pickle <big-pickle@opencode.ai>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 27, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4b2cf960-a3fd-4725-bf14-b8aeb5d85606

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch spec/persona

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

JarbasAl and others added 6 commits May 28, 2026 00:19
…edded commands, discovery, default persona, register/deregister

- §5: self-summon and external-summon pathways; one-off query (ask) as non-activating embedded command; unknown persona query rule
- §6: self-release via match added to dismiss pathways
- §7.1: two-phase match — route 1 (embedded commands) before route 2 (persona_id catch-all)
- §7.2, §7.5: updated for broader route 1
- §8.5: added rationale for out-of-band query
- §8.7 (new): persona discovery (ovos.persona.list / .list.response)
- §4: default persona deployment note
- §9: dynamic register/deregister (ovos.persona.register / .deregister)
- §11: bus surface table extended
- §12: conformance updated for discovery (SHOULD) and register/deregister (MAY)
- Cross-reference fix: §8.5→§8.6 in conformance stop item
- §3, §4: softened absolute MUST-return-None to allow embedded commands

Co-Authored-By: Claude Code <claude@anthropic.com>
Bugs fixed:
- §6: "client by omitting persona_id" is wrong (omission ≠ clearing per
  SESSION-1 §4); corrected to explicit clearing. Stop-cascade dependency
  demoted from normative SHOULD on STOP-1 to informative deployment note.
- §5: "summon MUST reference existing persona_id" contradicts self-summon
  (which creates the identity); replaced with "unknown persona falls through"
- §9: MUST NOT duplicate persona_id vs. "multiple stages share same id"
  contradiction resolved — demoted to SHOULD NOT, behaviour described correctly
- §8.6: SHOULD check + MUST cease → both MUST (the MUST was conditional on
  the SHOULD, making it toothless)
- §8.3: add listen:true requirement on multi-turn speak prompt (CONVERSE-1
  §5.1); explain why converse routes to persona (skill_id == pipeline_id)

Underspecified fixed:
- §8.5: add response payload table with field definitions; add source
  requirement for reply() routing; note on broadcast noise and mitigation
- §8.4: remove suggested persona_context field name (not in SESSION-1
  registry); require plugin-specific namespaced name claimed in registry
- §11: add ovos.persona.activated / ovos.persona.dismissed signals with
  payload definitions and best-effort caveat

Overspecified fixed:
- §7.2: "MUST NOT use intent-matching" was too broad (route 1 IS intent-
  matching); rewritten to scope confidence-gating prohibition to route 2 only
- §6: remove MUST NOT rate-limit (too specific, no clear rationale)

Too loose fixed:
- §7.1: one-off query MAY claim even for unsupported persona_id changed to
  MUST NOT (footgun: downstream plugin that actually handles the id never fires)
- §7.2: removed "minimum utterance length" from allowed gate-logic examples

Structural:
- One-off query moved from §5 (Summon) to §7.1 where it belongs
- §7.1 + §7.2 merged; catch-all rule and gate-logic restriction now in one place
- §7.2/7.3/7.4/7.5 renumbered to 7.2/7.3/7.4
- §2: remove implementation vocabulary from capabilities bullet
- Conformance updated throughout

Appendix:
- Add appendix/persona-flow.md: annotated bus sequences for summon,
  active-persona turn, multi-turn, self-release dismiss, stop-cascade
  dismiss, and out-of-band query

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
session_id must not appear in message.data. The out-of-band query
caller sets context.session.session_id for history scoping; the
plugin reads from there. Added a clarifying sentence to that effect.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Trim / implementation leakage:
- §2: remove trailing paragraph that restates §1 "not define"
- §3: remove explanatory sentence about why propagation matters
- §4: remove tautological third bullet ("persona-related behaviour is absent")
- §8.1: collapse verbose "Zero emissions is conformant" into the MAY line
- §8.3: cut streaming token-by-token detail (covered by PIPELINE-1 §6.5);
  add MUST listen:true on get_response prompts; simplify multi-turn step list
- §8.4: remove LLM-specific examples (embeddings, model state, transcripts);
  require session field be registered per SESSION-1 §2.1 rather than naming it
- §9: remove internal "wiring, solver chain" comment from register payload
- §10: collapse numbered justification list into one prose sentence

Bug fixes:
- §6: fix "client omitting persona_id" being listed as a dismiss mechanism —
  SESSION-1 §4 carries fields forward; only explicit clear counts; rewrite
  paragraph to reflect this and remove the rate-limit MUST NOT (impl concern)
- §8.5: add response payload table; add MUST respond None for unknown persona_id
- §8.6: both conditions become MUST (was SHOULD+MUST)
- §9: MUST NOT serve same persona_id → SHOULD NOT (first match wins, not error)
- §11: add ovos.persona.activated / ovos.persona.dismissed advisory signals
- §12: move stop-awareness to separate MUST block; add listen:true to SHOULD;
  fix persona_id uniqueness wording

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rmers

Multi-persona coexistence (§9):
- Reframe as the primary pluggable-capabilities mechanism
- Add capability-based routing: routing skill/UI queries ovos.persona.list
  tags to select persona_id; plugin only declares, doesn't participate
- Define persona-fallback pipeline_id: secondary pipeline position that
  claims utterances when persona_id is absent (route 3 catch-all)
- Only one fallback stage SHOULD be active per pipeline

Match contract (§7.1):
- Add route 3: fallback_pipeline_id match rules — claim when persona_id
  absent or supported; return None when another persona's id is active

Discovery (§8.7):
- ovos.persona.list.response now carries per-persona objects with
  persona_id, name (optional), tags (optional freeform string array)
- Response also carries fallback_pipeline_id when registered
- Tags are advisory, vocabulary is deployment-defined

Pipeline positioning (§10):
- Distinguish main pipeline_id position (active-persona) from
  fallback_pipeline_id position (persona-fallback catch-all)
- Updated typical ordering example with both positions

§2 (What is a persona):
- Explicit "black box" statement — internal machinery is out of scope
- Add dialog transformers note: personality shaping belongs in
  TRANSFORM-1, not in the persona plugin

§3:
- Explicit single-value statement: one persona_id per session

§4 (No-persona mode):
- Remove default-persona policy paragraph (deployment concern)
- Reference persona-fallback as the mechanism that handles utterances
  in no-persona mode

§1 / See also:
- Add output transformation to "does not define"

§11 (Bus surface):
- Add fallback_pipeline_id dispatch row

§12 (Conformance):
- Add SHOULD include tags in list response
- Add MAY register fallback_pipeline_id
- Add deployment SHOULD rules for fallback positioning and designation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…data

ovos.persona.ask / ovos.persona.ask.response → ovos.persona.query /
ovos.persona.answer. The verb pair query/answer is unambiguous,
drops the .response suffix, and fits the established pattern for
data-exchange topics per AGENTS.md §4.5.

Also remove session_id from the ovos.persona.query request payload —
session context is read from context.session.session_id, never data.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@JarbasAl JarbasAl changed the title OVOS-PERSONA-1: Persona specification (v1 draft) OVOS-PERSONA-1: Persona Pipeline Plugin Specification May 28, 2026
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.

1 participant