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>
This commit is contained in:
2026-05-01 16:09:55 -07:00
commit b758d7ea60
35 changed files with 6344 additions and 0 deletions

112
gates/contract.md Normal file
View File

@@ -0,0 +1,112 @@
# Gate Interface Contract
A gate is a small, independent recognizer that detects whether a particular relation family is likely relevant to the input. Gates are the cheapest component in the pipeline and run first, in parallel.
---
## Design principle
Gates are **high-recall by design**. It is better to activate an unnecessary specialist than to miss a needed one. A false positive costs budget. A false negative corrupts the answer.
Gates do not solve the task. They do not produce objects, facets, or constraints. They only emit a `GateSignal`.
---
## Input
```
GateInput {
text: string -- raw input text
context: string? -- optional prior context
span_start: integer? -- if operating on a specific span
span_end: integer?
gate_id: string -- which gate is being invoked
}
```
---
## Output
```
GateSignal {
gate_id: string -- must match the invoking gate_id
activated: boolean -- did this gate fire?
confidence: float [0, 1] -- confidence in the activation decision
evidence_spans: Span[]? -- text spans that triggered the gate
method: string -- "regex" | "rule" | "classifier" | "neural" | "hybrid"
}
```
See `schemas/routing.json#/$defs/GateSignal` for the normative schema.
---
## Invariants
Every gate implementation MUST satisfy all of the following:
1. **Bounded output.** A gate emits exactly one `GateSignal`. No additional text, no secondary outputs.
2. **Idempotent.** Calling a gate twice with the same input produces the same output.
3. **No side effects.** A gate does not modify WorldState. It only reads input text.
4. **Declared method.** The `method` field must accurately reflect how the gate works (regex, rule, classifier, neural, hybrid). This is used for diagnostic filtering.
5. **High-recall posture.** When uncertain, a gate should prefer `activated: true` with lower confidence over `activated: false`. A gate should only return `activated: false, confidence: 0.99` if the signal is clearly and definitively absent.
6. **Self-contained.** A gate may not depend on the outputs of other gates. Gates run in parallel with no inter-gate dependencies.
---
## Standard gate IDs
Gates are identified by string IDs. The following IDs are reserved and have defined semantics. Additional domain-specific gates may be added to the registry.
| gate_id | Fires when input probably contains... |
|---|---|
| `is_math` | Numeric computation, arithmetic, algebra |
| `is_code` | Source code, pseudocode, program structures |
| `has_temporal_relation` | Before/after/during/recurring/sequence |
| `has_spatial_relation` | Location, containment, direction, proximity |
| `has_causal_relation` | Cause/effect/enable/block |
| `has_entity_reference` | Named or implied entities |
| `has_coreference` | Pronouns or aliases that refer back |
| `has_quantity` | Counts, amounts, measures, percentages |
| `has_logical_negation` | Not, unless, except, never |
| `has_comparison` | More/less/same/different/equal |
| `has_planning` | Steps, goals, prerequisites, sequencing |
| `has_constraint` | Requirements, restrictions, conditions |
| `has_state_change` | Status transitions, possession changes |
| `has_ownership_transfer` | Give, sell, take, receive, lose |
| `has_social_intent` | Belief, desire, obligation, deception, trust |
| `requires_external_knowledge` | World facts not inferable from input alone |
| `requires_synthesis_only` | Input is direct and needs no decomposition |
---
## Testing a gate implementation
A gate implementation is valid if it passes all of the following test classes:
**Positive recall tests:** Given input known to contain the relation, the gate fires.
**True negative tests:** Given input that clearly lacks the relation, the gate does not fire.
**Confidence calibration tests:** Confidence scores are higher for clear positives than for ambiguous cases.
**Boundary tests:** Very short input, empty input, non-linguistic input (numbers only, code only) produce valid GateSignal objects.
**Idempotency tests:** Same input, same output on repeated calls.
See `tests/contracts/gate_contract_tests.md` for test case templates.
---
## Implementation guide
A gate may be implemented in any language or framework, as long as it satisfies the contract above. Common approaches:
- **Regex / keyword rules:** fast, zero training cost, fragile on unusual phrasing
- **Feature classifier:** small model trained on labeled examples, better generalization
- **Small neural classifier:** ~1M10M parameter binary classifier, highest recall potential
- **Hybrid:** rules for high-confidence cases, classifier for uncertain cases
The gate registry (`gates/registry.md`) specifies how to register a new gate implementation.