Files
ucwm/gates/contract.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

113 lines
4.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.