pre-review fixes
This commit is contained in:
37
LOGIC DOCS/002-guardrails-via-intrinsic-properties.md
Normal file
37
LOGIC DOCS/002-guardrails-via-intrinsic-properties.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# Guardrails via intrinsic properties, not special cases
|
||||
|
||||
## The goal
|
||||
|
||||
Full recombination across the existing catalog — any platform × any actuator × any energy source — should stay possible, while physically impossible pairings (a nuclear reactor on a bicycle, a solar sail in an atmosphere) get blocked automatically. Neither half is negotiable: too loose and the results are nonsense, too special-cased and the combinatorics stop being the point of the project.
|
||||
|
||||
## The mechanism (already in place)
|
||||
|
||||
Entities never reference each other. Each one only declares its own physical envelope:
|
||||
|
||||
- `requires`/`provides`/`excludes` — categorical compatibility (`energy_form`, `medium`, `atmosphere`)
|
||||
- `range_min`/`range_max` — numeric floors and ceilings on a shared key (`mass`, `footprint`, `energy_density`, ...)
|
||||
|
||||
`ConstraintResolver` (`src/physcom/engine/constraint_resolver.py`) then runs generic, entity-agnostic rules across every pair in a combo: requires-vs-excludes, mutual exclusion, range incompatibility, provides-vs-range deficit, unmet requirements. A combo gets blocked because two numbers or two category tags collided — never because code somewhere says "if X and Y, block." Blocking is emergent from the data, not authored per pair.
|
||||
|
||||
This is what makes "nuclear reactor won't fit on a bicycle" work today: Nuclear Thermal Drive declares `mass range_min = 1500kg`, Light Personal Vehicle declares `mass range_max = 60kg`, and Rule 3 (`_check_range_incompatibility`) blocks the combo without either entity knowing the other exists.
|
||||
|
||||
## Why this breaks silently
|
||||
|
||||
The mechanism only blocks what the data describes. A category missing a `mass range_min` or `footprint range_min` it should physically have doesn't get blocked — not because the rule is wrong, but because nothing told the resolver there was a limit. This is an easy failure mode: the constraint system looks like it's working (it blocks the pairs someone thought to test) while quietly admitting nonsense pairs nobody happened to check.
|
||||
|
||||
Two such gaps were found and fixed 2026-07 (see git history around this doc's commit):
|
||||
|
||||
- Solar Sail declared its size under the key `surface_area` instead of `footprint` — a naming mismatch made it invisible to every cross-check, silently a no-op.
|
||||
- Nuclear Thermal Drive and Nuclear Fuel had a `mass range_min` but no `footprint range_min` — reactor mass was guarded, reactor size was not.
|
||||
|
||||
Both were fixed by adding/renaming a `Dependency`, zero changes to `ConstraintResolver` itself. That's the intended shape of a fix here.
|
||||
|
||||
## The standing question for review
|
||||
|
||||
For every actuator and energy_storage entity: what is the **full set of intrinsic physical floors and ceilings** a real version of this technology imposes at any scale — structural mass, footprint, radiation shielding, minimum coolant/containment volume, thermal rejection surface area, etc. — and is each one expressed as a `range_min`/`range_max`/`provides`/`requires` dependency using a key that **already exists** in the vocabulary (`grep -oP 'Dependency\("[a-z]+", "\K[a-z_]+'` over `seed/transport_example.py` lists it), so it actually cross-checks against every other entity that shares that key?
|
||||
|
||||
A missing floor is a silent guardrail hole, not a missing detail.
|
||||
|
||||
## Non-goal
|
||||
|
||||
Do not add pairwise special cases (`if actuator == "Nuclear Thermal Drive" and platform == "..."`). That defeats the architecture — the whole point is that the catalog recombines freely and physics falls out of shared, generic constraints. Any new realism belongs on the entity as a property, not in `ConstraintResolver` as a rule.
|
||||
Reference in New Issue
Block a user