Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions APPENDIX.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ The appendix content has been split into topic-specific files:
| [appendix/divergences.md](appendix/divergences.md) | §5 | Where the specs differ from current OVOS code — divergences, renames, topic mapping |
| [appendix/reference.md](appendix/reference.md) | §6 | Implementer reference — session-field cheat-sheet, stamp rules, introspection patterns |
| [appendix/gaps.md](appendix/gaps.md) | §7 | Known gaps and planned work — deferred specs, tooling, corpora |
| [appendix/persona-flow.md](appendix/persona-flow.md) | §8 | Persona lifecycle — annotated bus sequences for summon, conversation, dismiss, and out-of-band query |
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ status quo, `2` once it is not backwards compatible. Entries are grouped under
the spec's current class. Every pull request that alters normative content adds
an entry here.

## OVOS-PERSONA-1 — Persona Pipeline Plugin

### 2

- Initial draft. Defines persona as a scoped match+handler layer with
its own pipeline position, `persona_id` session field, summon and
dismiss bus messages, match contract (MAY return `None` for pass-
through), handler contract, no-persona mode, multiple-persona
coexistence rules, `fallback_pipeline_id` for escalation, dialog-
transformer compatibility, capability-discovery via
`ovos.persona.capabilities`, and conformance roles (Persona Plugin,
Orchestrator, Skill).
## OVOS-CONTEXT-1 — Intent Context

### 2
Expand Down
144 changes: 144 additions & 0 deletions appendix/persona-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
---
[← APPENDIX.md](../APPENDIX.md) · Non-normative

> **⚠️ AI-generated draft — not yet fully reviewed.** This content
> was produced by a large language model (Claude Code) and
> has not yet been fully reviewed for accuracy, completeness, or
> consistency with the specifications. The normative specifications
> themselves are human-reviewed; this appendix is supplementary
> context. Readers should verify claims before relying on them.

# Persona lifecycle — annotated bus sequences

This section shows the full observable bus sequence for the three
main persona lifecycle events: summon, a two-turn conversation, and
dismiss. All events are on the shared messagebus unless noted.
Session state changes are shown inline.

---

## Summon via utterance ("hey alice")

```
ovos.utterance.handle [utterances=["hey alice"], session={persona_id: absent}]
├─ pipeline: stop_high → None
├─ pipeline: converse → None (no active handler)
├─ pipeline: skill_high → None
├─ pipeline: persona → Match (route 1: embedded summon command detected)
│ Match.updated_session = {persona_id: "alice"}
ovos.intent.matched
<pipeline_id>:persona [dispatch; session now has persona_id="alice"]
ovos.intent.handler.start
ovos.utterance.speak ["Sure, I'm Alice. How can I help?"]
ovos.persona.activated [persona_id="alice", session_id="..."]
ovos.intent.handler.complete
ovos.utterance.handled
```

Session state after: `{persona_id: "alice"}` — carried on all
subsequent utterances in this session.

---

## Active-persona conversation turn

```
ovos.utterance.handle [utterances=["what's the weather?"], session={persona_id: "alice"}]
├─ pipeline: stop_high → None
├─ pipeline: converse → None (no active response-mode)
├─ pipeline: skill_high → None (or may match — skills run first)
├─ pipeline: persona → Match (route 2: persona_id="alice" supported)
ovos.intent.matched
<pipeline_id>:persona [dispatch]
ovos.intent.handler.start
ovos.utterance.speak ["It's 18 degrees and sunny."]
ovos.intent.handler.complete
ovos.utterance.handled
```

---

## Multi-turn (persona asks a follow-up question)

```
ovos.utterance.handle [utterances=["tell me a story"], session={persona_id: "alice"}]
├─ pipeline: persona → Match (route 2)
<pipeline_id>:persona
ovos.intent.handler.start
ovos.utterance.speak ["What kind of story? (listen: true)"]
← listen:true re-opens mic after TTS
[handler sets session.response_mode = {skill_id: pipeline_id, expires_at: ...}]
ovos.intent.handler.complete
ovos.utterance.handled

[user speaks reply]

ovos.utterance.handle [utterances=["a dragon story"], session={persona_id: "alice", response_mode: {...}}]
├─ pipeline: converse → Match (response_mode held by persona plugin)
│ dispatches <pipeline_id>:response
<pipeline_id>:response
ovos.intent.handler.start
ovos.utterance.speak ["Once upon a time, a dragon..."]
[handler clears session.response_mode]
ovos.intent.handler.complete
ovos.utterance.handled
```

---

## Dismiss via self-release ("goodbye alice")

```
ovos.utterance.handle [utterances=["goodbye alice"], session={persona_id: "alice"}]
├─ pipeline: persona → Match (route 1: release command detected)
│ Match.updated_session = {persona_id: absent}
<pipeline_id>:persona
ovos.intent.handler.start
ovos.utterance.speak ["Goodbye! Switching back to normal mode."]
ovos.persona.dismissed [persona_id="alice", session_id="..."]
ovos.intent.handler.complete
ovos.utterance.handled
```

Session state after: `{persona_id: absent}` — no-persona mode
resumes. The next utterance goes through the full deterministic
pipeline.

---

## Dismiss via stop cascade

This is deployment-specific. A deployment that wires stop to clear
`persona_id` typically does so in its stop pipeline plugin's
cascade step, setting `persona_id` to absent in the session before
or after emitting the stop dispatch. The persona plugin then detects
the cleared field on the next utterance (if any) and emits
`ovos.persona.dismissed`. There is no dedicated stop↔persona bus
event; the session field change is the signal.

---

## Out-of-band query (skill asks persona directly)

```
ovos.persona.ask [persona_id="alice", utterance="summarise X", source=<skill>]
├─ persona plugin (supports "alice") receives it
│ generates reply internally
ovos.persona.ask.response [persona_id="alice", utterance="summarise X", response="..."]
routed via reply() back to <skill>
```

No pipeline interaction, no `ovos.utterance.handle`, no
handler-lifecycle trio. Session state is unchanged.
Loading