Skip to content

spec: OVOS-TRANSFORM-1 — audio/intent IO contracts, error-handling state model, pre-entry cancellation - #143

Open
JarbasAl wants to merge 1 commit into
devfrom
spec/transformer-audit
Open

spec: OVOS-TRANSFORM-1 — audio/intent IO contracts, error-handling state model, pre-entry cancellation#143
JarbasAl wants to merge 1 commit into
devfrom
spec/transformer-audit

Conversation

@JarbasAl

@JarbasAl JarbasAl commented Aug 4, 2026

Copy link
Copy Markdown
Member

🤖 Auto-generated by Claude Fable 5 (claude-fable-5) via Claude Code — NOT human-reviewed. Verify before acting. Cross-spec citations were model-verified against dev source; behavior-change sections need owner judgment.

Audit fixes to transformer.md (OVOS-TRANSFORM-1 v2). Within-v2 refinement — no compatibility-class change, with one caveat noted below.

Critical — contracts that could not be satisfied as written

  • §3.1 audio IO is now a 4-tuple(chunk, lang, metadata, context). The chain had no context surface, yet §3.0 (lang threaded "alongside the artifact and Message.context"), §5 (per-session overrides live on session), §7.1 (audio transformers write session.detected_lang), §8.1 (cancellation keys are set in the returned context) and OVOS-AUDIO-IN-1 §4 all assumed one. The audio metadata object (per chunk) and Message.context (per capture) are now named as distinct surfaces with distinct lifetimes.
  • §3.4 intent transformers gain Message.context. §8.2 legislated intent-transformer cancellation but no channel existed to signal it — the Match carries no context keys. The context object is the carrier, and §3.4 now says so explicitly.
  • §7 drops "list shrunk to empty" from the shape-violation list. It contradicted §3.2's empty-list semantics and made the OVOS-PIPELINE-1 §6.2 non-cancellation branch unreachable. §3.2 is the single home for what an empty list means.

Error handling — what "returned its input unchanged" means

Every §3 artifact type permits in-place mutation, so the old wording was unimplementable: a transformer that raises half-way through has already changed the object the orchestrator holds.

  • §7 restates the rule as control flow, not state: discard the failing call's return value, continue with the artifact and context as they stand. Partial in-place mutation survives a raise and is not unwound.
  • An orchestrator MAY snapshot per call to provide stronger isolation. That is a conformant strategy, not an obligation, and transformers MUST NOT depend on either behaviour.
  • §3.4's identity-invariant safety net restated on the same footing: skill_id / intent_name are the only fields the orchestrator must restore.

Cancellation

  • §8.2.1 (new) — cancellation before lifecycle entry. The audio chain runs pre-STT, before ovos.utterance.handle. The §8.2 terminal pair is unsatisfiable there, and under a split orchestrator the emitting process is a different one. Pre-entry cancellation now suppresses the entry event, emits neither ovos.utterance.handled nor ovos.intent.unmatched, and MAY emit a standalone ovos.utterance.cancelled. The OVOS-PIPELINE-1 §9.5 invariant binds lifecycles that start; this one does not start.
  • §8.1 malformed signals. The no-strip rule and the malformed-signal rule were mutually exclusive once §7 lets partial mutation stand: a malformed canceled: true would survive into the next call and be attributed to the wrong transformer. No-strip is now scoped to valid signals, and the orchestrator MUST clear a malformed canceled / cancel_reason before continuing.
  • §8.1 step 2 chain-skipping scoped to the process that runs the chain; other processes are skipped as a consequence of not being handed the artifact.

Composition, ordering, introspection

  • §3.3 keeps the same-utterance session.pipeline claim and now grounds it: OVOS-PIPELINE-1 §6.1 composes the effective pipeline after the metadata chain, so the composition reads what this chain leaves behind. The asymmetry with the six §5 transformer-chain fields (composed at utterance start, effective next utterance) is stated explicitly, and "for this utterance" is struck from that bullet — §5.3 governs it.
  • §5.3 availability = loaded AND eligible at this hook. Under an explicit deployer order (§4), a session preference MUST NOT resurrect a transformer the deployer excluded.
  • §5.3 nested lifecycles compose their own six chains and start fresh <type>_transformer_ids stamp lists; nothing is deduplicated against the outer lifecycle.
  • §6 gains an OPTIONAL order array so a response can report an explicit deployer order — previously inexpressible. §1.3's example of a payload-subject transformer_id repointed to fields that actually exist (cancel_by, loaded / priorities / order).
  • §9 gains the missing §5.2 denylist MUST bullet, plus the pre-entry cancellation rules, the malformed-signal clearing rule, and order.

