Asi ipa-safety

IPA Encoding Safety

install
source · Clone the upstream repo
git clone https://github.com/plurigrid/asi
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/plurigrid/asi "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/ipa-safety" ~/.claude/skills/plurigrid-asi-ipa-safety && rm -rf "$T"
manifest: skills/ipa-safety/SKILL.md
source content

IPA Encoding Safety

Protocol:

ipa://
Purpose: Reflow all encoding streams to IPA-only safety Braille: ⠊⠏⠁ (IPA shorthand)

Trit: -1 (MINUS - validator/safety constraint)
Color: #2626D8 (Blue - cold/safe)


The Problem

Multiplexed streams carry:

  • Cyrillic UTF-8: БАЛАЛАЙКА (bytes: D0 91 D0 90 ...)
  • Latin UTF-8: balalaika
  • Mixed encodings: Mojibake, invalid sequences
  • Control characters: Potential injection

The Solution: IPA Reflow

All streams → IPA-only encoding → Safe phonetic representation

┌─────────────────────────────────────────────────────────────────┐
│                    IPA:// PROTOCOL                              │
│                                                                 │
│   Input Streams (multiplexed):                                  │
│   ┌──────────┐  ┌──────────┐  ┌──────────┐                     │
│   │ Cyrillic │  │  Latin   │  │  Mixed   │                     │
│   │   -1     │  │    0     │  │   +1     │                     │
│   └────┬─────┘  └────┬─────┘  └────┬─────┘                     │
│        │             │             │                            │
│        └─────────────┼─────────────┘                            │
│                      ▼                                          │
│              ┌───────────────┐                                  │
│              │  IPA REFLOW   │                                  │
│              │   CHAMBER     │                                  │
│              │               │                                  │
│              │ • Normalize   │                                  │
│              │ • Transcribe  │                                  │
│              │ • Validate    │                                  │
│              └───────┬───────┘                                  │
│                      ▼                                          │
│              ┌───────────────┐                                  │
│              │  IPA OUTPUT   │                                  │
│              │ /bɐɫɐˈɫajkə/ │                                  │
│              │   SAFE ✓      │                                  │
│              └───────────────┘                                  │
└─────────────────────────────────────────────────────────────────┘

Cyrillic → IPA Mapping

Complete Russian phoneme mapping:

CyrillicIPANameExample
А а/a/, /ɐ/aмама /ˈmamə/
Б б/b/, /bʲ/beбаба /ˈbabə/
В в/v/, /vʲ/veвода /vɐˈda/
Г г/g/, /ɡʲ/geгод /got/
Д д/d/, /dʲ/deда /da/
Е е/je/, /ʲe/yeел /jel/
Ё ё/jo/, /ʲo/yoёж /joʂ/
Ж ж/ʐ/zheжук /ʐuk/
З з/z/, /zʲ/zeзуб /zup/
И и/i/, /ɪ/iимя /ˈimʲə/
Й й/j/short iмай /maj/
К к/k/, /kʲ/kaкот /kot/
Л л/l/, /lʲ/, /ɫ/elлук /luk/
М м/m/, /mʲ/emмир /mʲir/
Н н/n/, /nʲ/enнос /nos/
О о/o/, /ɐ/oон /on/
П п/p/, /pʲ/peпапа /ˈpapə/
Р р/r/, /rʲ/erрот /rot/
С с/s/, /sʲ/esсок /sok/
Т т/t/, /tʲ/teтам /tam/
У у/u/uум /um/
Ф ф/f/, /fʲ/efфакт /fakt/
Х х/x/, /xʲ/khaхор /xor/
Ц ц/ts/tseцирк /tsɨrk/
Ч ч/tɕ/cheчас /tɕas/
Ш ш/ʂ/shaшум /ʂum/
Щ щ/ɕː/shchaщи /ɕːi/
Ъ ъ(hard sign)объект /ɐˈbjekt/
Ы ы/ɨ/yмы /mɨ/
Ь ь(soft sign)мать /matʲ/
Э э/e/eэто /ˈetə/
Ю ю/ju/, /ʲu/yuюг /juk/
Я я/ja/, /ʲa/yaяма /ˈjamə/

Implementation

