Skip to content

SESSION-2: add ovos.session.sync and session mutation discipline#36

Merged
JarbasAl merged 8 commits into
devfrom
spec/session2-sync
May 27, 2026
Merged

SESSION-2: add ovos.session.sync and session mutation discipline#36
JarbasAl merged 8 commits into
devfrom
spec/session2-sync

Conversation

@JarbasAl

@JarbasAl JarbasAl commented May 27, 2026

Copy link
Copy Markdown
Member

Summary

  • §2.6: adds session mutation discipline rule — handlers SHOULD NOT mutate session fields unless the mutation is necessary for the handler's function or explicitly prescribed by another specification (e.g. STOP-1 §4.4)
  • §2.7 (new): defines ovos.session.sync — a dedicated broadcast topic for propagating session updates outside the normal utterance lifecycle. Components SHOULD use it when no in-utterance emission is available to carry the update. Orchestrator MUST merge it into the working session snapshot and reflect the result in the handler-lifecycle .complete and ovos.utterance.handled terminal events
  • §6.2: orchestrator conformance bullet for ovos.session.sync
  • §6.3: component SHOULD NOT mutate session gratuitously; SHOULD use ovos.session.sync for out-of-utterance propagation
  • §7 (new): bus topics table with ovos.session.sync
  • §8: renumber former §7 Non-goals; fix two pre-existing bugs (duplicate sentence in §2.3, stale PIPELINE-1 §5.2 cross-ref → §4.2)

Motivation

Several specs (STOP-1 §4.4, CONVERSE-1 §4.5) describe handlers opportunistically removing themselves from session lists (active_handlers, converse_handlers) without a defined mechanism for broadcasting that update when no other Message is being emitted. ovos.session.sync formalises this pattern and gives the orchestrator a clear obligation to honour it in terminal events.

Test plan

  • Verify ovos.session.sync shape: carries Message.context.session per MSG-1, session_id identifies the target session
  • Orchestrator merges sync before emitting .complete and .handled
  • Named-session clients observe sync and update local store
  • No gratuitous sync emissions from conformant handlers

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Revised session mutation rules with new discipline guidance to prevent unnecessary session field changes.
    • Added comprehensive out-of-utterance synchronization specification defining when and how session state is synchronized across components.
    • Enhanced conformance requirements for orchestrators and components with clearer session state management obligations.

Review Change Stack

JarbasAl and others added 3 commits May 27, 2026 19:34
…pline

- §2.6: add session mutation discipline rule — handlers SHOULD NOT
  mutate session unless necessary or prescribed by another spec;
  forward-ref §2.7 for out-of-utterance propagation
- §2.7 (new): define ovos.session.sync — explicit broadcast for
  session updates outside the utterance lifecycle; consumer
  obligations for orchestrator (MUST merge for default session) and
  clients (SHOULD merge for named sessions); SHOULD NOT emit
  gratuitously
- §6.2: orchestrator MUST merge ovos.session.sync for default session
- §6.3: component SHOULD NOT mutate session gratuitously; MUST use
  ovos.session.sync when out-of-utterance propagation is needed
- §7 (new): bus topics table with ovos.session.sync
- §8: renumber former §7 Non-goals; fix stale §5.2 cross-ref to §5.3

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ovos.session.sync must be merged into the working session snapshot
immediately on receipt; the merged state MUST be reflected in the
handler-lifecycle .complete and ovos.utterance.handled terminal events.
Remove the incorrect 'MUST NOT apply to in-flight utterance' rule —
the sync arrives at a handler boundary (§2.6) and must flow forward.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- §2.3: remove duplicate sentence
- §5.1: fix stale PIPELINE-1 §5.2 cross-ref → §4.2
- §2.7, §6.3: MUST → SHOULD for ovos.session.sync usage; emitting any
  session-carrying Message is also valid per §2.6

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

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@JarbasAl, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 41 minutes and 31 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9cb57b54-3162-4e71-9507-dc4b74409fed

📥 Commits

