12. Limits and honesty
What PYRION does not claim.
What the engine does not do
PYRION's engine is a filing and comparison system with strict rules. It is not a fire simulator. Specifically, it does not:
- Simulate or predict flames. There is no solver and no CFD. It never says how a flame would behave on the Moon.
- Interpolate behaviour. "Inside the tested region" means the numbers are within what was measured. It does not claim the flame behaves smoothly between measurements: combustion can change abruptly near limits such as extinction.
- Say that something is safe or unsafe. A verdict is about comparability with recorded tests, nothing more.
- Cross regimes. A different gravity, fuel phase, diluent or flame type is a different situation, never a "long distance".
- Fill in what a record does not state. If the extracted records of an investigation do not state something, the engine says so ("insufficient evidence") and does not assume it.
- Know anything outside PSI. It speaks only about the PSI records it has. It says "in PSI" and never "no data exists".
- Read documents or the web on its own. It reads condition records; they are extracted, with quotes, by a separate process that checks every number against its source.
- Use a language model to decide. See "The model never decides".
What it does do is small and checkable: it compares your condition with each investigation's recorded conditions, by fixed rules, and shows its work.
## For engineers
Structural reasons in the code:
- No physics model:
engine/srccontains geometry (engine/src/geometry.ts), unit conversion (engine/src/quantity.ts), comparison rules (engine/src/verdict.ts) and text builders; the stretch-rate and chamber-balance modules (engine/src/stretch.ts,engine/src/fm2.ts) are labelled hypotheses and instrument arithmetic respectively (see "Hypotheses and proposals"). - Regimes are barriers:
distance = nullacross a barrier (engine/src/verdict.ts). - Unknown is a result:
INSUFFICIENT_EVIDENCE; records with statusinsufficient_evidencenever count (counts,engine/src/evidence.ts). - Wording rules enforced by tests: no "no data exists", no "undefined", no snake_case or enum names in sentences, at most 4 significant figures (
engine/test/wording.test.ts,answer.test.ts). - Dependencies: zero; the engine imports no Node module except
engine/src/load.ts(file reading for tests and the CLI).
The model never decides
A language model is used for two jobs only: understanding what you typed and wording an answer. It is never allowed to decide a verdict, convert a unit or do arithmetic.
- Verdicts come from the engine's rules. Swap the model and the verdict, and the fingerprint, do not change.
- Units and numbers come from code. When a model must quote a number (an oxygen partial pressure, a conversion), it has to call a calculator, and the number it writes must be the one the calculator returned. In a benchmark of three models on expert questions, all three put at least one wrong number in; that is why this rule exists.
- Quotes from NASA are checked by code: the quote must be on the page of the document the model cites, with the numbers exactly as written (1.5 is never accepted for 15). If the quote is not there, the whole statement is dropped and not shown.
- General background knowledge is allowed, but it is always labelled "TARS own reasoning — not verified against a source", and any number in it that does not come from a calculator or a verified quote is replaced by "[number removed: not from a source]".
A model can still misunderstand a question. That is why the extractor reads the question first by code, shows you what it understood, and lets you correct it before anything is computed.
## For engineers
threePartAnswer(engine/src/answer.ts:87) builds the content from engine results; the model only words it.checkAnswer(answer, { corpus, engine, tools })(web/lib/expert/claims.ts): layersnasa,engine,expert.nasa: every citation must passcitationProblem(document and page exist, at least 15 letters,quoteFoundletters-only match with elisions,numbersFoundnumbers as written: same rules asvalidation/run_all.py); one failure drops the block, its text is not in the output.engine: needs a reference to an engine output; numbers (also ×100 for fractions) and ids (PSI-nn, DOI) must be in it, else dropped.expert: labelEXPERT_LABEL; untraced numbers replaced byNUMBER_REMOVEDand logged inreport.flaggedNumbers.- Calculators (
web/lib/expert/calculators.ts):o2PartialPressure,convertPressure,convertTemperature,compareAtmospheres,gravityValue; each returnsprovenance: "computed by code (...)". - Extraction first:
extractQuantities(engine/src/extract.ts:83).
The conventions PYRION chose (not NASA values)
Some numbers in PYRION are not measurements and not NASA's: they are choices made so that the tool is usable. They are listed here, each with the reason, and each is shown as a convention wherever it changes a result.
- 0.5 % measurement tolerance. So 101.3 kPa and 101.325 kPa are the same condition.
- Below 0.01 g is microgravity. NASA's chart shows 1e-4 g and 1e-2 g on one continuous axis, so this cut is a modelling choice.
- 0.9 to 1.1 g is normal gravity. A band so that 0.998 g is not "partial".
- Above 1.1 g: not covered. No PSI regime exists there.
- Extrapolation levels at 10 % and 30 %. To make the word "extrapolation" informative; the axis floor is 5 % of the axis range.
- Plausibility windows for habitat questions: oxygen 5 to 60 %, pressure 20 to 120 kPa. They only trigger a warning.
- Test matrix. Oxygen steps of 4 and 8 points (the 4-point step follows FM2's own steps) and pressure steps of 15 %.
- Order of priority of the proposal: untested regime, then solids, then far outside, outside, just outside.
If you disagree with one of these, the constants are named in the code and the reasoning is in the matching topic; the engine would be re-run with another value, and the results would change accordingly. Nothing here is hidden.
## For engineers
| Convention | Constant | Location |
|---|---|---|
| tolerance | MEASUREMENT_TOLERANCE_REL = 0.005 | engine/src/types.ts:175 |
| microgravity cut | MICROGRAVITY_BELOW_G = 0.01 | engine/src/quantity.ts:385 |
| normal band | NORMAL_GRAVITY_BAND = { lo: 0.9, hi: 1.1 } | engine/src/quantity.ts:392 |
| gravity bound | BOUNDS.gravity_level = [0, 3] | engine/src/quantity.ts:125 |
| level thresholds | EXTRAPOLATION_LEVELS = { just_outside: 0.1, outside: 0.3 } | engine/src/levels.ts:14 |
| axis floor | EXTRAPOLATION_AXIS_FLOOR = 0.05 | engine/src/levels.ts:17 |
| plausibility windows | HABITAT_WINDOWS = { o2_mole_fraction: [0.05, 0.6], pressure: [20, 120] } | engine/src/quantity.ts:184 |
| matrix steps | TEST_MATRIX_O2_OFFSETS_POINTS = [-8, -4, 0, 4, 8], TEST_MATRIX_PRESSURE_FRACTIONS = [-0.15, 0, 0.15] | engine/src/experiments.ts:16-17 |
Each has a note constant (MEASUREMENT_TOLERANCE_NOTE, MICROGRAVITY_CONVENTION_NOTE, NORMAL_GRAVITY_CONVENTION_NOTE, EXTRAPOLATION_LEVEL_NOTE, TEST_MATRIX_NOTE) that begins "PYRION convention, not a NASA value" or says "PYRION design convention, not a NASA design", and the plausibility warnings say "PYRION plausibility window, not a NASA value". Tests check these strings (engine/test/judge.test.ts, levels.test.ts, quantity.test.ts, experiments.test.ts).
What the data can and cannot tell you
Everything PYRION says rests on condition records extracted from PSI investigations: tables and documents, one value at a time, with the quote it came from. That has consequences, stated plainly:
- Only PSI. Experiments outside PSI do not exist for PYRION. A condition with no comparable investigation here may have been tested elsewhere; PYRION says "in PSI".
- Only what was extracted. If a table has a column PYRION has not extracted, or states a regime in a figure rather than in text, the investigation shows as "insufficient evidence" for that point. That is a limit of the extraction, not a finding about the experiment.
- Unverified is not wrong, but it is not checked. Records are extracted with their quotes and the numbers are located in the source by code; a record is "verified" only after a person has compared it with the source. Verification wording appears in a result only if you ask the engine to count only verified records.
- Ranges and approximate values. A range like 15 to 25 % counts as both ends; "about 21 %" is stored as 21. The engine does not know the uncertainty of a measurement unless the source states it.
- Several regimes in one investigation are judged cluster by cluster; an investigation can be Applicable in one regime and not comparable in another.
- The numbers change as extraction advances. More records can turn "insufficient evidence" into a verdict. Counts quoted in this encyclopedia are not fixed; what is fixed is the rules.
When the data cannot answer, the engine says exactly what is missing and what would help (routes, and "What would close this gap").
## For engineers
- Record validation (
parseConditionCsv,engine/src/records.ts): required fields, allowed variables (regime axes, continuous axes,fuel,material,geometry,flow_configuration,platform,outcome:*), statusesextracted | verified | insufficient_evidence, rangeslo..hi, rejected rows reported with file and line (ParseResult.rejected). - Counting:
counts(status, minimum)inengine/src/evidence.ts:insufficient_evidencenever counts;minimumStatus: 'verified'dropsextracted.Evaluation.countsreportsrecordsUsed,recordsFlaggedInsufficient,recordsBelowMinimumStatus. - Missing regimes:
RegimeState.statemissing(no usable record) orconflicting(several values);regimeUntestedwhen the target regime is stated by no cluster (engine/src/verdict.ts). - No uncertainty model: values are numbers, ranges are intervals; the only tolerance is the 0.5 % convention.
- The condition records are produced and audited outside the engine (extraction and validation;
validation/run_all.pychecks quotes, numbers and units of every record); the engine takes them as given.
PYRION is not a safety tool
Nothing PYRION says is a statement that a material, a cabin atmosphere or a design is safe, or unsafe.
- Applicable means your numbers fall within what a recorded investigation tested, in the same regime. It does not mean the same result would happen to your material or geometry.
- Extrapolation levels measure distance from the tested data, not how reliable or safe a condition is. NASA's own work notes that flames can change abruptly near limits, so even "just outside" is an extrapolation.
- Material selection for spacecraft is governed by NASA's standards and tests. PYRION quotes what the NASA standard NASA-STD-6001B measures (for example maximum oxygen concentration and burn length in Test 1), but it does not apply the standard and does not replace it.
- "What would close this gap" is a testable plan proposed by PYRION. It is not a NASA plan and has not been reviewed or approved by anyone at NASA.
No one at NASA has endorsed, validated or reviewed PYRION, and the phrase "validated by NASA" must never be applied to it. Checks mentioned in the project (cross-checks by separate AI reviewer agents) are internal; they are not a NASA review or expert validation.
## For engineers
Code-level guarantees:
EXTRAPOLATION_LEVEL_NOTE(engine/src/levels.ts:19): "PYRION convention: these levels measure distance from the tested data, not how reliable or safe the condition is; combustion can change abruptly near limits (e.g. extinction), so even "just outside" is an extrapolation." Attached astechnicalNoteto everyextrapolation_levelreason.EXPERIMENT_LABEL(engine/src/experiments.ts:13) heads every proposal.- NASA-STD-6001B appears only as a quoted list of what its Test 1 measures (
TESTING_MEASURES, PDF pp. 28-30) withdoi: null. - Wording tests forbid unsupported claims in engine sentences (
engine/test/wording.test.ts: no snake_case or verdict codes, "verified" only with the verified-only option).
What the AI does and does not do
The language model never decides a verdict, and it never supplies a number. It may translate a question into a target, and it may add a short description of that target that code checks sentence by sentence.
Verdicts, counts, distances and every figure come from the deterministic engine. If a value cannot be verified, the answer is "insufficient evidence". PYRION states what PSI contains ("in PSI"), never that no data exists anywhere.
Hypotheses and proposals are not evidence
Two parts of PYRION go beyond comparing recorded conditions, and both are labelled so they cannot be taken for evidence.
The bridge from microgravity to the Moon (a hypothesis). In some flames, the flow of gas past the sample matters in much the same way as gravity does: a "stretch rate" is a number that combines them. NASA papers give formulas for it. PYRION uses them to ask: could a microgravity test with this flow be in the same stretch range as a flame at lunar gravity? A test whose range falls inside is a candidate analog hypothesis. It is never counted as evidence and never makes an investigation Applicable. The limits are stated with every result: the formulas are for round samples (cylinders, rod tips), not flat sheets; the effect of gravity depends on the material; the sample size and test duration differ between an ISS glovebox, a centrifuge drop (about 5 s) and the lunar surface; pressure is a separate axis that the stretch equivalence does not cover; and it is a hypothesis that an experiment like FM2 is designed to test.
The FM2 chamber arithmetic. A closed-chamber oxygen balance computed from FM2's published chamber volume, pressure and starting oxygen. It is arithmetic about an instrument, with every assumption stated (ideal gas, fixed temperature, products ignored); it is not a flame model.
"What would close this gap" is a proposal, labelled as one.
## For engineers
engine/src/transfer.ts: TRANSFER_HYPOTHESIS results have kind: 'TRANSFER_HYPOTHESIS', evidenceClass: 'hypothesis', countsAsApplicable: false; they are reported in addition to REGIME_BARRIER and never change evaluate(). Limits (TRANSFER_LIMITS, engine/src/transfer.ts:107): geometry (stagnation-point flow on curved bodies; flat fabric sheets have no radius R, so no stretch rate); material dependence (NTRS 20250006779, pp. 18-19); scale and time; pressure stays a separate axis; "It is a hypothesis."
Formulas (engine/src/stretch.ts): forced stretch of a cylinder a_f = 2 U / R (NTRS 20000004509 p. 3), rod tip a_f = 3/2 U / R (NTRS 20150008961 p. 7), buoyant a_b = [((T* - Te)/T*) g/R]^1/2 (NTRS 20000004509 p. 11, Eqn. 1; a differently printed form on p. 3 is documented as a discrepancy and not used), mixed a = sqrt(a_f² + a_b²); all inputs are bands and results are bands.
engine/src/fm2.ts: fm2Balance, fm2FinalO2, fm2Chamber (volume 14.4 L, 8.2 psia ± 0.3 psi, starting oxygen 37, 33, 29, 25 %, NTRS 20260001966); temperature is a required input and is never defaulted; the check case (PMMA at 34 %, 8.2 psi, 1.2 g burned, NASA estimate of final oxygen 13 to 21 %) is on PDF p. 26.