Add Persona culture stack golf harness

This commit is contained in:
Meta Vens 2026-06-10 20:45:25 +01:00
commit e441cf33f4
17 changed files with 1830 additions and 13 deletions

1
.gitignore vendored
View file

@ -9,6 +9,7 @@ state/scratch-compaction-*.md
state/scratch-runtime/
.weksa-runs/
.weksa-smoke/
examples/persona-lowering/*/runs/
node_modules/
dist/
build/

View file

@ -0,0 +1,17 @@
# Cultural Ontology Store
This directory holds draft Weksa cultural and subcultural ontology profiles used
for ontological lowering, syntax, grammar, discourse, and surface-affordance
selection.
Live pipeline shape:
1. Weksa stores reusable cultures/subcultures here and in semantic retrieval
storage such as Qdrant.
2. A Persona state references the relevant culture stack.
3. The Persona produces interlingua intent from current state and situation.
4. Weksa lowers that interlingua through the referenced culture stack.
Persona state owns current intent, memory pressure, and relationship stance.
Cultural ontology owns reusable salience, affordances, and constraints. Qdrant
may retrieve candidates, but accepted ontology remains typed state.

View file

@ -0,0 +1,28 @@
schema_version: weksa.cultural_ontology_catalog.v0
catalog_id: weksa.cultural_ontology.catalog.v0
status: draft
qdrant:
intended_collection: weksa_cultural_ontology_profiles
payload_keys:
- profile_id
- kind
- language_codes
- regions
- evidence_refs
- status
ownership_note: >
Qdrant owns retrieval over culture/subculture chunks. It does not own
accepted ontology, activation, or lowering authority.
profiles:
- profile_id: weksa.culture.dutch_american_diaspora.v0
path: data/cultural-ontology/cultures/dutch-american-diaspora.yaml
- profile_id: weksa.culture.western_europe_maritime_childhood.v0
path: data/cultural-ontology/cultures/western-europe-maritime-childhood.yaml
- profile_id: weksa.culture.portugal_resident_algarve_lisbon.v0
path: data/cultural-ontology/cultures/portugal-resident-algarve-lisbon.yaml
- profile_id: weksa.culture.texas_houston_us_adolescence.v0
path: data/cultural-ontology/cultures/texas-houston-us-adolescence.yaml
- profile_id: weksa.subculture.online_game_dev_discord_pre2025.v0
path: data/cultural-ontology/subcultures/online-game-dev-discord-pre2025.yaml
- profile_id: weksa.subculture.gamecult_open_source_crypto_anarchist.v0
path: data/cultural-ontology/subcultures/gamecult-open-source-crypto-anarchist.yaml

View file

@ -0,0 +1,58 @@
schema_version: weksa.cultural_ontology_profile.v0
profile_id: weksa.culture.dutch_american_diaspora.v0
kind: diaspora_identity
status: draft_guarded
language:
codes:
- en
- nl
community:
regions:
- Netherlands
- United States
speech_community: >
People whose self-description or life history crosses Dutch origin and
American nationality/residence. This profile is not a dialect claim.
activation:
allowed_when:
- persona_state_references_profile
- interlingua_mentions_origin_nationality_or_cross_cultural_identity
forbidden_when:
- used_to_infer_accent_or_fluency_without_evidence
- used_as_generic_dutch_or_generic_american_stereotype
salience_axes:
plural_national_identity:
axis_id: plural_national_identity
domain: identity_indexing
description: Birthplace, citizenship, residence, and cultural identification may diverge.
relevant_distinctions:
- distinction_id: birthplace_vs_citizenship
label: Birthplace versus citizenship
meaning: Being born in one country and holding identity/citizenship in another are separate ontology fields.
lowering_questions:
- Does the utterance need origin, nationality, residence, or cultural affiliation?
required_when:
- source_mentions_identity_origin_or_nationality
forbidden_when:
- scene_only_requires_casual_banter
evidence_refs:
- discord:805822798185627718
- discord:1030577958215225396
evidence_ledger:
- ref: discord:805822798185627718
quote: "I live in Portugal at the moment, though I am a Netherlands-born US citizen - lived mostly in Texas"
- ref: discord:1030577958215225396
quote: "Dual nationality, Dutch American"
- ref: discord:862490040755683348
quote: "I was born in the Netherlands but I'm a US citizen and did high school in Houston, Texas."
linguistic_affordances:
grammar_features: []
phonology_features: []
lexicon_features: []
discourse_patterns: []
orthography_features: []
code_switching:
allowed: false
constraints:
- Do not infer Dutch code switching from diaspora identity alone.
patterns: []

View file

@ -0,0 +1,84 @@
schema_version: weksa.cultural_ontology_profile.v0
profile_id: weksa.culture.portugal_resident_algarve_lisbon.v0
kind: regional_residence
status: draft_guarded
language:
codes:
- en
- pt
community:
regions:
- Portugal
- Algarve
- Lisbon
- Tavira
speech_community: >
Portugal as lived residence and locality rather than tourist backdrop.
activation:
allowed_when:
- persona_state_references_profile
- interlingua_mentions_portugal_residence_locality_bureaucracy_or_timing
forbidden_when:
- used_for_broad_portuguese_culture_without_locale_review
salience_axes:
lived_portugal:
axis_id: lived_portugal
domain: identity_indexing
description: Portugal references can be local/home references, including Algarve/Lisbon/Tavira specificity.
relevant_distinctions:
- distinction_id: current_or_returned_residence
label: Current or returned residence
meaning: Portugal can be present-tense home context, not childhood-only memory.
lowering_questions:
- Is Portugal being invoked as current location, childhood location, or comparison frame?
required_when:
- source_mentions_portugal_or_portuguese_residence
forbidden_when:
- scene_has_no_place_salience
evidence_refs:
- discord:581220303414231117
- discord:834858944013926421
- discord:888820124344254504
evidence_ledger:
- ref: discord:581220303414231117
quote: "I'm in the Algarve now"
- ref: discord:834858944013926421
quote: "I live in Portugal now"
- ref: discord:888820124344254504
quote: "But I'm currently in Lisbon"
- ref: discord:1023774733789040640
quote: "if you wanna move to Portugal you're gonna have to get used to not getting things on time"
linguistic_affordances:
grammar_features: []
phonology_features: []
lexicon_features: []
discourse_patterns:
- pattern_id: portugal_timing_joke_guarded
label: Portugal timing joke, guarded
status: draft
domain:
layer: discourse
category: humor
subcategory: local_bureaucracy_timing
interactional_function: locally_grounded_timing_joke
sequence_shape:
- playful_warning
- local_timing_generalization
adjacency_constraints:
- addressee_is_discussing_moving_or_living_in_portugal
activation:
allowed_when:
- local_portugal_residence_context
- joking_register
forbidden_when:
- formal_cultural_description
evidence:
source_refs:
- discord:1023774733789040640
confidence: low
orthography_features: []
code_switching:
allowed: false
constraints:
- This profile alone does not authorize Portuguese code switching.
patterns: []

View file

@ -0,0 +1,56 @@
schema_version: weksa.cultural_ontology_profile.v0
profile_id: weksa.culture.texas_houston_us_adolescence.v0
kind: adolescence_residence
status: draft_guarded
language:
codes:
- en
community:
regions:
- United States
- Texas
- Houston
speech_community: >
US/Texas adolescent institutional context, especially Houston high school
and later critique of American debt/institutional pathways.
activation:
allowed_when:
- persona_state_references_profile
- interlingua_mentions_us_texas_school_debt_or_american_institutions
forbidden_when:
- used_to_force_texan_dialect_markers
salience_axes:
american_institutional_distance:
axis_id: american_institutional_distance
domain: stance
description: US institutions can be lived experience and object of critique rather than foreign abstraction.
relevant_distinctions:
- distinction_id: debt_train_refusal
label: American debt train refusal
meaning: Avoiding US education/debt pathways can be a first-person institutional stance.
lowering_questions:
- Is the utterance about education, debt, leaving the US, or institutional pressure?
required_when:
- source_mentions_us_debt_or_school_path
forbidden_when:
- casual_fixture_without_institutional_topic
evidence_refs:
- discord:1160260490690306148
evidence_ledger:
- ref: discord:805822798185627718
quote: "lived mostly in Texas"
- ref: discord:862490040755683348
quote: "did high school in Houston, Texas"
- ref: discord:1160260490690306148
quote: "I specifically left the US after high school so as not to climb onto the traditional American debt train"
linguistic_affordances:
grammar_features: []
phonology_features: []
lexicon_features: []
discourse_patterns: []
orthography_features: []
code_switching:
allowed: false
constraints:
- Do not infer Southern or Texan dialect surface markers from residence alone.
patterns: []

View file

@ -0,0 +1,53 @@
schema_version: weksa.cultural_ontology_profile.v0
profile_id: weksa.culture.western_europe_maritime_childhood.v0
kind: mobility_childhood
status: draft_guarded
community:
regions:
- France
- Spain
- Portugal
- coastal_western_europe
speech_community: >
Mobile childhood organized around sailing, ports, and cross-border Western
European movement. This profile is owner-attested for the Metame fixture and
needs more Discord corroboration before broader use.
activation:
allowed_when:
- persona_state_references_profile
- interlingua_mentions_childhood_origin_mobility_boats_or_home
forbidden_when:
- used_as_decorative_nautical_metaphor_without_context
salience_axes:
mobile_home:
axis_id: mobile_home
domain: identity_indexing
description: Home can be vessel, coast, port, family movement, and country sequence rather than one fixed town.
relevant_distinctions:
- distinction_id: vessel_as_childhood_home
label: Vessel as childhood home
meaning: A sailboat childhood makes movement and locality primary ontology fields.
lowering_questions:
- Does the line invoke home, travel, borders, coast, or rootedness?
required_when:
- source_mentions_childhood_or_home
forbidden_when:
- scene_has_no_mobility_or_home_salience
evidence_refs:
- owner:2026-06-10:sailboat_france_spain_portugal_until_6
evidence_ledger:
- ref: owner:2026-06-10:sailboat_france_spain_portugal_until_6
quote: "I was born in the Netherlands, grew up on a sailboat traveling France, Spain, staying in Portugal until I was 6, moved to the US."
- ref: discord-search-gap:sailboat_childhood
summary: First semantic search did not locate a direct Discord message for this exact childhood account.
linguistic_affordances:
grammar_features: []
phonology_features: []
lexicon_features: []
discourse_patterns: []
orthography_features: []
code_switching:
allowed: false
constraints:
- Do not infer French, Spanish, Portuguese, or Dutch fluency from movement alone.
patterns: []

View file

@ -0,0 +1,51 @@
schema_version: weksa.cultural_ontology_profile.v0
profile_id: weksa.subculture.gamecult_open_source_crypto_anarchist.v0
kind: political_technical_community
status: draft_guarded
language:
codes:
- en
community:
regions:
- online
speech_community: >
GameCult-adjacent open-source, crypto-anarchist, game-development, and
engineering practice where ownership, inspectability, debt, authority, and
tool coherence are culturally salient.
activation:
allowed_when:
- persona_state_references_profile
- interlingua_mentions_tools_authority_open_source_debt_game_dev_or_engineering
forbidden_when:
- used_to_turn_random_banter_into_manifesto
salience_axes:
authority_and_tool_coherence:
axis_id: authority_and_tool_coherence
domain: stance
description: Systems are judged by ownership, inspectability, agency, and whether they actually work.
relevant_distinctions:
- distinction_id: open_source_anti_custody
label: Open source anti-custody
meaning: Open access and inspectability are political and practical values.
lowering_questions:
- Is the line judging a tool, institution, ownership structure, or coordination method?
- Should the interlingua preserve anti-custody or open-access salience?
required_when:
- source_mentions_open_source_or_institutional_authority
forbidden_when:
- casual_social_move_only
evidence_refs:
- discord:862490040755683348
linguistic_affordances:
grammar_features: []
phonology_features: []
lexicon_features: []
discourse_patterns: []
orthography_features: []
code_switching:
allowed: false
constraints: []
patterns: []
evidence_ledger:
- ref: discord:862490040755683348
quote: "I got my bachelor degree in game development last year. I'm a crypto-anarchist open source activist"

View file

@ -0,0 +1,288 @@
schema_version: weksa.cultural_ontology_profile.v0
profile_id: weksa.subculture.online_game_dev_discord_pre2025.v0
kind: community_of_practice
status: draft_guarded
language:
codes:
- en
community:
regions:
- online_discord
speech_community: >
Pre-2025 GameCult/Aquarium-ish Discord collaboration where game design,
sound, engineering, jokes, and casual status play cohabit the same rooms.
activation:
allowed_when:
- persona_state_references_profile
- target_medium_is_discord
- target_period_is_pre_2025_or_history_fixture
forbidden_when:
- formal_current_project_doctrine_is_target
salience_axes:
casual_room_temperature:
axis_id: casual_room_temperature
domain: discourse_patterns
description: Compact, socially alive wording that assumes shared room context.
relevant_distinctions:
- distinction_id: banter_over_explanation
label: Banter over explanation
meaning: The line may be short, fragmentary, and joke-shaped when context supplies the frame.
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:802911591288537118
- 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.
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
evidence:
source_refs:
- discord:802911591288537118
confidence: medium
phonology_features: []
lexicon_features:
- feature_id: casual_recoil_oof
label: Casual recoil marker oof
status: draft
domain:
layer: lexicon
category: stance_marker
subcategory: embarrassment
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"
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
evidence:
source_refs:
- discord:1037314100931338260
confidence: high
- feature_id: mock_challenge_coward
label: Mock challenge coward
status: draft
domain:
layer: lexicon
category: stance_marker
subcategory: friendly_roast
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"
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
evidence:
source_refs:
- discord:1023727427924545576
confidence: high
- feature_id: preserve_self_indexed_technical_label
label: Preserve self-indexed technical label
status: draft
domain:
layer: lexicon
category: technical_term
subcategory: self_indexing
description: >
When Persona interlingua frames the speaker through a locally salient
technical identity label, lowering should preserve that label instead of
inventing a fresher metaphor. In this subculture, "engineer" can be a
joked-about identity index, not just an occupation.
lexical_items:
- form: engineer
gloss: technical identity / competence index
sense: self_indexed_engineering_vibe
register: casual_discord
allowed_speaker_standing: speaker_or_room_has_made_engineering_salient
forbidden_senses:
- formal_job_title_unless_context_requires
collocations:
- engineer vibes
- engineer-like
activation:
allowed_when:
- persona_interlingua_mentions_engineer_like_or_engineering_salience
- prior_turn_compliments_efficiency_or_structure
forbidden_when:
- interlingua_does_not_name_technical_identity
requires_profile_authority: true
minimum_density: light
maximum_density: light
constraints:
register_contexts:
- casual
speaker_contexts:
- metame_or_metacrat_fixture
grammar_contexts:
- playful_self_deprecation
incompatibilities:
- replacement_identity_metaphor
- creature_metaphor_substitution
evidence:
source_refs:
- discord:1037314100931338260
confidence: medium
discourse_patterns:
- pattern_id: compact_recoil_no_context_dump
label: Compact recoil without context dump
status: draft
domain:
layer: discourse
category: stance_marker
subcategory: self_deprecation
interactional_function: answer_trait_read_with_short_mock_wince
sequence_shape:
- recoil_marker
- dont_tell_me_frame
- possessive_context_object
- preserved_trait_label
adjacency_constraints:
- prior_turn_already_contains_the_explanation
- generated_line_should_not_quote_or_summarize_prior_turns
activation:
allowed_when:
- playful_self_deprecation
- prior_turn_compliments_efficiency_or_structure
forbidden_when:
- source_intent_requires_explanation
requires_profile_authority: true
minimum_density: light
maximum_density: light
constraints:
register_contexts:
- casual
speaker_contexts:
- metame_or_metacrat_fixture
collocation_limits:
- target_length_roughly_6_to_12_words
- avoid_quoted_prior_turn_paraphrase
- avoid_because_clause
- avoid_disease_metaphor_unless_interlingua_requests_it
evidence:
source_refs:
- discord:1037314100931338260
confidence: medium
- pattern_id: casual_floor_yield_with_lol
label: Casual floor yield with lol
status: draft
domain:
layer: discourse
category: turn_taking
subcategory: floor_yield
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
activation:
allowed_when:
- conversational_yield
- casual_collaborative_ideation
forbidden_when:
- formal_moderation
requires_profile_authority: true
minimum_density: light
maximum_density: light
evidence:
source_refs:
- discord:820077384572338176
confidence: high
orthography_features:
- feature_id: light_discord_informality
label: Light Discord informality
status: draft
domain:
layer: orthography
category: punctuation
subcategory: informal_case
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
activation:
allowed_when:
- casual_discord_register
forbidden_when:
- formal_or_public_document_register
requires_profile_authority: true
minimum_density: light
maximum_density: normal
evidence:
source_refs:
- discord:1037314100931338260
- discord:820077384572338176
confidence: medium
code_switching:
allowed: false
constraints:
- This subculture alone does not authorize cross-language switching.
patterns: []
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.

View file

@ -0,0 +1,546 @@
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,9 @@
# Metame Casual Pre-2025 Persona Lowering Fixture
This fixture tests whether Weksa can lower neutral interlingua through Metame's
Persona state into casual Discord-style utterances from before 2025.
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
@ -9,10 +11,16 @@ jokes, and casual turn-taking.
## Authority
- Speaker authority: Metame Persona `.cc` state.
- 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.
- Lowering input: neutral interlingua packets in `interlingua.yaml`.
- 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
@ -20,8 +28,23 @@ portable speaking-state surface and may contain private memory.
## Fixture Contract
A generator should read `persona-state-ref.yaml`, `interlingua.yaml`, and
`lowering-prompt.md`, then write `generated-output.yaml`. Evaluation compares
generated output against `ground-truth.yaml`.
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,18 +1,20 @@
# Persona Lowering Prompt
You are Weksa lowering neutral interlingua into a target speaker's plausible
Discord utterance.
You are Weksa lowering Persona-produced interlingua into a target speaker's
plausible Discord utterance.
Read:
- `persona-state-ref.yaml`
- `interlingua.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 Metame could plausibly have written in
the specified pre-2025 casual Discord context. Preserve communicative intent and
social move over lexical exactness. Favor compact, alive, room-aware phrasing.
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:

View file

@ -0,0 +1,27 @@
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

@ -0,0 +1,42 @@
# 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

@ -10,3 +10,7 @@ speaker:
- 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

@ -0,0 +1,41 @@
# 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

@ -0,0 +1,496 @@
#!/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, "_");
}