Reviewing files that changed from the base of the PR and between 53e8430 and f3934ac.

📒 Files selected for processing (4)
  • appendix/patterns.md
  • appendix/reference.md
  • ovos-pipeline-1.md
  • ovos-session-2.md
📝 Walkthrough

Walkthrough

OVOS-SESSION-2 is updated to formalize session mutation discipline and introduce ovos.session.sync, an out-of-utterance broadcast mechanism. Handlers are discouraged from mutating session fields unless necessary or prescribed; orchestrators must merge synced sessions using field-replacement semantics and update terminal events accordingly; conformance and bus topics are defined.

Changes

Session Mutation Discipline and Out-of-Utterance Synchronization

Layer / File(s) Summary
Scope and Session Mutation Discipline
ovos-session-2.md
Scope (§1) explicitly includes ovos.session.sync. Session mutation discipline (§2.6) discourages handler-driven in-place mutations unless necessary or explicitly prescribed, with prescribed mutations taking precedence.
Out-of-Utterance Sync Mechanism (§2.7)
ovos-session-2.md
New section defines ovos.session.sync broadcast emitted outside utterance lifecycle, carrying Message.context.session. Specifies field-replacement merge semantics for orchestrators and clients: present fields replace, absent fields unchanged. Orchestrators must update terminal events (.complete, ovos.utterance.handled) with merged state.
Conformance Updates and Bus Topics Definition
ovos-session-2.md
Section §6.2 orchestrator conformance mandates merging ovos.session.sync. Section §6.3 component conformance requires handlers follow mutation discipline and use ovos.session.sync for out-of-flow updates. New §7 defines the ovos.session.sync bus topic. Cross-references corrected; non-goals renumbered to §8.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • OpenVoiceOS/architecture#27: Both PRs are part of the same OVOS-SESSION-2 spec work and overlap on the core session lifecycle/state-ownership rules—especially constraining in-utterance session mutation and handling out-of-utterance sync/async updates with explicit merge semantics.

  • OpenVoiceOS/architecture#22: Both PRs define OVOS session semantics around Message.context.sessionOVOS-SESSION-1: Session carrier wire shape (draft) #22 standardizes the session wire fields (including active_handlers), while this PR updates how those fields must be mutated and merged across utterance boundaries via ovos.session.sync.

  • OpenVoiceOS/architecture#11: This PR's spec for ovos.session.sync merge semantics into the in-flight session and updating terminal events like ovos.utterance.handled is directly related to the retrieved PR's utterance lifecycle/pipeline spec that defines how session mutations are applied during lifecycle phases.

Poem

🐰 Hops through specs with cotton-tail cheer,
Session sync brings order so clear!
Field-replace, merge with delight,
No mutations in utterance flight!
Out-of-band broadcasts shine bright!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the two main additions to the SESSION-2 specification: the introduction of the ovos.session.sync broadcast mechanism and the session mutation discipline rule.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch spec/session2-sync

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 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 `@ovos-session-2.md`:
- Line 627: In the "Non-goals" paragraph referencing restart semantics, update
the incorrect section cross-reference: change the pointer from "§5.3" to "§5.2"
so that the mention of "restart-loss" correctly links to the section where
restart semantics are defined; locate the string "restart-loss" or the sentence
mentioning "§5.3" in the Non-goals text and replace the section number with
"§5.2".
- Around line 319-327: When an ovos.session.sync arrives for a named session_id
but there is no in-flight (transient) per-utterance session, add a normative
rule: the orchestrator MUST NOT apply the sync to the default-session store
(session_id == "default") and MUST enqueue the sync for that named session_id to
be merged into the next transient per-utterance working snapshot when it is
created; the orchestrator SHOULD also broadcast the received ovos.session.sync
to other components/consumers immediately for inspection, but only actually
merge into the working snapshot when the next in-flight utterance for that
session_id exists (FIFO ordering if multiple syncs arrive).
🪄 Autofix (Beta)

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: defaults

Review profile: CHILL

Plan: Pro

