- 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>
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:
- Running the Relation Gate Array on the input text, producing
GateSignal[] - Running the perception / object proposal stage, producing initial
CanonicalObject[] - Packaging both into a
WorldStatewithstage = "post_gate"or"post_proposal" - 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:
- Run all gates using rule-based implementations from
gates/simple_rules.md - For each activated gate, tag relevant spans
- Propose one
CanonicalObjectper clearly identified entity, quantity, or event span - 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:
- Checking WorldState.stage = "resolved" (reject otherwise with an error)
- Delegating to the synthesis module (see
synthesis/contract.md) - 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
-
Round-trip transparency. For any resolved WorldState W:
from_ucwm(W).derivation_trace must reference only IDs that exist in W -
Stage enforcement.
to_ucwmalways produces a WorldState with stage at or beforepost_proposal.from_ucwmalways requires stage =resolved. The pipeline between them is the responsibility of the caller. -
Stateless bindings. Neither binding holds state. Multi-turn context is passed as an argument, not stored inside the binding.
-
Language is at the edges only. Raw language appears only at the input of
to_ucwmand the output offrom_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
}