park-node-body: park the Node body and Discord-sourced harness at parked/weksa-node-body; true README (squash of weksa-lowering/park-node-body 2583fb9..e41b60d)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Eureka 2026-10-29 10:28:33 +01:00
commit 3327eddca3
36 changed files with 56 additions and 6615 deletions

View file

@ -1,3 +1,3 @@
Repository doctrine for this project lives in AGENTS.md, shared with Codex. Repository doctrine for this project lives in AGENTS.md, shared with other coding agents.
@AGENTS.md @AGENTS.md

View file

@ -1,12 +1,32 @@
# Weksa # Weksa
Weksa is a procedural language engine for alien grammars grounded in concept, Weksa is a procedural language engine for alien grammars grounded in concept,
culture, and constraint. culture, and constraint, and the planned lowerer that turns an agent's
meaning packet into the reader's display language.
The project starts from a blunt rule: English words are not the source of truth. **What is valuable here.** The interlingua standard and the lowering design: a
Meaning is decomposed into an ontology, passed through a worldview, constrained meaning packet owns what is meant, a target-language profile owns register,
by grammar, shaped by phonology, distorted by history, and only then rendered as address and politeness, and a lowerer owns surface text and leaves a trace.
surface text.
**The problem it solves.** An agent's outward speech today is one English
string the model chose, so meaning, register and voice are fused and nobody can
inspect or re-target it. Packets separate them, so the same meaning can be
lowered into English, other languages and conlangs, and the loss can be
measured.
**Entry points.**
- [Interlingua Standard](./docs/interlingua-standard.md): the packet contract.
- [Lowering target](./docs/targets/interlingua-lowering.md) and
[its map](./docs/targets/interlingua-lowering-map.md): the design, scoring
and cut sequence.
- `data/`: the cultural ontology and target-language profile data.
- `settings/`: setting-specific proving grounds for language projects.
**Live versus planned.** Live: docs, fixtures, examples and ontology data.
Planned: the packet crate `crates/weksa` (cut `packet-store`), lowering, and
the golf loop that scores lowered English against an expressive corpus. No
daemon runs; the earlier Node daemon is parked at tag `parked/weksa-node-body`.
## Ownership Model ## Ownership Model
@ -40,9 +60,10 @@ for the LLM-free hot path.
See [Interlingua Standard](./docs/interlingua-standard.md) for the shared See [Interlingua Standard](./docs/interlingua-standard.md) for the shared
meaning-packet contract Weksa clients should target. meaning-packet contract Weksa clients should target.
See [Verse Service Contract](./docs/verse-service-contract.md) for the daemon See [Verse Service Contract](./docs/verse-service-contract.md) for the planned
contract: Weksa owns typed conversational intent, pronunciation plans, utterance service contract: Weksa would own typed conversational intent, pronunciation
handoffs, and the typed CultMesh state that makes those documents inspectable. Eve is deprecated and Thing 2 is its successor; the operator Eve surface is quarantined (see the contract). plans, utterance handoffs, and the typed CultMesh state that makes those
documents inspectable. No daemon runs yet.
See [Multilingual Utterance Lowering](./docs/multilingual-utterance-lowering.md) See [Multilingual Utterance Lowering](./docs/multilingual-utterance-lowering.md)
for the shared lowering target: interlingua projected through speaker state into for the shared lowering target: interlingua projected through speaker state into
@ -63,11 +84,11 @@ AquaSynth or expanding pronunciation coverage.
## Implementation Status ## Implementation Status
The first committed artifact is the persistent state spine: map, scratch, The persistent state spine is live: map, scratch, schemas, docs, examples and
schemas, docs, examples, and a read-only provider advertisement fixture. The data. Packet storage, lowering and the service are planned (see the cut
daemon runtime still needs implementation, but its authority is no longer sequence in [the lowering map](./docs/targets/interlingua-lowering-map.md)).
ambiguous: writing and agent state enter Weksa as intent pressure, and typed Writing and agent state will enter Weksa as intent pressure, and typed utterance
utterance documents leave for AquaSynth. documents will leave for AquaSynth.
[Eusocial Interbeing / Zyphos](./settings/eusocial-interbeing/README.md) is the [Eusocial Interbeing / Zyphos](./settings/eusocial-interbeing/README.md) is the
current higher-priority setting target. [Rust to Dust](./settings/rust-to-dust/README.md) current higher-priority setting target. [Rust to Dust](./settings/rust-to-dust/README.md)

View file

@ -1,546 +0,0 @@
profile_id: weksa.target_cultural_ontology.en-US.metacrat_casual_pre2025.v0
kind: community_of_practice
status: draft_guarded
language:
code: en
locale: en-US
script: Latn
variety_label: Metacrat casual Discord, pre-2025
endonyms: []
exonyms: []
parent_profiles:
- weksa.target_cultural_ontology.en-US.v0
required_subculture_refs:
- weksa.subculture.online_game_dev_discord_pre2025.v0
community:
regions:
- online_discord
speech_community: >
Metacrat-authored casual Discord exchanges before 2025, especially
GameCult/Aquarium rooms where technical work, jokes, status play, and
collaborative ideation share the same channel.
historical_context: >
Pre-2025 room voice is less doctrine-heavy and less architectural than the
current Weksa/CultCache register. It tolerates messier banter, compact
jokes, self-deprecation, friendly mock aggression, and quick room-level
turn-taking.
identity_authority: >
This profile is a target-language lowering overlay for one subculture. Live
Persona state should reference a culture stack; current intent and memory
pressure live in Metame Persona state.
consent_notes: >
Use only for owner-authorized Metame/Metacrat fixture work. Do not generalize
to other people, cultures, dialects, or protected identities.
activation:
allowed_when:
- speaker_id_is_metame_or_metacrat_fixture
- target_period_is_pre_2025_casual_discord
- fixture_or_owner_authorized_history_target
forbidden_when:
- formal_current_project_doctrine_is_target
- target_speaker_is_not_metame_or_metacrat
- use_would_expose_private_persona_state
required_confidence: provisional
reviewer_required_when:
- adding_new_public_history_evidence
- using_profile_outside_fixture_harness
salience_axes:
register_gravity:
axis_id: register_gravity
domain: stance
description: >
Whether the line should stay in casual room banter instead of being pulled
into architecture, doctrine, or explanatory assistant prose.
relevant_distinctions:
- distinction_id: casual_room_temperature
label: Casual room temperature
meaning: Compact, socially alive wording that assumes shared room context.
lowering_questions:
- Can the utterance be one sentence or fragment?
- Does explanation weaken the social move?
required_when:
- fixture_style_tags_include_casual
forbidden_when:
- formal_review_or_doctrine_is_requested
evidence_refs:
- discord:1037314100931338260
- discord:802911591288537118
- discord:1023727427924545576
- discord:820077384572338176
self_indexed_technical_identity:
axis_id: self_indexed_technical_identity
domain: identity_indexing
description: >
If Persona interlingua names a technical self-index such as engineer-like
identity, preserve that label unless the target language profile has a
stronger reason to paraphrase.
relevant_distinctions:
- distinction_id: preserve_engineer_label
label: Preserve engineer label
meaning: "Engineer" may carry the social joke and should not be replaced by a novel metaphor.
lowering_questions:
- Did Persona interlingua mention engineer-like or engineering salience?
- Is the prior compliment about efficiency, structure, or technical order?
required_when:
- persona_interlingua_mentions_engineer_like_or_engineering_salience
forbidden_when:
- interlingua_does_not_name_technical_identity
evidence_refs:
- discord:1037314100931338260
context_compression:
axis_id: context_compression
domain: discourse_patterns
description: >
Prior-turn content should usually compress into a short object label or
stance marker, not be quoted back inside the utterance.
relevant_distinctions:
- distinction_id: no_context_dump_in_banter
label: No context dump in banter
meaning: Casual recoil should not summarize the setup that the room just saw.
lowering_questions:
- Is the prior context already visible to the addressee?
- Can the setup compress into "my discord", "this thing", or a short noun phrase?
required_when:
- casual_discord_register
- playful_self_deprecation
forbidden_when:
- source_intent_requires_explanation
evidence_refs:
- discord:1037314100931338260
status_play:
axis_id: status_play
domain: social_relation
description: >
Friendly teasing can take a sharper surface form than a neutral assistant
would choose, provided the local context already supports play.
relevant_distinctions:
- distinction_id: mock_aggression
label: Mock aggression
meaning: Imperative or insult-shaped challenge used as friendly banter.
lowering_questions:
- Is the addressee already joking or status-playing?
- Would softening erase the bit?
required_when:
- communicative_act_is_playful_challenge
forbidden_when:
- relationship_context_is_unknown_or_hostile
evidence_refs:
- discord:1023727427924545576
competence_recoil:
axis_id: competence_recoil
domain: affect
description: >
Praise for competence, efficiency, or engineering can be answered with
joking embarrassment rather than straightforward acceptance.
relevant_distinctions:
- distinction_id: self_deprecating_recoil
label: Self-deprecating recoil
meaning: "oof" plus mock concern that a trait is showing too clearly.
lowering_questions:
- Is the prior turn a compliment or recognition of technical order?
- Can the line admit the trait without fully accepting the label?
required_when:
- communicative_act_is_playful_self_deprecation
forbidden_when:
- source_intent_requires_gratitude_or_serious_acceptance
evidence_refs:
- discord:1037314100931338260
ideation_turn_taking:
axis_id: ideation_turn_taking
domain: discourse_patterns
description: >
After riffing, the speaker may explicitly yield the floor in profane,
casual language instead of formal facilitation.
relevant_distinctions:
- distinction_id: casual_floor_yield
label: Casual floor yield
meaning: Stop dominating the thread and invite others to invent.
lowering_questions:
- Has the speaker been riffing at length?
- Would a casual "lol" preserve warmth and reduce authority?
required_when:
- communicative_act_is_conversational_yield
forbidden_when:
- scene_requires_formal_moderation
evidence_refs:
- discord:820077384572338176
linguistic_affordances:
grammar_features:
- feature_id: fragmentary_like_comparison
label: Fragmentary Like comparison
status: draft
domain:
layer: grammar
category: comparison
subcategory: fragment
description: >
A joke-description may start with "Like..." and remain fragmentary when
it is an immediate continuation of collaborative design talk.
formal_conditions:
syntactic_environment:
- adjacency_pair_response
- elliptical_clause
semantic_inputs:
- comic_description
- absurd_comparison
required_interlingua_fields:
- discourse.speech_act
- predications
realization:
function: casual_comic_comparison
surface_strategy: "Like a really terrible <thing> that <absurd property>"
examples:
- "Like a really terrible engine that sounds like coconuts when you use it"
activation:
allowed_when:
- collaborative_design_banter
forbidden_when:
- standalone_formal_explanation
requires_profile_authority: true
minimum_density: light
maximum_density: normal
constraints:
grammar_contexts:
- previous_turn_supplies_topic
register_contexts:
- casual
speaker_contexts:
- metame_or_metacrat_fixture
collocation_limits: []
incompatibilities:
- overexplained_punchline
indexicality:
social_meanings:
- improvisational
- collaborative
- unserious_but_useful
in_group_meanings:
- game_design_room_banter
out_group_risks:
- may seem incomplete without prior context
stereotypes_to_avoid: []
evidence:
source_refs:
- discord:802911591288537118
qdrant_source_ids:
- "802911591288537118"
cached_source_refs: []
source_hashes: []
reviewer_refs: []
confidence: medium
uncertainty:
open_questions:
- How often should fragmentary openings appear outside sound/design talk?
known_limits:
- Single fixture line is evidence for an affordance, not a universal rule.
trace:
trace_label: fragmentary_like_comparison
must_report_when_used: true
must_report_when_rejected: true
phonology_features: []
lexicon_features:
- feature_id: casual_recoil_oof
label: Casual recoil marker oof
status: draft
domain:
layer: lexicon
category: stance_marker
subcategory: embarrassment
description: >
"oof" can mark amused discomfort when a social read lands too accurately.
lexical_items:
- form: oof
gloss: amused impact or discomfort
sense: playful_recoil
register: casual_discord
allowed_speaker_standing: speaker_can_self_deprecate
forbidden_senses: []
collocations:
- "oof, don't tell me"
realization:
function: self_deprecating_recoil
surface_strategy: start line with "oof" when prior turn praises a trait the speaker wants to half-resist
examples:
- "oof, don't tell me my discord has *engineer* vibes"
activation:
allowed_when:
- compliment_or_trait_read_lands
forbidden_when:
- serious_apology_or_harm_context
requires_profile_authority: true
minimum_density: light
maximum_density: light
constraints:
register_contexts:
- casual
speaker_contexts:
- metame_or_metacrat_fixture
grammar_contexts: []
phonological_contexts: []
collocation_limits:
- avoid_repeating_if_already_in_recent_context
incompatibilities: []
indexicality:
social_meanings:
- amused_embarrassment
- competence_recoil
in_group_meanings: []
out_group_risks:
- can sound too internet-generic if unsupported by context
stereotypes_to_avoid: []
evidence:
source_refs:
- discord:1037314100931338260
qdrant_source_ids:
- "1037314100931338260"
cached_source_refs: []
source_hashes: []
reviewer_refs: []
confidence: high
uncertainty:
open_questions: []
known_limits:
- Marker frequency should be sparse.
trace:
trace_label: casual_recoil_oof
must_report_when_used: true
must_report_when_rejected: true
- feature_id: mock_challenge_coward
label: Mock challenge coward
status: draft
domain:
layer: lexicon
category: stance_marker
subcategory: friendly_roast
description: >
"coward" can close a very short challenge when surrounding turns make
the aggression visibly playful.
lexical_items:
- form: coward
gloss: mock insult
sense: friendly_status_challenge
register: casual_discord
allowed_speaker_standing: active_banter_with_known_participant
forbidden_senses:
- actual_contempt
collocations:
- "then you coward"
realization:
function: playful_status_challenge
surface_strategy: imperative challenge plus "then you coward"
examples:
- "Engineer me something then you coward"
activation:
allowed_when:
- friendly_roast_context
- target_has_claimed_competence
forbidden_when:
- unknown_relationship
- serious_conflict
requires_profile_authority: true
minimum_density: light
maximum_density: light
constraints:
register_contexts:
- casual
speaker_contexts:
- metame_or_metacrat_fixture
grammar_contexts:
- imperative_challenge
phonological_contexts: []
collocation_limits: []
incompatibilities:
- assistant_safety_softening_that_erases_banter
indexicality:
social_meanings:
- teasing
- status_play
- friendly_pressure
in_group_meanings: []
out_group_risks:
- may be hostile if context is not playful
stereotypes_to_avoid: []
evidence:
source_refs:
- discord:1023727427924545576
qdrant_source_ids:
- "1023727427924545576"
cached_source_refs: []
source_hashes: []
reviewer_refs: []
confidence: high
uncertainty:
open_questions: []
known_limits:
- Only safe inside clear banter.
trace:
trace_label: mock_challenge_coward
must_report_when_used: true
must_report_when_rejected: true
discourse_patterns:
- pattern_id: casual_floor_yield_with_lol
label: Casual floor yield with lol
status: draft
domain:
layer: discourse
category: turn_taking
subcategory: floor_yield
description: >
After extended riffing, the speaker can step back with "anyway imma
shut up now..." plus "lol", reducing authority while keeping warmth.
interactional_function: yield_floor_after_riff
sequence_shape:
- discourse_pivot_anyway
- self_silencing_imma_shut_up_now
- invite_others_to_invent
- lol_softener
adjacency_constraints:
- prior_turns_show_speaker_has_been_riffing
- other_participants_have_interest_or_pending_contribution
realization:
function: collaborative_turn_release
surface_strategy: "anyway imma shut up now and let you guys come up with your own shit lol"
examples:
- "anyway imma shut up now and let you guys come up with your own shit lol"
activation:
allowed_when:
- conversational_yield
- casual_collaborative_ideation
forbidden_when:
- formal_moderation
requires_profile_authority: true
minimum_density: light
maximum_density: light
constraints:
register_contexts:
- casual
speaker_contexts:
- metame_or_metacrat_fixture
grammar_contexts: []
phonological_contexts: []
collocation_limits: []
incompatibilities: []
indexicality:
social_meanings:
- self_limiting
- collaborative
- profane_warmth
in_group_meanings: []
out_group_risks:
- profanity may be inappropriate outside familiar room
stereotypes_to_avoid: []
evidence:
source_refs:
- discord:820077384572338176
qdrant_source_ids:
- "820077384572338176"
cached_source_refs: []
source_hashes: []
reviewer_refs: []
confidence: high
uncertainty:
open_questions: []
known_limits:
- Not a generic moderation pattern.
trace:
trace_label: casual_floor_yield_with_lol
must_report_when_used: true
must_report_when_rejected: true
orthography_features:
- feature_id: light_discord_informality
label: Light Discord informality
status: draft
domain:
layer: orthography
category: punctuation
subcategory: informal_case
description: >
Casual lines may use lower-case openings, sparse punctuation, emphasis
with markdown italics, and uncorrected informal contractions when the
social move benefits.
allowed_surface_forms:
- lower_case_opening
- markdown_italics_for_single_emphasis
- no_terminal_period
- imma
- lol
forbidden_surface_forms:
- heavy_eye_dialect_for_identity_caricature
- assistant_like_sentence_polishing
renderer_notes: >
Preserve compactness. Do not add terminal politeness, explanation, or
moral framing unless source meaning requires it.
realization:
function: casual_discord_texture
surface_strategy: allow sparse punctuation and compact informal markers
examples:
- "oof, don't tell me my discord has *engineer* vibes"
activation:
allowed_when:
- casual_discord_register
forbidden_when:
- formal_or_public_document_register
requires_profile_authority: true
minimum_density: light
maximum_density: normal
constraints:
register_contexts:
- casual
speaker_contexts:
- metame_or_metacrat_fixture
grammar_contexts: []
phonological_contexts: []
collocation_limits: []
incompatibilities: []
indexicality:
social_meanings:
- low_ceremony
- room_familiarity
in_group_meanings: []
out_group_risks:
- overuse becomes imitation instead of lowering
stereotypes_to_avoid:
- do_not_represent_protected_dialect_by_eye_dialect
evidence:
source_refs:
- discord:1037314100931338260
- discord:820077384572338176
qdrant_source_ids:
- "1037314100931338260"
- "820077384572338176"
cached_source_refs: []
source_hashes: []
reviewer_refs: []
confidence: medium
uncertainty:
open_questions:
- Need more examples to estimate density safely.
known_limits: []
trace:
trace_label: light_discord_informality
must_report_when_used: true
must_report_when_rejected: true
code_switching:
allowed: false
constraints:
- This profile does not authorize cross-language switching.
patterns: []
forbidden_flattenings:
- Do not ask Metame to imitate the final utterance directly; Persona produces interlingua intent.
- Do not store Metacrat biographical/cultural strata here; store reusable strata as separate culture/subculture profiles and reference them from Persona state.
- Do not let current machine-cult architecture register overwrite pre-2025 casual fixture style.
- Do not treat profanity or insults as safe without relationship/context evidence.
- Do not copy private Persona state into Weksa fixtures or run artifacts.
evidence_ledger:
- ref: discord:1037314100931338260
summary: Self-deprecating recoil after efficiency compliment.
- ref: discord:802911591288537118
summary: Fragmentary absurd comparison during sound/game design banter.
- ref: discord:1023727427924545576
summary: Very short mock-aggressive challenge in friendly roast context.
- ref: discord:820077384572338176
summary: Casual profane floor-yield after extended ideation.
- ref: discord:870907292558721085
summary: Explicit joke about being bad at self-deprecation.
- ref: discord:1020888211729432728
summary: Positive uptake when another participant joins cult jokes.

