RustPEP

Release notes

What was added to RustPEP in each version, newest first.

The current Windows release is 0.71.1. Installed copies from 0.2.0 on update themselves: RustPEP offers the new version in the sidebar when it starts. The Linux packages are at 0.67.2 and the macOS package at 0.67.2. They do not update themselves, so download the new package.

  1. Version 0.71.1

    Current

    The erosive-burning "from" box keeps your choice, and can fill in the model's paper as the source.

    "From" keeps what you pick
    On the Formulation tab's **Properties**, choosing where a model's erosive-burning constants come from now sticks even before you type any values. Before, it jumped straight back to **Literature**. The source recorded with the values now follows that choice too, instead of always being marked as your own.
    Use the model's paper
    When a model's values are from the literature, a **Use the model's paper** button fills in that model's citation as the source.
  2. Version 0.71.0

    The Export page puts the Rocket Salvo apps first.

    Rocket Salvo apps first on the Export page
    The Export page now starts with a card titled **Rocket Salvo apps: RustCore and RustStand**, holding **Add to RustCore library** and **Save for RustCore…**, the only coloured buttons on the page. BurnSim, openMotor, the summary, the PDF data sheet and PEPCODED follow under **Other programs and files**. No button was renamed and none does anything different.
  3. Version 0.70.0

    The Binder and Bonding agent lists offer only ingredients that could be the answer, and keep up as you type weights. Desmodur E 744 and Magnalium join the library.

    Binder and bonding-agent lists that make sense
    Under the recipe on the Formulation page, the **Binder** and **Bonding agent** lists used to offer every ingredient in the recipe, and only refreshed when the table was rebuilt — so an ingredient added at 0 g and then given a weight, such as Tepanol, never appeared. They now update as you type weights, leave out oxidizers, metals, curatives and plasticizers, and list the likely answers first: binders in one, recognised bonding agents in the other. More bonding agents are recognised by name, including HX-868 and Dantocol. An answer you saved earlier is still shown even if the new filter would hide it.
    Desmodur E 744, with its own library entry
    Covestro’s MDI prepolymer curative is now a library ingredient, with the NCO content (23.5%) and equivalent weight (179) Covestro publishes, and the curative calculator adds it instead of PAPI. Covestro does not publish the polyol, so its composition is estimated as 80% MDI and 20% polypropylene glycol; the chemistry of a recipe using it is close rather than exact.
    Magnalium
    Magnalium 50/50, the magnesium–aluminium alloy, is now in the library.
  4. Version 0.69.0

    The one-click density offers a density you actually measured on a batch of this recipe, instead of a fraction of the theoretical one.

    A density you measured, not a fraction of the theoretical one
    Where density has a one-click value — on the Properties tab, and on the Erosive Burning page — it now offers the newest density you measured on a batch of this recipe in the **Batch log**, in place of 95% of theoretical. It arrives recorded as measured, with the batch it came from named, so the number carries where it came from rather than sitting in the field looking like every other number. Measured density has been enterable under a batch since 0.65.0; this is the version that does something with it.
    Without a measured batch, still an estimate, and still labelled one
    With no measured batch for the recipe, the one-click value is 95% of theoretical as before, and says it is an estimate. That is the point of the change rather than an exception to it: 95% of theoretical is a reasonable guess at how completely a mix packs, and a figure from your own cured batch is a measurement of this propellant. They are different kinds of number and the field now says which one you have.
    Nothing else has to be installed
    Batches and their measured densities are logged inside RustPEP, so this works for anyone on this version today. Worth saying plainly, because several recent additions were RustPEP’s half of an exchange with RustCore or RustStand and do nothing until those ship. This one does not depend on another program.
  5. Version 0.68.0

    Guided mode’s burn-rate and constant steps show the test campaigns RustStand has published for the open recipe.

    A campaign’s progress, in the step that waits on it
    Characterizing a propellant means firing motors, and firings are recorded in RustStand, not here. From this version the two steps that wait on them — the burn-rate step and the model-constant step — show what RustStand has published for the recipe you have open: how many firings a campaign planned and how many of them could be used, how many were fired where that number differs, and a chip for each firing showing its state, with discarded ones struck through and RustStand’s note on each in the tooltip. Base-rate campaigns appear in the burn-rate step, erosive and validation campaigns in the constant step, and each says what it produced. Both steps used to say that planning and following a campaign was not built yet.
    Nothing appears there today, and the step says so
    RustStand writes the campaign files, and RustStand has no installers yet, so on every machine there are no campaigns to show. The step says that plainly instead of drawing an empty list, because an empty list reads as “you have not done the work” when the truth is “the program that records it does not exist yet”. That is the honest size of this feature today: it is RustPEP’s half of something that becomes useful when RustStand ships, and it is listed here so the version is accounted for, not because there is anything new you can do with it.
    Matched by the recipe’s identity
    A campaign is shown when RustStand recorded it against the formulation you have open, matched on the recipe’s identity rather than on its name, so two recipes called the same thing cannot borrow each other’s firings. A recipe that has no identity yet says that is how the matching is done, so an empty view is explained rather than puzzling. RustPEP keeps no campaign state of its own: coming back to RustPEP re-reads the files, and a campaign file it cannot read is listed as unreadable rather than quietly dropped — a firing missing from a count is worse than one you can see is broken.
    RustStand’s sentences, word for word
    Where a campaign is blocked, the reason shown is the sentence RustStand wrote, passed through unchanged. RustStand rewrote those sentences for readers once it knew they would be displayed verbatim rather than summarized. The alternative is RustPEP paraphrasing a condition it cannot see for itself, which is how two programs come to say different things about the same campaign.
  6. Version 0.67.5

    The one-click burning-surface temperature takes the figure the shared registry states for the propellant class, and a batch can always be removed from the log.

    The class default, not the middle of the range
    The one-click default for **burning-surface temperature** now uses the figure the shared field registry states for the propellant class — 1000 K for AP composites, 700 K for KN sugars — rather than the middle of that class’s range, which gave 950 K and 750 K. The registry marks these as guidance, not as values checked against a source paper, so a figure you measured for your own propellant is always worth more than any default. The one-click default exists to get a model running, not to stand in for a measurement.
    A batch can always leave the log
    Deleting a batch from the **Batch log** now removes it from the log even when its shared file cannot be deleted — because another program is holding the file open, say. The log names the file that was left behind, so you can remove it yourself rather than being left to guess what remains where. Through 0.67.4, Delete reported the error and the batch stayed in the log, with no way to remove the entry until the file itself could go. Deleting a batch whose file could be removed always worked, so nothing anyone had saved was affected — what was stuck was the log entry.
  7. Version 0.67.4

    A calibration that arrives without a valid mass-flux range no longer reports that range as “NaN to NaN”.

    No more NaN to NaN
    Fixed: in **Suggestions**, a calibration sent from RustCore whose valid mass-flux range could not be established showed that range as “NaN to NaN”. It now says plainly that the range is not known. Whether a calibration ever reaches you without one depends on RustCore, so this may be a case you never meet — but if you do, it reads as a missing figure rather than as a broken one, and the difference matters when you are deciding whether to accept the constants.
  8. Version 0.67.3

    Adding a propellant to RustCore’s library no longer silently replaces an older file of the same name.

    It asks before replacing a file it cannot identify
    A propellant added to RustCore’s library from the Export page is matched by its identity, so adding the same propellant again updates its own file and leaves everything else alone. An older file written before propellants carried an identity has none to match, so a name was all there was to go on — and a file of the same name was replaced without asking. It now asks first. Nothing about adding a propellant that does carry an identity changed.
    What the Wimpy Red example says about its own law
    Inside RustPEP, the Wimpy Red example now states that its burn-rate law comes from four BATES motor firings at 400 to 1000 psi, which is what this site has said since the test was confirmed. The recipe file records the measurements and the fit but not the kind of test, so earlier wording in the program described the tests without naming them.
  9. Version 0.67.2

    Five fixes, mostly about a propellant keeping its identity and its provenance when you move it around.

    A revision that only rises when something changed
    Fixed: publishing an unchanged propellant after updating RustPEP gave it a new revision, as though the recipe had moved when only the program had. A revision should mark a change to the propellant, so that a design or a firing recorded against one can be trusted to mean what it says.
    Saving the example makes your own copy
    Fixed: saving the **Wimpy Red** example to a file or to **My propellants** now makes a copy with an identity of its own, rather than a second thing claiming to be the published Wimpy Red. The example is there to be adjusted, and an adjusted copy is yours, not the one RustCore starts its designs from.
    Retyping a value keeps where it came from
    Fixed: on the Properties tab, erasing a value and typing it again lost its provenance, so a measured figure could come back as though nobody knew where it came from. The origin now survives the round trip.
    An unsettled calibration is a caveat, not a result
    Erosive constants from a calibration whose search did not settle are shown as a caveat and never as a requirement met. This one is no longer theoretical: **RustCore 0.22.2** can send such a calibration, so the case can now reach you rather than waiting for a sender.
    Where Wimpy Red sits, and what it says
    Wimpy Red is listed first among the composite formulations, and its burn-rate law is described as four BATES motor firings at 400 to 1000 psi — which is what it is. Earlier wording in RustPEP described the tests without naming the kind, because the recipe file records the measurements and the fit but not the test; that detail came from Geoff Huber directly.
  10. Version 0.67.1

    The Help now says which versions of RustCore share the Wimpy Red example, instead of implying every version does.

    Which RustCore shares Wimpy Red
    Corrected: the Help said Wimpy Red kept the identity RustCore ships it under, without saying which RustCore. That reads as though any version matches, and the published RustCore does not — Wimpy Red arrives in a later one. The Help now names the versions, so the sentence stays true while 0.21.6 is the version you can download.
    And how RustCore carries it
    Corrected: the Help also said that adding Wimpy Red to RustCore’s library matched “RustCore’s own copy”. RustCore keeps no copy there — that library is the folder RustPEP writes and RustCore reads. What a later RustCore does is start every new design with Wimpy Red under this same identity, so a design begun there links to this recipe once you add it to RustCore’s library from the Export page. The Help says that instead. Nothing in the program changed in either case; both are Help text only.
  11. Version 0.67.0

    The Propellant Library’s worked example is now Wimpy Red, a real propellant fitted from real firings, in place of six fictitious ones.

    Wimpy Red
    The library’s worked example is now **Wimpy Red**, a red-flame AP/HTPB propellant whose burn-rate law is fitted from four BATES motor firings at 400 to 1000 psi rather than generated from a fixture. Load it and adjust it as you would any reference formulation.
    The six fictitious examples are gone
    The **Examples — FICTITIOUS** family added at 0.50.0 — six formulations generated from the shared erosive-burning fixture set — is no longer in the Propellant Library. They were built to check what each program reported about made-up data, which is work they have now done, and they were never meant as a starting point for a motor. Copies you saved to **My propellants** or as recipe files are kept and still open, and anything you published from one into RustCore’s library is untouched — only the six built-in entries went. Everything that makes fictitious data visible is unchanged: a propellant resting on anything synthetic or fictitious still carries the **FICTITIOUS TEST DATA** banner wherever it is shown.
  12. Version 0.66.3

    A batch logged before its recipe reached RustCore’s library can be shared afterwards, instead of only at the moment it was logged.

    Share a batch after the fact
    From 0.65.0 a batch was shared only if the recipe was already in RustCore’s library when you logged it, which put the two in an order the bench does not follow: you mix a batch first, and decide the propellant is worth keeping afterwards. A batch logged before that now shows **Share** in the **Batch log** once its recipe is in the library, and a second click confirms which revision of the recipe the batch was mixed to — so the record says what was actually in the mixing bowl, not whatever the recipe has become since.
    What a shared batch is good for yet
    Sharing writes the batch into the folder the Rocket Salvo programs share. **RustCore 0.22.2** reads it: where a firing names the batch it was mixed from, RustCore uses that batch’s measured density in place of the recipe’s. Only RustStand publishes firings that name a batch, and RustStand has no installers, so in practice nothing makes a shared batch matter today — but it is read rather than merely written.
  13. Version 0.66.2

    An accepted calibration’s constants now say so when the burn-rate law in force has moved since they were fitted.

    Constants that no longer match the law they were fitted against
    Erosive constants are fitted against one particular burn-rate law, and a calibration arriving under **Suggestions** is refused outright if a different law is in force. Nothing caught the same mismatch afterwards: put a different law in force *after* accepting a calibration and the Erosive Burning page went on naming the old law as though it still applied. The evidence line now compares the calibration’s basis against the law in force every time it is drawn, and where they differ it says the constants are wrong against the law now in force, and what to do about it — put the old law back in force on the Burn Rate page, or calibrate again in RustCore.
    What can reach it
    The warning needs a calibration that arrived carrying a record of the law it was fitted against, and only an accepted calibration carries one. Nothing could send such a calibration when this version shipped; **RustCore 0.22.2** can, so the warning is now reachable — accept a calibration, put a different law in force, and the page says the constants no longer match it. Erosive constants you typed on the Erosive Burning page yourself have nothing to compare against and never warn; neither do calibrations stored before 0.66.0.
  14. Version 0.66.1

    A fix to how accepted calibrations and validations are shown on the Erosive Burning page.

    What an accepted calibration or validation shows
    Fixed: a calibration or validation taken in through **Suggestions** was shown on the Erosive Burning page without the number of firings it rested on or the batch, without the burn-rate law its constants were fitted against, with no sign that a calibration had not settled, and with every failed validation described simply as “a test”. All four are now shown, a failed validation with the signed peak error of each failure. When this version shipped nothing could send a calibration or a validation, so nobody had seen the old display. **RustCore 0.22.2** can send both, which means this is the display you now get rather than a fix waiting for a sender. The property values RustCore pushes are a different kind of suggestion and were never affected.
  15. Version 0.66.0

    Suggestions can take in a burn-rate law, an erosive constant or a validation worked out from your own firings, alongside the property values RustCore already sends.

    What already arrives, and is unchanged
    The dialog that has taken property values pushed from RustCore’s Erosive inputs panel since 0.63.0 is now called **Suggestions** rather than Suggested values. Nothing about those values changed: the sidebar still offers to review them, each still sits beside your recipe’s current value with its source, each still has its own Accept and Decline with Accept all and Decline all, and **Done** still applies what you accepted, keeps the value it replaced in that property’s history and tells RustCore what you did.
    Three new kinds of suggestion
    Alongside those values, the dialog can now take a burn-rate law fitted from a test campaign, an erosive constant from a calibration, and the result of a validation. Each appears as its own card below the values, says what it was worked out from, and is accepted or declined on its own. A law you accept is added beside your others and is put in force only if you choose. A constant fitted against a burn-rate law you have since changed can only be declined, because the number no longer belongs to the law it was fitted to. Anything worked out from synthetic test data goes on saying so wherever it ends up.
    What can send them, as of RustCore 0.22.2
    When this version shipped nothing could send any of the three, and it was RustPEP’s half of something unfinished. That changed with **RustCore 0.22.2**: its Calibrate and Validate send erosive constants and validation results here with **Send to RustPEP**, so two of the three kinds arrive today. The third does not — a fitted burn-rate law comes from RustStand, which has no installers yet, so nothing sends one. Property values from RustCore are a separate kind and go on arriving as they have since 0.63.0.
  16. Version 0.65.0

    A batch you log can carry its identity beyond RustPEP, and take its measured density once it has cured.

    Log this batch can share the batch
    When the recipe is in RustCore’s library unchanged, **Log this batch** also writes the batch to the folder the Rocket Salvo programs share, and the dialog tells you beforehand whether it will, so it is never a surprise. If the recipe is not in RustCore’s library, or has been changed since it was, the batch is logged inside RustPEP exactly as before.
    What reads a shared batch
    The purpose of sharing is that a firing should be tied to the mix it was fired on rather than to a name typed in a second time. Nothing read a shared batch when this version shipped. **RustCore 0.22.2** does: given a firing that names its batch, it uses that batch’s measured density instead of the recipe’s, and refuses a set of firings that spans two batches. Since only RustStand publishes firings that name a batch, and RustStand has no installers, the batch you share is still waiting for something to point at it.
    Measured density, after it has cured
    A batch’s measured density can now be added under the batch in the **Batch log**. Density is one of the few things about a mix you cannot know while you are making it, so it is entered when you have it rather than at mixing time.
  17. Version 0.64.2

    The version every platform ships, because it is the one that builds everywhere. Nothing in the program changed.

    A build fix, and nothing else
    Fixed: the Linux `.deb` and `.rpm` could not be built at 0.64.0 or 0.64.1. A library used by the new link handling stopped compiling after an unrelated dependency added two fields to one of its structures, and it is now pinned to the last version that works. Nothing in the program itself changed, which is why this is the version all three platforms carry — 0.64.0 and 0.64.1 were never published anywhere.
  18. Version 0.64.1

    On macOS, RustPEP claims the RustCore links only when it is running as an installed app.

    Never a button that could do nothing
    On macOS, RustPEP now tells RustCore it handles the links only when it is running from an installed `.app` bundle, which is when macOS has learned the bundle’s schemes. A copy run from a build folder says it does not, which is what Windows already did. Nothing changes for anyone today: RustCore is published for Windows only, so nothing on macOS asks the question. It is here so that if RustCore ever reaches macOS, the **Open in RustPEP** button cannot appear somewhere that pressing it would do nothing. Windows and Linux are unchanged.
  19. Version 0.64.0

    RustCore can bring RustPEP to the exact value it needs, on the right page with the box already open.

    Open in RustPEP
    When RustCore needs a propellant value only RustPEP can supply, its **Open in RustPEP** button brings RustPEP to the front on the Erosive Burning page, at that value, with the entry box open. If the recipe is not open, RustPEP opens it from My propellants, or says which propellant is meant and offers to open its file. The installer registers the links this uses, and uninstalling removes them.
    Where it works
    On Windows, in an installed copy — the setup program or the MSI. It needs RustCore to press the button in, and RustCore is published for Windows only. The portable zip does not register the links either, so RustCore’s button stays hidden there and tells you where to enter the value instead, as it did before. That is deliberate: a button that did nothing would be worse than no button.
  20. Version 0.63.3

    Help now describes copies, the same-name question, value history and suggestions from RustCore.

    Help caught up with saving and publishing
    Four passages in Help had been made untrue by the three releases before it. Saving said nothing about copies: saving somewhere new while the recipe is kept elsewhere makes a copy with its own identity, and that copy never replaces the original in RustCore’s library. Adding to RustCore’s library said a propellant with the same name simply replaces the earlier copy — the same propellant still does, renamed or not, but a different propellant that happens to share a name is now asked about. Identity now explains that the library decides the revision, not the recipe file, so a stale file cannot reuse a number and unchanged content keeps the one it had. Properties said nothing about value history, Restore, or that only the current value is published.
    What a suggestion from RustCore is
    Help has a new section on values RustCore sends: where they appear, how to review them, why some can only be declined, that accepting publishes nothing by itself, and that RustCore is told which were taken and which were not.
  21. Version 0.63.2

    A readiness rule stated anywhere in RustCore’s registry is now honoured, and the Erosive Burning title stays on one line.

    A rule read wherever RustCore states it
    Lenoir-Robillard’s alpha is required only when you have told the model you will supply it. RustCore can now state that condition on the constant itself, and RustPEP reads it there first, falling back to the place older registries used. Nothing changes for anyone today, because the older place still works and still does. What it buys is the promise the Erosive Burning page already makes: a rule RustCore adds takes effect without a new version of RustPEP.
    The same answer in all three programs
    The readiness test cases RustPEP, RustCore and RustStand check themselves against now agree byte for byte across all eighteen, including the case none of them could reach before: a model told alpha will be supplied, with none supplied. That case is what every reader called ready until 0.60.0. This is groundwork rather than something new to use — it is what keeps the three programs from telling you three different things about the same propellant.
    A title that stays whole
    Fixed: in a narrow window the Erosive Burning title wrapped to two lines with its “?” stranded below. The title stays on one line and the controls wrap instead.
  22. Version 0.63.1

    Test-firing boxes show their whole value, and switching units and back gives exactly what you typed.

    The value you entered, in full
    Fixed: a test-firing box cut its value off. A recipe entered in millimetres and viewed in inches showed “1.96” for 1.9685, with the rest simply not there. The boxes now show four significant figures, the full value while you are editing it, and the full value in the tooltip.
    Units that round-trip
    Fixed: switching units and switching back now returns exactly what you typed. 50 mm used to come back as 49.9999.
  23. Version 0.63.0

    Values worked out in RustCore arrive in RustPEP to accept or decline, one at a time or all at once.

    A suggestion inbox
    When RustCore sends values for a propellant, the sidebar says so and offers **Review**, which shows each suggested value beside the one the recipe holds now. Accept or decline each, or all at once. Accepting replaces the current value and moves the old one into that property’s history, so nothing you typed is lost by taking a suggestion. Nothing is published by accepting: you still add the propellant to RustCore’s library on the Export page, and RustCore is told which values were taken and which were not. Suggestions for a recipe that is not open say so, and offer to open it when it is in My propellants. This works end to end with RustCore 0.21.1 or later: a value entered in RustCore’s Erosive inputs panel arrives here as a suggestion, and once your library carries it, RustCore clears its own copy.
    Some suggestions can only be declined
    Three kinds, each with the reason shown rather than a bare refusal: a value that belongs to a firing rather than to a propellant, such as grain temperature; a value in the wrong unit, because nothing is silently converted; and a value that is impossible for this recipe, such as a surface temperature above its own flame temperature.
  24. Version 0.62.0

    Typing on the Properties tab works, and a value you replace is kept rather than lost.

    Typing on the Properties tab works
    Fixed, and long overdue: only the first character typed into a value or source box was kept. The tab redrew on every keystroke and replaced the box being typed in — the same fault manual burn-rate points had in 0.60.1. It has been there for as long as the tab has had editable boxes, so every earlier build is affected.
    Earlier values are kept
    Replace or remove a value you entered and the old one is kept in that property’s history. “N earlier values” appears under the property, on the Properties tab and in the Enter value box, listing them with **Restore**. Restoring swaps rather than overwrites: the current value goes into the history in its place. The history is saved with the recipe.
    Changing a value you already entered
    A row on the Erosive Burning page holding your own value now offers **Change** and **Remove**. A row that was already satisfied used to offer nothing, so correcting a value meant knowing to go to another tab. Remove goes back to RustPEP’s own figure where it has one, and keeps yours in the history.
    Smaller things on the same pages
    The Enter value box carries the unit in its label, where a placeholder vanished as soon as you typed, and it starts from the current value’s own provenance rather than always assuming literature. The line under each row that said where to enter a value no longer names the page you are already on — another app is still named where that is where the value lives, and a missing burn-rate law now says so with a button that takes you to the Burn Rate page. Numbers no longer break across lines in the middle of a unit.
  25. Version 0.61.0

    A copy of a recipe is a separate propellant, and a propellant’s revision number only ever goes up.

    Saving to a new file makes a copy
    If the recipe is already saved somewhere, saving it to a different file — or into My propellants under a different name — now makes a copy. The copy goes to RustCore as a new propellant, and the original keeps its place in RustCore’s library. The status line says so when it happens. Saving over the same file changes nothing.
    Adding to the library asks before replacing
    If RustCore’s library already holds a different propellant under the same name — a copy you did not rename, say — RustPEP now asks, with the choice put plainly: “Don’t add — I’ll rename this one”, or “Replace it”, which means RustCore designs using the other one will no longer find it. Renaming a propellant and adding it again now replaces its old entry rather than leaving two behind.
    Revisions only go up
    Each time you add a changed propellant, RustCore’s library gives it the next revision number, even if the recipe file you opened was an older one. Adding it unchanged keeps the number it already had. This is what lets RustCore offer to update a design when the library holds a newer revision of the propellant it uses: the offer is only safe if a revision never repeats for the same propellant, and if two different propellants can never share one.
  26. Version 0.60.1

    Typing a burn-rate point no longer loses the box under your cursor, and a row’s help stays on screen near the bottom of the window.

    The box vanished as you typed
    Fixed: on **Enter points manually…** every keystroke refitted, and the refit rebuilt the whole table — destroying the input your cursor was in. In a real window you typed the first digit, the box disappeared from under you, and the rest of the number went nowhere. The table is now built once and only the result line updates, and because every keystroke is a round trip, a newer fit now wins over an older one that answers late.
    Help that stayed below the edge of the window
    Fixed: a row’s **?** always opened below the row, so for a row near the bottom of the window most of the help sat past the edge — 450 px of a 700 px window — and because the popover is fixed in place, scrolling could not reach it. It now opens above when there is more room there, never past either edge, and scrolls inside itself when the help is longer than the room.
    A fit called an estimate
    Fixed: a law kept from points that miss an acceptance criterion was labelled estimated. It is a fit, and the shortfall already earns it a caveat of its own, so the old label both named it wrongly and penalised it twice.
    Imports checked against a real file
    **Import a RustStand fit…** was checked against RustStand’s own sample file: the coefficient, exponent, range, conditioning temperature, provenance and both excluded firings all come through. The source line had been naming the campaign twice, since RustStand’s own text already says it, and now adds only what is missing.
  27. Version 0.60.0

    Saving a value on the Erosive Burning page now saves — and nine more faults the same review turned up.

    Save did nothing
    Reported and fixed: on the Erosive Burning page, entering a value by hand and pressing Save appeared to do nothing. The value was in fact stored, but the page redrew from the readiness worked out *before* the save, so the row still said Missing, the status did not move, and the box simply closed. Pressing an **Estimate** on a row had the same fault. Both now recompute before redrawing, and Enter saves from the value or source box the way a form would.
    The worst answer the checklist can give
    Fixed: with Lenoir-Robillard’s alpha set to be supplied rather than computed, and no alpha supplied, the page said **Can predict**. Nothing computes alpha in that mode, so it cannot run. The registry states the condition in as many words, and the rule now reads it and marks the row blocked — and a blocked row never counts as ready. Telling someone they can predict when they cannot is the worst thing this page can do, and it was doing it.
    Nowhere to supply what it asked for
    Fixed: the page could then say one input was needed and offer no way to supply it, because a model’s own constants had no **Enter value**. They do now, with the words for where a set came from.
    Constants that claimed to be calibrated
    Fixed, in three places: a parameter set started by hand was recorded as *fitted*, so a constant typed from a paper claimed to be calibrated from firings; a supplied alpha was stamped fitted whatever you said; and a beta typed from a paper showed a tick. Only a fit from your own firings earns that tick — anything else is usable and uncalibrated — and one rule now covers all three, keyed on the registry’s own flag for which constants can be calibrated. A set started by hand defaults to *literature*, which is the rule the Properties tab already stated.
    The model settings picker, which had gone missing
    Fixed: the switch for whether Lenoir-Robillard’s alpha is computed or supplied had vanished from the page when settings stopped being checklist rows in 0.59.7, leaving no way to change it here. It is back as **Model settings**, read from the registry directly rather than riding along as a row.
    A test that passed by accident
    The test covering that setting supplied the alpha every time, so it could never meet the missing case, and used a mode the registry does not allow. It passed for the wrong reason. Every one of these ten was reproduced in a harness before a line was changed, and checked again after.
  28. Version 0.59.9

    A second opinion that should not have existed: two readiness panels, driven by two different implementations of the same rules.

    One answer, in one place
    Fixed: the Erosive Burning page of 0.54.0 was meant to replace the readiness panel on the Properties tab and was added beside it instead. The two ran different implementations of the same rules — the page calling the shared function the three apps agree on, the tab still running an older copy with three states, no limit checks, no run-condition handling, no constant policies and no blocked rows — so one app could give two answers about the same propellant. That is precisely the problem the shared function was written to end. Nothing failed a test, because no test compares two screens.
    What stays on the Properties tab
    The duplicate rules are gone, along with the two private helpers behind them. What remains there is the part that was never a judgement: each model’s own constants, in a form built from the registry’s description of them. Above them is a line saying where the readiness question is answered, and a button that takes you to it.
  29. Version 0.59.8

    Checklist accuracy, a model whose own default was being asked of the user, and a sensitivity figure in the help that was wrong in four places.

    A sentence that sounded too settled to check
    Fixed in the help: the estimate tooltip on the checklist, two places in the Erosive burning chapter and the summary line of the roughness field’s own page all said that a tenth of a millimetre of burning-surface roughness roughly doubles the predicted erosion. It depends entirely on what “the erosion” means. On the worked example the burn-rate ratio goes from 1.34 to 2.49, which is 1.86 times — but the extra burning, which is that ratio less one and what most readers picture, goes from 0.34 to 1.49, which is 4.33 times. The short sentence stated the first as though it were the second, so a reader who checked would have found it wrong and a reader who did not would have carried away a figure too small by half. The three one-line mentions now say that a tenth of a millimetre is enough to change the answer severalfold, and the field’s page keeps both ratios with the conditions they were computed at, says why the one-line version is the dangerous one, and adds that both are single-point values rather than a converged motor prediction — an input to that calculation, not its answer.
    A value the model supplies itself
    Fixed: Ma’s burning-surface roughness was shown as a missing input when it is not one. The model’s own answer for an absent roughness is a smooth surface, so a user was being told to go and find a number nobody can measure. RustCore publishes that default alongside the input, and the checklist now reads it — which is the point: RustPEP knows nothing about roughness, and the registry is where that fact lives. Worth knowing if you are tempted to enter a value anyway: roughness is by a wide margin the most sensitive input Ma has — a tenth of a millimetre is enough to change the answer severalfold — so it defaults to smooth, and you should not enter anything else without a test behind it. The field’s own help page and the Erosive burning chapter give the figures with the conditions they were computed at.
    A provisional constant that went missing
    Fixed: a misreading of RustCore’s registry made King’s provisional constant disappear from the checklist altogether — a row a user would have noticed was not there. The canonical readiness files now agree across all three apps, and a dependency setting that could silently re-order the generated files the three repositories hold at pinned hashes is guarded against.
    Blocked, missing and neither
    Fixed: a value RustCore works out at prediction time was shown as blocked when one of its inputs was absent, which told a user a row was stuck when nothing was being asked of them; and a derived value was shown as missing on a propellant that already carried everything it is made of.
    The same files in all three apps
    The canonical propellant files that RustPEP, RustCore and RustStand all read now agree between the three, and are published as test files rather than described in prose.
  30. Version 0.59.2

    Four checklist rows that were silently missing now appear, including the ones that say there is nothing left to do.

    The rows that say you are ready
    Fixed: port mass flux, hydraulic diameter and chamber pressure never appeared on a Lenoir-Robillard checklist, nor port length on Ma’s. These are the rows RustCore supplies when you predict, so they are the rows that tell you there is nothing to go and get — an absence that is easy to miss precisely because it looks like a shorter list. The rules and RustCore’s registry were both right; the reader between them was dropping every field it had not been taught to name, and handing the checklist a thinner description of the method than the registry actually holds.
    A reader that keeps what it does not understand
    The types RustPEP reads RustCore’s method registry into now keep every field the file holds, named or not, and a test writes each method back out and checks that nothing was lost on the way. A reader typed more narrowly than the file it reads has been behind every interop problem in this work, and it is the worst kind, because a field quietly dropped leaves nothing downstream able to tell.
  31. Version 0.59.1

    A correction to the advice about fitting through erosive firings: the reason given was wrong, though the advice stands.

    Why erosive firings stay out of a base-rate fit
    The help chapter and the burn-rate-law help page said what is widely repeated: that fitting through erosive firings inflates the coefficient because the grain burned faster. Measured on the synthetic series, it does not. Web divided by burn time is set by the slowest station, and erosion spends the aft web first, so the aft end burns through while the head end is still holding propellant at very nearly the non-erosive rate — on a test whose erosive ratio peaks at 1.86 the method still reports 0.993 of the non-erosive law. What is inflated is the measured pressure, which moves the point rightward on the log-log plot, so the bias in the coefficient is small and downward. Keep erosive firings out of a base-rate fit, but for the better reason: the law is meant to describe the propellant with nothing flowing over it, and a firing with crossflow is not a measurement of that.
    Every unchecked range written down
    A list now records every range shown to a user that nobody has checked against a source, alongside the decision records behind grain temperature being a run condition, the single shared readiness function, and the shared burn-rate fit.
  32. Version 0.59.0

    Three figures in the help, drawn by code from the same numbers the software uses.

    Figures that cannot drift from the data
    The five-stage path from a recipe to a characterized propellant, with the status ladder aligned to the stage each status is reached at; measuring density as cast, with a BATES segment drawn to the reference motor’s own proportions beside the displacement method; and how to read d10, d50 and d90 off a supplier’s cumulative curve. Each is generated from the data it illustrates rather than drawn by hand, and each reads in both light and dark themes with alt text.
    A warning worth repeating
    The density figure carries the warning about measuring by displacement in a liquid the propellant dissolves in. It is not a detail: sugar propellants dissolve in water.
  33. Version 0.58.0

    Groundwork: somewhere for a fitted constant to carry the record of the fit that produced it.

    The evidence beside the constants
    An erosive parameter set can now hold the calibration record RustCore produces — which tests, over what window, with what residual, by which version of which app — and, for a method with no constants to fit, a validation record of predicted against measured for each erosive test. RustPEP interprets neither: it stores them, shows them, and hands them back exactly as they arrived, because the app that fitted the constants is the only one that can say what the fit was worth. Nothing produces such a record yet, so there is nothing to see on screen today; this is the place for it to live when there is.
    A set that carries only evidence is still a set
    An erosive parameter set used to need parameters to be real. Mukunda-Paul and Ma have no constants to fit, so a set that exists only to carry a validation record is a real set, and it now survives.
    Still the same file version
    A propellant file carrying erosive blocks now declares which revision of them it is, and only when it actually carries something erosive. The file’s own version is unchanged, because the version number’s job is to say that a reader must understand this to read the file correctly, which an optional block a reader can ignore does not trip. An older erosive set still reads, and absent evidence reads as absent rather than as an empty claim of evidence.
  34. Version 0.57.0

    Burn-rate points measured elsewhere can be entered by hand or imported from RustStand, fitted by one shared function.

    One fit across three programs
    Under Burn rate laws: “Enter points manually…” for burn-rate points measured somewhere else, and “Import a RustStand fit…”, both fitted with the same function RustStand fits with. The reason is not tidiness: type three firings in by hand, then import RustStand’s fit of the same three, and the two laws must agree — otherwise a real difference in the data cannot be told apart from an arithmetic difference between two programs, and that second kind is invisible and permanent. RustPEP cannot build on RustStand’s code, so RustStand wrote the algorithm down and generated test vectors from its own implementation; RustPEP reproduces all twelve to within a billionth, the nine fits and the three refusals alike. The Help gains a section on both.
    The quick look and the law stay consistent
    The Burn Rate page keeps its looser preview fit, which will draw a line through two firings as a quick look — a different thing from a law. A test now asserts the two agree for any input the shared fit accepts, so the page and the workbench cannot describe the same firings differently.
  35. Version 0.56.0

    Guide me: a resumable seven-step guided layer over the erosive-burning checklist.

    Seven steps, and no wizard
    Characterizing a propellant takes days or weeks of casting and firing across three programs, so there is nothing a wizard could finish in one sitting. What is here instead is a guided layer over the same checklist: choose a model, run the thermochemistry at the pressure the motor will actually run at, measure or estimate the density as cast, supply the solid thermal properties, get a burn-rate law from firings that were not themselves eroding, deal with the model’s own constants, and review. It stores nothing of its own — every step edits the same values the checklist rows edit — and closing the panel loses nothing but the place you were at.
    Done means done
    A step is marked done when the work it stands for is actually done, read off the checklist, not when a button was pressed. Choosing a model is the one exception, because it is a decision rather than a value, and that answer is remembered per formulation so you can resume. Two steps say plainly that part of what they describe is not built yet — planning a base-rate or an erosive campaign from this page waits on the other two apps — and say what to do in the meantime rather than offering a button that does nothing.
  36. Version 0.55.0

    A “?” beside every checklist row, twenty-one field pages behind it, and a new erosive-burning chapter in the Help.

    What is this, and where do I get it?
    Every checklist row gets a “?” that opens a page for that input: what it is, why this model needs it, how to determine it with the routes ranked best first and the provenance each route earns, how sensitive the result is, an example, and the common mistakes. Twenty-one of them, shared with RustCore and RustStand so the three apps answer the question with the same words. The “why this model needs it” section is model-aware — burning-surface temperature explains itself one way under Lenoir-Robillard, where it sits at both ends of a fraction, another under Ma, where it also scales the Nusselt number, and says plainly that the model does not use it under the two that do not.
    Numbers in one place only
    Valid values, units, where a field is entered and its figures are deliberately not written into that prose; the popover composes them from the field registry instead, so there is no second copy of a number that could drift. Where a range is still only guidance, the popover says it has not been checked against a source — shown so that a typing error is caught, not as published fact. Every example says its numbers are fictitious, because a help page is exactly where a made-up number gets mistaken for a measured one.
    The erosive-burning chapter
    New in the Help: what erosive burning is and why it is a safety question, the five-stage path to a characterized propellant, which model to use and why they disagree, how to read the five row states, the solid thermal properties and where they come from, measuring density as cast, why grain temperature is a run condition rather than a propellant property, and what the two test campaigns are for.
  37. Version 0.54.0

    A new Erosive Burning page: whether you can predict erosive burning for a propellant, and exactly what is still missing.

    The models themselves are RustCore’s
    Before the feature list, the thing most worth saying plainly: the erosive-burning models live in RustCore, not in RustPEP. RustPEP supplies the propellant and tells you what each model still needs from it; RustCore is what predicts. This page is how you find out whether a propellant is ready — it is not a prediction in itself.
    One page, one question
    A new top-level Erosive Burning page answers whether erosive burning can be predicted for this propellant and, if not, exactly what you still need — and gives every answer somewhere to go. Pick a model and you get a checklist grouped as the shared contract groups it: the base values, the properties that model needs, the model’s own constants, and the things RustCore supplies when you predict. Every row carries its state as a word as well as an icon, where its value came from, and what to do about it. Entering a value writes the same stored value the Properties tab writes: one place to keep it, two places to enter it. “All models” swaps the checklist for a matrix across the methods.
    The end of dead ends
    This page exists because of one that did the opposite: a panel in RustCore that told a user four things were missing and gave them no way to fix any of them. Every row here names what is missing, why that model needs it, where it is entered, and offers an estimate where one honestly exists. The promise the work was built to keep is that no screen tells you something is missing without telling you what to do about it.
    The page decides nothing
    The model pulldown is RustCore’s registry; every row’s label, symbol, unit, limits and owner path comes from the shared field registry; and the rules live in one shared function. Both registry files come from RustCore, which published them while this was being built. A copy ships with RustPEP so a fresh install has a registry before RustCore has ever run, and the live file always wins over that snapshot — a snapshot that outranked the live file would be the drift this whole arrangement exists to prevent.
    Read the file, not the description of it
    Reading what RustCore actually published turned up two things worth naming. The documented-constants list is the paper’s, and it is empty for the two methods whose constants can only be fitted — read alone, it would say threshold-linear needs nothing and Lenoir-Robillard’s beta is settled, both wrong in the direction that tells a user they are ready when they are not. The lists are merged by name instead, an explicit policy always wins, and where none is published the policy is read off whether the method ends in a calibration or a validation. And a published range in a shape that cannot be evaluated reads as “not checked”, never as “checked and passed”.
  38. Version 0.53.0

    Groundwork: one readiness function and one registry reader, so three apps cannot give three answers about the same propellant.

    What’s missing, answered once
    Each app used to work out what a propellant was still missing on its own, so the lists drifted and the same propellant could get one answer in RustPEP and another in RustCore. There is now one function, reading one registry, for every panel to render. It has two entry points, deliberately different: one answers for what this app knows, the other answers from an exchange document and nothing else — no solver, no library, no cache. RustPEP computes gas viscosity and Prandtl number for any solved recipe, so its live answer can name two missing inputs where the published document has four. Both are right, to different questions, and the result says which one you are looking at. RustCore and RustStand have both agreed to this reading. Nothing calls it yet in this version; the page that does arrives in 0.54.0.
    A blocked row is not a missing input
    The counting rule matters more than it looks: a derived row that is blocked — Ma’s gas conductivity, Lenoir-Robillard’s alpha — is not a missing input, because you cannot supply it directly. So “2 inputs needed” always means two things to go and get. One consequence surfaced while this was built: Lenoir-Robillard’s alpha is computed from the properties unless you fit it, but the first registry could only mark it fitted-only, which read as a missing input nobody could supply. The newer registry states that policy explicitly instead of leaving it to be inferred.
  39. Version 0.52.0

    The solid thermal properties no thermochemistry solve can produce, with an estimate for the one where real work backs it.

    Somewhere for the solid properties to live
    Lenoir-Robillard, Ma and King all divide by the specific heat of the cured solid propellant, and a thermochemistry solve produces nothing of the kind — it is about the gas the propellant becomes. The Properties tab is now grouped the way the shared field registry groups these: base, chamber gas, solid thermal properties and run conditions. Two values join it: gas thermal conductivity, which RustPEP already had from the NASA data and never published, and burning-surface roughness, which only Ma uses. Grain temperature moves into run conditions with a line saying why — it belongs to a firing, not to a propellant.
    Estimate, with the estimate’s worth stated
    Four rows now offer an Estimate beside the value box. None is applied on its own: the button produces a value you can see, replace or delete, and its tooltip says what the estimate is worth before you take it.
    The solid specific heat estimate
    This is the one with real work behind it: the mix’s specific heat is mass-weighted from its ingredients’ own cited figures. Each ingredient’s specific heat at 298.15 K is the NASA CEA condensed-phase fit for the species with that ingredient’s formula, carrying that record’s own citation — 1,090 J/(kg K) for ammonium perchlorate from Chase 1998, 897 for aluminium from Cox 1989, 940 for potassium nitrate from Gurvich 1982. 145 library ingredients have one. HTPB, sorbitol and sucrose have no condensed species in the NASA file, so they have no value and are named rather than assumed, and the estimate reports the mass fraction it actually covered and what it left out. Covering the whole mix from cited figures earns the value “computed”; anything less is “estimated”, and that distinction travels with the number so RustCore does not have to guess it.
  40. Version 0.51.1

    A burn-rate law taken from a paper can be published to RustCore, and model parameters that are a choice get a dropdown.

    A law from a paper can be exported
    Fixed: a recipe whose burn-rate law had no firings behind it — one typed in from a paper, or one of the example formulations — published no pressure limits at all, and the RustCore export refused it. The pressure range now comes from the law’s own valid range, falling back to the firings it was fitted from, and then to the value this file format uses to mean no limit. Nothing could have a law without firings before 0.47.0, so nothing had run into it.
    Parameters that are a choice, not a number
    RustCore’s model registry gained typed parameters, so a parameter that is a choice now appears as a dropdown of the values the registry allows, rather than a number box that could never hold one, and a parameter set can carry a word as well as a number. Where the registry says a parameter is needed only under some condition but states it only in prose, RustPEP treats it as required and shows the registry’s own note beside it, so the panel’s strictness is visible rather than hidden.
    Examples written by the real exporter
    The example formulations are now written out through the same exporter a user’s own propellant goes through, and they sit in the shared library folder as files RustPEP actually wrote rather than samples authored by hand.
  41. Version 0.50.0

    Example formulations for erosive-burning work, all of them marked fictitious.

    The erosive-burning examples
    The Propellant Library gains an “Examples — FICTITIOUS” family holding all six formulations of the shared fixture set: three composite examples for Lenoir-Robillard, Mukunda-Paul and the threshold-linear model, a sugar one that carries all three methods, a control with no erosive model, and a deliberately incomplete one for checking what each app reports as missing. They are generated from the frozen fixture rather than typed by hand, and the compositions use real library ingredients carrying the fixture’s roles.
    Fictitious, and visibly so
    Everything in them is marked fictitious, so the banner appears wherever they are shown. Every property the fixture states is pinned, so an example does not move when the solver changes, and each pinned value sits beside what RustPEP computes for the same mix — 1,750 against 1,727 kg/m³ for density, 3,200 K against 3,232 K for flame temperature. Each example carries the fixture’s burn-rate law and its erosive parameters, which a preset can now do because a preset can hold a whole recipe rather than only a mix.
    Reading the model registry as written
    A model parameter’s default can be prose rather than a number, which previously made RustCore’s whole registry unreadable. Both the default and its provenance are now taken as written and only displayed. A model whose fitted-only parameters have no values is also no longer reported as ready, since without them it cannot run.
  42. Version 0.49.0

    Each erosive-burning model carries its own parameters for this propellant.

    Parameters for each model
    Each model in the readiness panel now has its own parameters for this propellant: the threshold-linear model’s G_th and k_G, Lenoir-Robillard’s beta, Mukunda-Paul’s published constants. The names, units, defaults and whether a value can only come from fitting all come from RustCore’s registry, so a model RustCore adds gets a working form here without a new version of RustPEP.
    Defaults, fitting and provenance
    A box left empty uses the registry’s value, shown greyed behind it. A parameter marked “from fitting” has no universal value and is RustCore’s to fit. Each set records where it came from and travels with the propellant, so a set fitted once need not be fitted again. A set with nothing in it is neither saved nor published.
  43. Version 0.48.0

    A panel saying what each erosive-burning model still needs from your formulation.

    Erosive burning readiness
    Under the property table, a panel says what each erosive-burning model still needs from this formulation. Each model reads Ready, Needs an estimate, or Not ready. The middle state matters: an input RustCore is willing to approximate is still absent, and RustCore refuses without it. A ready model also says how good its weakest input is, because a model running on estimates is an estimate.
    The model list is RustCore’s, not RustPEP’s
    The models, what each needs and whether an estimate will do come from the registry file RustCore publishes in the RocketSalvo folder under Documents. RustPEP hard-codes no model and no required-input list, so a model RustCore adds appears here with no change to this app. Where there is no registry the panel says so rather than inventing one.
    A pinned value now reaches every reader
    Fixed: a property you had pinned reached the provenance block of a published propellant but not the plain field beside it, so a reader that ignored provenance was handed the value you had overridden. Density, flame temperature, c*, the ratio of specific heats and the five chamber gas values now follow their pins into the plain fields too.
  44. Version 0.47.0

    A propellant can hold more than one burn-rate law, and you say which is in use.

    More than one burn rate law
    A law is a measurement of a particular batch under particular conditions, so a recipe can now keep several side by side and you say which is in use. The first row is always the fit from the Burn Rate page’s firings and follows them. Save this fit as a law takes a copy that stays put, and Add a law by hand is for one from a paper or another program.
    What each law records
    Each law carries the pressure range it was measured over, the grain temperature it applies to, its R², the tests behind it and where it came from, on the same provenance scale as the Properties tab.
    The law in use drives everything
    The law in use drives the Kn card, the BurnSim and openMotor exports, the RustCore file, the data sheet and the summary text, and it sets the provenance floor: put a fictitious law in use and everything carries the banner. The fit shown above the list stays the fit from the firings, so the two can differ, and a line under the list says which one the rest of RustPEP is working from.
    Coefficients published with their reference pressure
    The propellant file publishes every law in SI with its reference pressure beside the coefficient, always, because the units of the coefficient depend on the exponent and a bare coefficient means nothing.
  45. Version 0.46.0

    A Properties tab where every value says where it came from, and a warning when a recipe rests on invented data.

    Every property says where it came from
    The new Properties tab, the last of the Performance detail tabs, lists every value a burn-rate or erosive-burning model can ask RustPEP for, under the names and units the shared RocketSalvo format uses, with the origin of each. RustPEP’s own figures are marked computed, or estimated where some combustion products had no measured transport data and had to be approximated.
    Room for what cannot be calculated
    The values nothing can work out from a formulation — burning surface temperature, solid specific heat and conductivity, heat of surface reaction, grain temperature and temperature sensitivity — now have somewhere to live, each with the citation or the test it came from. A typed value can be marked measured, literature, estimated, synthetic or fictitious, but never computed or fitted, because RustPEP did not work it out. Typing over a figure RustPEP calculated never hides it: the row and the published file keep RustPEP’s value beside the pin.
    A warning when the data is invented
    The weakest origin among everything a propellant rests on is worked out and published with it. When that is synthetic or fictitious, the banner “FICTITIOUS TEST DATA: not measured, not for motor design or flight” appears on the Formulation and Export pages, in the summary export and across the top of the PDF data sheet.
    Propellant files are checked before they are written
    Writing a propellant file for RustCore now validates it first, so no path out of RustPEP can write a file the rules refuse; only the command line checked before. The file stays at version 3: the new properties and the notice are optional fields beside the plain ones, never in place of them, so a reader that ignores them still reads the file correctly.
  46. Version 0.45.0

    Say which ingredient is the binder and which is the bonding agent.

    Name the binder and the bonding agent
    Two selects under the recipe notes on the Formulation page say which ingredient is the binder and which is the bonding agent. RustPEP could only guess before: the binder came from the library’s categories, and a bonding agent was recognised only if its name matched one of six products, so a formulation using any other one was published as “not recorded”. Naming either records it as your own answer, and a named bonding agent goes out as present whatever it is called. RustPEP still guesses when nothing is named, and still marks a guessed binder unconfirmed.
    None and not recorded stay apart
    The bonding agent has three distinct answers: an ingredient, None in this formulation, and Not recorded. The 0.43.0 “No bonding agent in this formulation” tick box is replaced by the select, and recipes saved with it load as the None answer. A name the recipe no longer holds falls back to the guess rather than publishing a stale ingredient.
  47. Version 0.44.0

    Each test firing’s port mass flux, so you can tell whether the firings behind a fit were burning erosively.

    Port flux of each firing
    The Burn Rate page gives each firing’s peak mass flux through the port, and beneath it the port-to-throat area ratio at the start of the burn, where it is smallest. A firing forcing a lot of gas through a narrow port burns faster than its pressure alone explains, so a law fitted from such firings already carries part of that effect, and correcting for erosive burning on top of it counts the same thing twice.
    Grain length and count in measured mode
    Measured mode now asks for the grain length and how many grains as well, in the same grouped Grain column that Kn mode already used, because the flux cannot be worked out without them. Its throat diameter column is optional and changes nothing in the fit; it only adds the port-to-throat ratio.
    What the firings cover
    A line under the fit tiles gives the flux range your firings span and says whether any of them started below a port-to-throat area ratio of 2, the usual design rule. RustPEP sets no threshold on the flux itself. A propellant published to RustCore now carries the mass flux of measured firings too, not just those with pressures estimated from Kn.
  48. Version 0.43.0

    Propellants sent to RustCore carry their composition and each firing’s mass flux.

    Composition for RustCore
    A propellant sent to RustCore now lists what it is made of: each ingredient with its percentage and role, the particle size grades, the binder, and whether it has a bonding agent. Each particle size says how well it is known: typed in by you, nominal for the grade, read from a label, or not recorded. A size nobody recorded is sent as unknown rather than guessed. Mesh-graded and flake powders get no single size.
    Mass flux of each test firing
    Each test firing goes to RustCore with the peak mass flux through its port, worked out from the grain geometry on the Burn Rate page. Together with whether the pressures were measured or estimated from Kn, this lets a model tell whether the burn rate fit already contains erosive burning.
    Grade sizes and bonding agent
    The Batch Sheet has a size box for each particle size grade. A new “No bonding agent in this formulation” tick box under the recipe notes separates deliberately having none from nobody having written it down.
  49. Version 0.42.0

    Propellants sent to RustCore carry their gas properties and keep their identity.

    Gas properties for RustCore
    A propellant sent to RustCore now includes the gas viscosity, thermal conductivity, Prandtl number and heat capacity at the chamber, throat and exit. RustCore needs these to predict erosive burning.
    Same propellant after a rename
    A propellant gets a lasting identity the first time you publish it, plus a revision number that goes up only when its numbers change. Renaming a recipe or refitting its burn rate updates the same propellant in RustCore instead of adding a new one. Save the recipe after publishing it to keep that identity.
    Erosive burning cautions
    Help, RustCore, explains two cautions. One is that a burn rate fitted from your own firings may already include erosive burning, so correcting for it again counts it twice.
  50. Version 0.41.0

    Gas viscosity, thermal conductivity and Prandtl number at the chamber, throat and exit.

    Gas transport properties
    Every result now gives the viscosity, frozen thermal conductivity and Prandtl number of the gas at the chamber, the throat and the nozzle exit. They use NASA’s transport data from CEA and the mixing method in NASA TM-86885. For a published CEA run (LOX/LH2 at 1000 psia, O/F 6) they agree with CEA to four figures at the chamber.
    Where to find them
    The new values appear on the Chamber & exit tab, on Compare, in the summary export and on the PDF data sheet. Help explains that they are frozen values for the gas alone.
  51. Version 0.40.0

    End burners on the Burn Rate page, and AP and aluminum grades as ingredients.

    End-burner test motors
    On the Burn Rate page, set Test motors to End burners to fit a and n from end-burner firings: solid grains with no core, burning only on the face. The web is the grain length and Kn stays constant, so each firing gives a clean single-pressure point. It works with measured pressures and with pressures estimated from Kn, and Import from openMotor reads end-burner motors.
    AP and aluminum grades
    Ammonium perchlorate at 400, 200, 90 and 20 micron, and aluminum as H-2, H-5, H-15 and H-30 spherical, 325 mesh atomized and dark pyro flake, are now ingredients of their own and in the Common list. They have the same chemistry as plain AP and aluminum, so results do not change, but a recipe can name them directly and the Batch Sheet gives each its own line. The stearin and oxide on dark pyro flake are not modelled, so its Isp is slightly optimistic.
    User manual
    The user manual is updated for 0.40.0.
  52. Version 0.39.2

    Ferrocene in the ingredient library; ferrocene and n-butyl ferrocene in the Common list.

    Ferrocene
    Ferrocene, a burn-rate catalyst for AP composites, is now in the ingredient library. Its heat of formation is the measured value from combustion calorimetry (Chipperfield, Sneyd et al., 1979, via the NIST WebBook), +158 kJ/mol, with a density of 1.49 g/cc.
    Common list
    Ferrocene and n-butyl ferrocene now appear in the Common ingredients list, next to Catocene. n-Butyl ferrocene was already in the full library; its density was checked against the published value.
  53. Version 0.39.1

    Catocene in the Common ingredients list.

    Catocene
    Catocene, the liquid ferrocene burn-rate catalyst, now appears in the Common ingredients list. It was already in the full ingredient library, and a search always found it; its data was checked against the published density.
  54. Version 0.39.0

    Send propellants to RustCore, the new motor core design software.

    Add to RustCore library
    A new button on the Export page puts the propellant in RustCore’s propellant library, with its density, burn-rate fit, gamma, chamber temperature, molar mass, ideal c*, c* efficiency and test firings. RustCore lists it on its Propellant page.
    Save for RustCore
    Saves the same propellant as a .rsprop file anywhere you choose, to copy to another computer or share.
  55. Version 0.38.0

    Chromium oxide, Tepanol and CAO-5 as ingredients, and Desmodur E 744 as a curative.

    Three new ingredients
    Chromium oxide, with data from NIST-JANAF, and the bonding agent Tepanol and the antioxidant CAO-5. No heat of formation is published for Tepanol or CAO-5, so theirs are estimated; at the usual 0.1 to 0.5% this makes no practical difference. All three are in the Common list.
    Desmodur E 744 curative
    Desmodur E 744 joins the curative list, using Covestro’s published figures.
  56. Version 0.37.0

    A Common list in the ingredient picker, and clearer labels.

    Common ingredients first
    The ingredient picker opens on a Common list of the 39 ingredients hobby motors use most. Searching still looks through all of them.
    Clearer labels
    The last vague labels are renamed, such as Price the batch, Mass unit and Number of points, and the longest hover hints are shorter.
  57. Version 0.36.1

    A layout fix on the Formulation page.

    Results stay in their column
    Scrolling down the Formulation page no longer slides the Results column over the Performance detail tabs.
  58. Version 0.36.0

    A hover hint on every control.

    Hover hints
    Every input, list, button, result tile and table heading now says what it is when you hover over it, with typical values where Help gives them. Screen readers get a name for every input. c* efficiency is described the same way everywhere.
  59. Version 0.35.0

    Every page tidied for first-time users.

    Formulation page
    Three columns: ingredients, the recipe and conditions, and the results, which stay in view. Performance detail is on five tabs underneath. The product database, ions, efficiencies and cone half-angle are folded into Nozzle and model settings. The big Isp tile shows the delivered value when an efficiency is set, hazard flags are a banner at the top of Results, and New, Open and a Save menu replace four buttons. On a narrow window the ingredient list becomes a drawer.
    One c* efficiency
    Burn Rate, Kn and the BurnSim export use the c* efficiency from the Formulation page. Each shows the value it uses and can override it, and the override is saved with the recipe.
    The other pages
    Library cards show ideal Isp and c*. Studies has X and Y axis rows for mix maps, a ring on the peak and shaded flow separation. Compare groups its rows and lets you choose the reference column. The Burn Rate table fits the window and explains each fit. Batch Sheet puts the settings first, with Grades and Curative as sections you can close, and grain sizes follow the Units switch. BurnSim comes first on Export. Empty pages say what to do next.
  60. Version 0.34.1

    A better flame color verdict for mixed colorants.

    Strong colorants outrank potassium
    A red sugar motor with strontium nitrate and more potassium nitrate used to read as lilac, because the verdict followed the color element with the most mass. Potassium’s lilac is faint, so strontium, barium, copper, lithium, calcium or boron at 1% or more now sets the color. Sodium at 1% overrides the rest, and two strong colorants in similar amounts are reported as a mixed flame.
  61. Version 0.34.0

    Help reorganized by task; ingredient data checked against sources.

    New Help
    Help now follows the order you work in, with a contents list, a search box and three step-by-step workflows: a first recipe to BurnSim, burn rate and a nozzle, and optimizing a mix and making a batch. Each card has a ? link that opens the matching section. New sections cover the recipe and notes, the results panels, the product database, each kind of study, Compare, the Propellant Library and each export.
    Ingredient data checked
    Curative NCO figures and strontium data were checked against the makers’ data sheets and published sources. Mondur MR is now 31.4% NCO, Rubinate M 31.0%, and strontium carbonate density 3.74 g/cc.
  62. Version 0.33.0

    Gas yield and specific force.

    Gas yield and specific force
    Moles of gas per gram, its volume in litres per gram at 0 °C and 1 atm, and the specific force at the chamber temperature, for gas generators, igniters and ejection charges. Shown under Chamber and exit, on Compare, in the export and as Studies charts.
  63. Version 0.32.0

    Ionized species.

    Include ions
    An Include ions option under Conditions adds ionized species to the calculation. It is saved with the recipe and used by studies and the data sheet, and the export notes when it is on.
  64. Version 0.31.0

    Two-ingredient mix maps, and faster studies.

    Mix map
    A new study on the Studies page varies two ingredients over a grid, with the others filling the rest, and shows the result as a heat map. It marks the best-Isp point and the current recipe, and Apply to recipe takes the chosen mix.
    Faster studies
    Studies now calculate their points on all processor cores.
  65. Version 0.30.0

    Conical nozzle divergence loss.

    Cone half-angle
    A Cone half-angle field beside the efficiencies takes the divergence loss of a conical nozzle off the delivered specific impulse, so Nozzle efficiency covers only the other losses. It is saved with the recipe and listed in the export.
  66. Version 0.29.0

    A warning for nozzle flow separation at sea level.

    Flow separation warning
    When the exit pressure is too low for a nozzle firing at sea level, the results warn that the flow would separate. The nozzle expansion study marks the expansion ratios whose sea-level specific impulse is unreliable.
  67. Version 0.28.0

    Specific impulse frozen at the throat.

    Frozen at the throat
    A third specific impulse beside frozen and shifting: equilibrium up to the throat, then the composition frozen to the exit. Shown in the performance table, on the Isp tile, on Compare, in the export and on the data sheet.
  68. Version 0.27.0

    Oxygen balance and equivalence ratio.

    Oxygen balance and equivalence ratio
    Worked out from the recipe’s elements, each burned to its usual combustion product. Shown under Performance detail, on Compare, in the export, on the data sheet and as a Studies chart.
  69. Version 0.26.1

    The save prompt also covers New, Open and Load. First macOS release since 0.1.0.

    Save prompt before New, Open and Load
    RustPEP now asks whether to save unsaved changes before New, Open, or loading a recipe from the Propellant Library, not only on closing.
    macOS catches up
    The macOS package moves from 0.1.0 to 0.26.1, so it now has everything added since, including the Batch Sheet. Windows, Linux and macOS are on the same version.
  70. Version 0.26.0

    RustPEP asks before closing with unsaved work.

    Save prompt on closing
    Closing RustPEP with a formulation that differs from what was last saved or loaded now asks what to do. You can save it to a file, save it to My propellants, close without saving, or cancel.
  71. Version 0.25.1

    The flame color estimate names the color to expect.

    Expected flame color
    The flame color estimate now states the color to expect, for example a bright red flame for a strontium recipe, judged from the amount of each color-giving element.
    Fix: color washed out by its own salts
    The estimate no longer counts the color element’s own condensed salts as particles that wash the color out.
  72. Version 0.25.0

    An estimate of flame color.

    Likely flame color
    The exhaust appearance estimate now covers flame color. RustPEP looks at the color-giving elements in the recipe, the emitting species the solver finds at the chamber and the nozzle exit, whether chlorine is present, and whether glowing particles or soot will wash the color out. It is a guide, and the page gives the reasons it cannot be exact.
    Strontium ingredients
    Adds strontium nitrate and strontium carbonate to the ingredient library.
  73. Version 0.24.0

    A smoke estimate for the exhaust.

    Exhaust smoke
    Results now include an appearance estimate read from the exhaust: the share that is liquid or solid particles (primary smoke), the hydrogen chloride and fluoride that can form a secondary trail, soot, and a class of smoky, reduced smoke or minimum smoke. It is shown under Performance detail, in Compare and in the summary export. The class limits are rules of thumb and are described as such.
  74. Version 0.23.0

    Grades and particle sizes on the Batch Sheet.

    Split an ingredient into grades
    A Grades and particle sizes card on the Batch Sheet splits one ingredient into lots weighed separately, such as two particle sizes of AP. The sheet, its CSV, the cost column and the batch log show one line per grade. The calculation is unaffected, and grades are saved with the recipe.
  75. Version 0.22.0

    Notes on every recipe.

    Recipe notes
    Each recipe has a free-text Notes box on the Formulation page. Notes are saved with the recipe file and in My propellants, printed on the batch sheet and included in the summary export.
  76. Version 0.21.0

    The curative follows the binder automatically.

    Keep the curative at the right ratio
    The curative calculator showed how much curative the binder needs but left the recipe to you. Turn on “Keep the recipe’s curative at this ratio automatically” and the curative’s weight follows the binder’s whenever the recipe, the hydroxyl value, the product, the equivalent weight or the NCO:OH ratio changes. Its weight box on the Formulation page is locked while this is on.
    Add the curative to a recipe
    For a recipe with a binder and no curative, one button adds the curative for the chosen product: PAPI for the MDI products, N-100 for the Desmodur N grades.
  77. Version 0.20.0

    A list of commercial curatives with their equivalent weights.

    Curative product list
    The equivalent weight in the curative calculator used to come from a data sheet. A Curative product list now fills it in for common commercial curatives: IPDI, PAPI 27 and 94, Mondur MR, Lupranate M20, Rubinate M, pure MDI, Isonate 143L, Desmodur N100, N3200, N3300, H and W, TDI 80/20 and DDI 1410. The values come from the NCO content each maker publishes. You can still type over the figure for your own lot, and the choice is saved with the recipe.
  78. Version 0.19.0

    See what is new before you install an update.

    Release notes in the update banner
    The update banner used to say only that a version was available. A What’s new button now opens the release notes, a paragraph per version, with Install and restart alongside. The same button appears on the Help page after a manual check.
    Fix: HMDI in the curative calculator
    A curative named only “HMDI” was not recognised. It is now.
  79. Version 0.18.0

    Compare burn rates between recipes.

    Burn rates on the Compare page
    A recipe added to Compare now brings its burn rate fit with it. The table lists each burn rate at the first recipe’s chamber pressure with the difference, the exponent, the coefficient and the number of firings. A chart overlays the fitted laws over the pressures each set of firings covered. This is the measured way to see what a catalyst does, which the equilibrium calculation cannot predict.
  80. Version 0.17.0

    Delivered performance from c* and nozzle efficiency.

    Delivered c* and specific impulse
    The Formulation page takes a c* efficiency and a nozzle efficiency. With either below 100%, the results show delivered c* and specific impulse next to the ideal values: on the tiles, in the performance table, in Compare, in the summary export and on the PDF data sheet. The settings are saved with the recipe and do not change the thermochemistry.
  81. Version 0.16.0

    Calibrate c* efficiency from a measured firing.

    c* efficiency from a pressure reading
    When fitting burn rate from Kn and burn time, a firing that also has a pressure reading shows what the c* efficiency actually was. The Burn Rate page reports the implied efficiency, with the spread when several firings have readings, and offers to use it for all firings.
  82. Version 0.15.1

    Clearer labelling on the PDF data sheet.

    Estimated fits labelled on the PDF data sheet
    The data sheet said every burn rate fit came from measured test firings. When the firing pressures were estimated from Kn it now says so, with the c* efficiency used.
  83. Version 0.15.0

    openMotor integration.

    Add to openMotor
    On the Export page, Add to openMotor puts the propellant straight into openMotor’s propellant library: density, fitted burn rate, specific heat ratio, combustion temperature and exhaust molar mass, with the pressure range of your firings as the range the burn rate is valid over. Your other openMotor propellants are left exactly as they were, and the previous library is kept as a backup file.
    Import from openMotor
    On the Burn Rate page, Import from openMotor reads the grains and nozzle throat from a motor file (.ric) into a new firing. It works for stacks of identical BATES grains.
  84. Version 0.14.0

    Fit burn rate without a pressure reading.

    Burn rate from Kn and burn time
    The Burn Rate page needed a measured chamber pressure for every firing. A second mode now estimates the pressure from each firing’s grain dimensions, throat diameter and burn time, using the recipe’s density and c*, reduced by a c* efficiency you set.
    How far to trust it
    A wrong c* efficiency shifts the coefficient a and leaves the exponent n unchanged. On simulated BATES burns the method recovers n within 1% and a within 2%. Fits made this way are labelled as estimated on the page and in the summary export.
  85. Version 0.13.1

    Exit gamma and molecular weight on screen, and study conditions spelled out.

    Exit gamma and molecular weight
    The specific heat ratio and molecular weight at the nozzle exit were calculated on every run but shown only in the text summary. They now appear on the Results tiles, in a new chamber-and-exit table, in Compare, in the summary export and on the PDF data sheet.
    Study conditions
    The Studies page now states the chamber pressure, exit pressure and database a study will use, shows them with the result, and writes them to the CSV.
  86. Version 0.13.0

    Bismuth support, with results that match the Air Force AFCESIC code.

    Bismuth recipes
    Recipes containing bismuth now solve with the NASA CEA database. NASA’s data has no bismuth species, so RustPEP adds its own: Bi, Bi2, BiO, BiCl and BiCl3 gas, and condensed Bi, Bi2O3 and BiCl3. Before this, a bismuth recipe stopped with an error.
    Results match AFCESIC
    The bismuth results were checked against the Air Force Chemical Equilibrium Specific Impulse Code (AFCESIC) on three recipes. RustPEP agrees within 0.3% on chamber temperature and within 0.1% on c* and specific impulse.
    Bismuth ingredients and a library formula
    Adds bismuth trioxide and four other bismuth ingredients, and an AP/HTPB/Bi2O3 formula in the Propellant Library.
    Know the limits
    Bismuth results are less certain than usual and RustPEP says so beside them. The Help page explains why. The legacy JANNAF database still has no bismuth species.
  87. Version 0.12.0

    A fuller PDF data sheet.

    Hazard flags and cost on the PDF data sheet
    The one-page PDF data sheet now includes the recipe’s hazard flags and the ingredient cost.
  88. Version 0.11.0

    Curative calculator and batch log.

    Curative calculator
    A Curative card on the Batch Sheet works out the curative needed from the binder’s OH value, the curative’s equivalent weight and the NCO:OH ratio. One button re-splits binder and curative in the recipe to match.
    Batch log
    Record each mix: planned and actual weights, batch number, date and notes.
  89. Version 0.10.0

    Imperial or SI units throughout.

    Units switch
    A Units choice in the sidebar switches pressures, velocities and lengths between psi, ft/s, in and MPa, m/s, mm on the Formulation, Studies, Compare and Burn Rate pages. Pressures you have typed are converted, and the choice is remembered.
  90. Version 0.9.0

    Your own propellant library.

    My propellants
    Save to library keeps a recipe inside RustPEP with its conditions, test firings, batch settings and Kn inputs. Saved recipes appear at the top of the Propellant Library page, with Load and Delete.
  91. Version 0.8.0

    Kn and nozzle throat calculator.

    Kn and nozzle throat calculator
    With a fitted burn rate and a solved recipe, the Burn Rate page shows the Kn needed for a chosen chamber pressure. Enter BATES grain dimensions and it gives the throat diameter that peaks at that pressure, with the ignition and burnout pressures.
  92. Version 0.7.0

    Cost per batch.

    Cost on the Batch Sheet
    Enter a price per kg or lb for each ingredient and the Batch Sheet shows the cost of each ingredient, the batch total, and the cost per kg, per lb and per grain. Prices are remembered across recipes.
  93. Version 0.6.0

    Hazard flags.

    Hazard flags
    Recipes are checked against a short list of well-known hazards: chlorate pairs, binderless flash mixes, metals that react when damp, explosives, toxic elements and unusually hot flames. Flags appear under the recipe and on the Batch Sheet.
  94. Version 0.5.0

    Send a propellant straight to BurnSim 4.

    Add to BurnSim 4
    On the Export page, Add to BurnSim 4 writes the propellant into BurnSim 4’s propellant list: c*, density, gamma, molecular weight and burn rate, with an optional c* efficiency. An entry with the same name has its values updated, and the previous list is kept as a backup file. Save as file writes the same format anywhere you choose.
    Fix: sidebar footer
    The sidebar footer is back at the bottom of the window.
  95. Version 0.4.0

    Import PEPCODED ingredient files.

    Import PEPCODED
    Import PEPCODED on the Formulation page reads a PEPCODED.DAF-format file and adds its ingredients as custom ingredients. Ingredients RustPEP already has are left alone. One that differs from a built-in ingredient of the same name comes in as “NAME (imported)”.
  96. Version 0.3.1

    Startup fix.

    Fix: RustPEP closing at startup
    A WebView2 helper process left over from an earlier run could make RustPEP exit as it started. RustPEP now retries and then carries on with a spare data folder.
    Batch Sheet help
    The Help page now covers the Batch Sheet.
  97. Version 0.3.0

    Batch Sheet.

    Batch Sheet
    A new page scales the recipe to the weights for one mix, sized by propellant mass or by grain dimensions, with a waste allowance, rounding and a running total. Print it, copy it or save it as CSV. The settings are saved with the recipe.
  98. Version 0.2.0

    Automatic updates on Windows.

    Automatic updates
    RustPEP for Windows checks for a new version when it starts and offers to install it from the sidebar. The Help page has a manual check.
  99. Version 0.1.0

    First release, for Windows, macOS and Linux.

    Equilibrium performance
    Chamber temperature, specific impulse, characteristic velocity, density, gamma, molecular weight and combustion products for a propellant recipe.
    Libraries
    More than 1,000 ingredients, your own custom ingredients, and a library of published reference formulations.
    Studies and comparison
    Sweep an ingredient, chamber pressure or nozzle expansion ratio and chart the result. Compare up to four recipes side by side.
    Burn-rate fitting
    Fit the burn-rate coefficient a and exponent n from BATES test firings.
    Export
    BurnSim summary, CSV, PDF data sheet and PEPCODED ingredient records.

Get the current version.

Version 0.71.1 for Windows, 0.67.2 for Linux and 0.67.2 for macOS.