# 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: ```json { "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 } ```