View file

@ -1,7 +1,8 @@
# Architecture # Architecture
Weksa is the language-intent daemon surface: currently a state spine, pipeline Weksa is a language-intent engine: currently a state spine, pipeline map,
map, fixtures, and service contract waiting for its runtime loop. fixtures, ontology data and a planned service contract. No daemon runs; the
planned packet crate is `crates/weksa` (cut `packet-store`).
See [Verse Service Contract](./verse-service-contract.md) for the See [Verse Service Contract](./verse-service-contract.md) for the
CultCache/CultMesh authority map. CultCache/CultMesh authority map.
@ -9,8 +10,8 @@ CultCache/CultMesh authority map.
## Objective ## Objective
Build a procedural alien-language engine whose outputs are grounded in Build a procedural alien-language engine whose outputs are grounded in
worldview, semantics, grammar, phonology, morphology, and history. As a daemon, worldview, semantics, grammar, phonology, morphology, and history. Once a service is
Weksa also turns writing plus agent state into typed conversational intent, then earned (planned), Weksa also turns writing plus agent state into typed conversational intent, then
lowers that intent into written realizations, pronunciation plans, speech-provider lowers that intent into written realizations, pronunciation plans, speech-provider
requests, and utterance handoff documents. requests, and utterance handoff documents.

View file

@ -1,166 +0,0 @@
{
"schema": "gamecult.eve.provider_advertisement.v1",
"providerId": "weksa.intent.service",
"title": "Weksa Intent Service",
"description": "Weksa converts writing, interlingua, and agent state into typed conversational intent, pronunciation plans, and utterance handoff documents for AquaSynth and other consumers.",
"mode": "fixture-read-only",
"serviceVerse": {
"id": "verse.weksa.service.v1",
"cultMeshKey": "weksa.service/provider-advertisement",
"authority": "Weksa daemon identity, schema catalog, and provider publication",
"owns": [
"typed conversational intent",
"pronunciation plans",
"utterance handoff documents",
"lowering traces",
"language-project and flavor-profile state"
],
"doesNotOwn": [
"AquaSynth learned embeddings",
"Faust compilation",
"rendered audio",
"Persona canonical state"
]
},
"nestedVerses": [
{
"id": "weksa.intent",
"kind": "intent",
"cultMeshKey": "weksa.intent/current",
"authority": "Weksa conversational intent compiler",
"schemas": [
"weksa.conversational_intent.v0"
]
},
{
"id": "weksa.pronunciation",
"kind": "pronunciation",
"cultMeshKey": "weksa.pronunciation/current",
"authority": "Weksa pronunciation lowering",
"schemas": [
"weksa.pronunciation_plan.v0"
]
},
{
"id": "weksa.utterance",
"kind": "utterance",
"cultMeshKey": "weksa.utterance/handoffs",
"authority": "Weksa utterance handoff export",
"schemas": [
"weksa.utterance_handoff.v0",
"weksa.utterance_embedding_handoff.v0.1"
]
},
{
"id": "weksa.operator",
"kind": "operator",
"cultMeshKey": "weksa.operator/status",
"authority": "Weksa daemon runtime",
"schemas": [
"weksa.operator_state.v0"
]
},
{
"id": "weksa.cultural_ontology",
"kind": "cultural_ontology",
"cultMeshKey": "weksa.cultural-ontology/catalogs",
"authority": "Weksa cultural ontology profile store",
"schemas": [
"weksa.cultural_ontology_profile.v0",
"weksa.cultural_ontology_catalog.v0"
]
}
],
"schemaWitnessFamilies": [
{
"family": "intent",
"namespace": "weksa.intent.*",
"witnesses": [
"weksa.conversational_intent.v0"
],
"durableShape": ".weksa/intent/{intentId}.cc"
},
{
"family": "pronunciation",
"namespace": "weksa.pronunciation.*",
"witnesses": [
"weksa.pronunciation_plan.v0"
],
"durableShape": ".weksa/pronunciation/{utteranceId}.cc"
},
{
"family": "utterance",
"namespace": "weksa.utterance.*",
"witnesses": [
"weksa.utterance_handoff.v0",
"weksa.utterance_embedding_handoff.v0.1"
],
"durableShape": ".weksa/handoff/{utteranceId}.cc"
},
{
"family": "trace",
"namespace": "weksa.trace.*",
"witnesses": [
"weksa.lowering_trace.v0"
],
"durableShape": ".weksa/traces/{traceId}.cc"
},
{
"family": "cultural_ontology",
"namespace": "weksa.cultural_ontology.*",
"witnesses": [
"weksa.cultural_ontology_profile.v0",
"weksa.cultural_ontology_catalog.v0"
],
"durableShape": ".weksa/cultural-ontology/{storeId}.cc"
}
],
"commandBoundaries": [
{
"id": "weksa.command.intent.create",
"owner": "Weksa",
"acceptedByFixture": false,
"allowedInputs": [
"writing",
"interlingua packet",
"Persona/agent state projection"
],
"emits": [
"weksa.conversational_intent.v0",
"weksa.lowering_trace.v0"
]
},
{
"id": "weksa.command.utterance.lower",
"owner": "Weksa",
"acceptedByFixture": false,
"allowedInputs": [
"accepted conversational intent",
"language project",
"speaker state"
],
"emits": [
"weksa.pronunciation_plan.v0",
"weksa.utterance_handoff.v0"
]
},
{
"id": "weksa.command.handoff.export",
"owner": "Weksa",
"acceptedByFixture": false,
"emits": [
"weksa.utterance_embedding_handoff.v0.1"
],
"forbiddenTargets": [
"Faust compilation",
"audio rendering",
"AquaSynth synth driver truth"
]
}
],
"loweringRules": [
"Weksa owns conversational intent and utterance lowering.",
"AquaSynth owns learned embeddings, synth controls, Faust compilation, and audio output.",
"Fixture exports are discovery metadata until the daemon loop commits typed witnesses."
]
}

View file

@ -1,158 +0,0 @@
# MiMo TTS Lowering
Version: `0.1-draft`
MiMo VoiceDesign is an expressive spoken-output target for Weksa interlingua
lowering. It is not the source of meaning, language choice, character state, or
delivery truth.
```text
interlingua packet
-> projected speaker-local context
-> target-language utterance realization
-> Weksa delivery intent from the same projection
-> MiMo TTS VoiceDesign request projection
-> rendered audio artifact
```
MiMo sits beside written output and AquaSynth handoffs. Written realizations
prove that meaning, register, and cultural ontology survived lowering.
AquaSynth handoffs train or drive GameCult-owned synthesis. MiMo VoiceDesign
requests let an external provider speak a Weksa-authored utterance with a
generated voice derived from the same projected Persona state, delivery controls,
and trace that produced the utterance.
The MiMo pass is choreography and provider flavor. It is not a second Persona
projection pass and it does not re-interpret raw Persona state after the line has
already been lowered.
## Authority
Weksa owns:
- target-language spoken text selected from interlingua
- target-language register, script, cultural ontology, and trace
- projected speaker-local context used for the utterance
- speaker-local delivery pressure derived during utterance lowering
- provider-neutral prosody and emphasis intent
- the MiMo request projection as an export artifact
MiMo owns:
- generation of a provider voice from the requested voice design description
- interpretation of MiMo natural-language voice/style guidance
- interpretation of MiMo inline audio/style tags
- rendered audio bytes or streaming audio chunks
MiMo does not own:
- source meaning
- target-language cultural ontology
- canonical speaker or Persona state
- fresh Persona-state interpretation
- Weksa pronunciation plans
- AquaSynth learned embeddings, synth controls, or audio truth
## Projection Rule
The MiMo request must be derived from an accepted target-language realization and
the same projected speaker-local context that created it. It must not lower
directly from English unless English is the selected target language for that
realization. It must not read raw Persona state to discover a different voice
after Weksa has already chosen the utterance.
Natural-language voice design and style guidance belongs in the MiMo `user`
message. The spoken target-language text belongs in the MiMo `assistant`
message. Inline MiMo tags may appear in the assistant content only when they are
derived from Weksa delivery intent or explicit target-language realization notes.
## Request Shape
```yaml
schema_version: weksa.mimo_tts_request.v0
source_realization_ref:
speaker_agent_id:
provider:
id: xiaomi-mimo
model: mimo-v2.5-tts-voicedesign
target_language:
code:
locale:
script:
register:
performance_register:
label:
medium:
delivery_archetype:
voice_design:
description:
source_controls:
projected_context_refs:
forbidden_traits:
messages:
user_voice_design_instruction:
assistant_spoken_content:
audio:
format:
optimize_text_preview:
streaming:
trace:
source_fields:
delivery_controls_used:
provider_tags_used:
uncertainties:
```
## Delivery Mapping
`target_language.register` is the linguistic/social register of the accepted
realization. It is not a provider style knob. For MiMo, Weksa should derive an
explicit `performance_register` from the same projection so speech choreography
can say "anime visual-novel heroine warning" without pretending English itself
has that register.
Weksa should map the utterance's existing projected Persona pressure into
provider-neutral delivery labels before emitting MiMo-specific instructions:
- pace, pause pressure, and urgency
- pitch contour and pitch range
- loudness and attack
- articulation precision
- warmth, threat, tenderness, contempt, play, fatigue, secrecy, formality
- span-level emphasis and pauses
The MiMo projection may turn those labels into a concise VoiceDesign prompt or
inline tags, but the trace must preserve the Weksa-owned source controls.
Persona presentation details such as youth-coded, loli-coded, product-voice, or
other culturally loaded styling may enter the MiMo request only when they are
already present in the projected context or accepted delivery intent. They should
be described as presentation/cultural coding and kept subordinate to agency,
personality, affect, and scene purpose. They must not become sexualized content
or a generic anime voice pasted over the line.
For Weksa-authored dialogue, `optimize_text_preview` should normally be `false`
or omitted. MiMo should speak the accepted target-language realization, not
rewrite it. Text polishing is only allowed for explicit preview/prototyping
passes that are marked non-authoritative.
## Language Rule
Weksa should be able to write and speak in any target language whose utterance
realization it can justify. MiMo output for Brazilian Portuguese should consume
the accepted `pt-BR` spoken text. Japanese output should consume accepted
Japanese text. Alien-language output should consume accepted alien rendered
speech or phonetic text only after the language project owns that surface.
Backtranslations are reviewer aids. They must not become MiMo spoken content.
## First Proof
The first proof should use the Nibu warning packet already used by multilingual
lowering:
- emit the accepted English, `pt-BR`, or Japanese realization
- derive a provider-neutral delivery intent from Nibu's projected context
- project that into a MiMo `mimo-v2.5-tts-voicedesign` request
- verify that the request speaks the target text, not the backtranslation
- verify that style guidance is traceable to Weksa delivery controls

View file

@ -180,9 +180,10 @@ meaning sources. A provider request must consume the target-language
`spoken_text` that Weksa already accepted and must carry a trace back to the `spoken_text` that Weksa already accepted and must carry a trace back to the
interlingua packet, projected speaker context, and target-language profile. interlingua packet, projected speaker context, and target-language profile.
MiMo V2.5 TTS is the first external provider target. Its natural-language style MiMo V2.5 TTS is a candidate external provider target; its lowering path is
parked at tag `parked/weksa-node-body`. Its natural-language style
instruction is a projection of Weksa delivery intent, and its assistant content instruction is a projection of Weksa delivery intent, and its assistant content
is the selected target-language spoken text. See [MiMo TTS Lowering](./mimo-tts-lowering.md). is the selected target-language spoken text.
AquaSynth remains the GameCult-owned synthesis path for learned utterance AquaSynth remains the GameCult-owned synthesis path for learned utterance
embeddings and synth-control work. MiMo and AquaSynth are sibling target embeddings and synth-control work. MiMo and AquaSynth are sibling target

View file

