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

132
specialists/quantity.md Normal file
View File

@@ -0,0 +1,132 @@
# Quantity Specialist
**specialist_id:** `quantity`
**trigger_gates:** `has_quantity`, `is_math`
---
## Responsibility
The quantity specialist extracts numeric values, attaches QuantityFacets to quantity objects, and emits arithmetic and comparison constraints. When arithmetic can be resolved deterministically, it resolves it. When resolution requires a solver, it emits a structured constraint for the resolver.
---
## Manifest
```
declared_facet_kinds:
- quantity
declared_constraint_types:
- quantity_equals
- quantity_sum
- quantity_difference
- quantity_product
- quantity_quotient
- quantity_greater
- quantity_less
- quantity_at_least
- quantity_at_most
- quantity_bound
budget_caps:
max_objects_proposed: 6
max_facets_emitted: 6
max_constraints_emitted: 10
max_merges: 0
max_splits: 0
```
---
## Output: QuantityFacet
Attach to any object of kind `quantity`.
```
QuantityFacet fields used:
- value: number or symbolic expression
- unit: string (apples, dollars, meters, etc.)
- is_exact: true/false
- derived_from_refs: quantity object IDs this was computed from
```
---
## Output: Constraints
### `quantity_equals(Q_result, expression)`
Emit when a quantity is defined as equal to an expression.
```
{
"constraint_type": "quantity_equals",
"argument_refs": ["Q_alice_final", "Q_expr_5_minus_2"],
"expression": "quantity(Q_alice_final) = quantity(Q1) - quantity(Q2)",
"strength": "hard"
}
```
### `quantity_difference(Q_result, Q_minuend, Q_subtrahend)`
Preferred form when the specific operation is subtraction.
```
argument_refs order: [result, minuend, subtrahend]
```
### `quantity_sum(Q_result, Q_addend1, Q_addend2, ...)`
Result equals the sum of all argument quantities.
### `quantity_greater(Q_a, Q_b)`
Q_a > Q_b.
### `quantity_less(Q_a, Q_b)`
Q_a < Q_b.
---
## Arithmetic resolution
When all inputs to an arithmetic constraint are exact numeric values, the quantity specialist SHOULD resolve the arithmetic inline and set the result quantity's `value` directly.
```
if quantity_difference(Q_result, Q1, Q2):
if Q1.value is exact numeric AND Q2.value is exact numeric:
Q_result.value = Q1.value - Q2.value
Q_result.is_exact = true
mark constraint as resolved
else:
emit constraint with status = unresolved
resolver handles it
```
This avoids unnecessary round-trips through the resolver for simple arithmetic.
---
## Unit tracking
Units must be tracked and propagated. Emitting a `quantity_difference` constraint without units is not sufficient — the result unit must be declared or inferred.
Rules:
- Same unit on both operands: result inherits unit
- Different units on operands: emit a `quantity_bound` constraint marking the result as unit-ambiguous until a converter is applied
- Unitless operands: result is unitless
---
## Contract test requirements
- Given `Alice had 5 apples. She gave Bob 2 apples.`:
- Must emit Q1 with value=5, unit="apples"
- Must emit Q2 with value=2, unit="apples"
- Must emit `quantity_difference(Q_alice_final, Q1, Q2)` or `quantity_equals(Q_alice_final, "5-2")`
- Must set Q_alice_final.value = 3 (inline resolution)
- Must not emit temporal or entity constraints
- All quantity facets must have `unit` set or explicitly `"unitless"`
- All emitted constraints must have `source_module: quantity`