Editorial

  • §1.1 — MUST NOT appear more than once (was "MAY appear at most once"); the §3.4 permission to overwrite a transformer's own earlier slot entries is dropped, since one transformer cannot run twice in a chain.
  • Citations — transformer_id charset stated directly and cited to OVOS-MSG-1 §2.1.1; session.lang repointed to OVOS-SESSION-1 §3.2.1.
  • §4 — the v1→v2 priority-renumbering paragraph removed as migration residue; the CHANGELOG already records the flip.
  • §1.2 scope item renamed to the language signals §7.1 actually defines; "registration" → "introspection"; §2 diagram splits intent-context decay into its prune and decrement halves per OVOS-CONTEXT-1 §4 and shows the §6.1 compose step; §5 preamble counts all twelve session fields; the "any subset" rule stated once in §9 with a single pointer.

Cross-PR dependency

§3.3 is written as the intended contract and depends on the pipeline-1 PR. OVOS-PIPELINE-1 §6.1 currently composes the effective pipeline before the utterance and metadata chains, which would make §3.3's same-utterance session.pipeline claim false. The pipeline-1 PR moves the compose step to after the metadata chain. Per-utterance routing is the touted feature of the metadata hook and OVOS-CONVERSE-1 §3.3 relies on it, so the claim is kept here and the ordering is fixed there. Merge the pipeline-1 PR first, or this citation is forward-looking.

Versioning

Within-v2 refinement; no Version bump. The one judgement call is C1: adding Message.context to the audio IO tuple is arguably class-relevant, since a host passing the legacy 3-tuple cannot satisfy the new contract. It is recorded as a SHOULD-migrate in the CHANGELOG rather than a version bump, because a 3-tuple host was already unable to satisfy §7.1, §8.1 and OVOS-AUDIO-IN-1 §4 — the tuple change documents an obligation that already existed rather than creating a new one.

Not in scope here

GLOSSARY transformer entries, the session-1 owner-column asymmetry, and the converse.md §6 miscitation are fixed in their own PRs.

…ate model, pre-entry cancellation

Audit fixes to the Transformer Plugins specification.

IO contracts
- §3.1 audio IO becomes a 4-tuple (chunk, lang, metadata, context);
  audio metadata and Message.context named as distinct surfaces.
- §3.0 exempts the audio chain from data.lang writeback; its output
  lang goes to session.detected_lang for AUDIO-IN-1 §5.1.
- §3.4 intent IO gains Message.context — the cancellation carrier and
  the live session.intent_context as of post-engine mutation.

Error handling and cancellation
- §7 defines "returned its input unchanged" as control flow, not
  state; partial in-place mutation survives a raise; snapshotting is
  an optional stronger guarantee.
- §7 drops the "list shrunk to empty" shape violation (defers to §3.2).
- §8.2.1 (new) pre-entry audio-chain cancellation suppresses
  ovos.utterance.handle; no handled, no unmatched, MAY emit a
  standalone cancelled.
- §8.1 scopes the no-strip rule to valid signals and requires the
  orchestrator to clear a malformed canceled key.

Composition and introspection
- §3.3 grounds the same-utterance session.pipeline effect in
  PIPELINE-1 §6.1 compose-after-metadata; §5.3 governs the six chain
  fields ("for this utterance" struck).
- §5.3 availability = loaded AND eligible at this hook.
- §5.3 nested lifecycles compose own chains and fresh stamp lists.
- §6 adds the OPTIONAL order array; §1.3 example repointed.
- §9 gains the §5.2 denylist MUST bullet and the new rules above.

Editorial: §1.1 MUST NOT appear more than once; charset cited to
MSG-1 §2.1.1; session.lang to SESSION-1 §3.2.1; §4 renumbering
paragraph removed; §2 diagram splits decay per CONTEXT-1 §4; §5
preamble counts twelve fields; "any subset" deduped to §9.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Warning

Review limit reached

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

Next review available in: 41 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

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.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 78b4c815-1212-4d29-afee-54efb8c6cd9f

📥 Commits

Reviewing files that changed from the base of the PR and between 1d3622b and 1f0428e.

📒 Files selected for processing (2)
  • CHANGELOG.md
  • transformer.md

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.

@JarbasAl
JarbasAl marked this pull request as ready for review August 4, 2026 12:46
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