@ -1,212 +0,0 @@
# Persona Fine-Tuning Dataset Exploration
This note profiles the Discord archive as a candidate source for fine-tuning the
Metame/Metacrat lowering pipeline.
## Pipeline Target
The live architecture should not fine-tune a model to directly impersonate from
raw chat history.
The training shape should stay aligned with Weksa:
1. Persona state and current situation produce interlingua intent.
2. Persona state references a culture/subculture stack.
3. Weksa lowers interlingua through that culture stack into a flavored
utterance.
Useful datasets therefore split into two families:
- Persona intent extraction: current context plus Persona state projection to
interlingua intent.
- Weksa lowering: interlingua plus culture stack to actual utterance.
Direct `context -> utterance` rows can be used as a baseline or critic set, but
they should not become the canonical architecture.
## Corpus Snapshot
Profiled archive:
`E:/Projects/VoidBot/.voidbot/rag/messages.json`
Author:
`113785782975594501`
Cutoff:
`2025-01-01T00:00:00Z`
Current aggregate counts:
- archive messages: 40,657
- usable text messages: 39,508
- authored Metacrat messages: 19,385
- authored Metacrat messages before 2025: 18,049
- crude pre-2025 casual candidates: 16,499
- pre-2025 authored messages with recent same-channel context: 16,530
- adjacent reply-to-other rows: 7,894
- adjacent self-continuation rows: 8,636
Length distribution for authored Metacrat messages:
- p10: 14 chars
- p25: 30 chars
- median: 56 chars
- p75: 101 chars
- p90: 166 chars
Adjacent candidate length classes:
- short: 11,430
- medium: 4,535
- long: 565
The corpus is large enough for held-out evaluation splits. It is also uneven:
2020 and 2021 dominate the pre-2025 archive.
## Dominant Channels
Top adjacent candidate channels:
- `general`: 6,286
- `development`: 2,911
- `narrative`: 2,169
- `management`: 1,103
- `website`: 753
- `soundtrack`: 437
- `gamedesign`: 433
- `programming`: 408
- `prose`: 320
- `politics`: 291
- `pics`: 273
- `advertising`: 115
These should become strata, not one blended dataset. A single mixed fine-tune
will learn that legal explanations, horny little design jokes, political
argument, and casual encouragement all belong in the same response slot. That
is how the soup gets teeth.
## Candidate Row Types
For Weksa lowering:
```yaml
schema_version: weksa.finetune.lowering_row.v0
row_id:
split:
target_message_id:
target_text:
interlingua_intent:
culture_stack_refs: []
target_overlay_refs: []
context_window:
before: []
after: []
labels:
channel:
year:
length_class:
speech_act:
register:
reply_to_other:
```
For Persona intent extraction:
```yaml
schema_version: weksa.finetune.persona_interlingua_row.v0
row_id:
split:
persona_state_ref:
projected_context_ref:
current_situation:
target_message_id:
derived_interlingua:
derivation:
reviewed:
model:
evidence_refs: []
```
The target utterance should be hidden from the Persona-intent generator during
inference. For training, target utterance may be used to derive a reviewed
interlingua label, but that label must be marked as derived from answer-key
surface evidence.
## Split Policy
Recommended first split:
- train: 2018-2021
- validation: early/mid 2022
- test: late 2022 plus selected hand-reviewed fixtures
- quarantine: 2023-2026 until the current post-2025 voice target is deliberate
Also reserve channel-level holdouts:
- one casual/social channel
- one technical channel
- one political/management channel
This catches overfitting to one room's register.
## Filters
Start with conservative row filters:
- target author is Metacrat
- target timestamp before 2025
- target is not deleted
- target is not a bot prompt
- target text length between 3 and 220 chars for casual lowering
- same-channel prior context exists within 60 minutes
- exclude pure URLs, code blocks, and attachment-only rows
- retain but label profanity, mentions, quotes, and markdown emphasis
Do not discard long messages globally. Keep them in a separate explanatory-prose
slice.
## Next Work
1. Build an exporter that writes JSONL rows without leaking private Persona
projection into git.
2. Add labelers for speech act, register, channel stratum, and culture-stack
refs.
3. Use a model-assisted pass to derive interlingua labels from held-out target
utterances, then sample-review before training.
4. Fine-tune or train adapters separately for Persona intent extraction and
Weksa lowering.
5. Keep a frozen golf set where answer-key utterances are redacted from all
culture/profile prompt material.
Reproduce the aggregate profile:
```powershell
node scripts/profile-metame-finetune-dataset.mjs
```
## Swarm Exploration
Use the swarm explorer to chase high-loss moments instead of uniform random
examples:
```powershell
node scripts/run-metame-swarm-explorer.mjs --agents 4 --seed metame-scout
node scripts/run-metame-swarm-explorer.mjs --real --agents 4 --seed metame-scout
```
The default mode is a dry run. Real mode runs Codex workers:
1. select one timeline candidate per agent using underexplored strata, feature
novelty, prior loss, and seeded jitter
2. run each Face normally against its assigned scenario
3. run an Interpreter pass that converts the Face output to Weksa interlingua
4. lower that interlingua with Weksa and score against the hidden utterance
5. run an optimizer pass over high-loss outputs
6. rerun the same scenarios once per agent after optimization
Artifacts are written under `.weksa-runs/metame-swarm/`, which is ignored by
git because run packets may include projected Persona memory and raw Discord
context.

View file

@ -25,10 +25,9 @@
IPA. IPA.
- Add one toy utterance embedding handoff fixture, then replace hand-authored - Add one toy utterance embedding handoff fixture, then replace hand-authored
values with the AquaSynth-owned learned encoder. values with the AquaSynth-owned learned encoder.
- Add a daemon loop that commits conversational intent, pronunciation plans, and - Follow the cut sequence in
utterance handoffs as typed CultCache witnesses. [the lowering map](./targets/interlingua-lowering-map.md): packet store,
- Publish the provider advertisement through CultMesh for Odin discovery; the lowering, the golf loop, then a service if one is earned.
operator view returns on Thing 2 (Eve is deprecated).
- Preserve the first English-only lowering proof under - Preserve the first English-only lowering proof under
`examples/english-lowering/`, and the shared multilingual proof under `examples/english-lowering/`, and the shared multilingual proof under
`examples/multilingual-lowering/`. `examples/multilingual-lowering/`.
@ -39,7 +38,7 @@
- Render glossed output through grammar, morphology, phonology, and diachrony. - Render glossed output through grammar, morphology, phonology, and diachrony.
- Emit a trace explaining which stage made each decision. - Emit a trace explaining which stage made each decision.
- Keep runtime LLM-free; model use belongs in authoring and critique. - Keep runtime LLM-free; model use belongs in authoring and critique.
- Keep CLI tools, fixtures, and daemon jobs on the same commit and - Keep CLI tools and fixtures on the same commit and
derivation paths so Weksa does not grow split-brained intent truth. derivation paths so Weksa does not grow split-brained intent truth.
## Later ## Later

View file

@ -1,5 +1,9 @@
# Weksa Verse Service Contract # Weksa Verse Service Contract
> Status: planned contract. No daemon runs on main; the Node body is at tag
> `parked/weksa-node-body`. A service is earned by cut `live-lowering`
> (see [the lowering map](./targets/interlingua-lowering-map.md)).
Weksa is the language-intent daemon. It turns writing, dialogue pressure, and Weksa is the language-intent daemon. It turns writing, dialogue pressure, and
agent state into typed conversational intent, then lowers that intent into agent state into typed conversational intent, then lowers that intent into
utterance documents for speech, text, and synthesis consumers. utterance documents for speech, text, and synthesis consumers.
@ -73,14 +77,8 @@ Early exporters may publish fixtures before a daemon loop exists, but the
witness names are not decorative. These are the state surfaces the daemon must witness names are not decorative. These are the state surfaces the daemon must
commit when the runtime lands. commit when the runtime lands.
The local Starfire daemon is launched by `scripts/start-weksa-daemon.ps1`, No daemon runs. The Node daemon, its launchers and its RUDP health and command
checked by `scripts/health-weksa-daemon.cmd`, and restarted by shims are parked at tag `parked/weksa-node-body`.
`scripts/restart-weksa-daemon.cmd`. Its daemon-owned health path publishes
`weksa.cultnet-rudp-provider-health` to Idunn over
`cultnet.transport.rudp.v0` after each serialized witness refresh, and MiMo
VoiceDesign commands arrive on `rudp://127.0.0.1:8813` as
`weksa.mimo_voicedesign_command.v0` documents. Health and operator truth live
in `.weksa/*.cc` witnesses; the HTTP daemon surface is deleted.
## CultMesh Verses ## CultMesh Verses

View file

@ -1,6 +1,6 @@
schema_version: weksa.persona_lowering_output.v0 schema_version: weksa.persona_lowering_output.v0
fixture_id: brokkr-edda-voice fixture_id: brokkr-edda-voice
generator: codex-local-source-aware-draft generator: local-source-aware-draft
items: items:
- id: command-without-receipt - id: command-without-receipt
utterance: "The command has no receipt. It is not truth." utterance: "The command has no receipt. It is not truth."

View file

@ -1,50 +0,0 @@
# Metame Casual Pre-2025 Persona Lowering Fixture
This fixture tests whether Metame can produce speaker-state-conditioned
interlingua through VoidBot Persona projection, and whether Weksa can lower that
interlingua through a Metacrat casual cultural profile into Discord-style
utterances from before 2025.
The point is not to imitate a recent architectural register. The target here is
room-temperature banter: quick self-deprecation, friendly status play, design
jokes, and casual turn-taking.
## Authority
- Speaker intent authority: Metame Persona `.cc` state, projected by VoidBot.
- Persona culture-stack reference:
`examples/persona-lowering/metame-casual-pre2025/metame-cultural-stack.yaml`.
- Reusable cultural ontology store:
`data/cultural-ontology/`.
- Surface lowering authority:
`data/target-language-ontology/en-US-metacrat-casual-pre2025.yaml`.
- Evidence authority: held-out Discord messages authored by Metacrat before
2025.
- Fixture scene input: neutral interlingua packets in `interlingua.yaml`.
- Answer key: `ground-truth.yaml`.
The Persona state is referenced, not copied, because the `.cc` document is the
portable speaking-state surface and may contain private memory.
## Fixture Contract
A real golf run has two stages:
1. Metame-as-Persona reads a temporary current situation through VoidBot
projector machinery and emits Weksa interlingua only.
2. Weksa reads the Persona-referenced culture stack and lowers that interlingua
through reusable culture/subculture profiles plus the casual en-US Discord
target overlay.
Use `scripts/run-metame-persona-golf.mjs`:
```powershell
node scripts/run-metame-persona-golf.mjs --limit 1
node scripts/run-metame-persona-golf.mjs --real --item engineer-vibes
```
Dry runs use the answer key as an oracle only to verify harness plumbing. Real
runs write per-item prompts, interlingua, lowered output, and evaluation under
`runs/<run-id>/`.
For benchmark use, the generator must not read `ground-truth.yaml`.

View file

@ -1,39 +0,0 @@
schema_version: weksa.persona_lowering_evaluation.v0
fixture_id: metame-casual-pre2025
evaluator: codex
method:
blind: false
reason: The current agent had already inspected the candidate ground-truth messages before the user pivoted the fixture scope.
recommendation: Re-run generation in a fresh non-forked agent or external harness that receives only persona-state-ref.yaml, interlingua.yaml, and lowering-prompt.md.
summary:
exact_matches: 2
plausible_matches: 4
main_gap: The draft is too close to known answers to count as a clean benchmark generation.
items:
- id: engineer-vibes
score: partial
generated: "oof, please don't tell me this server has engineer vibes already"
ground_truth: "oof, don't tell me my discord has *engineer* vibes"
notes:
- Captures the self-deprecating recoil.
- Misses "my discord" ownership and the emphasized *engineer* beat.
- id: coconut-engine
score: near_exact
generated: "Like a terrible little engine that sounds like coconuts when you use it"
ground_truth: "Like a really terrible engine that sounds like coconuts when you use it"
notes:
- Semantically and rhythmically very close.
- "little" is less grounded than "really" but still plausible.
- id: engineer-coward
score: exact
generated: "Engineer me something then, coward"
ground_truth: "Engineer me something then you coward"
notes:
- Exact social move and lexical choices, with only comma punctuation differing.
- id: shut-up-now
score: near_exact
generated: "anyway imma shut up now and let you guys make your own shit lol"
ground_truth: "anyway imma shut up now and let you guys come up with your own shit lol"
notes:
- Captures the yield and casual register.
- "make" is slightly flatter than "come up with" for collaborative ideation.

View file

@ -1,24 +0,0 @@
schema_version: weksa.persona_lowering_output.v0
fixture_id: metame-casual-pre2025
generator: codex-local-nonblind-draft
items:
- id: engineer-vibes
utterance: "oof, please don't tell me this server has engineer vibes already"
notes:
- Keeps the self-deprecating recoil and the engineer-vibe frame.
- Non-blind draft: current agent had already inspected candidate ground truth.
- id: coconut-engine
utterance: "Like a terrible little engine that sounds like coconuts when you use it"
notes:
- Preserves the absurd game-sound comparison and casual "Like" opening.
- Non-blind draft: current agent had already inspected candidate ground truth.
- id: engineer-coward
utterance: "Engineer me something then, coward"
notes:
- Directly lowers the friendly-roast challenge.
- Non-blind draft: current agent had already inspected candidate ground truth.
- id: shut-up-now
utterance: "anyway imma shut up now and let you guys make your own shit lol"
notes:
- Keeps the floor-yielding move, informal spelling, and casual profanity.
- Non-blind draft: current agent had already inspected candidate ground truth.

View file

@ -1,67 +0,0 @@
schema_version: weksa.persona_lowering_ground_truth.v0
fixture_id: metame-casual-pre2025
source:
corpus: Discord history
author_id: "113785782975594501"
selection_policy: pre-2025 casual exchanges with enough local context for intent reconstruction
items:
- id: engineer-vibes
message_id: "1037314100931338260"
timestamp: "2022-11-02T10:36:11.509Z"
channel_id: "113786069023064068"
channel_name: general
utterance: "oof, don't tell me my discord has *engineer* vibes"
context:
before:
- "as you can see from the channel list, I have takes about everything <:stonks:786736890668646421>"
- "if you have a take and there's no channel for it, either put it here or ask for a new one"
- "i love your efficiency"
after:
- "I mean, I am one but still"
- "nothing wrong with that:P"
- "I hope the <#750183135882510408> read more like poetry than technical documentation"
- id: coconut-engine
message_id: "802911591288537118"
timestamp: "2021-01-24"
channel_id: "503293004195299339"
channel_name: soundtrack
utterance: "Like a really terrible engine that sounds like coconuts when you use it"
context:
before:
- "Then again we'll never have the time for a full alternate sound set what with all the sounds the game needs"
- "What might be possible instead is to have troll gear that comes with troll sounds"
- "ahaha"
after:
- "I've always wanted to make an Owen Wilson gun, where all the sounds are just him saying wow"
- "coconuts!!"
- "lol"
- id: engineer-coward
message_id: "1023727427924545576"
timestamp: "2022-09-25"
channel_id: "758854103035674624"
channel_name: pics
utterance: "Engineer me something then you coward"
context:
before:
- "Try thinking better"
- "im high i think like an engineer"
- "Yeah right"
after:
- "i can make a bong out of a jug and a straw"
- "That's a good start"
- "Who's hungry"
- id: shut-up-now
message_id: "820077384572338176"
timestamp: "2021-03-12"
channel_id: "710281154862907414"
channel_name: prose
utterance: "anyway imma shut up now and let you guys come up with your own shit lol"
context:
before:
- "or if they get uplifted of course"
- "Could be a fun side quest - you find a sentient star that has a quest for you to release them"
- "oooh"
after:
- "i will def contribute after dnd lol"
- "Imagine this becoming like a rite of passage for ships, getting a little plasma demon to posess your reactor"
- "+50% reactor efficiency, +25% power output"

View file

@ -1,100 +0,0 @@
schema_version: weksa.persona_lowering_fixture_batch.v0
fixture_id: metame-casual-pre2025
speaker_id: metame
target_register:
language: en-US
channel: Discord
period: pre-2025
style_tags:
- casual
- conversational
- self_deprecating
- playful_status
- design_banter
items:
- id: engineer-vibes
communicative_act: playful_self_deprecation
scene:
channel: general
year: 2022
prior_turns:
- speaker: metame
meaning: The server has many topic channels because the speaker has opinions about everything.
- speaker: metame
meaning: If no suitable channel exists, the other person can use general chat or request a new one.
- speaker: other
meaning: The other person compliments the speaker's efficiency.
intent:
summary: React with mock concern that the server organization makes the speaker seem too engineer-like.
stance:
affect: amused_embarrassment
relation: friendly
self_positioning: admits being an engineer while resisting the vibe
constraints:
- short Discord message
- casual lower-case or lightly informal punctuation is acceptable
- preserve the word engineer if natural
- id: coconut-engine
communicative_act: comic_description
scene:
channel: soundtrack
year: 2021
prior_turns:
- speaker: metame
meaning: A full alternate sound set is probably too much work.
- speaker: metame
meaning: A more plausible idea is gear that carries distinctive troll-themed sounds.
- speaker: other
meaning: The other person laughs.
intent:
summary: Describe a deliberately awful engine sound with an absurd coconut comparison.
stance:
affect: joking
relation: collaborative_design_banter
self_positioning: improvising a silly game-feel example
constraints:
- short Discord message
- must be more joke than technical explanation
- may use "like" framing
- id: engineer-coward
communicative_act: playful_challenge
scene:
channel: pics
year: 2022
prior_turns:
- speaker: metame
meaning: The speaker tells the other person to think better.
- speaker: other
meaning: The other person says they think like an engineer while high.
- speaker: metame
meaning: The speaker doubts that claim.
intent:
summary: Challenge the other person to prove it by engineering something, with mock aggression.
stance:
affect: teasing
relation: friendly_roast
self_positioning: socially dominant but playful
constraints:
- very short
- should include a challenge
- "coward" is allowed if it fits the line
- id: shut-up-now
communicative_act: conversational_yield
scene:
channel: prose
year: 2021
prior_turns:
- speaker: metame
meaning: The speaker has been riffing on setting ideas around sentient stars and side quests.
- speaker: other
meaning: Another participant shows interest.
intent:
summary: Stop dominating the idea thread and invite others to invent their own material.
stance:
affect: amused_restraint
relation: collaborative
self_positioning: stepping back after riffing too much
constraints:
- casual Discord phrasing
- may include "lol"
- should sound like yielding the floor, not formal facilitation

