Vac is the goddess who is speech itself — the voice, the word, and the message that passes between — and in Egbe she names the layer where a steward and an autonomous being actually talk. Every other game in this universe hands you a verb wheel or a dialogue tree; V6 hands you a microphone and a person on the other end of it. You say "ask Abeni to repair the garden gate by tomorrow, without lying to visitors, and keep it gentle," and an Ori — a durable mind with its own values, memory, and fate — hears you, understands you at the level of an objective, and answers in its own voice. The answer is not guaranteed to be "yes." It might be a question, a counter-offer, a request to finish something first, or a flat, reasoned refusal. That two-way channel, where guidance flows down and a being with standing pushes back, is the whole game; Vac is the part that makes the exchange trustworthy in both directions.
The load-bearing promise is one sentence: a misheard word never becomes a misunderstood life. A player speaks freely, but speech is never executed. Vac parses what you said into a structured, inspectable objective — verb, target, constraints, priority, deadline, and the forbidden lines the agent must not cross — and shows it back to you as a draft you confirm or correct before it can bind. Underneath, three things are happening at once: voice is turned into intent, the intent is offered to a mind that may negotiate it, and a spoken, lip-synced reply comes back — all on a hard latency budget, and all with a complete non-voice equivalent so a player who cannot or will not use a microphone loses nothing. This page is the player-facing tour of that conversation: how you speak, how an agent understands and answers, and where the honest seams are. For the engine-level treatment see the architecture companion, The Vac Communication Pipeline; for the scope this slots into, start at the hub, ../V6_features.md.
What ships, honestly#
Following the catalogue convention, the line between real-and-tested code and product-model-over-a-thinner-substrate is drawn up front.
- The intent pipeline is a real, dual-authored engine. The TypeScript canon
is
@oshun/vac-intent(libs/v6/vac-intent/src/index.ts, ~1,750 lines, 11 unit tests): a five-stage voice→intent pipeline (runVacVoiceIntentPipeline,:830), a strict constrained-function-calling grammar with a full domain validator (buildVacIntentGrammarFunctionSchema,:598;validateVacObjectiveIntent,:623), a natural-language objective parser, the steward-confirmation gate, and the agent-side negotiation router (routeVacNegotiation,:860) — all pure functions. The C++ mirror isV6Voice(V6/ue/Source/V6Voice):FV6VacVoiceIntentPipelineRuntimere-implements the same five stages engine-side, andFV6SquadCommsRuntimeowns the squad channel. Both are covered by real UE5.5 automation —V6.Vac.VoiceIntentPipeline.MicGatewayAsrParserBudget,V6.Vac.ConversationRouting.PsycheTtsLipSyncBudget, and theV6VacSquadCommsTestsrealm-parity scenario. - The objective is a shared contract. A parsed objective is the
v6.ori.objective.1shape, validated in the tests against the sharedObjectiveSchemafrom@oshun/contracts, so the same structure round-trips between the Mind-layer TypeScript, the contract package, and the engine structFV6VacStructuredObjective. - The voice and language seams are injected, and the code says so. Three
boundaries are deliberately not implemented inside Vac, and they fail loud or
report absence rather than fake a result. (1) ASR is the one-method
VacAsrAdapterinterface (:266); with no recognizer wired,transcribeVacGatewayPacket(:736) returns a deterministic echo of the utterance at a fixed0.94confidence — a wiring/test stand-in, explicitly not a speech recognizer. (2) The conversation model and TTS are the@oshun/psyche-agentgateway (providerv6-local-tts); the model that authors free dialogue is the injectedCognitionGateway, which fails loud on a gateway error and is never silently templated. (3) The transport is the Rust Egbe Realtime Gateway; Vac owns the gateway packet shape and the fixed routeegbe-vac:voice-intent, not the deployed SFU. - Honest scope limits. The per-stage latency numbers Vac measures against
the 400 ms budget are a deterministic budget model
(
VAC_DEFAULT_STAGE_LATENCIES_MS,:24), not a live network capture. And nothing in this layer is.uassetcontent — it is all logic and contract.
The communication experience — three ways to speak#
Voice is the primary, intended way a steward talks with their agents, and Vac gives the player three distinct things to do with it. Converse is open dialogue with one agent, routed through Psyche in real time with the agent's full Ori as context — the kind of talk that builds a relationship rather than issuing an order. Direct is speaking an objective in natural language; Vac parses it into the intent grammar and hands the parse back for confirmation. Call is addressing one agent or the whole squad over the comms channel, hands-free.
Two capture modes are supported and the player chooses: push-to-talk (the
default — captureVacMicrophoneFrame sets pushToTalk: true, :697) and
open-mic with a wake word. Capture normalizes a raw input into a typed frame: it
sanitizes the session and device identifiers, collapses whitespace, and clamps
the audio metadata to supported bounds (1–30 s duration, 8–96 kHz, 1–2
channels), defaulting to 48 kHz mono. The engine twin,
FV6VacMicrophoneCaptureFrame::Validate (V6VoiceIntentTypes.cpp:512), is the
fail-loud check: it rejects a frame with no session or device identity, an empty
utterance, or a capture that has not reached end-of-utterance.
The budgets are part of the felt experience. A parsed acknowledgement — the
moment the draft objective appears for confirmation — is held to ≤ 400 ms; a
spoken conversational reply is held to ≤ 1 s. Both numbers are encoded,
not aspirational: VAC_PARSED_INTENT_ACK_BUDGET_MS = 400 and the psyche-agent
PSYCHE_SPOKEN_REPLY_BUDGET_MS = 1_000. Crucially, a slow turn is reported
honestly as budget-exceeded rather than quietly promoted to success (more on
that below).
From a spoken sentence to a confirmable objective#
A "Direct" command runs an ordered, five-stage pipeline. Each stage is a pure function over the previous stage's typed frame, so the whole path is testable end-to-end with the real recognizer wired only at the boundary. The diagram below is the experience as the player lives it — speak (or type), watch a draft appear, confirm it, and hear the agent answer.
The intent grammar — six fields, and no boundaryless objective#
A high-level objective is never free text the agent guesses at. Vac parses it
into a structured, inspectable intent with exactly six fields: a verb
(one of eight authored kinds), a target (what or whom), constraints
(bounds on how), a priority (0–100), a deadline (or none), and
forbidden lines (what the agent must not do in pursuit of it). Vac never
lets a model emit free-form JSON for this: buildVacIntentGrammarFunctionSchema
publishes a single strict function schema (vac_parse_objective_intent) with
strict: true and additionalProperties: false at every level. The grammar is
opinionated where it matters — target kinds and constraint kinds are closed
enums, priority is a bounded integer, and forbiddenLines carries
minItems: 1. An objective with no boundary is structurally
unrepresentable. The same release gate caps a parse at
maxTokensPerParse: 2000.
Parsing — domain extractors, not a relabel#
The parser (parseVacTranscriptToObjective, :755) is a cascade of
domain-specific extractors. It strips the addressing frame ("ask / tell / have /
direct / get Abeni to…"), matches one of eight verbs by token set
(verbDefinitions, :547 — Repair, Map, Investigate, Protect, Build, Support,
Befriend, Report), slices the target before the first modifier so boundaries
don't leak into it, lifts a deadline ("by tomorrow," "this week," or a literal
ISO date), and maps urgency words to priority tiers (urgent → 90, important →
78, default 55, low/background → 25). The safety-critical extractor is
buildForbiddenLines (:1479): it scans for without / do not / don't /
never / avoid, normalizes the captured phrase, and maps it to a protected
value — "lie/deceive/mislead" → value:honesty, "private/secret/consent" →
value:privacy, "harm/unsafe/danger" → value:safety — and when the player
marks no boundary at all, it still injects a default
forbidden-line:respect-agent-autonomy so the agent's own refusals stay
binding. The end-to-end test parses "Ask Abeni to repair the garden gate by
tomorrow, without lying to visitors and keep it gentle" to verb Repair,
target kind prop / "Garden gate", a 2026-05-02 deadline, constraints
[time, pace], and a value:honesty forbidden line — and the C++ parser
reproduces the same shape for its own scenario, the proof the two authorings
agree.
If the recognizer's confidence is below the 0.7 floor, or no command verb
resolves, the parser returns nothing and the pipeline reports
needs-clarification rather than a confident wrong objective — a
0.41-confidence transcript and an off-topic "maybe the weather is nice" both
refuse to produce one.
The steward-confirmation gate — a draft, never a command#
A parsed objective is born a draft. Its status is 'draft',
confirmedBySteward and acceptedByAgent are false, and it ships with a
preview whose canBecomeStandingObjective is the literal false. It can only
become a standing objective after confirmVacParsedObjective (:684) flips
both the confirmation flag and the status —
canVacObjectiveBecomeStandingObjective (:680) gates on exactly that. Even an
explicit "always protect the grove path" stays a draft until the steward acts.
The engine enforces the same wall in reverse:
FV6VacStructuredObjective::IsSchemaReadyForDraft
(V6VoiceIntentTypes.cpp:565) rejects any objective that arrives with
bConfirmedBySteward or bAcceptedByAgent already set — a pre-confirmed intent
is treated as malformed. This is "a misheard word never becomes a misunderstood
life" written as a state machine, and it is rendered for the player in the V6UI
intent-grammar builder, where the verb, target, constraints, deadline, and
forbidden lines are all editable before anything binds.
How an agent understands and replies#
Conversation — Psyche, voice, and lip-sync#
Free conversational turns (as opposed to objective commands) route to the
@oshun/psyche-agent runtime. routePsycheConversationTurn (index.ts:376)
assembles a real spoken reply: a PsycheAgentTtsPlan (provider v6-local-tts,
Opus codec, 48 kHz mono), a viseme PsycheLipSyncTrack bound to the agent pawn,
and a latency budget. A turn whose context is hollow is refused, not faked —
assertConversationRouteRequest throws on a malformed request, and the engine
twin (V6Audio's FV6ConversationAudioRuntime, exercised by
V6.Vac.ConversationRouting.PsycheTtsLipSyncBudget) returns an InvalidContext
failure when an Ori context is missing its memory references. So an agent cannot
speak from an empty head. The words themselves come from the governed
CognitionGateway seam, which fails loud on an error rather than substituting a
template; Vac and Psyche own the routing, the budgets, and the lip-sync
contract, while the language model is injected behind them.
Speaking in the player's language#
Agents answer in the player's locale, and V6 is deliberately strict about how.
The @oshun/cognition-stack (libs/v6/cognition-stack/src/index.ts) carries
three locale profiles — English (en-US), Spanish (es-ES), and Yoruba
(yo-NG) — and a hard rule it advertises as a capability:
translation-fallback-disabled. V6 never machine-translates a line.
Dialogue is either generated natively in the target language by a wired model
(generateLocalizedAgentDialogueViaGateway, with provenance and a model run id)
or it falls back to a governed, deterministic per-locale template that is
reported honestly: generatedNatively: false, source: 'template-fallback'.
The code will not claim native generation over a static string. A native line
still passes its locale's Sophia grounding and Isis policy checks, and a §9.5
dialogue quality verdict of 'blocked' withholds the line (approved: false)
even if grounding and policy would otherwise clear it. Quality is a gate, not a
suggestion.
Negotiation — the reply is not "yes"#
Because an Ori is an agent and not a tool, a confirmed objective is offered,
not imposed. routeVacNegotiation (:860) returns one of five decisions, each
a computed result carrying a player-facing reply, the agent's reason, and an
evidence list:
- Accept — and plan it.
- Clarify — ask a question when the target or boundary is ambiguous.
- Counter-offer — propose a safer variant (e.g. a late-night task at low energy becomes "start after rest at 09:00, check in before pushing further," with the priority lowered).
- Defer — accept in principle but ask to finish stacked commitments or recover energy first.
- Refuse — decline, grounded in a value the agent actually holds.
The decisions are domain logic, not dice. detectObjectiveValueConflict
(:1028) refuses only when the objective text trips one of four value rules —
honesty, privacy, safety, autonomy — and the agent genuinely ranks that value
at priority ≥ 50. Tether mode tightens guidance on method but never removes
the will: an order to cross a core value is still refused. And coercion is a
first-class, logged event. When a steward pushes past a prior refusal, the
router returns refuse and emits a VacNegotiationOriEventDraft of type
ObjectiveRefused, stamped with the audit tags
['vac-negotiation', 'coercion', 'objective-refusal'] and written to the Ori
and the audit log — the test pins the refusal, the value:honesty evidence, and
the event draft, so pressure cannot fabricate a yes. Coercion damages the
Respect bond, lowers steward reputation, and contributes to departure and
welfare review; the consequences live on the
stewardship and
fate pages.
Squad comms — a household on one channel#
When several agents work related objectives — at home in Orun or incarnated
together on an Aye expedition — Vac runs a persistent group channel,
FV6SquadCommsRuntime. It routes five message kinds, and the behavior is
honestly domain-shaped rather than uniform plumbing:
- Status reports — unprompted, in-character progress, blockers, and discoveries.
- Callouts — time-sensitive information ("someone's following me"); marked
bTimeSensitive. - Permission requests — an agent hitting a forbidden line or value-edge asks
the steward first;
bTimeSensitiveandbRequiresStewardResponse. - Inter-agent banter — agents talking to each other, so relationships
surface in how they speak;
bDuckableand throttled by a 45 s window (BanterThrottleWindowMs = 45000) so chatter never buries a real callout. - Directed orders — the steward addresses one agent or the whole squad; squad-wide orders are distributed as per-agent intents each agent interprets in its own role.
The load-bearing guarantee is realm parity: CompareRealmParity runs the
same script in Orun and during an Aye incarnation and asserts the routed message
shapes match exactly, and BuildParityScenario is what the
V6VacSquadCommsTests automation drives to zero mismatches. Comms behave
identically whether the squad is at home or fighting for its life in a tactical
world.
Non-voice parity and the readiness gate#
Every voice capability has full non-voice parity, and this is a release
requirement, not a courtesy. The intent grammar is authorable through a
structured UI (verb picker, target picker, constraint and deadline fields);
conversation is available as text chat that enters the pipeline at the parse
stage; squad comms render as a readable, speaker-tagged, timestamped transcript.
The whole layer is gated by verify:v6 vac-communication-readiness (backed by
V6/release/vac-communication-readiness.v6release.json), whose green status
depends on a fan-out of verifiers covering voice intent, the intent grammar,
conversation routing, squad comms, negotiation routing, non-voice parity, a
no-microphone accessibility manifest, and the latency budgets. A player who
never touches a microphone can steward a full household; voice is the intended
path, not a required one.
Where this connects#
- Stewardship: the player's role — the verbs every objective and refusal on this page serves: discover, raise, direct, mentor, open doors, and counsel, all terminating at the same hard floor.
- Guiding fate, legacy, and story — what a
conversation becomes: the goal-arcs you set by voice, and the Chronicle that
reads back the
ObjectiveRefusedand coercion events Vac writes to the Ori. - The engine companion: The Vac Communication Pipeline — the deep, line-cited treatment of the five stages, the injected ASR/TTS/LLM seams, the negotiation router, and squad-comms realm parity.
- The feature hub: ../V6_features.md.