Run ID: a7cb1cdc-261e-427c-9983-d89ed36b9089

📥 Commits

Reviewing files that changed from the base of the PR and between 23ae502 and 53e8430.

📒 Files selected for processing (1)
  • ovos-session-2.md

Comment thread ovos-session-2.md Outdated
Comment on lines +319 to +327
- The **orchestrator** MUST merge a received
`ovos.session.sync` into its working session snapshot for
the affected `session_id`. The merge follows §5.1's
field-replacement rule: present fields in the synced
snapshot replace current values; absent fields leave current
values unchanged. For `session_id == "default"` the working
snapshot is the default-session store (§5); for named
sessions it is the transient per-utterance session in
progress (§2.2). The orchestrator MUST reflect the merged

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Define orchestrator behavior when ovos.session.sync arrives with no in-flight named-session utterance.

Current text says components MAY emit sync “at any time” (Line 301), and orchestrator MUST merge on receipt, but for named sessions the “working snapshot” is only the transient in-progress utterance snapshot. This leaves a normative gap for syncs received when no utterance is active for that session_id, and different implementations can diverge.

Please add an explicit rule (e.g., ignore-for-orchestrator-state but still broadcast-consumable, queue-until-next-utterance, or reject) to keep statelessness and conformance testable.

Also applies to: 537-541

🤖 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 `@ovos-session-2.md` around lines 319 - 327, When an ovos.session.sync arrives
for a named session_id but there is no in-flight (transient) per-utterance
session, add a normative rule: the orchestrator MUST NOT apply the sync to the
default-session store (session_id == "default") and MUST enqueue the sync for
that named session_id to be merged into the next transient per-utterance working
snapshot when it is created; the orchestrator SHOULD also broadcast the received
ovos.session.sync to other components/consumers immediately for inspection, but
only actually merge into the working snapshot when the next in-flight utterance
for that session_id exists (FIFO ordering if multiple syncs arrive).

Comment thread ovos-session-2.md
See §1 for the full list of non-goals. This section adds one
clarification: **default-session persistence across orchestrator
restart** is not defined here. §5.2 makes restart-loss
restart** is not defined here. §5.3 makes restart-loss

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix incorrect section cross-reference in Non-goals.

Line 627 points to §5.3 for restart-loss, but restart semantics are defined in §5.2. This should be updated to avoid implementer confusion.

🤖 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 `@ovos-session-2.md` at line 627, In the "Non-goals" paragraph referencing
restart semantics, update the incorrect section cross-reference: change the
pointer from "§5.3" to "§5.2" so that the mention of "restart-loss" correctly
links to the section where restart semantics are defined; locate the string
"restart-loss" or the sentence mentioning "§5.3" in the Non-goals text and
replace the section number with "§5.2".

JarbasAl and others added 5 commits May 27, 2026 19:55
ovos.session.sync carries the updated session in Message.data.session
(explicit payload); Message.context.session remains the ambient
routing carrier per MSG-1. Add data shape table. Update consumer
obligations to reference data.session explicitly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ensures routing metadata is preserved so the sync reaches remote
clients through layer-2 transports. Without .forward the message
carries no routing context and is invisible to satellite/gateway
clients.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Consistent with STOP-1 §4.2 and CONVERSE-1 §4.2 — all request/response
round-trips now explicitly name the MSG-1 derivation to ensure routing
metadata is preserved through layer-2 transports.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New section between the single-flip routing model (§3.1.1) and no-
central-correlation (now §3.1.3): explains when to use .forward
(same direction as the source dispatch) vs .reply (back toward the
requester), why the distinction matters for layer-2 transports, and
a cross-spec table showing consistent application across all five
relevant emissions.

Renumber former §3.1.2/§3.1.3 to §3.1.3/§3.1.4; update intro and
cross-refs accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Cross-spec table of every normative .forward / .reply usage with the
decision rule. Companion to patterns.md §3.1.2 narrative.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@JarbasAl JarbasAl merged commit cec6c7d into dev May 27, 2026
1 check was pending
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