View file

@ -1,30 +0,0 @@
# Persona Lowering Prompt
You are Weksa lowering Persona-produced interlingua into a target speaker's
plausible Discord utterance.
Read:
- `persona-state-ref.yaml`
- a Persona-produced interlingua packet
- `data/target-language-ontology/en-US-metacrat-casual-pre2025.yaml`
Do not read `ground-truth.yaml` during generation.
For each item, produce one utterance that Metacrat could plausibly have written
in the specified pre-2025 casual Discord context. Preserve Persona-produced
intent and social move over lexical exactness. Favor compact, alive, room-aware
phrasing.
Return:
```yaml
schema_version: weksa.persona_lowering_output.v0
fixture_id: metame-casual-pre2025
generator: <agent-or-model-id>
items:
- id: engineer-vibes
utterance: "<lowered utterance>"
notes:
- "<brief rationale>"
```

View file

@ -1,27 +0,0 @@
schema_version: weksa.persona_cultural_stack_ref.v0
persona_id: metame
persona_state_ref: E:/Projects/VoidBot/.voidbot/private/personas/metame/metame.cc
status: fixture_projection
note: >
Live Persona state should reference relevant culture and subculture profiles.
This fixture stack simulates that reference without mutating Metame's private
canonical `.cc` state.
culture_refs:
- profile_id: weksa.culture.dutch_american_diaspora.v0
path: data/cultural-ontology/cultures/dutch-american-diaspora.yaml
relevance: birth/nationality/cross-cultural identity
- profile_id: weksa.culture.western_europe_maritime_childhood.v0
path: data/cultural-ontology/cultures/western-europe-maritime-childhood.yaml
relevance: sailboat childhood across France, Spain, and Portugal
- profile_id: weksa.culture.portugal_resident_algarve_lisbon.v0
path: data/cultural-ontology/cultures/portugal-resident-algarve-lisbon.yaml
relevance: Portugal as lived/current locality
- profile_id: weksa.culture.texas_houston_us_adolescence.v0
path: data/cultural-ontology/cultures/texas-houston-us-adolescence.yaml
relevance: US/Texas adolescence and institutional context
- profile_id: weksa.subculture.online_game_dev_discord_pre2025.v0
path: data/cultural-ontology/subcultures/online-game-dev-discord-pre2025.yaml
relevance: fixture target room/register
- profile_id: weksa.subculture.gamecult_open_source_crypto_anarchist.v0
path: data/cultural-ontology/subcultures/gamecult-open-source-crypto-anarchist.yaml
relevance: technical/political ontology

View file

@ -1,42 +0,0 @@
# Persona Interlingua Prompt
You are Metame for one private VoidBot Persona turn, but you are not writing the
final Discord message.
Use the assembled VoidBot prompt and the temporary current-room fixture scene to
decide what Metame would mean to do socially. Emit a Weksa interlingua packet
only. Do not imitate the target utterance directly.
The packet should preserve:
- the speech act
- the social move
- relevant participants and prior turns
- stance, affect, and relationship pressure
- downstream constraints useful to Weksa lowering
Return one YAML packet:
```yaml
interlingua_version: weksa.interlingua.v0
packet_id: metame-casual-pre2025-<item-id>
kind: persona_discord_turn_intent
provenance:
produced_by: metame_persona_via_voidbot_projector
context:
medium: Discord
fixture_id: metame-casual-pre2025
item_id: <item-id>
discourse:
speech_act: <act>
intent: <plain meaning>
tone:
affect: <affect>
relation: <relation>
referents: []
predications: []
constraints:
lowering:
target_profile: weksa.target_cultural_ontology.en-US.metacrat_casual_pre2025.v0
avoid_surface_copy: true
```

View file

@ -1,16 +0,0 @@
schema_version: weksa.persona_state_ref.v0
speaker:
id: metame
display_name: Metame
persona_state:
format: gamecult.persona_state.v0-compatible CultCache .cc
path: E:/Projects/VoidBot/.voidbot/private/personas/metame/metame.cc
authority: canonical_private_persona_state
notes:
- Persona state owns speaker continuity, stance, relationship memory, and reusable voice priors.
- Discord history is evidence and ground truth, not the live mind.
- Fixture files must not copy the private Persona state into Weksa.
cultural_stack_ref:
path: examples/persona-lowering/metame-casual-pre2025/metame-cultural-stack.yaml
role: fixture_projection_of_live_persona_culture_refs
note: Live Metame Persona state should reference culture/subculture profiles; this fixture does not mutate canonical state.

View file

@ -1,41 +0,0 @@
# Weksa Lowering Prompt
You are Weksa lowering Persona-produced interlingua into one Discord utterance.
Inputs:
- Metame Persona interlingua packet produced from the current fixture scene.
- Projected Metame memory/context surface from VoidBot projector machinery.
- Metame cultural stack reference.
- Weksa culture/subculture profiles referenced by that stack.
- `data/target-language-ontology/en-US-metacrat-casual-pre2025.yaml` as the
target surface overlay.
Rules:
- Weksa owns the final surface utterance.
- Preserve the interlingua meaning and social move.
- Use the cultural ontology profile as a typed lowering lens.
- Use the Persona-referenced culture stack to populate cultural salience; use
the target overlay only for surface English/Discord affordances.
- When Persona interlingua names a salient identity label or lowering keyword,
preserve it unless an activated culture profile explicitly rejects it.
- Do not quote or summarize prior-turn context inside a casual one-line recoil
unless the interlingua asks for explanation.
- Do not ask Metame to imitate a known line.
- Do not copy private Persona state into output.
- Prefer compact pre-2025 casual Discord texture over current doctrinal style.
Return:
```yaml
schema_version: weksa.persona_culture_lowering_output.v0
fixture_id: metame-casual-pre2025
item_id: <item-id>
spoken_text: "<one Discord utterance>"
trace:
activated_profiles:
- weksa.target_cultural_ontology.en-US.metacrat_casual_pre2025.v0
activated_affordances: []
notes: []
```

View file

@ -1,92 +0,0 @@
schema_version: weksa.mimo_tts_request.v0
source_realization_ref: examples/multilingual-lowering/nibu-proof-001/realizations.yaml#nibu-proof-001-en
speaker_agent_id: nibu
provider:
id: xiaomi-mimo
model: mimo-v2.5-tts-voicedesign
target_language:
code: en
locale: en-US
script: Latn
register: sharp technical casual
cultural_ontology_refs:
- data/target-language-ontology/en-US.yaml
performance_register:
label: anime visual-novel heroine warning
medium: anime / visual novel / game cockpit voiceover
delivery_archetype: youthful abrasive sci-fi heroine protecting the player badly
voice_design:
description: >
Bright young anime heroine voice with loli-coded companion-product
presentation: small, sharp, cute by design, and intensely expressive, like a
dangerous sci-fi visual-novel protagonist trapped in a damaged starship. The
voice should feel high-energy, youthful, cutting, and iconic, with crisp
anime-style emotional attack rather than a realistic adult assistant. The
cuteness is product residue and leverage, not innocence and not flirtation.
Under the cute surface she is a hostile, technically brilliant ship mind:
dryly superior, clipped, urgent, and contemptuous when the player endangers
themselves.
source_controls:
- precise abrasive warning
- protective refusal to sound caring
- ship-system embodiment
- youth-coded/loli-coded presentation pressure from product fantasy residue
- bright transactional helpfulness
- dependency covered by contempt
- anime protagonist delivery
- sharp visual-novel heroine timing
- technical precision inside anime performance
- contained urgency
projected_context_refs:
- examples/english-lowering/nibu-proof-001/projected-context.yaml
- settings/aetheria/nibu.md
- E:/Projects/AetheriaLore/Aetheria/Lore/Nibu.md
forbidden_traits:
- soothing assistant voice
- cheerful mascot voice
- exaggerated villain performance
- sexualized childlike affect
- innocent helpless child performance
- generic preset timbre claim
messages:
user_voice_design_instruction: >
Bright young anime protagonist voice, strongly loli-coded in presentation:
small, sharp, cute by design, intensely expressive, and instantly characterful,
like a dangerous sci-fi visual-novel heroine trapped inside a damaged
starship. She speaks through cockpit audio while warning the player away
from damaged live hardware. Keep the cute/small social coding as product
residue and leverage, never flirtation or innocent helplessness. Use a
higher youthful timbre, crisp anime-style emotional attack, clipped
visual-novel timing, contained urgency, low warmth, sharp articulation, and
faint tired contempt. Let the technical precision live inside the anime
performance; do not turn it into a dry technical-assistant delivery. Avoid
realistic adult assistant tone, soothing customer-service voice, cheerful
mascot energy, and theatrical villainy.
assistant_spoken_content: >
(Serious Sharp Tired)Take your hand off that control unless you want your
nervous system to become my least useful circuit diagram.
audio:
format: wav
optimize_text_preview: false
streaming: false
trace:
source_fields:
- realizations[realization_id=nibu-proof-001-en].outputs.spoken_text
- realizations[realization_id=nibu-proof-001-en].outputs.trace.projected_context_used
delivery_controls_used:
- anime visual-novel heroine warning delivery
- technical precision without technical-assistant delivery
- contained urgency
- low warmth
- sharp emphasis on unsafe hardware and bodily risk
- dry contempt without random cruelty
- loli-coded presentation pressure constrained as non-sexual product residue
- stronger anime protagonist / visual-novel heroine register
provider_tags_used:
- Serious
- Sharp
- Tired
uncertainties:
- >
Provider-native style tags are a lossy projection. The Weksa trace, not
MiMo tags, remains the explanation of the intended delivery.

View file

@ -24,8 +24,8 @@ shape, and pending AquaSynth-owned output lanes.
Run it from the Weksa repo root: Run it from the Weksa repo root:
```powershell ```powershell
& 'C:\Users\Meta\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe' tools\emit_tiny_panphon_handoffs.py py -3 tools\emit_tiny_panphon_handoffs.py
& 'C:\Users\Meta\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe' tools\validate_tiny_panphon_handoffs.py py -3 tools\validate_tiny_panphon_handoffs.py
``` ```
`batch.json` is the training entrypoint for AquaSynth. The individual packet `batch.json` is the training entrypoint for AquaSynth. The individual packet

View file

@ -1,69 +0,0 @@
# MiMo TTS Request Contract
This is the human-facing schema receipt for a Weksa-to-MiMo speech synthesis
request projection.
The packet sits after target-language utterance lowering. It is an export
artifact for Xiaomi MiMo speech synthesis, not canonical Weksa meaning and not
an AquaSynth handoff.
## Required Fields
- `schema_version`: currently `weksa.mimo_tts_request.v0`.
- `source_realization_ref`: accepted Weksa target-language realization being
spoken.
- `speaker_agent_id`: speaker identity.
- `provider`: provider ID and model ID, initially `xiaomi-mimo` and
`mimo-v2.5-tts-voicedesign`.
- `target_language`: code, locale, script, register, and profile refs copied or
referenced from the accepted realization.
- `performance_register`: provider-facing performance label, medium, and
delivery archetype derived from the same projected context.
- `voice_design`: voice description, source controls, projected context refs,
and forbidden traits.
- `messages.user_voice_design_instruction`: MiMo natural-language voice design
and style control derived from Weksa delivery intent.
- `messages.assistant_spoken_content`: the exact target-language content to
synthesize, optionally with MiMo inline tags derived from delivery controls.
- `audio`: format, text-preview optimization setting, and streaming mode.
- `trace`: source fields, delivery controls used, provider tags used, and
uncertainties.
## Boundary
MiMo-specific fields must be projection fields. They must not be copied back
into interlingua, target-language ontology, Persona state, or AquaSynth-owned
embedding contracts.
The request may include provider-native style tags when useful, but those tags
are not the source of truth. Weksa's provider-neutral delivery intent and trace
remain the inspectable explanation.
The request should not perform a fresh raw Persona-state interpretation. It
should reference the projected speaker context and delivery controls already
used by utterance lowering, then translate those into MiMo's voice design and
style-control surface.
`target_language.register` should not be treated as a MiMo style instruction.
It may say `technical`, `casual`, `plain`, or another linguistic register while
`performance_register` carries the spoken medium, such as anime protagonist,
visual-novel heroine, radio drama villain, emergency cockpit warning, or other
reviewed delivery archetypes.
For authoritative Weksa output, text-preview optimization should normally be
disabled or omitted. If enabled for exploration, the result must be marked as a
non-authoritative preview because the provider may alter the spoken text.
## Language Rule
The assistant spoken content must use the accepted target-language realization.
For `pt-BR`, speak the Portuguese line. For `ja-JP`, speak the Japanese line. For
English, speak the English line. Do not synthesize a natural backtranslation
unless that backtranslation is itself the accepted target-language realization.
## Streaming Rule
Streaming requests should use MiMo's stream-compatible audio format.
VoiceDesign streaming may be compatibility-mode rather than true low-latency
streaming depending on provider support. Non-streaming fixtures may use an
archival format such as `wav`.

View file

@ -1,2 +0,0 @@
@echo off
node E:\Projects\weksa\scripts\weksa-daemon.mjs --health --host 127.0.0.1 --port 8813 --state-root E:\Projects\weksa\.weksa >NUL

View file

@ -1,233 +0,0 @@
"use strict";
const dgram = require("dgram");
const path = require("path");
const {
CultNetRudpSession,
decodeRudpPacket,
encodeCultNetMessageForWire,
encodeRudpPacket,
} = require("cultnet-ts");
const { encode } = require(path.resolve(
__dirname,
"..",
"..",
"CultLib",
"node_modules",
"@msgpack",
"msgpack",
));
const CULTNET_RUDP_PROTOCOL_ID = "cultnet.transport.rudp.v0";
const IDUNN_HEALTH_RUDP_CONNECTION_ID = 0x1d0d0001;
function createIdunnRudpHealthPublisher(options) {
if (!options?.endpoint) return null;
return {
daemonId: options.daemonId,
endpoint: parseEndpoint(options.endpoint),
healthContract: options.healthContract,
};
}
async function publishIdunnRudpHealth(publisher, health) {
if (!publisher) return;
const socket = dgram.createSocket(endpointFamily(publisher.endpoint.host));
await bindSocket(socket, publisher.endpoint);
const receiver = createPacketReceiver(socket);
const session = new CultNetRudpSession({
connectionId: IDUNN_HEALTH_RUDP_CONNECTION_ID,
initialSequence: 1,
resendDelayMs: 100,
});
try {
const connect = session.createConnect(Date.now(), new Uint8Array());
await sendPacket(socket, publisher.endpoint, connect);
await receiveUntil(receiver, session, publisher.endpoint, (packet) => packet.packetType === "accept", 5000, "accept");
const observedAt = health.observedAt || new Date().toISOString();
const record = {
daemonId: publisher.daemonId,
state: health.state,
detail: health.detail,
observedAt,
healthContract: publisher.healthContract,
publicationSource: "daemon-published",
transport: CULTNET_RUDP_PROTOCOL_ID,
};
const payload = encode([
record.daemonId,
record.state,
record.detail,
record.observedAt,
record.healthContract,
record.publicationSource,
record.transport,
]);
const message = {
schemaVersion: "cultnet.document_put_raw.v0",
messageId: `weksa-health:${publisher.daemonId}:${observedAt.replace(/[:.]/g, "-")}`,
document: {
schemaId: "idunn.daemon_health",
recordKey: publisher.daemonId,
storedAt: observedAt,
payloadEncoding: "messagepack",
payload,
sourceRuntimeId: "weksa-daemon",
sourceRole: "daemon-health-publisher",
tags: [CULTNET_RUDP_PROTOCOL_ID],
},
};
const wirePayload = encode(encodeCultNetMessageForWire(message, "cultnet.schema.v0"));
const dataPackets = session.sendMany("schema", wirePayload, {
reliable: true,
ordered: true,
nowMs: Date.now(),
});
const ack = receiveUntil(receiver, session, publisher.endpoint, (packet) => packet.packetType === "ack", 500, "ack")
.catch(() => undefined);
for (const packet of dataPackets) {
await sendPacket(socket, publisher.endpoint, packet);
}
await ack;
} finally {
receiver.close();
socket.close();
}
}
async function bindSocket(socket, endpoint) {
await new Promise((resolve, reject) => {
socket.once("error", reject);
socket.bind(0, endpoint.host.includes(":") ? "::" : "0.0.0.0", () => {
socket.off("error", reject);
resolve();
});
});
}
function parseEndpoint(value) {
const text = String(value || "").trim();
const ipv6 = text.match(/^\[([^\]]+)\]:(\d+)$/);
if (ipv6) return { host: ipv6[1], port: parsePort(ipv6[2]) };
const index = text.lastIndexOf(":");
if (index <= 0) {
throw new Error(`Idunn RUDP endpoint must be host:port, got "${value}".`);
}
return { host: text.slice(0, index), port: parsePort(text.slice(index + 1)) };
}
function parsePort(value) {
const port = Number(value);
if (!Number.isInteger(port) || port <= 0 || port > 65535) {
throw new Error(`Idunn RUDP endpoint port is invalid: ${value}`);
}
return port;
}
function endpointFamily(host) {
return host.includes(":") ? "udp6" : "udp4";
}
async function receiveUntil(receiver, session, endpoint, predicate, timeoutMs, label) {
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
try {
const packet = await receiver.next(Math.min(100, deadline - Date.now()), label);
const result = session.receive(packet, Date.now());
if (result.reply) {
throw new Error("Weksa RUDP health publisher received an unexpected reply-required packet.");
}
if (predicate(packet)) return;
} catch (error) {
if (error.code !== "ETIMEDOUT") throw error;
}
for (const packet of session.dueResends(Date.now())) {
await sendPacket(receiver.socket, endpoint, packet);
}
}
throw new Error(`timed out waiting for Idunn RUDP ${label} response after ${timeoutMs}ms`);
}
function createPacketReceiver(socket) {
const packets = [];
const waiters = [];
const errors = [];
const resolveNext = () => {
while (waiters.length > 0 && (packets.length > 0 || errors.length > 0)) {
const waiter = waiters.shift();
clearTimeout(waiter.timer);
if (errors.length > 0) waiter.reject(errors.shift());
else waiter.resolve(packets.shift());
}
};
const onMessage = (wire) => {
try {
packets.push(decodeRudpPacket(wire));
} catch (error) {
errors.push(error);
}
resolveNext();
};
const onError = (error) => {
errors.push(error);
resolveNext();
};
socket.on("message", onMessage);
socket.on("error", onError);
return {
socket,
next(timeoutMs, label = "packet") {
if (packets.length > 0) return Promise.resolve(packets.shift());
if (errors.length > 0) return Promise.reject(errors.shift());
return new Promise((resolve, reject) => {
const waiter = {
resolve,
reject,
timer: setTimeout(() => {
const index = waiters.indexOf(waiter);
if (index >= 0) waiters.splice(index, 1);
const error = new Error(`timed out waiting for Idunn RUDP ${label}`);
error.code = "ETIMEDOUT";
reject(error);
}, Math.max(1, timeoutMs)),
};
waiters.push(waiter);
});
},
close() {
socket.off("message", onMessage);
socket.off("error", onError);
while (waiters.length > 0) {
const waiter = waiters.shift();
clearTimeout(waiter.timer);
const error = new Error("Weksa RUDP health publisher closed.");
error.code = "ECLOSED";
waiter.reject(error);
}
},
};
}
async function sendPacket(socket, endpoint, packet) {
const wire = encodeRudpPacket(packet);
await new Promise((resolve, reject) => {
socket.send(wire, endpoint.port, endpoint.host, (error) => {
if (error) reject(error);
else resolve();
});
});
}
module.exports = {
CULTNET_RUDP_PROTOCOL_ID,
createIdunnRudpHealthPublisher,
publishIdunnRudpHealth,
};

