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:
112
gates/contract.md
Normal file
112
gates/contract.md
Normal 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:** ~1M–10M 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.
|
||||
70
gates/registry.md
Normal file
70
gates/registry.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# Gate Registry
|
||||
|
||||
The gate registry maps gate IDs to their implementations and metadata. The registry is the authoritative list of which gates are active in the system.
|
||||
|
||||
---
|
||||
|
||||
## Registry entry format
|
||||
|
||||
```
|
||||
GateRegistryEntry {
|
||||
gate_id: string -- must match a standard gate_id or be a registered extension
|
||||
display_name: string -- human-readable label
|
||||
description: string -- one sentence on what this gate detects
|
||||
method: string -- "regex" | "rule" | "classifier" | "neural" | "hybrid"
|
||||
implementation: string -- reference to implementation module or file
|
||||
version: string -- semver
|
||||
enabled: boolean -- false to disable without removing from registry
|
||||
recall_threshold: float [0, 1] -- minimum recall this gate is expected to maintain
|
||||
activates_specialists: string[] -- hint: which specialists this gate commonly triggers
|
||||
notes: string? -- optional
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Active gate registry (initial)
|
||||
|
||||
These are the initial gate implementations. All use rule/regex methods as starting points. They will be upgraded to classifiers or neural models as the contract tests stabilize.
|
||||
|
||||
| gate_id | method | activates_specialists | enabled |
|
||||
|---|---|---|---|
|
||||
| `is_math` | rule | quantity, logic | true |
|
||||
| `is_code` | rule | code | true |
|
||||
| `has_temporal_relation` | rule | temporal | true |
|
||||
| `has_spatial_relation` | rule | spatial | true |
|
||||
| `has_causal_relation` | rule | causal | true |
|
||||
| `has_entity_reference` | rule | entity | true |
|
||||
| `has_coreference` | rule | entity | true |
|
||||
| `has_quantity` | rule | quantity | true |
|
||||
| `has_logical_negation` | rule | logic | true |
|
||||
| `has_comparison` | rule | quantity, logic | true |
|
||||
| `has_planning` | rule | planning | true |
|
||||
| `has_constraint` | rule | logic, planning | true |
|
||||
| `has_state_change` | rule | ownership, temporal | true |
|
||||
| `has_ownership_transfer` | rule | ownership, entity | true |
|
||||
| `has_social_intent` | rule | social | true |
|
||||
| `requires_external_knowledge` | rule | — | true |
|
||||
| `requires_synthesis_only` | rule | — | true |
|
||||
|
||||
---
|
||||
|
||||
## Adding a new gate
|
||||
|
||||
1. Define a gate ID. Use `has_{relation_family}` for relation detectors and `is_{domain}` for domain detectors.
|
||||
2. Write the implementation satisfying `gates/contract.md`.
|
||||
3. Write at least 5 positive recall tests and 5 true negative tests per `tests/contracts/gate_contract_tests.md`.
|
||||
4. Add an entry to this registry.
|
||||
5. Update `activates_specialists` with which specialists this gate commonly triggers. This is a hint to the router, not a constraint.
|
||||
|
||||
---
|
||||
|
||||
## Upgrading a gate implementation
|
||||
|
||||
A gate's contract (gate_id, output schema, invariants) does not change when the implementation method changes. A regex gate may be replaced by a neural gate without any other component knowing. The registry `method` field and `version` field must be updated.
|
||||
|
||||
---
|
||||
|
||||
## Disabling a gate
|
||||
|
||||
Set `enabled: false`. Do not remove entries — removal loses the `activates_specialists` hint and breaks the audit trail.
|
||||
223
gates/simple_rules.md
Normal file
223
gates/simple_rules.md
Normal file
@@ -0,0 +1,223 @@
|
||||
# Simple Rule-Based Gate Definitions
|
||||
|
||||
This file specifies the rule logic for the initial rule-based gate implementations. These are starter gates — high-recall, zero training cost, acceptable false positive rate.
|
||||
|
||||
Each gate spec below is language-agnostic. Any implementation must produce identical `GateSignal` outputs for the given inputs.
|
||||
|
||||
---
|
||||
|
||||
## Gate: `is_math`
|
||||
|
||||
**Detects:** numeric computation, arithmetic, algebra, equations.
|
||||
|
||||
**Rule logic:**
|
||||
|
||||
1. Activate if input contains any digit sequence (regex: `\d+`)
|
||||
2. Activate if input contains math keywords: `how many`, `total`, `sum`, `difference`, `product`, `divided by`, `minus`, `plus`, `equals`, `more than`, `less than`, `percent`, `ratio`
|
||||
3. Activate if input contains operator symbols: `+`, `-`, `*`, `/`, `=`, `%`, `^`
|
||||
|
||||
**Confidence assignment:**
|
||||
- Multiple signals present → 0.95
|
||||
- One signal, multiple instances → 0.85
|
||||
- One signal, one instance → 0.70
|
||||
|
||||
---
|
||||
|
||||
## Gate: `has_entity_reference`
|
||||
|
||||
**Detects:** named or implied entities (people, organizations, places, objects, artifacts).
|
||||
|
||||
**Rule logic:**
|
||||
|
||||
1. Activate if any token starts with a capital letter and is not the first word of the sentence
|
||||
2. Activate if input contains proper-noun indicators: `Mr.`, `Ms.`, `Dr.`, `the`, followed by capitalized noun
|
||||
3. Activate if input contains pronouns: `he`, `she`, `they`, `it`, `him`, `her`, `them`
|
||||
4. Activate if input contains possessive markers: `Alice's`, `Bob's`, `its`
|
||||
|
||||
**Confidence assignment:**
|
||||
- Capital-letter token found → 0.90
|
||||
- Pronoun only → 0.75
|
||||
- Neither, but possessive marker found → 0.80
|
||||
|
||||
---
|
||||
|
||||
## Gate: `has_quantity`
|
||||
|
||||
**Detects:** counts, amounts, measures, percentages, ordinals.
|
||||
|
||||
**Rule logic:**
|
||||
|
||||
1. Activate if input contains a digit sequence
|
||||
2. Activate if input contains number words: `one`, `two`, `three`, ... `ten`, `hundred`, `thousand`, `million`
|
||||
3. Activate if input contains measure words: `apples`, `dollars`, `meters`, `kilograms`, `minutes`, `hours`, `days`
|
||||
4. Activate if input contains ordinals: `first`, `second`, `third`, `last`
|
||||
|
||||
**Confidence assignment:**
|
||||
- Digit + measure word → 0.99
|
||||
- Digit only → 0.85
|
||||
- Number word only → 0.80
|
||||
|
||||
---
|
||||
|
||||
## Gate: `has_ownership_transfer`
|
||||
|
||||
**Detects:** give, sell, take, receive, lose, transfer of possession.
|
||||
|
||||
**Rule logic:**
|
||||
|
||||
1. Activate if input contains transfer verbs: `give`, `gave`, `gives`, `take`, `took`, `takes`, `sell`, `sold`, `sells`, `receive`, `received`, `receives`, `lose`, `lost`, `loses`, `transfer`, `transferred`, `hand`, `handed`, `pass`, `passed`
|
||||
2. Activate if input contains indirect-object patterns: `gave [entity] [object]`, `[entity] sold [object] to [entity]`
|
||||
|
||||
**Confidence assignment:**
|
||||
- Transfer verb present → 0.92
|
||||
- Indirect-object pattern confirmed → 0.97
|
||||
|
||||
---
|
||||
|
||||
## Gate: `has_temporal_relation`
|
||||
|
||||
**Detects:** before/after/during/recurring/sequential ordering.
|
||||
|
||||
**Rule logic:**
|
||||
|
||||
1. Activate if input contains temporal connectives: `before`, `after`, `during`, `when`, `then`, `next`, `later`, `previously`, `first`, `second`, `finally`, `since`, `until`, `while`
|
||||
2. Activate if input contains time expressions: `yesterday`, `tomorrow`, `at noon`, `on Monday`, day/month/year patterns
|
||||
3. Activate if input contains sequence markers: `step 1`, `then`, `afterward`, `subsequently`
|
||||
|
||||
**Confidence assignment:**
|
||||
- Temporal connective + time expression → 0.97
|
||||
- Temporal connective only → 0.82
|
||||
- Sequence marker only → 0.75
|
||||
|
||||
---
|
||||
|
||||
## Gate: `has_logical_negation`
|
||||
|
||||
**Detects:** not, never, unless, except, no, without, deny, false.
|
||||
|
||||
**Rule logic:**
|
||||
|
||||
1. Activate if input contains negation words: `not`, `no`, `never`, `none`, `neither`, `nor`, `without`, `unless`, `except`, `deny`, `denied`, `false`, `incorrect`, `wrong`
|
||||
2. Activate if input contains negative contractions: `isn't`, `aren't`, `wasn't`, `weren't`, `doesn't`, `don't`, `didn't`, `can't`, `won't`, `wouldn't`, `couldn't`, `shouldn't`
|
||||
|
||||
**Confidence assignment:**
|
||||
- Negation word found → 0.92
|
||||
|
||||
---
|
||||
|
||||
## Gate: `has_causal_relation`
|
||||
|
||||
**Detects:** cause, effect, enable, block, because, therefore, so.
|
||||
|
||||
**Rule logic:**
|
||||
|
||||
1. Activate if input contains causal connectives: `because`, `therefore`, `so`, `thus`, `hence`, `consequently`, `as a result`, `due to`, `caused by`, `leads to`, `results in`, `enables`, `prevents`, `blocks`, `allows`
|
||||
|
||||
**Confidence assignment:**
|
||||
- Causal connective found → 0.90
|
||||
|
||||
---
|
||||
|
||||
## Gate: `has_coreference`
|
||||
|
||||
**Detects:** pronouns and aliases that refer to previously mentioned entities.
|
||||
|
||||
**Rule logic:**
|
||||
|
||||
1. Activate if input contains personal pronouns: `he`, `she`, `they`, `it`, `him`, `her`, `them`, `his`, `hers`, `their`, `its`
|
||||
2. Activate if input contains demonstrative references: `this`, `that`, `these`, `those` followed by a noun that was mentioned earlier
|
||||
3. Activate if multiple entities are named AND pronouns are present
|
||||
|
||||
**Confidence assignment:**
|
||||
- Pronoun present + multiple named entities → 0.90
|
||||
- Pronoun only, single entity → 0.70
|
||||
|
||||
---
|
||||
|
||||
## Gate: `has_spatial_relation`
|
||||
|
||||
**Detects:** location, containment, direction, proximity.
|
||||
|
||||
**Rule logic:**
|
||||
|
||||
1. Activate if input contains spatial prepositions: `in`, `at`, `on`, `above`, `below`, `inside`, `outside`, `near`, `far`, `left`, `right`, `north`, `south`, `east`, `west`, `between`, `next to`, `adjacent to`
|
||||
2. Activate if input contains place names (capitalized geographics) or location indicators: `street`, `city`, `country`, `room`, `building`, `floor`
|
||||
|
||||
**Confidence assignment:**
|
||||
- Spatial preposition + place indicator → 0.92
|
||||
- Spatial preposition only → 0.72
|
||||
|
||||
---
|
||||
|
||||
## Gate: `has_planning`
|
||||
|
||||
**Detects:** goals, steps, prerequisites, sequencing of actions.
|
||||
|
||||
**Rule logic:**
|
||||
|
||||
1. Activate if input contains planning vocabulary: `plan`, `goal`, `step`, `procedure`, `prerequisite`, `depends on`, `requires`, `in order to`, `so that`, `to achieve`
|
||||
2. Activate if input contains numbered or ordered list markers
|
||||
|
||||
**Confidence assignment:**
|
||||
- Planning vocabulary present → 0.88
|
||||
|
||||
---
|
||||
|
||||
## Gate: `has_social_intent`
|
||||
|
||||
**Detects:** beliefs, desires, obligations, deception, trust, social roles.
|
||||
|
||||
**Rule logic:**
|
||||
|
||||
1. Activate if input contains mental state verbs: `believe`, `believes`, `think`, `thinks`, `want`, `wants`, `know`, `knows`, `intend`, `intends`, `expect`, `expects`, `hope`, `hopes`
|
||||
2. Activate if input contains obligation/permission words: `must`, `should`, `ought`, `may`, `allowed`, `permitted`, `required`, `obligated`
|
||||
3. Activate if input contains social verbs: `promise`, `lie`, `deceive`, `trust`, `cooperate`, `compete`, `agree`, `refuse`
|
||||
|
||||
**Confidence assignment:**
|
||||
- Mental state verb present → 0.85
|
||||
- Obligation/permission word → 0.80
|
||||
- Social verb → 0.90
|
||||
|
||||
---
|
||||
|
||||
## Gate: `requires_external_knowledge`
|
||||
|
||||
**Detects:** queries that require facts not present in the input text.
|
||||
|
||||
**Rule logic:**
|
||||
|
||||
1. Activate if input contains knowledge-seeking patterns: `who is`, `what is`, `where is`, `when did`, `how does`, `why does` combined with named entities
|
||||
2. Activate if input references historical events, scientific facts, or world geography without providing context
|
||||
|
||||
**Note:** This gate has higher false-positive tolerance than most. When uncertain, fire.
|
||||
|
||||
**Confidence assignment:**
|
||||
- Knowledge-seeking pattern with named entity → 0.85
|
||||
- Named entity without provided context → 0.70
|
||||
|
||||
---
|
||||
|
||||
## Gate: `requires_synthesis_only`
|
||||
|
||||
**Detects:** inputs that are complete, self-contained, and require no structural decomposition.
|
||||
|
||||
**Rule logic:**
|
||||
|
||||
1. Activate only if all of the following hold:
|
||||
- No other gates fire with confidence > 0.70
|
||||
- Input is a direct factual statement with no quantities, entities, or relations to track
|
||||
- Input length < 15 tokens
|
||||
|
||||
**Note:** This gate is a low-priority catch-all. It should rarely fire when other gates fire.
|
||||
|
||||
**Confidence assignment:**
|
||||
- All conditions met → 0.80
|
||||
|
||||
---
|
||||
|
||||
## Implementation notes
|
||||
|
||||
- All keyword lists should be treated as seed lists. Implementors should extend them for their target domain.
|
||||
- Case-insensitive matching is preferred.
|
||||
- Lemmatization or stemming is recommended for verb forms.
|
||||
- Do not hardcode language; design for swappable tokenizers and keyword tables.
|
||||
Reference in New Issue
Block a user