Files
ucwm/synthesis/language_bindings.md
bill b758d7ea60 Sprint 1: project skeleton, type system, and all architecture specs
- src/types.hpp: complete UCWM type system in C++20 — 19 enums, 11 facet
  data types, all core structs (CanonicalObject, Constraint, Facet,
  GateSignal, WorldState, etc.) with full JSON round-trip serialization
- src/main.cpp: smoke test — constructs apple-problem WorldState by hand,
  serializes to JSON
- tests/test_types.cpp: 19 tests, 123 assertions, all passing
- CMakeLists.txt: CMake + CPM build with nlohmann/json, spdlog, Catch2
- schemas/: JSON Schema contracts for all UCWM data types
- gates/, specialists/, resolver/, synthesis/: language-agnostic interface
  contracts and domain specs for all pipeline layers
- docs/: architecture, vocabulary, decision matrices, roadmap (6 phases,
  28 sprints), sprint_001, implementation_constraints

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 16:09:55 -07:00

4.7 KiB

Language Binding Interface

The language binding layer is the boundary between messy natural language and the structured UCWM reasoning core. It consists of exactly two interface stubs:

to_ucwm(text_input) → WorldState
from_ucwm(world_state) → text_output

These must remain separable. The reasoning core must never depend on how language enters or exits.


to_ucwm — Input binding

to_ucwm {
  input:
    text:     string           -- raw natural language input
    context:  WorldState?      -- optional prior world state (multi-turn)
    options:  BindingOptions?

  output:
    world_state: WorldState    -- stage = "post_gate" with gate_signals populated
                               -- and initial object proposals if perception runs here

  BindingOptions {
    run_gates:       boolean   -- default: true
    run_perception:  boolean   -- default: true (runs object proposal)
    language:        string?   -- ISO 639-1 language code, default "en"
    debug:           boolean   -- emit step-by-step trace
  }
}

Responsibilities

to_ucwm is responsible for:

  1. Running the Relation Gate Array on the input text, producing GateSignal[]
  2. Running the perception / object proposal stage, producing initial CanonicalObject[]
  3. Packaging both into a WorldState with stage = "post_gate" or "post_proposal"
  4. Returning a valid WorldState — never raw text, never embeddings as primary output

What to_ucwm must NOT do

  • Run specialists
  • Emit constraints
  • Produce answers
  • Modify a prior WorldState in-place (multi-turn must pass context as a separate field, not mutate)

Naive implementation (first slice)

A minimal to_ucwm implementation:

  1. Run all gates using rule-based implementations from gates/simple_rules.md
  2. For each activated gate, tag relevant spans
  3. Propose one CanonicalObject per clearly identified entity, quantity, or event span
  4. Return WorldState with these proposals

This is sufficient for the first vertical slice. Upgrade to a neural perception model later.


from_ucwm — Output binding

from_ucwm {
  input:
    world_state:     WorldState   -- must have stage = "resolved"
    original_query:  string       -- original user input text
    mode:            string       -- "direct" | "explain" | "trace"
    options:         OutputOptions?

  output:
    text:            string       -- natural language answer
    confidence:      float
    derivation_trace: string[]
    open_questions:  string[]?

  OutputOptions {
    max_length:   integer?   -- max characters in output text
    language:     string?    -- ISO 639-1, default "en"
    debug:        boolean
  }
}

Responsibilities

from_ucwm is responsible for:

  1. Checking WorldState.stage = "resolved" (reject otherwise with an error)
  2. Delegating to the synthesis module (see synthesis/contract.md)
  3. Returning a typed SynthesisOutput — never directly generating text from tokens

What from_ucwm must NOT do

  • Access raw input tokens
  • Run specialists or the resolver
  • Add facts not present in resolved WorldState

Contract invariants

  1. Round-trip transparency. For any resolved WorldState W:

    from_ucwm(W).derivation_trace must reference only IDs that exist in W
    
  2. Stage enforcement. to_ucwm always produces a WorldState with stage at or before post_proposal. from_ucwm always requires stage = resolved. The pipeline between them is the responsibility of the caller.

  3. Stateless bindings. Neither binding holds state. Multi-turn context is passed as an argument, not stored inside the binding.

  4. Language is at the edges only. Raw language appears only at the input of to_ucwm and the output of from_ucwm. No other module may receive or emit raw language as a primary typed output.


Multi-turn handling

For conversational multi-turn:

turn_1:
  ws_1 = to_ucwm(text="Alice had 5 apples")
  ws_1_resolved = pipeline(ws_1)

turn_2:
  ws_2 = to_ucwm(text="She gave Bob 2.", context=ws_1_resolved)
  -- ws_2 inherits E1 (Alice), O_apples, Q1 from ws_1_resolved
  -- entity specialist resolves "She" → E1 via existing alias

The context WorldState is read-only in to_ucwm. New proposals may reference objects from context but do not modify them directly. The resolver handles merges.


Debug trace format

When options.debug = true, both bindings emit a structured log:

{
  "stage": "to_ucwm",
  "input_length": 42,
  "gates_fired": ["has_entity_reference", "has_quantity", "has_ownership_transfer"],
  "objects_proposed": 5,
  "world_state_stage": "post_proposal"
}

{
  "stage": "from_ucwm",
  "world_state_stage": "resolved",
  "answer": "Alice has 3 apples.",
  "confidence": 0.97,
  "derivation_steps": 7
}