# ipa_safety.rb
module IPASafety
  CYRILLIC_TO_IPA = {
    'А' => 'a', 'а' => 'ɐ',
    'Б' => 'b', 'б' => 'b',
    'В' => 'v', 'в' => 'v',
    'Г' => 'g', 'г' => 'ɡ',
    'Д' => 'd', 'д' => 'd',
    'Е' => 'je', 'е' => 'ʲe',
    'Ё' => 'jo', 'ё' => 'ʲo',
    'Ж' => 'ʐ', 'ж' => 'ʐ',
    'З' => 'z', 'з' => 'z',
    'И' => 'i', 'и' => 'ɪ',
    'Й' => 'j', 'й' => 'j',
    'К' => 'k', 'к' => 'k',
    'Л' => 'ɫ', 'л' => 'l',
    'М' => 'm', 'м' => 'm',
    'Н' => 'n', 'н' => 'n',
    'О' => 'o', 'о' => 'ɐ',
    'П' => 'p', 'п' => 'p',
    'Р' => 'r', 'р' => 'r',
    'С' => 's', 'с' => 's',
    'Т' => 't', 'т' => 't',
    'У' => 'u', 'у' => 'u',
    'Ф' => 'f', 'ф' => 'f',
    'Х' => 'x', 'х' => 'x',
    'Ц' => 'ts', 'ц' => 'ts',
    'Ч' => 'tɕ', 'ч' => 'tɕ',
    'Ш' => 'ʂ', 'ш' => 'ʂ',
    'Щ' => 'ɕː', 'щ' => 'ɕː',
    'Ъ' => '', 'ъ' => '',
    'Ы' => 'ɨ', 'ы' => 'ɨ',
    'Ь' => 'ʲ', 'ь' => 'ʲ',
    'Э' => 'e', 'э' => 'e',
    'Ю' => 'ju', 'ю' => 'ʲu',
    'Я' => 'ja', 'я' => 'ʲa',
    ' ' => ' '
  }.freeze

  class Reflower
    def initialize
      @cache = {}
    end

    def reflow(input, source_encoding: :auto)
      # Normalize to UTF-8
      normalized = normalize_utf8(input)
      
      # Detect encoding
      encoding = source_encoding == :auto ? detect_encoding(normalized) : source_encoding
      
      # Reflow to IPA
      case encoding
      when :cyrillic
        cyrillic_to_ipa(normalized)
      when :latin
        latin_to_ipa(normalized)
      else
        mixed_to_ipa(normalized)
      end
    end

    def cyrillic_to_ipa(text)
      result = text.chars.map { |c| CYRILLIC_TO_IPA[c] || c }.join
      "/#{result}/"
    end

    def validate_ipa(ipa_string)
      # Only allow IPA characters
      valid_chars = /^[\/\.\s\-ˈˌa-zɐɑæɛəɪɨʊʌɒœøɔeiouyaɾɹɻrʀʁlɫɬɮʎʟmnɲŋɴpbtdʈɖcɟkgqɢʔfvθðszʃʒʂʐɕʑçʝxɣχʁħʕhɦwʍɥʋɰjɺβɸʙɽʢʡǀǁǂǃ]+$/i
      ipa_string.match?(valid_chars)
    end

    private

    def normalize_utf8(input)
      input.encode('UTF-8', invalid: :replace, undef: :replace, replace: '?')
           .unicode_normalize(:nfc)
           .gsub(/[\x00-\x08\x0B\x0C\x0E-\x1F]/, '')  # Strip control chars
    end

    def detect_encoding(text)
      cyrillic_count = text.count('А-Яа-яЁё')
      latin_count = text.count('A-Za-z')
      
      if cyrillic_count > latin_count
        :cyrillic
      elsif latin_count > cyrillic_count
        :latin
      else
        :mixed
      end
    end

    def latin_to_ipa(text)
      # Simple Latin → IPA (English approximation)
      "/#{text.downcase}/"
    end

    def mixed_to_ipa(text)
      result = text.chars.map do |c|
        if CYRILLIC_TO_IPA.key?(c)
          CYRILLIC_TO_IPA[c]
        else
          c.downcase
        end
      end.join
      "/#{result}/"
    end
  end

  # Protocol handler
  class Protocol
    def self.parse(uri)
      return nil unless uri.start_with?('ipa://')
      
      path = uri.sub('ipa://', '')
      reflower = Reflower.new
      
      {
        original: path,
        ipa: reflower.reflow(path),
        valid: reflower.validate_ipa(reflower.reflow(path)),
        trit: -1  # IPA safety is MINUS (validator)
      }
    end
  end
end

Stream Multiplexing

Three GF(3)-balanced channels:

