From dc7ce8c99396812e8ea3b3444ebb32068741e536 Mon Sep 17 00:00:00 2001 From: JarbasAi Date: Mon, 7 Sep 2026 18:11:26 +0100 Subject: [PATCH] =?UTF-8?q?spec:=20SESSION-2=20=C2=A73.3=20converges=20on?= =?UTF-8?q?=20each=20handled=20marker=20of=20a=20session?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit §3.3 said `ovos.utterance.handled` is emitted exactly once per utterance. PIPELINE-1 §6.5 makes that false for a round that opens a nested lifecycle: the inner and the outer lifecycle each end with a marker for the same `session_id`, and no field ranks them. §3.2 and §3.3 now say once per lifecycle. The client rule is order-independent, as §3.2 requires: a client that adopts at the marker MUST apply that adoption to every marker for its session and MUST NOT discard a second one as a duplicate, MUST NOT take arrival order as emission order, and whichever marker it holds when the round is over is a conformant snapshot. Adopting incrementally only stays conformant. The incremental pointer reads §3.2, where that rule lives. CHANGELOG entry under OVOS-SESSION-2, Version stays 1. Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 11 +++++++++++ session-2.md | 34 ++++++++++++++++++++++++++-------- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fdeb40b..a5efaa5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -387,6 +387,17 @@ version 2: its `{{ … }}` sequences become substitution points, and its ### 1 +- §3.2, §3.3 — `ovos.utterance.handled` is emitted once per + lifecycle, not once per utterance: a round that opens a nested + lifecycle (OVOS-PIPELINE-1 §6.5) produces an inner and an outer + marker for the same `session_id`, and nothing ranks one above the + other. A client that adopts at the marker **MUST** apply that + adoption to every marker for its session and **MUST NOT** discard a + second one as a duplicate. The rule is order-independent: a client + **MUST NOT** take the arrival order of two markers as their emission + order (§3.2), and whichever it holds when the round is over is a + conformant snapshot. No producer obligation changes, and no wire + change: the marker was already emitted per lifecycle. - The state-ownership model (stateless bus, stateless orchestrator for named sessions, orchestrator-owned default session), the mutation boundaries, convergence without push topics (§2.7), client-side diff --git a/session-2.md b/session-2.md index e2c320a..17adb08 100644 --- a/session-2.md +++ b/session-2.md @@ -411,8 +411,8 @@ does not define an ordering, and no client may assume one. It is instead **RECOMMENDED** that a client adopt at the universal end-marker `ovos.utterance.handled` (PIPELINE-1 §9.5), -which is emitted exactly once per utterance (§3.3) and so needs -no ordering to be unambiguous. +which is emitted exactly once per lifecycle (§3.3) and so needs +no ordering within that lifecycle to be unambiguous. **Adopt from what you render.** Independently of that convergence point, a client **adopts the session of any @@ -442,12 +442,30 @@ the round. ### 3.3 `ovos.utterance.handled` is the canonical convergence point -When a client wants a single canonical "round is over" snapshot, -the universal end-marker `ovos.utterance.handled` (PIPELINE-1 -§9.5) is the recommended adoption point: emitted exactly once per -utterance on every terminal path, carrying the assistant's final -session for the round. A client may also adopt incrementally per -§3.1, or combine both; all are conformant. +When a client wants a "round is over" snapshot, the universal +end-marker `ovos.utterance.handled` (PIPELINE-1 §9.5) is the +recommended adoption point: emitted once per lifecycle, and a +round that opens a nested lifecycle (PIPELINE-1 §6.5) produces +one for each — an inner marker for the nested lifecycle and an +outer marker for the round that opened it, both correlated by +the shared `session_id` and neither carrying any further field +that ranks one above the other. + +A client that adopts at `ovos.utterance.handled` **MUST** apply +that adoption to every marker it receives for its session: each +marker closes one lifecycle, and a second marker for the same +session is not a duplicate of the first and **MUST NOT** be +discarded as one. Each marker's session supersedes whatever the +client accumulated incrementally (§3.2) before that marker +arrived. Between the markers of one round this specification +ranks neither (§3.2, PIPELINE-1 §6.5): the bus guarantees no +delivery order, so a client **MUST NOT** take the order in which +two markers arrive as the order in which they were emitted, and +whichever marker's session it holds when the round is over is a +conformant snapshot. A client that adopts incrementally +**SHOULD** also adopt at every such marker. A client may also +adopt incrementally only, per §3.2, or combine both; all are +conformant. ---