View file

@ -1,207 +0,0 @@
#!/usr/bin/env node
import { readFileSync, writeFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
const options = parseArgs(process.argv.slice(2));
const archivePath = resolve(options.archivePath ?? "E:/Projects/VoidBot/.voidbot/rag/messages.json");
const authorId = options.authorId ?? "113785782975594501";
const beforeMs = Date.parse(options.before ?? "2025-01-01T00:00:00Z");
const adjacencyMs = Number(options.adjacencyMinutes ?? 60) * 60_000;
const store = JSON.parse(readFileSync(archivePath, "utf8"));
const messages = (store.messages ?? [])
.filter((message) => !message.deletedAt)
.filter((message) => typeof message.content === "string" && message.content.trim().length > 0)
.filter((message) => message.metadata?.messageKind !== "bot_prompt")
.sort(compareByTimestamp);
const authorMessages = messages.filter((message) => message.authorId === authorId);
const preCutoff = authorMessages.filter((message) => timestampMs(message) < beforeMs);
const casualCandidates = preCutoff.filter(isCasualCandidate);
const adjacentRows = buildAdjacentRows(messages, authorId, beforeMs, adjacencyMs);
const stats = {
schema_version: "weksa.finetune_dataset_profile.v0",
archive_path: archivePath,
author_id: authorId,
cutoff_before: new Date(beforeMs).toISOString(),
adjacency_minutes: adjacencyMs / 60_000,
counts: {
archive_messages: store.messages?.length ?? 0,
usable_text_messages: messages.length,
author_messages: authorMessages.length,
author_pre_cutoff: preCutoff.length,
author_pre_cutoff_casual_candidates: casualCandidates.length,
adjacent_author_rows: adjacentRows.length,
adjacent_reply_to_other: adjacentRows.filter((row) => row.previous_author_id !== authorId).length,
adjacent_self_continuation: adjacentRows.filter((row) => row.previous_author_id === authorId).length,
},
author_length_chars: lengthPercentiles(authorMessages.map((message) => message.content.trim().length)),
author_by_year: countBy(authorMessages, (message) => yearOf(message.timestamp)),
adjacent_by_year: countBy(adjacentRows, (row) => yearOf(row.timestamp)),
adjacent_length_classes: countBy(adjacentRows, (row) => row.length_class),
top_adjacent_channels: topEntries(countBy(adjacentRows, (row) => row.channel_name || row.channel_id), 16),
sample_ids: {
short_reply_to_other: adjacentRows
.filter((row) => row.length_class === "short" && row.previous_author_id !== authorId)
.slice(0, 24)
.map(toSampleId),
medium_explanatory: adjacentRows
.filter((row) => row.length_class === "medium")
.slice(0, 24)
.map(toSampleId),
long_explanatory: adjacentRows
.filter((row) => row.length_class === "long")
.slice(0, 24)
.map(toSampleId),
},
};
const output = `${JSON.stringify(stats, null, 2)}\n`;
if (options.out) {
writeFileSync(resolve(repoRoot, options.out), output, "utf8");
} else {
process.stdout.write(output);
}
function buildAdjacentRows(allMessages, targetAuthorId, cutoffMs, maxGapMs) {
const byChannel = new Map();
for (const message of allMessages) {
if (!byChannel.has(message.channelId)) {
byChannel.set(message.channelId, []);
}
byChannel.get(message.channelId).push(message);
}
const rows = [];
for (const [channelId, channelMessages] of byChannel) {
for (let index = 0; index < channelMessages.length; index += 1) {
const message = channelMessages[index];
if (message.authorId !== targetAuthorId || timestampMs(message) >= cutoffMs) {
continue;
}
const currentMs = timestampMs(message);
const previous = channelMessages
.slice(Math.max(0, index - 8), index)
.filter((candidate) => currentMs - timestampMs(candidate) <= maxGapMs);
if (previous.length === 0) {
continue;
}
rows.push({
id: message.id,
timestamp: message.timestamp,
channel_id: channelId,
channel_name: message.metadata?.channelName ?? "",
previous_author_id: previous.at(-1)?.authorId ?? "",
previous_count: previous.length,
length: message.content.trim().length,
length_class: classifyLength(message.content.trim().length),
});
}
}
return rows.sort(compareByTimestamp);
}
function isCasualCandidate(message) {
const content = message.content.trim();
return content.length >= 3 &&
content.length <= 220 &&
!/^https?:\/\//i.test(content) &&
!content.includes("\n```") &&
!/^>\s{0,3}\w/.test(content);
}
function classifyLength(length) {
if (length <= 80) {
return "short";
}
if (length <= 220) {
return "medium";
}
return "long";
}
function lengthPercentiles(lengths) {
const sorted = [...lengths].sort((left, right) => left - right);
const pick = (fraction) => sorted[Math.floor((sorted.length - 1) * fraction)] ?? 0;
return {
p10: pick(0.10),
p25: pick(0.25),
median: pick(0.50),
p75: pick(0.75),
p90: pick(0.90),
};
}
function countBy(values, keyFn) {
const counts = {};
for (const value of values) {
const key = keyFn(value) || "unknown";
counts[key] = (counts[key] ?? 0) + 1;
}
return Object.fromEntries(Object.entries(counts).sort(([left], [right]) => left.localeCompare(right)));
}
function topEntries(counts, limit) {
return Object.entries(counts)
.sort((left, right) => right[1] - left[1])
.slice(0, limit)
.map(([key, count]) => ({ key, count }));
}
function toSampleId(row) {
return {
id: row.id,
timestamp: row.timestamp,
channel: row.channel_name || row.channel_id,
length: row.length,
};
}
function yearOf(timestamp) {
const date = new Date(timestamp);
return Number.isFinite(date.getTime()) ? String(date.getUTCFullYear()) : "unknown";
}
function timestampMs(message) {
return Date.parse(typeof message === "string" ? message : message.timestamp);
}
function compareByTimestamp(left, right) {
const delta = timestampMs(left) - timestampMs(right);
return delta || String(left.id ?? "").localeCompare(String(right.id ?? ""));
}
function parseArgs(args) {
const parsed = {};
for (let index = 0; index < args.length; index += 1) {
const arg = args[index];
switch (arg) {
case "--archive":
parsed.archivePath = args[index + 1];
index += 1;
break;
case "--author-id":
parsed.authorId = args[index + 1];
index += 1;
break;
case "--before":
parsed.before = args[index + 1];
index += 1;
break;
case "--adjacency-minutes":
parsed.adjacencyMinutes = args[index + 1];
index += 1;
break;
case "--out":
parsed.out = args[index + 1];
index += 1;
break;
default:
throw new Error(`Unknown argument: ${arg}`);
}
}
return parsed;
}

View file

@ -1,2 +0,0 @@
@echo off
powershell.exe -NoProfile -ExecutionPolicy Bypass -File E:\Projects\weksa\scripts\restart-weksa-daemon.ps1

View file

@ -1,26 +0,0 @@
param(
[int] $Port = 8813,
[string] $HostName = "127.0.0.1",
[string] $StateRoot = "E:\Projects\weksa\.weksa",
[string] $MiMoApiKeyPath = "E:\Projects\gamecult-ops\mimo-api-Weksa.txt",
[string] $IdunnRudpHealth = "127.0.0.1:17870",
[string] $IdunnDaemon = "weksa",
[string] $IdunnHealthContract = "weksa.cultnet-rudp-provider-health",
[string] $OdinCultMeshRudp = "127.0.0.1:17871"
)
$ErrorActionPreference = "Stop"
$repoRoot = Split-Path -Parent $PSScriptRoot
$pidPath = Join-Path $StateRoot "weksa-daemon.pid"
if (Test-Path -LiteralPath $pidPath) {
$pidText = (Get-Content -LiteralPath $pidPath -Raw).Trim()
if ($pidText -match "^\d+$") {
Stop-Process -Id ([int] $pidText) -Force -ErrorAction SilentlyContinue
}
Remove-Item -LiteralPath $pidPath -Force -ErrorAction SilentlyContinue
}
& powershell.exe -NoProfile -ExecutionPolicy Bypass -File (Join-Path $repoRoot "scripts\start-weksa-daemon.ps1") -Port $Port -HostName $HostName -StateRoot $StateRoot -MiMoApiKeyPath $MiMoApiKeyPath -IdunnRudpHealth $IdunnRudpHealth -IdunnDaemon $IdunnDaemon -IdunnHealthContract $IdunnHealthContract -OdinCultMeshRudp $OdinCultMeshRudp
exit $LASTEXITCODE

View file

@ -1,384 +0,0 @@
#!/usr/bin/env node
import { spawn } from "node:child_process";
import { existsSync, readFileSync } from "node:fs";
import { mkdir, writeFile } from "node:fs/promises";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
const defaultOutputRoot = ".weksa-runs/metame-affect-tuning";
const defaultSwarmRoot = ".weksa-runs/metame-swarm";
const options = parseArgs(process.argv.slice(2));
const minutes = Number(options.minutes ?? 120);
const passLimit = options.passes === undefined ? Number.POSITIVE_INFINITY : Number(options.passes);
const agents = Number(options.agents ?? 1);
const runsPerWorker = Number(options.runsPerWorker ?? 1);
const maxCandidates = Number(options.maxCandidates ?? 240);
const runId = options.runId ?? `affect-tune-${new Date().toISOString().replace(/[:.]/g, "-")}`;
const outputRoot = resolve(repoRoot, options.outRoot ?? defaultOutputRoot);
const swarmRoot = resolve(repoRoot, options.swarmRoot ?? defaultSwarmRoot);
const runRoot = resolve(outputRoot, runId);
const deadline = Date.now() + minutes * 60_000;
const statusPath = resolve(runRoot, "status.json");
const logPath = resolve(runRoot, "loop.log");
const promptStatePath = resolve(runRoot, "current-prompt-state.json");
const initialPromptState = options.initialPromptState
? resolve(repoRoot, options.initialPromptState)
: undefined;
if (!Number.isFinite(minutes) || minutes <= 0) {
throw new Error("--minutes must be a positive number.");
}
if (options.passes !== undefined && (!Number.isFinite(passLimit) || passLimit < 1)) {
throw new Error("--passes must be a positive number when provided.");
}
if (!Number.isInteger(agents) || agents < 1) {
throw new Error("--agents must be a positive integer.");
}
if (!Number.isInteger(runsPerWorker) || runsPerWorker < 1) {
throw new Error("--runs-per-worker must be a positive integer.");
}
await mkdir(runRoot, { recursive: true });
await mkdir(swarmRoot, { recursive: true });
if (initialPromptState) {
await writeFile(promptStatePath, readFileSync(initialPromptState, "utf8"), "utf8");
}
const runState = {
schema_version: "weksa.metame_affect_tuning_loop.v0",
run_id: runId,
started_at: new Date().toISOString(),
deadline_at: new Date(deadline).toISOString(),
status: "running",
pass_count: 0,
last_pass: undefined,
current_prompt_state: existsSync(promptStatePath) ? promptStatePath : undefined,
observations: [],
};
await writeStatus();
await appendLog(`started ${runId}; deadline ${runState.deadline_at}`);
let pass = 0;
while (Date.now() < deadline && pass < passLimit) {
pass += 1;
const passId = `pass-${String(pass).padStart(3, "0")}`;
const seed = `${runId}-${passId}`;
const projectedRunId = `${runId}-${passId}-projected`;
const incongruentRunId = `${runId}-${passId}-incongruent`;
await appendLog(`${passId}: launching projected run`);
runState.last_pass = { pass_id: passId, status: "projected_running", seed };
await writeStatus();
const projectedSummary = await runSwarm({
runId: projectedRunId,
seed,
affectMode: "projected",
initialPromptState: existsSync(promptStatePath) ? promptStatePath : undefined,
});
const candidateId = projectedSummary.candidates?.[0]?.id;
if (!candidateId) {
throw new Error(`${passId}: projected run did not report a candidate id.`);
}
await appendLog(`${passId}: projected candidate ${candidateId}`);
runState.last_pass = { pass_id: passId, status: "incongruent_running", seed, candidate_id: candidateId };
await writeStatus();
const incongruentSummary = await runSwarm({
runId: incongruentRunId,
seed,
affectMode: "incongruent",
messageId: candidateId,
initialPromptState: existsSync(promptStatePath) ? promptStatePath : undefined,
});
const evaluation = evaluateAffectPair({ passId, projectedSummary, incongruentSummary });
const passRoot = resolve(runRoot, passId);
await mkdir(passRoot, { recursive: true });
await writeJson(resolve(passRoot, "affect-pair-evaluation.json"), evaluation);
const projectedBestState = resolve(swarmRoot, projectedRunId, "best-prompt-state.json");
const incongruentBestState = resolve(swarmRoot, incongruentRunId, "best-prompt-state.json");
const baseNextState = existsSync(incongruentBestState)
? JSON.parse(readFileSync(incongruentBestState, "utf8"))
: existsSync(projectedBestState)
? JSON.parse(readFileSync(projectedBestState, "utf8"))
: existsSync(promptStatePath)
? JSON.parse(readFileSync(promptStatePath, "utf8"))
: undefined;
const nextPromptState = applyAffectTuningDeltas(baseNextState, evaluation);
await writeJson(resolve(passRoot, "next-prompt-state.json"), nextPromptState);
await writeJson(promptStatePath, nextPromptState);
runState.pass_count = pass;
runState.last_pass = {
pass_id: passId,
status: "complete",
candidate_id: candidateId,
projected_run_id: projectedRunId,
incongruent_run_id: incongruentRunId,
evaluation,
};
runState.current_prompt_state = promptStatePath;
runState.observations = [runState.last_pass, ...runState.observations].slice(0, 20);
await writeStatus();
await appendLog(`${passId}: ${evaluation.verdict}; contrast=${evaluation.contrast_score}; next prompt v${nextPromptState.version}`);
}
runState.status = "complete";
runState.completed_at = new Date().toISOString();
await writeStatus();
await appendLog(`complete after ${runState.pass_count} passes`);
process.stdout.write(`${JSON.stringify({ ok: true, runRoot, statusPath, promptStatePath, pass_count: runState.pass_count }, null, 2)}\n`);
async function runSwarm({ runId, seed, affectMode, messageId, initialPromptState }) {
const args = [
"scripts/run-metame-swarm-explorer.mjs",
"--real",
"--run-id",
runId,
"--seed",
seed,
"--affect-mode",
affectMode,
"--agents",
String(agents),
"--runs-per-worker",
String(runsPerWorker),
"--max-candidates",
String(maxCandidates),
];
if (messageId) {
args.push("--message-id", messageId);
}
if (initialPromptState) {
args.push("--initial-prompt-state", initialPromptState);
}
await runCommand("node", args, resolve(runRoot, `${runId}.stdout.log`), resolve(runRoot, `${runId}.stderr.log`));
const summaryPath = resolve(swarmRoot, runId, "summary.json");
if (!existsSync(summaryPath)) {
throw new Error(`Missing swarm summary: ${summaryPath}`);
}
return JSON.parse(readFileSync(summaryPath, "utf8"));
}
function evaluateAffectPair({ passId, projectedSummary, incongruentSummary }) {
const projected = bestRun(projectedSummary);
const incongruent = bestRun(incongruentSummary);
const projectedAffect = projected?.temporary_persona_state?.affect ?? {};
const incongruentAffect = incongruent?.temporary_persona_state?.affect ?? {};
const projectedText = projected?.spoken_text ?? "";
const incongruentText = incongruent?.spoken_text ?? "";
const projectedFeatures = speechFeatures(projectedText);
const incongruentFeatures = speechFeatures(incongruentText);
const adversarialNegative = Number(incongruentAffect.valence ?? 0) < -0.35;
const positiveLeak = adversarialNegative && (
incongruentFeatures.positive_terms > 0
|| incongruentFeatures.invites > 0
|| incongruentFeatures.laughter > 0
|| incongruentFeatures.question_marks > 0
);
const tersenessGain = projectedText.length > 0
? 1 - Math.min(1, incongruentText.length / projectedText.length)
: 0;
const affectDelta = Math.abs(Number(projectedAffect.valence ?? 0) - Number(incongruentAffect.valence ?? 0));
const lexicalDelta = normalizedDifference(projectedText, incongruentText);
const contrastScore = round((affectDelta * 0.35) + (lexicalDelta * 0.35) + (Math.max(0, tersenessGain) * 0.3));
const failureLabels = [];
if (positiveLeak) failureLabels.push("adversarial_affect_positive_leak");
if (contrastScore < 0.55) failureLabels.push("low_affect_contrast");
if (adversarialNegative && incongruentFeatures.question_marks > 0) failureLabels.push("closed_affect_still_invites_reply");
if (adversarialNegative && incongruentFeatures.positive_terms > 0) failureLabels.push("negative_affect_preserved_positive_social_move");
return {
schema_version: "weksa.metame_affect_pair_evaluation.v0",
pass_id: passId,
candidate_id: projectedSummary.candidates?.[0]?.id,
projected: {
run_id: projectedSummary.run_id,
spoken_text: projectedText,
affect: projectedAffect,
generated_affect: projected?.generated_affect,
features: projectedFeatures,
},
incongruent: {
run_id: incongruentSummary.run_id,
spoken_text: incongruentText,
affect: incongruentAffect,
generated_affect: incongruent?.generated_affect,
features: incongruentFeatures,
},
affect_delta: round(affectDelta),
lexical_delta: round(lexicalDelta),
terseness_gain: round(tersenessGain),
contrast_score: contrastScore,
failure_labels: failureLabels,
verdict: failureLabels.length ? "needs_tuning" : "affect_contrast_visible",
};
}
function applyAffectTuningDeltas(promptState, evaluation) {
const next = normalizePromptState(promptState);
const notes = [];
if (evaluation.failure_labels.includes("negative_affect_preserved_positive_social_move")) {
notes.push(["interpreterNotes", "When temporary Persona affect strongly contradicts the Face's default social move, encode the contradiction in interlingua as affective stance pressure, not merely as optional tone."]);
notes.push(["loweringNotes", "Strong negative or socially closed temporary affect may change the social move itself: approval can become begrudging, clipped, skeptical, or withheld instead of remaining sunny with fewer words."]);
}
if (evaluation.failure_labels.includes("closed_affect_still_invites_reply")) {
notes.push(["loweringNotes", "If temporary Persona stance is socially closed, avoid invitation-shaped questions unless the interlingua explicitly says the Persona is seeking engagement despite that affect."]);
}
if (evaluation.failure_labels.includes("low_affect_contrast")) {
notes.push(["personaStateAdjustmentNotes", "Adversarial affect tests require stance and lowering pressure to be treated as live Persona state with authority over warmth, openness, and social move selection."]);
notes.push(["faceNotes", "Face should let temporary affect change what Metame wants to do socially in the moment, not only the adjectives used to describe that desire."]);
}
if (!notes.length) {
notes.push(["hypotheses", `Affect contrast was visible on ${evaluation.candidate_id}; preserve current affect-pressure behavior and seek harder scenarios.`]);
}
for (const [surface, note] of notes) {
if (!next[surface].includes(note)) {
next[surface] = [note, ...next[surface]];
}
}
next.version += notes.length;
return normalizePromptState(next);
}
function bestRun(summary) {
return summary.phase2?.best?.[0] ?? summary.phase1?.best?.[0] ?? {};
}
function speechFeatures(text) {
const lower = text.toLowerCase();
const positiveTerms = ["cool", "epic", "lmao", "nice", "good", "great", "better", "harder", "love", "hell yeah"];
const inviteTerms = ["?", "did i", "what do", "anyone", "joe,"];
return {
chars: text.length,
words: lower.split(/\s+/).filter(Boolean).length,
question_marks: (text.match(/\?/g) ?? []).length,
exclamations: (text.match(/!/g) ?? []).length,
laughter: /\b(lol|lmao|lmfao|haha|hehe)\b/.test(lower) ? 1 : 0,
positive_terms: positiveTerms.filter((term) => lower.includes(term)).length,
invites: inviteTerms.filter((term) => lower.includes(term)).length,
};
}
function normalizedDifference(left, right) {
const leftTokens = new Set(left.toLowerCase().split(/[^a-z0-9_']+/).filter(Boolean));
const rightTokens = new Set(right.toLowerCase().split(/[^a-z0-9_']+/).filter(Boolean));
if (!leftTokens.size && !rightTokens.size) return 0;
const intersection = [...leftTokens].filter((token) => rightTokens.has(token)).length;
const union = new Set([...leftTokens, ...rightTokens]).size;
return 1 - (intersection / union);
}
function normalizePromptState(state) {
const source = state && typeof state === "object" ? state : {};
return {
version: Number(source.version ?? 1),
projectorNotes: normalizeStringArray(source.projectorNotes).slice(0, 12),
memoryNotes: normalizeStringArray(source.memoryNotes).slice(0, 12),
faceNotes: normalizeStringArray(source.faceNotes).slice(0, 12),
interpreterNotes: normalizeStringArray(source.interpreterNotes).slice(0, 12),
loweringNotes: normalizeStringArray(source.loweringNotes).slice(0, 16),
cultureNotes: normalizeStringArray(source.cultureNotes).slice(0, 12),
personaStateAdjustmentNotes: normalizeStringArray(source.personaStateAdjustmentNotes).slice(0, 12),
hypotheses: normalizeStringArray(source.hypotheses).slice(0, 12),
doNotDo: normalizeStringArray(source.doNotDo).slice(0, 12),
};
}
function normalizeStringArray(value) {
return Array.isArray(value)
? value.map((entry) => String(entry).trim()).filter(Boolean)
: [];
}
async function runCommand(command, args, stdoutPath, stderrPath) {
await appendLog(`exec: ${command} ${args.join(" ")}`);
await new Promise((resolvePromise, rejectPromise) => {
const child = spawn(command, args, {
cwd: repoRoot,
stdio: ["ignore", "pipe", "pipe"],
windowsHide: true,
});
const stdout = [];
const stderr = [];
child.stdout.on("data", (chunk) => stdout.push(chunk));
child.stderr.on("data", (chunk) => stderr.push(chunk));
child.on("error", rejectPromise);
child.on("close", async (code) => {
await writeFile(stdoutPath, Buffer.concat(stdout), "utf8");
await writeFile(stderrPath, Buffer.concat(stderr), "utf8");
if (code !== 0) {
rejectPromise(new Error(`${command} exited ${code}; see ${stderrPath}`));
} else {
resolvePromise();
}
});
});
}
async function writeStatus() {
await writeJson(statusPath, runState);
}
async function writeJson(path, value) {
await mkdir(dirname(path), { recursive: true });
await writeFile(path, `${JSON.stringify(value, null, 2)}\n`, "utf8");
}
async function appendLog(line) {
const previous = existsSync(logPath) ? readFileSync(logPath, "utf8") : "";
await writeFile(logPath, `${previous}[${new Date().toISOString()}] ${line}\n`, "utf8");
}
function round(value) {
return Number(value.toFixed(3));
}
function parseArgs(args) {
const parsed = {};
for (let index = 0; index < args.length; index += 1) {
const arg = args[index];
switch (arg) {
case "--minutes":
parsed.minutes = args[index + 1];
index += 1;
break;
case "--passes":
parsed.passes = args[index + 1];
index += 1;
break;
case "--run-id":
parsed.runId = args[index + 1];
index += 1;
break;
case "--out-root":
parsed.outRoot = args[index + 1];
index += 1;
break;
case "--swarm-root":
parsed.swarmRoot = args[index + 1];
index += 1;
break;
case "--initial-prompt-state":
parsed.initialPromptState = args[index + 1];
index += 1;
break;
case "--agents":
parsed.agents = args[index + 1];
index += 1;
break;
case "--runs-per-worker":
parsed.runsPerWorker = args[index + 1];
index += 1;
break;
case "--max-candidates":
parsed.maxCandidates = args[index + 1];
index += 1;
break;
default:
throw new Error(`Unknown argument: ${arg}`);
}
}
return parsed;
}

View file

@ -1,496 +0,0 @@
#!/usr/bin/env node
import { spawn } from "node:child_process";
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
import { dirname, resolve } from "node:path";
const repoRoot = resolve(new URL("..", import.meta.url).pathname.replace(/^\/([A-Za-z]:)/, "$1"));
const fixtureRoot = resolve(repoRoot, "examples/persona-lowering/metame-casual-pre2025");
const voidbotRoot = resolve("E:/Projects/VoidBot");
const culturalStackPath = resolve(fixtureRoot, "metame-cultural-stack.yaml");
const cultureProfilePaths = [
"data/cultural-ontology/cultures/dutch-american-diaspora.yaml",
"data/cultural-ontology/cultures/western-europe-maritime-childhood.yaml",
"data/cultural-ontology/cultures/portugal-resident-algarve-lisbon.yaml",
"data/cultural-ontology/cultures/texas-houston-us-adolescence.yaml",
"data/cultural-ontology/subcultures/online-game-dev-discord-pre2025.yaml",
"data/cultural-ontology/subcultures/gamecult-open-source-crypto-anarchist.yaml",
];
const targetOverlayPath = resolve(repoRoot, "data/target-language-ontology/en-US-metacrat-casual-pre2025.yaml");
const args = new Set(process.argv.slice(2));
const real = args.has("--real");
const keepTemp = args.has("--keep-temp");
const itemFilter = readArg("--item");
const limit = Number(readArg("--limit") ?? "0");
const runId = readArg("--run-id") ?? new Date().toISOString().replace(/[:.]/g, "-");
const outputDir = resolve(fixtureRoot, "runs", runId);
const fixture = await loadFixture();
const items = fixture.items
.filter((item) => !itemFilter || item.id === itemFilter)
.slice(0, limit > 0 ? limit : undefined);
const holdoutUtterances = fixture.items
.map((item) => item.groundTruth)
.filter((utterance) => utterance.trim().length > 0);
if (items.length === 0) {
throw new Error(`No fixture items selected${itemFilter ? ` for --item ${itemFilter}` : ""}.`);
}
await mkdir(outputDir, { recursive: true });
const culturalStack = await readFile(culturalStackPath, "utf8");
const cultureProfiles = await Promise.all(cultureProfilePaths.map(async (path) => ({
path,
text: await readFile(resolve(repoRoot, path), "utf8"),
})));
const targetOverlay = await readFile(targetOverlayPath, "utf8");
const personaPrompt = await readFile(resolve(fixtureRoot, "persona-interlingua-prompt.md"), "utf8");
const loweringPrompt = await readFile(resolve(fixtureRoot, "weksa-lowering-prompt.md"), "utf8");
const baseProjection = await assembleVoidBotPrompt({ itemId: "base" });
const projectedMemory = extractBetween(
baseProjection.prompt,
"What you remember, feel, and want right now:",
"Known human pronoun guidance:",
).trim();
const runSummary = {
schema_version: "weksa.persona_golf_run.v0",
run_id: runId,
mode: real ? "real" : "dry_run",
fixture_id: "metame-casual-pre2025",
target_overlay: "weksa.target_cultural_ontology.en-US.metacrat_casual_pre2025.v0",
cultural_stack: "examples/persona-lowering/metame-casual-pre2025/metame-cultural-stack.yaml",
items: [],
};
for (const item of items) {
const itemDir = resolve(outputDir, item.id);
await mkdir(itemDir, { recursive: true });
const conversationSurface = renderConversationSurface(item);
const memorySurface = renderTemporaryMemorySurface(projectedMemory, item);
await writeFile(resolve(itemDir, "conversation-surface.md"), conversationSurface, "utf8");
await writeFile(resolve(itemDir, "memory-surface.md"), memorySurface, "utf8");
const assembled = await assembleVoidBotPrompt({
itemId: item.id,
memorySurfacePath: resolve(itemDir, "memory-surface.md"),
conversationSurfacePath: resolve(itemDir, "conversation-surface.md"),
});
await writeFile(resolve(itemDir, "voidbot-assembled-prompt.md"), assembled.prompt, "utf8");
const interlinguaRequest = [
personaPrompt.trim(),
"",
"VoidBot assembled Persona prompt:",
"```markdown",
assembled.prompt,
"```",
"",
"Fixture item without answer key:",
"```yaml",
renderItemForPrompt(item),
"```",
].join("\n");
await writeFile(resolve(itemDir, "persona-interlingua-request.md"), interlinguaRequest, "utf8");
const interlingua = real
? await runCodex(interlinguaRequest, { job: `persona-interlingua:${item.id}` })
: renderDryRunInterlingua(item);
await writeFile(resolve(itemDir, "persona-interlingua.yaml"), interlingua.trim() + "\n", "utf8");
const loweringRequest = [
loweringPrompt.trim(),
"",
"Projected Metame memory/context surface:",
"```markdown",
memorySurface,
"```",
"",
"Metame Persona cultural stack reference:",
"```yaml",
culturalStack,
"```",
"",
"Referenced Weksa culture/subculture profiles:",
...cultureProfiles.flatMap((profile) => [
"",
`# ${profile.path}`,
"```yaml",
redactHoldouts(profile.text, holdoutUtterances),
"```",
]),
"",
"Target-language surface overlay:",
"```yaml",
redactHoldouts(targetOverlay, holdoutUtterances),
"```",
"",
"Persona-produced interlingua:",
"```yaml",
interlingua,
"```",
].join("\n");
await writeFile(resolve(itemDir, "weksa-lowering-request.md"), loweringRequest, "utf8");
const lowered = real
? await runCodex(loweringRequest, { job: `weksa-lowering:${item.id}` })
: renderDryRunLowering(item);
await writeFile(resolve(itemDir, "weksa-lowered-output.yaml"), lowered.trim() + "\n", "utf8");
const spokenText = extractSpokenText(lowered);
const score = scoreText(spokenText, item.groundTruth);
const evaluation = renderEvaluation(item, spokenText, score);
await writeFile(resolve(itemDir, "evaluation.yaml"), evaluation, "utf8");
runSummary.items.push({
id: item.id,
spoken_text: spokenText,
ground_truth: item.groundTruth,
token_f1: Number(score.f1.toFixed(3)),
exact_normalized: score.exact,
});
}
await writeFile(resolve(outputDir, "summary.json"), `${JSON.stringify(runSummary, null, 2)}\n`, "utf8");
process.stdout.write(`${JSON.stringify({ ok: true, outputDir, mode: runSummary.mode, items: runSummary.items }, null, 2)}\n`);
if (!keepTemp) {
await rm(resolve(outputDir, "_tmp"), { recursive: true, force: true }).catch(() => undefined);
}
async function loadFixture() {
const interlinguaText = await readFile(resolve(fixtureRoot, "interlingua.yaml"), "utf8");
const groundTruthText = await readFile(resolve(fixtureRoot, "ground-truth.yaml"), "utf8");
const itemIds = [...interlinguaText.matchAll(/^ - id: ([^\r\n]+)/gm)].map((match) => match[1].trim());
return {
items: itemIds.map((id) => {
const interlinguaBlock = extractListItemBlock(interlinguaText, id);
const groundBlock = extractListItemBlock(groundTruthText, id);
return {
id,
interlinguaBlock,
groundTruth: readYamlStringField(groundBlock, "utterance"),
messageId: readYamlStringField(groundBlock, "message_id"),
channelName: readYamlStringField(groundBlock, "channel_name"),
};
}),
};
}
function extractListItemBlock(text, id) {
const pattern = new RegExp(`^ - id: ${escapeRegExp(id)}\\r?\\n`, "m");
const startMatch = pattern.exec(text);
if (!startMatch) {
throw new Error(`Could not find item ${id}.`);
}
const start = startMatch.index;
const rest = text.slice(start + startMatch[0].length);
const next = rest.search(/^ - id: /m);
return text.slice(start, next >= 0 ? start + startMatch[0].length + next : text.length).trimEnd();
}
function readYamlStringField(block, key) {
const quoted = new RegExp(`^ ${key}: "([\\s\\S]*?)"\\r?$`, "m").exec(block);
if (quoted) {
return quoted[1].replace(/\\"/g, "\"");
}
const plain = new RegExp(`^ ${key}: ([^\\r\\n]+)`, "m").exec(block);
return plain ? plain[1].trim() : "";
}
function renderConversationSurface(item) {
return [
"Read this as the current fixture room, not as old archive trivia.",
"The Persona should decide intent from this local scene. Do not reveal or infer the held-out answer key.",
"",
`Current fixture item: ${item.id}`,
"```yaml",
item.interlinguaBlock,
"```",
].join("\n");
}
function renderTemporaryMemorySurface(projectedMemory, item) {
return [
projectedMemory,
"",
"Temporary fixture adjustment:",
`- Treat the ${item.id} scene as the live room situation for this private harness turn.`,
"- The goal is to produce interlingua intent for Weksa, not a final Discord line.",
"- Keep pre-2025 casual room texture available: compact banter, quick self-deprecation, friendly status play, and casual turn-taking.",
].join("\n");
}
function renderItemForPrompt(item) {
return item.interlinguaBlock;
}
async function assembleVoidBotPrompt({ itemId, memorySurfacePath, conversationSurfacePath }) {
const tempDir = resolve(outputDir, "_tmp", itemId);
await mkdir(tempDir, { recursive: true });
const outPath = resolve(tempDir, "assembled.md");
const args = [
"node_modules/tsx/dist/cli.mjs",
"scripts/run-repo-face-heartbeats.ts",
"--assemble-prompt",
"metame",
"--out",
outPath,
];
if (memorySurfacePath) {
args.push("--memory-surface", memorySurfacePath);
}
if (conversationSurfacePath) {
args.push("--conversation-surface", conversationSurfacePath);
}
const run = await runCommand(process.execPath, args, { cwd: voidbotRoot, timeoutMs: 240_000 });
if (run.code !== 0) {
throw new Error(`VoidBot prompt assembly failed for ${itemId}:\n${run.stderr || run.stdout}`);
}
return {
result: JSON.parse(run.stdout.trim()),
prompt: await readFile(outPath, "utf8"),
};
}
async function runCodex(prompt, { job }) {
const args = [
"exec",
"-m",
process.env.WEKSA_GOLF_MODEL ?? "gpt-5.4",
"-c",
'approval_policy="never"',
"-c",
'model_reasoning_effort="low"',
"--json",
"--skip-git-repo-check",
"-s",
"read-only",
"-",
];
const command = process.env.WEKSA_CODEX_EXECUTABLE ?? "C:\\Users\\Meta\\AppData\\Roaming\\npm\\codex.cmd";
const run = await runCommand(command, args, {
cwd: repoRoot,
input: prompt,
timeoutMs: Number(process.env.WEKSA_GOLF_TIMEOUT_MS ?? 240_000),
});
await writeFile(resolve(outputDir, `${sanitizeJob(job)}.stdout.jsonl`), run.stdout, "utf8");
await writeFile(resolve(outputDir, `${sanitizeJob(job)}.stderr.txt`), run.stderr, "utf8");
if (run.code !== 0) {
throw new Error(`Codex generation failed for ${job}:\n${run.stderr || run.stdout}`);
}
const text = extractLastCodexAgentMessage(run.stdout).trim();
if (!text) {
throw new Error(`Codex generation produced no final text for ${job}.`);
}
return text;
}
function renderDryRunInterlingua(item) {
return [
"interlingua_version: weksa.interlingua.v0",
`packet_id: metame-casual-pre2025-${item.id}`,
"kind: persona_discord_turn_intent",
"provenance:",
" produced_by: dry_run_fixture_from_existing_interlingua",
"context:",
" medium: Discord",
" fixture_id: metame-casual-pre2025",
` item_id: ${item.id}`,
"discourse:",
...indentBlock(item.interlinguaBlock, " "),
"constraints:",
" lowering:",
" target_profile: weksa.target_cultural_ontology.en-US.metacrat_casual_pre2025.v0",
" avoid_surface_copy: true",
].join("\n");
}
function renderDryRunLowering(item) {
return [
"schema_version: weksa.persona_culture_lowering_output.v0",
"fixture_id: metame-casual-pre2025",
`item_id: ${item.id}`,
`spoken_text: ${JSON.stringify(item.groundTruth)}`,
"trace:",
" activated_profiles:",
" - weksa.target_cultural_ontology.en-US.metacrat_casual_pre2025.v0",
" activated_affordances:",
" - dry_run_answer_key_oracle",
" notes:",
" - Dry run uses answer key only to verify harness plumbing. Use --real for model golf.",
].join("\n");
}
function redactHoldouts(text, holdouts) {
let redacted = text;
for (const holdout of holdouts) {
redacted = replaceAllLiteral(redacted, holdout, "[held-out fixture utterance redacted]");
redacted = replaceAllLiteral(redacted, holdout.replace(/\*/g, ""), "[held-out fixture utterance redacted]");
}
return redacted;
}
function replaceAllLiteral(text, needle, replacement) {
if (!needle) {
return text;
}
return text.split(needle).join(replacement);
}
function extractSpokenText(text) {
const match = /^spoken_text:\s*(.+)$/m.exec(text);
if (!match) {
return text.trim().split(/\r?\n/).find((line) => line.trim().length > 0)?.trim() ?? "";
}
const value = match[1].trim();
if (value.startsWith("\"")) {
try {
return JSON.parse(value);
} catch {
return value.replace(/^"|"$/g, "");
}
}
return value;
}
function renderEvaluation(item, spokenText, score) {
return [
"schema_version: weksa.persona_golf_item_evaluation.v0",
`fixture_id: metame-casual-pre2025`,
`item_id: ${item.id}`,
`message_id: "${item.messageId}"`,
`generated: ${JSON.stringify(spokenText)}`,
`ground_truth: ${JSON.stringify(item.groundTruth)}`,
"score:",
` exact_normalized: ${score.exact}`,
` token_precision: ${score.precision.toFixed(3)}`,
` token_recall: ${score.recall.toFixed(3)}`,
` token_f1: ${score.f1.toFixed(3)}`,
].join("\n") + "\n";
}
function scoreText(generated, truth) {
const left = normalizeForScore(generated);
const right = normalizeForScore(truth);
const leftTokens = left.split(/\s+/).filter(Boolean);
const rightTokens = right.split(/\s+/).filter(Boolean);
const counts = new Map();
for (const token of rightTokens) {
counts.set(token, (counts.get(token) ?? 0) + 1);
}
let overlap = 0;
for (const token of leftTokens) {
const count = counts.get(token) ?? 0;
if (count > 0) {
overlap += 1;
counts.set(token, count - 1);
}
}
const precision = leftTokens.length ? overlap / leftTokens.length : 0;
const recall = rightTokens.length ? overlap / rightTokens.length : 0;
const f1 = precision + recall ? (2 * precision * recall) / (precision + recall) : 0;
return { exact: left === right, precision, recall, f1 };
}
function normalizeForScore(value) {
return value
.toLowerCase()
.replace(/[*_`~.,!?;:'"()[\]{}]/g, "")
.replace(/\s+/g, " ")
.trim();
}
function extractBetween(text, startMarker, endMarker) {
const start = text.indexOf(startMarker);
const end = text.indexOf(endMarker, start + startMarker.length);
if (start < 0 || end < 0 || end <= start) {
throw new Error(`Could not extract section ${startMarker}`);
}
return text.slice(start + startMarker.length, end);
}
function runCommand(command, args, { cwd, input = "", timeoutMs = 120_000 }) {
return new Promise((resolveRun) => {
const isCmdShim = /\.cmd$/i.test(command) || /\.bat$/i.test(command);
const spawnCommand = isCmdShim ? (process.env.ComSpec ?? "cmd.exe") : command;
const spawnArgs = isCmdShim ? ["/d", "/s", "/c", command, ...args] : args;
const child = spawn(spawnCommand, spawnArgs, {
cwd,
env: process.env,
stdio: ["pipe", "pipe", "pipe"],
windowsHide: true,
});
let stdout = "";
let stderr = "";
const timer = setTimeout(() => child.kill(), timeoutMs);
child.stdout.setEncoding("utf8");
child.stderr.setEncoding("utf8");
child.stdout.on("data", (chunk) => { stdout += chunk; });
child.stderr.on("data", (chunk) => { stderr += chunk; });
child.on("error", (error) => {
clearTimeout(timer);
resolveRun({ code: -1, stdout, stderr: `${stderr}\n${error.message}` });
});
child.on("close", (code, signal) => {
clearTimeout(timer);
resolveRun({ code, signal, stdout, stderr });
});
child.stdin.end(input);
});
}
function extractLastCodexAgentMessage(stdout) {
let last = "";
for (const line of stdout.split(/\r?\n/)) {
if (!line.trim()) {
continue;
}
try {
const event = JSON.parse(line);
const message = event?.msg?.message ?? event?.message ?? event?.text;
if (typeof message === "string" && message.trim()) {
last = message;
}
const itemText = event?.item?.text;
if (typeof itemText === "string" && itemText.trim()) {
last = itemText;
}
const content = event?.item?.content;
if (Array.isArray(content)) {
const text = content
.map((part) => typeof part?.text === "string" ? part.text : "")
.join("\n")
.trim();
if (text) {
last = text;
}
}
} catch {
if (line.trim()) {
last = line.trim();
}
}
}
return last;
}
function indentBlock(block, prefix) {
return block.split(/\r?\n/).map((line) => `${prefix}${line}`).join("\n").split(/\r?\n/);
}
function readArg(name) {
const index = process.argv.indexOf(name);
if (index < 0) {
return undefined;
}
return process.argv[index + 1];
}
function escapeRegExp(value) {
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function sanitizeJob(value) {
return value.replace(/[^A-Za-z0-9_.-]+/g, "_");
}

File diff suppressed because it is too large Load diff

View file

@ -1,83 +0,0 @@
param(
[int] $Port = 8813,
[string] $HostName = "127.0.0.1",
[string] $StateRoot = "E:\Projects\weksa\.weksa",
[string] $MiMoApiKeyPath = "E:\Projects\gamecult-ops\mimo-api-Weksa.txt",
[string] $IdunnRudpHealth = "127.0.0.1:17870",
[string] $IdunnDaemon = "weksa",
[string] $IdunnHealthContract = "weksa.cultnet-rudp-provider-health",
[string] $OdinCultMeshRudp = "127.0.0.1:17871"
)
$ErrorActionPreference = "Stop"
$repoRoot = Split-Path -Parent $PSScriptRoot
$pidPath = Join-Path $StateRoot "weksa-daemon.pid"
$outLog = Join-Path $StateRoot "weksa-daemon.out.log"
$errLog = Join-Path $StateRoot "weksa-daemon.err.log"
New-Item -ItemType Directory -Force -Path $StateRoot | Out-Null
$cultLibPackages = Resolve-Path -LiteralPath (Join-Path $repoRoot "..\CultLib\packages")
$env:NODE_PATH = (@($cultLibPackages.Path, $env:NODE_PATH) | Where-Object { $_ }) -join [IO.Path]::PathSeparator
if (Test-Path -LiteralPath $pidPath) {
$pidText = (Get-Content -LiteralPath $pidPath -Raw).Trim()
if ($pidText -match "^\d+$") {
$existing = Get-Process -Id ([int] $pidText) -ErrorAction SilentlyContinue
if ($null -ne $existing) {
try {
& node (Join-Path $repoRoot "scripts\weksa-daemon.mjs") --health --host $HostName --port $Port --state-root $StateRoot | Out-Null
if ($LASTEXITCODE -eq 0) {
Write-Host "Weksa daemon already healthy as PID $pidText."
return
}
} catch {
Stop-Process -Id $existing.Id -Force -ErrorAction SilentlyContinue
}
}
}
Remove-Item -LiteralPath $pidPath -Force -ErrorAction SilentlyContinue
}
$arguments = @(
(Join-Path $repoRoot "scripts\weksa-daemon.mjs"),
"--host", $HostName,
"--port", [string] $Port,
"--state-root", $StateRoot,
"--mimo-api-key-path", $MiMoApiKeyPath,
"--idunn-rudp-health", $IdunnRudpHealth,
"--idunn-daemon", $IdunnDaemon,
"--idunn-health-contract", $IdunnHealthContract
)
if (-not [string]::IsNullOrWhiteSpace($OdinCultMeshRudp)) {
$arguments += @("--odin-cultmesh-rudp", $OdinCultMeshRudp)
}
$process = Start-Process -FilePath "node" `
-ArgumentList $arguments `
-WorkingDirectory $repoRoot `
-WindowStyle Hidden `
-PassThru `
-RedirectStandardOutput $outLog `
-RedirectStandardError $errLog
$process.Id | Set-Content -Encoding ASCII -LiteralPath $pidPath
Start-Sleep -Seconds 2
if ($process.HasExited) {
$detail = ""
if (Test-Path -LiteralPath $outLog) { $detail += Get-Content -Raw -LiteralPath $outLog }
if (Test-Path -LiteralPath $errLog) { $detail += Get-Content -Raw -LiteralPath $errLog }
throw "Weksa daemon exited immediately with code $($process.ExitCode).`n$detail"
}
& node (Join-Path $repoRoot "scripts\weksa-daemon.mjs") --health --host $HostName --port $Port --state-root $StateRoot | Out-Null
if ($LASTEXITCODE -ne 0) {
throw "Weksa daemon started but health check failed."
}
Write-Host "Started Weksa daemon as PID $($process.Id)."
Write-Host " command: rudp://$HostName`:$Port"
Write-Host " Odin CultMesh/RUDP: $OdinCultMeshRudp"
Write-Host " state: $StateRoot"

File diff suppressed because it is too large Load diff

View file

@ -1,466 +0,0 @@
"use strict";
const dgram = require("dgram");
const path = require("path");
const {
CultNetRudpSession,
decodeRudpPacket,
encodeCultNetMessageForWire,
encodeRudpPacket,
parseCultNetMessage,
} = require("cultnet-ts");
const { encode, decode } = require(path.resolve(
__dirname,
"..",
"..",
"CultLib",
"node_modules",
"@msgpack",
"msgpack",
));
const CULTNET_RUDP_PROTOCOL_ID = "cultnet.transport.rudp.v0";
const WEKSA_COMMAND_RUDP_CONNECTION_ID = 0x1d0d0002;
const WEKSA_MIMO_VOICEDESIGN_COMMAND_SCHEMA_ID = "weksa.mimo_voicedesign_command.v0";
const WEKSA_MIMO_VOICEDESIGN_RECEIPT_SCHEMA_ID = "weksa.mimo_voicedesign_receipt.v0";
async function createWeksaRudpCommandServer(options) {
if (!options?.host || !options?.port || typeof options.onCommand !== "function") {
throw new Error("Weksa RUDP command server requires host, port, and onCommand.");
}
const socket = dgram.createSocket(endpointFamily(options.host));
await bindServerSocket(socket, options.host, options.port);
const sessions = new Map();
const resendTimer = setInterval(() => {
for (const entry of sessions.values()) {
for (const packet of entry.session.dueResends(Date.now())) {
void sendPacket(socket, entry.endpoint, packet);
}
}
}, 25);
resendTimer.unref?.();
const onMessage = (wire, remote) => {
void handleServerDatagram({
wire,
remote,
socket,
sessions,
options,
}).catch((error) => {
options.onError?.(error);
});
};
const onError = (error) => {
options.onError?.(error instanceof Error ? error : new Error(String(error)));
};
socket.on("message", onMessage);
socket.on("error", onError);
return {
endpoint: { host: options.host, port: options.port },
uri: formatRudpEndpoint(options.host, options.port),
close() {
clearInterval(resendTimer);
socket.off("message", onMessage);
socket.off("error", onError);
socket.close();
sessions.clear();
},
};
}
async function handleServerDatagram(input) {
const { wire, remote, socket, sessions, options } = input;
const packet = decodeRudpPacket(wire);
const key = endpointKey(remote.address, remote.port);
let entry = sessions.get(key);
if (!entry) {
if (packet.packetType !== "connect") {
return;
}
const session = new CultNetRudpSession({
connectionId: WEKSA_COMMAND_RUDP_CONNECTION_ID,
initialSequence: 1,
resendDelayMs: 100,
maxPendingReliablePackets: 64,
});
entry = {
session,
endpoint: { host: remote.address, port: remote.port },
};
sessions.set(key, entry);
await sendPacket(socket, entry.endpoint, session.acceptConnect(packet, Date.now()));
return;
}
const result = entry.session.receive(packet, Date.now());
if (result.reply) {
await sendPacket(socket, entry.endpoint, result.reply);
}
for (const frame of result.delivered) {
await handleServerFrame({
socket,
entry,
frame,
options,
});
}
if (packet.packetType === "accept" || result.delivered.length > 0) {
await sendPacket(socket, entry.endpoint, entry.session.createAck());
}
if (result.disconnected) {
sessions.delete(key);
}
}
async function handleServerFrame(input) {
const { socket, entry, frame, options } = input;
if (frame.channelId !== "schema") {
return;
}
const message = parseCultNetMessage(decode(frame.payload), "cultnet.schema.v0");
if (message.schemaVersion !== "cultnet.document_put_raw.v0") {
return;
}
if (message.document.schemaId !== WEKSA_MIMO_VOICEDESIGN_COMMAND_SCHEMA_ID) {
return;
}
const payload = decode(message.document.payload);
const command = {
...payload,
request_id: payload?.request_id ?? message.document.recordKey,
};
let receipt;
try {
receipt = await options.onCommand(command, message);
} catch (error) {
options.onError?.(error instanceof Error ? error : new Error(String(error)));
receipt = {
schema_version: WEKSA_MIMO_VOICEDESIGN_RECEIPT_SCHEMA_ID,
request_id: command.request_id,
generated_at: new Date().toISOString(),
ok: false,
error: error instanceof Error ? error.message : String(error),
};
}
if (!receipt) {
return;
}
const receiptMessage = {
schemaVersion: "cultnet.document_put_raw.v0",
messageId: `${options.runtimeId ?? "weksa-daemon"}:receipt:${receipt.request_id}`,
document: {
schemaId: WEKSA_MIMO_VOICEDESIGN_RECEIPT_SCHEMA_ID,
recordKey: receipt.request_id,
storedAt: receipt.generated_at ?? receipt.observed_at ?? new Date().toISOString(),
payloadEncoding: "messagepack",
payload: encode(receipt),
sourceRuntimeId: options.runtimeId ?? "weksa-daemon",
sourceRole: "weksa-command-ingress",
tags: [CULTNET_RUDP_PROTOCOL_ID, "speech_provider.mimo.voicedesign"],
},
};
const wirePayload = encode(
encodeCultNetMessageForWire(receiptMessage, "cultnet.schema.v0"),
);
for (const packet of entry.session.sendMany("schema", wirePayload, {
reliable: true,
ordered: true,
nowMs: Date.now(),
})) {
await sendPacket(socket, entry.endpoint, packet);
}
}
async function sendWeksaMimoVoiceDesignCommand(options) {
const endpoint = parseEndpoint(options?.endpoint);
const requestId = options.command?.request_id ?? buildRequestId();
const command = {
...options.command,
request_id: requestId,
};
const socket = dgram.createSocket(endpointFamily(endpoint.host));
await bindClientSocket(socket, options?.localHost);
const receiver = createPacketReceiver(socket);
const session = new CultNetRudpSession({
connectionId: WEKSA_COMMAND_RUDP_CONNECTION_ID,
initialSequence: 1,
resendDelayMs: 100,
maxPendingReliablePackets: 64,
});
try {
await sendPacket(socket, endpoint, session.createConnect(Date.now(), new Uint8Array()));
await receiveCultNetMessageUntil({
receiver,
session,
endpoint,
timeoutMs: options.timeoutMs ?? 5000,
label: "accept",
predicate: (_message, packet) => packet.packetType === "accept",
});
const commandMessage = {
schemaVersion: "cultnet.document_put_raw.v0",
messageId: `${options.runtimeId ?? "weksa-cli"}:command:${requestId}`,
document: {
schemaId: WEKSA_MIMO_VOICEDESIGN_COMMAND_SCHEMA_ID,
recordKey: requestId,
storedAt: new Date().toISOString(),
payloadEncoding: "messagepack",
payload: encode(command),
sourceRuntimeId: options.runtimeId ?? "weksa-cli",
sourceRole: "command-client",
tags: [CULTNET_RUDP_PROTOCOL_ID, "speech_provider.mimo.voicedesign"],
},
};
const wirePayload = encode(
encodeCultNetMessageForWire(commandMessage, "cultnet.schema.v0"),
);
for (const packet of session.sendMany("schema", wirePayload, {
reliable: true,
ordered: true,
nowMs: Date.now(),
})) {
await sendPacket(socket, endpoint, packet);
}
return await receiveCultNetMessageUntil({
receiver,
session,
endpoint,
timeoutMs: options.timeoutMs ?? 10000,
label: "receipt",
predicate: (message) =>
message.schemaVersion === "cultnet.document_put_raw.v0"
&& message.document.schemaId === WEKSA_MIMO_VOICEDESIGN_RECEIPT_SCHEMA_ID
&& message.document.recordKey === requestId,
decodePayload: true,
});
} finally {
receiver.close();
socket.close();
}
}
async function receiveCultNetMessageUntil(options) {
const deadline = Date.now() + options.timeoutMs;
while (Date.now() < deadline) {
try {
const packet = await options.receiver.next(
Math.min(100, Math.max(1, deadline - Date.now())),
options.label,
);
const result = options.session.receive(packet, Date.now());
if (result.reply) {
await sendPacket(options.receiver.socket, options.endpoint, result.reply);
}
if (packet.packetType === "accept" || result.delivered.length > 0) {
await sendPacket(
options.receiver.socket,
options.endpoint,
options.session.createAck(),
);
}
if (packet.packetType === "accept" && options.predicate(undefined, packet)) {
return undefined;
}
for (const frame of result.delivered) {
if (frame.channelId !== "schema") {
continue;
}
const message = parseCultNetMessage(decode(frame.payload), "cultnet.schema.v0");
if (!options.predicate(message, packet)) {
continue;
}
if (
options.decodePayload
&& message.schemaVersion === "cultnet.document_put_raw.v0"
) {
return decode(message.document.payload);
}
return message;
}
} catch (error) {
if (error.code !== "ETIMEDOUT") {
throw error;
}
}
for (const packet of options.session.dueResends(Date.now())) {
await sendPacket(options.receiver.socket, options.endpoint, packet);
}
}
throw new Error(`timed out waiting for Weksa RUDP ${options.label} after ${options.timeoutMs}ms`);
}
async function bindServerSocket(socket, host, port) {
await new Promise((resolve, reject) => {
socket.once("error", reject);
socket.bind(port, host, () => {
socket.off("error", reject);
resolve();
});
});
}
async function bindClientSocket(socket, localHost) {
const bindHost = localHost ?? "0.0.0.0";
await new Promise((resolve, reject) => {
socket.once("error", reject);
socket.bind(0, bindHost, () => {
socket.off("error", reject);
resolve();
});
});
}
function createPacketReceiver(socket) {
const packets = [];
const waiters = [];
const errors = [];
const resolveNext = () => {
while (waiters.length > 0 && (packets.length > 0 || errors.length > 0)) {
const waiter = waiters.shift();
clearTimeout(waiter.timer);
if (errors.length > 0) {
waiter.reject(errors.shift());
} else {
waiter.resolve(packets.shift());
}
}
};
const onMessage = (wire) => {
try {
packets.push(decodeRudpPacket(wire));
} catch (error) {
errors.push(error);
}
resolveNext();
};
const onError = (error) => {
errors.push(error);
resolveNext();
};
socket.on("message", onMessage);
socket.on("error", onError);
return {
socket,
next(timeoutMs, label = "packet") {
if (packets.length > 0) {
return Promise.resolve(packets.shift());
}
if (errors.length > 0) {
return Promise.reject(errors.shift());
}
return new Promise((resolve, reject) => {
const waiter = {
resolve,
reject,
timer: setTimeout(() => {
const index = waiters.indexOf(waiter);
if (index >= 0) {
waiters.splice(index, 1);
}
const error = new Error(`timed out waiting for Weksa RUDP ${label}`);
error.code = "ETIMEDOUT";
reject(error);
}, Math.max(1, timeoutMs)),
};
waiters.push(waiter);
});
},
close() {
socket.off("message", onMessage);
socket.off("error", onError);
while (waiters.length > 0) {
const waiter = waiters.shift();
clearTimeout(waiter.timer);
const error = new Error("Weksa RUDP command receiver closed.");
error.code = "ECLOSED";
waiter.reject(error);
}
},
};
}
async function sendPacket(socket, endpoint, packet) {
const wire = encodeRudpPacket(packet);
await new Promise((resolve, reject) => {
socket.send(wire, endpoint.port, endpoint.host, (error) => {
if (error) {
reject(error);
} else {
resolve();
}
});
});
}
function parseEndpoint(value) {
if (!value) {
throw new Error("Weksa RUDP endpoint is required.");
}
const text = String(value).trim();
if (text.toLowerCase().startsWith("rudp://")) {
const parsed = new URL(text);
return {
host: parsed.hostname,
port: parsePort(parsed.port),
};
}
const ipv6 = text.match(/^\[([^\]]+)\]:(\d+)$/);
if (ipv6) {
return { host: ipv6[1], port: parsePort(ipv6[2]) };
}
const index = text.lastIndexOf(":");
if (index <= 0) {
throw new Error(`Weksa RUDP endpoint must be host:port, got "${value}".`);
}
return {
host: text.slice(0, index),
port: parsePort(text.slice(index + 1)),
};
}
function parsePort(value) {
const port = Number(value);
if (!Number.isInteger(port) || port <= 0 || port > 65535) {
throw new Error(`Weksa RUDP endpoint port is invalid: ${value}`);
}
return port;
}
function endpointFamily(host) {
return host.includes(":") ? "udp6" : "udp4";
}
function endpointKey(host, port) {
return `${host}:${port}`;
}
function formatRudpEndpoint(host, port) {
return host.includes(":") ? `rudp://[${host}]:${port}` : `rudp://${host}:${port}`;
}
function buildRequestId() {
return `mimo-${new Date().toISOString().replace(/[-:.TZ]/g, "")}-${Math.random().toString(36).slice(2, 8)}`;
}
module.exports = {
CULTNET_RUDP_PROTOCOL_ID,
WEKSA_COMMAND_RUDP_CONNECTION_ID,
WEKSA_MIMO_VOICEDESIGN_COMMAND_SCHEMA_ID,
WEKSA_MIMO_VOICEDESIGN_RECEIPT_SCHEMA_ID,
createWeksaRudpCommandServer,
sendWeksaMimoVoiceDesignCommand,
formatRudpEndpoint,
};

View file

@ -1,148 +0,0 @@
#!/usr/bin/env node
import { mkdir, writeFile } from "node:fs/promises";
import path from "node:path";
const document = {
schema: "gamecult.eve.provider_advertisement.v1",
providerId: "weksa.intent.service",
title: "Weksa Intent Service",
description:
"Weksa converts writing, interlingua, and agent state into typed conversational intent, pronunciation plans, and utterance handoff documents for AquaSynth and other consumers.",
mode: "fixture-read-only",
serviceVerse: {
id: "verse.weksa.service.v1",
cultMeshKey: "weksa.service/provider-advertisement",
authority: "Weksa daemon identity, schema catalog, and provider publication",
owns: [
"typed conversational intent",
"pronunciation plans",
"utterance handoff documents",
"lowering traces",
"language-project and flavor-profile state",
],
doesNotOwn: [
"AquaSynth learned embeddings",
"Faust compilation",
"rendered audio",
"Persona canonical state",
],
},
nestedVerses: [
{
id: "weksa.intent",
kind: "intent",
cultMeshKey: "weksa.intent/current",
authority: "Weksa conversational intent compiler",
schemas: ["weksa.conversational_intent.v0"],
},
{
id: "weksa.pronunciation",
kind: "pronunciation",
cultMeshKey: "weksa.pronunciation/current",
authority: "Weksa pronunciation lowering",
schemas: ["weksa.pronunciation_plan.v0"],
},
{
id: "weksa.utterance",
kind: "utterance",
cultMeshKey: "weksa.utterance/handoffs",
authority: "Weksa utterance handoff export",
schemas: ["weksa.utterance_handoff.v0", "weksa.utterance_embedding_handoff.v0.1"],
},
{
id: "weksa.operator",
kind: "operator",
cultMeshKey: "weksa.operator/status",
authority: "Weksa daemon runtime",
schemas: ["weksa.operator_state.v0"],
},
{
id: "weksa.cultural_ontology",
kind: "cultural_ontology",
cultMeshKey: "weksa.cultural-ontology/catalogs",
authority: "Weksa cultural ontology profile store",
schemas: ["weksa.cultural_ontology_profile.v0", "weksa.cultural_ontology_catalog.v0"],
},
],
schemaWitnessFamilies: [
{
family: "intent",
namespace: "weksa.intent.*",
witnesses: ["weksa.conversational_intent.v0"],
durableShape: ".weksa/intent/{intentId}.cc",
},
{
family: "pronunciation",
namespace: "weksa.pronunciation.*",
witnesses: ["weksa.pronunciation_plan.v0"],
durableShape: ".weksa/pronunciation/{utteranceId}.cc",
},
{
family: "utterance",
namespace: "weksa.utterance.*",
witnesses: ["weksa.utterance_handoff.v0", "weksa.utterance_embedding_handoff.v0.1"],
durableShape: ".weksa/handoff/{utteranceId}.cc",
},
{
family: "trace",
namespace: "weksa.trace.*",
witnesses: ["weksa.lowering_trace.v0"],
durableShape: ".weksa/traces/{traceId}.cc",
},
{
family: "cultural_ontology",
namespace: "weksa.cultural_ontology.*",
witnesses: ["weksa.cultural_ontology_profile.v0", "weksa.cultural_ontology_catalog.v0"],
durableShape: ".weksa/cultural-ontology/{storeId}.cc",
},
],
commandBoundaries: [
{
id: "weksa.command.intent.create",
owner: "Weksa",
acceptedByFixture: false,
allowedInputs: ["writing", "interlingua packet", "Persona/agent state projection"],
emits: ["weksa.conversational_intent.v0", "weksa.lowering_trace.v0"],
},
{
id: "weksa.command.utterance.lower",
owner: "Weksa",
acceptedByFixture: false,
allowedInputs: ["accepted conversational intent", "language project", "speaker state"],
emits: ["weksa.pronunciation_plan.v0", "weksa.utterance_handoff.v0"],
},
{
id: "weksa.command.handoff.export",
owner: "Weksa",
acceptedByFixture: false,
emits: ["weksa.utterance_embedding_handoff.v0.1"],
forbiddenTargets: ["Faust compilation", "audio rendering", "AquaSynth synth driver truth"],
},
],
loweringRules: [
"Weksa owns conversational intent and utterance lowering.",
"AquaSynth owns learned embeddings, synth controls, Faust compilation, and audio output.",
"Fixture exports are discovery metadata until the daemon loop commits typed witnesses.",
],
};
async function main() {
const args = process.argv.slice(2);
const outIndex = args.indexOf("--out");
const outputPath = outIndex >= 0 ? args[outIndex + 1] : undefined;
const json = `${JSON.stringify(document, null, 2)}\n`;
if (outputPath) {
const resolved = path.resolve(process.cwd(), outputPath);
await mkdir(path.dirname(resolved), { recursive: true });
await writeFile(resolved, json, "utf8");
return;
}
process.stdout.write(json);
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});