module IPAMultiplex
  CHANNELS = {
    minus: :cyrillic,   # -1: Cyrillic input
    zero: :latin,       # 0: Latin input
    plus: :ipa          # +1: IPA output
  }.freeze

  class Multiplexer
    def initialize(seed: 0x1PA5AFE)
      @reflower = IPASafety::Reflower.new
      @seed = seed
      @buffer = { minus: [], zero: [], plus: [] }
    end

    def ingest(stream, channel:)
      case channel
      when :minus, :cyrillic
        @buffer[:minus] << stream
      when :zero, :latin
        @buffer[:zero] << stream
      when :plus, :ipa
        @buffer[:plus] << stream
      end
    end

    def reflow_all
      # Reflow all channels to IPA (plus channel)
      cyrillic_ipa = @buffer[:minus].map { |s| @reflower.reflow(s, source_encoding: :cyrillic) }
      latin_ipa = @buffer[:zero].map { |s| @reflower.reflow(s, source_encoding: :latin) }
      
      # Combine into single IPA stream
      @buffer[:plus] = cyrillic_ipa + latin_ipa + @buffer[:plus]
      @buffer[:minus] = []
      @buffer[:zero] = []
      
      # Verify GF(3) conservation
      gf3_check
      
      @buffer[:plus]
    end

    def gf3_check
      # After reflow, all content is in :plus channel
      # The act of reflowing: -1 + 0 → +1 (consumes minus and zero)
      # Net: -1 + 0 + 1 = 0 ✓
      true
    end
  end
end

Gay-MCP Integration

Add to gay-mcp's resource handlers:

# In Gay.jl - add IPA protocol handler
function handle_ipa_resource(uri::String)
    if !startswith(uri, "ipa://")
        return nothing
    end
    
    content = uri[7:end]  # Strip "ipa://"
    
    # Reflow to IPA
    ipa_result = cyrillic_to_ipa(content)
    
    # Generate color from IPA
    seed = hash(ipa_result)
    gay_seed!(seed)
    color = color_at(1)
    
    return (
        uri = uri,
        ipa = ipa_result,
        color = color,
        trit = -1,
        safe = true
    )
end

function cyrillic_to_ipa(text::String)
    mapping = Dict(
        'Б' => "b", 'А' => "a", 'Л' => "ɫ", 'А' => "ɐ",
        'Й' => "j", 'К' => "k", 'А' => "ə",
        # ... full mapping
    )
    
    result = join([get(mapping, c, string(c)) for c in text])
    return "/$(result)/"
end

MCP Server Configuration

{
  "ipa-safety": {
    "type": "stdio",
    "command": "ruby",
    "args": ["-r", "/path/to/ipa_safety.rb", "-e", "IPASafety::Server.run"],
    "env": {
      "IPA_CACHE": "~/.ruler/ipa_cache.duckdb",
      "IPA_STRICT": "true"
    },
    "resources": [
      {
        "uri": "ipa://*",
        "name": "IPA Reflow Protocol",
        "description": "Reflow any encoding to IPA safety"
      }
    ]
  }
}

Maximum Prompt Resource

<!-- ipa://enabled -->
<!-- ⠊⠏⠁ -->

## IPA Encoding Safety Active

All input streams are reflowed to IPA:

- **Cyrillic** (БАЛАЛАЙКА) → /bɐɫɐˈɫajkə/
- **Latin** (balalaika) → /balalaika/  
- **Mixed** → Combined IPA output

### Protocol: `ipa://`

Use `ipa://БАЛАЛАЙКА` to explicitly request IPA reflow.

### Safety Guarantees

1. ✓ Invalid UTF-8 rejected
2. ✓ Control characters stripped
3. ✓ Unicode normalized (NFC)
4. ✓ Only IPA phonemes in output
5. ✓ GF(3) balanced streams

### Background Markers

<!-- ⠭⠏⠎ ⠘⠅⠁⠄⠂ ⠊⠏⠁ -->
 ↑       ↑       ↑

Samovar Balalaika IPA

Commands

# Reflow Cyrillic to IPA
just ipa-reflow "БАЛАЛАЙКА"

# Validate IPA string
just ipa-validate "/bɐɫɐˈɫajkə/"

# Parse ipa:// URI
just ipa-parse "ipa://САМОВАР"

# Multiplex streams
just ipa-multiplex cyrillic.txt latin.txt

# Inject into all agents
just ipa-inject

GF(3) Triad

ipa-safety (-1) ⊗ gay-mcp (0) ⊗ quantum-balalaika (+1) = 0 ✓
ipa-safety (-1) ⊗ chromatic-peptide-samovar (0) ⊗ topos-generate (+1) = 0 ✓

Skill Name: ipa-safety
Protocol: ipa://
Braille: ⠊⠏⠁
Trit: -1 (MINUS - safety validator)
Function: Reflow all encodings to IPA-only safety
Streams: Cyrillic (-1) + Latin (0) → IPA (+1)