Changelog — Suite Updates & Calculation Record
High-level record of changes to the Piping Toolset suite — the browser tools, calculation engines, reports, plans, and the site/API surface. Calculation behavior is the versioned core of this record: if a number a calculator produces could change, it is recorded here, and the entry names the affected module ids and the fixture files that lock the change. No calculation ships without a green fixture; "Verified" notes the derivation basis (hand calculation, PVP Suite validation set, or published source-sheet example). UI-only and content-only changes are summarized at suite level.
The site's /trust/changelog page is generated from this file at build time.
2026-10-12 — Hydrogen (B31.12) line checked against the 2023 edition
- Edition of record is now ASME B31.12-2023. The Part IP pressure-design equations (¶IP-3.2.1 Eq. (3a), ¶IP-3.3.1 Eq. (3c), ¶IP-3.3.3 Eqs. (4a)–(4c), ¶IP-3.4.2 Eqs. (6a)–(8)), the test-pressure rules (¶IP-10.6.2 Eq. (24), ¶IP-10.7.4) and the Mf tables (IX-5B, IX-5C) are unchanged from 2019. No calculated number changes for inputs that were already correct.
- Bend and miter cards now ask for Mf, not W on the Hydrogen line. B31.12 Eqs. (3c) and (4a)–(4c) carry S·E·Mf and have no weld joint strength reduction factor. The cards used to show a "Weld W" field there, which left Mf out unless the user folded it into S or E. The field is now "Perf. factor Mf". It sits where W sat, so the engines (
piping.bend-thickness,piping.miter-allowable-pressure) are unchanged. - Leak test uses the B31.12 ratio cap and pneumatic bound (
piping.leak-test-pressure, unit tests inleak-test-pressure.test.ts). B31.12 Eq. (24) limits Rr = ST/S to 6.5, unlike B31.3 Eq. (24). The Hydrogen card now starts with the cap at 6.5 and reports it as the code minimum when it binds. Pneumatic factors above 1.33 (¶IP-10.7.4(a)) are flagged. On every line, ST/S below 1 now gives a warning that the 1.5 × P floor of ¶345.4.2(a) / ¶IP-10.6.2(a) governs. - New boundary warnings on allowable pressure (
piping.b31-allowable-pressure, unit tests inb31-allowable-pressure.test.ts). The engine warns when P/(S·E·Mf) is above 0.385 (B31.3 ¶304.1.2(b), B31.12 ¶IP-3.2.1(b)) and when Mf is above 1.0. Outputs are unchanged and the fixture still passes. - Citations corrected. The Hydrogen allowable-pressure card cited "¶GR-2.1", which is the materials chapter. It now cites ¶IP-3.2.1 Eq. (3a). All five Hydrogen cards now name the B31.12-2023 clause, its limits and the source table for each input. The Mf FAQ said Mf depends on hydrogen partial pressure. Tables IX-5B and IX-5C use system design pressure, and they apply only to carbon and low- and intermediate-alloy steels up to 300°F.
2026-10-12 — B31.5 cards checked against ASME B31.5-2022; B31.5 gets its own leak test
- B31.5 wall thickness has no separate E or W (
piping.b311-wall-thickness, fixtureb311-wall-thickness.json, unchanged). B31.5-2022 ¶504.1.2 Eq. (3a) is t = P·Do / 2(S + P·y). S is the allowable hoop stress from Table 502.3.1-1, and for welded pipe that table value already includes the joint factor (¶502.3.1(a)). B31.5 also has no weld strength reduction factor. With B31.5 selected, the Building & HVAC wall card now hides its Factor E and W fields and runs with both at 1.0, so a joint factor can no longer be applied twice. It also hides the B31.9 Table I-1 stress picker, which holds B31.9 values. The numbers are unchanged when E = W = 1.0. - B31.5 validity range. Eq. (3a) applies for Do/t > 4, not the t < D/6 limit of the B31.1/B31.3 form. In B31.5 mode the card now warns when Do/t is 4 to 6 (¶504.1.1 then calls for y = d/(d + Do)) and when Do/t is 4 or less (outside ¶504.1.2; design per ¶504.7). It no longer sends those designs to a thick-wall method.
- B31.5 leak test (
piping.leak-test-pressure, fixtures unchanged). New B31.5 card on the Building & HVAC line: pneumatic test at least 1.10×P and at most 1.30× the design pressure of any component (¶538.4.2(e)); hydrostatic 1.5×P for secondary coolant piping only (¶538.6(a)). Until now the line offered only a B31.9 leak test card. - Pneumatic-cap warning names the right code. The warning shown when the pneumatic factor exceeds the code bound always quoted B31.3 ¶345.5.4(b), on the B31.1 card as well. It now gives the B31.5 ¶538.4.2(e) limit on the B31.5 card and no B31.3 reference on the B31.1 card. The B31.3 card is unchanged.
- Card bases. The Building & HVAC allowable-pressure, bend and branch cards now cite B31.5-2022. Allowable pressure: enter E = 1.0 for B31.5. Bends: ¶504.2.1(a) requires the straight-pipe wall everywhere, so read the centerline row and take no extrados credit. Branch: same area-replacement form as ¶504.3.1(f).
2026-10-11 — Allowable pressure now applies the weld joint strength reduction factor W
- B31.3 and B31.1 Allowable Pressure take W (
piping.b31-allowable-pressure, fixtureb31-allowable-pressure.json, one new case). The engine used P = 2·S·E·Mf·tp / (D − 2·y·tp) with no W. B31.3 ¶304.1.2 Eq. (3a), t = PD / 2(SEW + PY), solved for P gives P = 2·S·E·W·tp / (D − 2·Y·tp), and B31.1 ¶104.1.2 Eq. (9) carries the same W. For welded pipe with W below 1.0 the old result overstated the allowable pressure by a factor of 1/W. W is now an input. It defaults to 1.0, so results with W = 1.0 are unchanged and older API calls that leave W out give the same numbers. Values outside (0, 1] are rejected. - Where W appears. The Process (B31.3) card has a Weld W field plus a Pro autofill from Table 302.3.5-1, the same picker the wall-thickness card uses. The Power (B31.1) card has a Weld W field. The Building & HVAC (B31.5/B31.9) and Hydrogen (B31.12) cards show no W field: B31.9 Eq. (2) and B31.12 Eq. (3a) have no W term, so W stays at 1.0 there.
- Verified by hand with fictitious round inputs: D = 10 in, t = 0.500 in, 10 % mill tolerance, A = 0.05 in, S = 20,000 psi, E = 1, W = 0.8, y = 0.4 give tp = 0.40 in and P = 12,800 / 9.68 = 1,322.314 psi, which is 0.800 × the W = 1 result (arithmetic in the fixture description). The existing NPS 8 case leaves W out and still returns 897.611 psi.
2026-10-04 — DNV-RP-F101 rejects defects deeper than 85 % of the wall; Section III NC-3658.3 flange guidance stated as checked against NC-2019
- DNV-RP-F101: defects deeper than 85 % of the wall are now rejected (
pipeline.dnv-f101-defect, fixturednv-f101-defect.json, two new cases). DNV-RP-F101 (September 2019, amended September 2025) Sec.4.3.2 says measured defect depths over 85 % of the wall are not accepted. The engine used to give a warning and still return a safe working pressure. For d/t > 0.85 it now returns FAIL, gives the reason innotAccepted, and leaves out Pf, Psw and utilization. It does this in capacity-only mode too. A defect at d/t = 0.85 exactly is still assessed. Verified by hand: at d/t = 0.85 the failure pressure is 1,134.470 psi and Psw = 735.137 psi (arithmetic in the fixture description). Results for d/t ≤ 0.85 are unchanged. - DNV-RP-F101 wording. The quantity the card computes is Part B's failure pressure Pf. It is not the recommended practice's mean (best-estimate) capacity, which carries an extra 1.05 factor and is about 5 % higher. The card, landing page and output descriptions now call it Pf; the output key stays
Pcapso API callers are unaffected. In Part B, F2 is described as the operational usage factor, normally the design factor. Inspection-accuracy terms belong to Part A and are no longer described as part of F2. The page now notes that the full-scale validation tests ran on grades up to X65. The equation and its numbers are unchanged. - Bolted flange and PSV support guides: NC-3658.3. The ASME BPVC III-1 Subsection NC-2019 text was checked. The guide now says NC covers Class 2 only. It states that NC-3658.3 applies only to B16.5 flanges, bolting and gaskets with bolting S at 100 °F of at least 20,000 psi. It adds the pressure caps by Service Level (rated, 1.1×, 1.5×, 2.0× for Levels A–D) and the Level C/D moment limit, eq. (17). It defines Sy at Design Temperature and Ab as the total root-of-thread bolt area. The worked example no longer assumes Sy/36,000 = 1.0 for A105 at 400 °F: the 120,272 in-lb limit is now shown as a ceiling, scaled by that ratio, and the check still passes with a wide margin.
- PiperFEA report basis line. The report no longer claims the results are post-processed to "ASME Section III and Section VIII, Division 2". It now names what is actually done: comparison with VIII-2 allowables, and VIII-2 Appendix 5 fatigue curves with a Ke in the form of Section III NB-3228.5.
- PiperFEA fatigue-curve temperature ceilings. ASME BPVC III-1 NC-1120 (NC-2019) says fatigue design curves do not apply above 700 °F for carbon and low-alloy steels (Fig. I-9.1) or above 800 °F for austenitic and nickel alloys (Fig. I-9.2). PiperFEA uses the matching VIII-2 Appendix 5 curves. A job whose design temperature is above the ceiling for its material now gets a "FATIGUE NOT APPLICABLE" advisory when it is submitted. The fatigue result is marked as not applicable (
curve_applicable: false), and the report's fatigue section says it is for reference only. No stress number or pass/fail status changes: the job still runs and the other checks are reported as before.
2026-10-04 — A guide to reading piping isometrics; PiperISO's Category M examination default corrected; vendor links are plain text
- New guide: How to Read a Piping Isometric Drawing (/guides/piping-isometric-drawings/). The isometric axes, the sheet in reading order, symbols and abbreviations, weld and spool marks, dimensions and elevations, the rolling offset with a worked example, and how a stress engineer reconciles an iso against the model — with four figures. Drawing conventions are stated as conventions; the project legend governs. No tabulated fitting dimension appears in it.
- Piping ISO drawing page (/tools/piping-iso-drawing/). Opens with what a piping isometric is, shows an annotated sheet, and adds two questions to its FAQ (what an isometric is; which symbols and weld marks the tool draws). Two statements are corrected: the dimension, weld-balloon and node-number toggles apply to the on-screen sheet, not to the PDF, and the tool currently marks every weld as a field weld. Title, description and the tool itself are unchanged.
- PiperISO datasheet: Category M examination default (
isodraftdatasheet, all exports that print it). With the service set to Cat M, the datasheet showed 20 % radiography. ASME B31.3 ¶M341.4(b) calls for 100 % of circumferential butt and miter groove welds in Category M fluid service; the default is now 100 %. Normal (5 %), Category D (visual only, 0 %) and severe cyclic (100 %) are unchanged. Affects the on-screen datasheet, the Excel weld and datasheet tabs, the PDF title block and the CSV summary. A unit test pins the default for all four service selections. If you exported a Category M datasheet from PiperISO before this date, re-export it. - PiperOCC and PiperBRC: reference-tool links. The links to the ASCE Hazard Tool and to ASC SeisBrace are now text links instead of logo buttons. Same destinations, still opening in a new tab.
2026-10-02 — Slope designations, CIP velocity, BN2 and the sulfur range served as cited data; the CIP branch advisory says what SD-6.3.5.2.1 says
The last ASME BPE-2026 values compiled into the BPE calculation engines now ship through the data service that gates and cites embedded standard data, and the /trust/sources.html embedded-data table lists each of them. Every value was re-read against the printed BPE-2026 page before it moved. No calculated number changes for any input the cards offered before.
- Slope designations (
bpe.slope-check,bpe.slope-report). The GSD1–GSD3 minimum slopes of Table SD-2.4.3.1-1 (1/16, 1/8 and 1/4 in./ft; printed p.55) and the SD-2.4.3.3 recommended minimum (GSD2) leave the engine. The engine still grades on the in./ft column, converted exactly; the table's nominal mm/m, % and degree columns are carried for the citation only (the degree column is the arctangent of the nominal percent, so the columns are not exact equivalents of each other). The cards no longer describe the thresholds as a definitional column rather than table content; the check card cites the table row beside its target and a report carries it as a source row. - CIP target velocity, and the branch advisory corrected (
bpe.cip-velocity). The 5 ft/sec (1.5 m/s) the SD-6.3.5.2.1 flow-rate table is built on (printed pp.142, 144) is served with the table itself, and the card cites it beside the target field; a CIP client's own target replaces it. The engine raised a "drainability minimum" advisory for any line I.D. under 1.5 in. — so 1-1/2 in. BPE tube (I.D. 1.370 in.) drew it. SD-6.3.5.2.1(e) is about solution contact in branches: at 5 ft/sec, short-outlet tees of 1.5 in. and larger may be adequate, smaller short-outlet tees and longer branches may need more. The advisory now says that and fires only on lines smaller than 1-1/2 in. tube. Its landing page no longer calls 5 ft/s an industry-accepted threshold. - BN2 limit and autogenous-weld sulfur range (
bpe.ferrite-number). The 7.70 limit of App G G-3(d) footnote 3 (printed p.344) and the 0.005–0.017 wt % range of MM-5.2.1.1(a) (printed p.31) leave the engine; the BN2 equivalents and the 0.91 coefficient, the criterion's closed form, stay. The card cites both beside the Si and S fields, and no longer calls the range a public closed form. - Dead-leg limit and small-branch size (
bpe.dead-leg). The engine read its own constant for the SD-3.1.2.2 L/d of 2 beside a dataset that already served it; it now reads the dataset, and the SD-2.4.3.2 3/4 in. (19 mm) small-branch size moves with the slope designations. An exceedance of the recommended limit now says the clause makes it a recommendation, not an absolute requirement. - Each engine names the source of a value in its result. If the gate refuses a dataset, the engine asks for the project's value (slope cannot be graded without the table) or, for BN2 and sulfur, reports without judging.
- Fixture cip-velocity.json: existing cases unchanged; added 1-1/2 in. tube (I.D. 1.370 in. → 22.97 gpm, 86.96 L/min, the 23 gpm / 87 L/min table row). Data-service tests pin every value and citation, check that Q = 2.448·v·ID² reproduces all five printed table flows, and check the slope table's columns against each other; engine tests pin the attribution, the advisory boundary and the gate-refusal behavior; end-to-end tests pin the citations on the free tier and the report source rows (Pro).
2026-10-02 — Spray-device bands and EP/passivation criteria served as cited data; duplex and nickel coupons no longer judged on criteria BPE does not set
Two BPE engines carried ASME BPE-2026 values compiled into the calculation code — outside the data service that gates and cites embedded standard data — and the embedded-data inventory on /trust/sources.html did not list them. Both are closed here. Every value was re-read against the printed BPE-2026 page before it moved. No calculated number changes for any input the cards offered before.
- Spray-device coverage bands move into the data service (
bpe.spray-flow). The six flow-rate guidelines of SD-3.9.2.1–SD-3.9.2.3 (printed pp.93 and 96) — static 2.5–3.0 / 2.0–3.0, single-axis 1.9–2.3 / 1.4–2.1, multi-axis 1.3–1.5 / 0.8–1.2 gal/min per ft, vertical / horizontal vessel — now ship as a cited dataset, and the engine no longer carries them (DEFAULT_COVERAGE_RATESis removed from @pcp/calc-core). With no manufacturer band entered, the engine takes the guideline through the data service and names the subparagraph in its result and warning; the card prints it beside the device-type control and a report carries it as a source row. The card, its landing page and the engine no longer describe the bands as method guidance outside the standard, and the warning now says what SD-3.9.1 says: they are guidelines for metallic vessels and water-based cleaning solutions, and the manufacturer confirms the application's flow. The trust page's embedded-data table gains the SD-3.9.2 row. - EP removal and passivation criteria move into the data service (
bpe.ep-passivation). Minimum removal 0.0002 in. (5 µm), total Cr/Fe ratio and passive-layer depth from App. H Table H-4.3-1 (printed p.348), and Cr/Fe by test method with oxide depth from App. E Table E-3.2-1 (printed p.332) now ship as two cited datasets; the engine's compiled defaults are gone, and a specification's own value still replaces any of them. The card printed these values as "user-supplied criteria" while offering no field to supply them; it now cites both tables, and a report carries both as source rows. The trust page's embedded-data table gains the H-4.3-1 and E-3.2-1 rows. - Alloy family, and the N/A rows of Table H-4.3-1 (
bpe.ep-passivation). H-4.3-1 sets Cr/Fe and passive-layer depth for austenitic and superaustenitic stainless steels only and prints N/A for duplex stainless steels and nickel alloys; E-3.2-1 is written for UNS S31600/S31603 samples. The engine applied one set of limits to every alloy, so a duplex or nickel coupon with a sound removal could be failed on a criterion the standard does not set. The card gains an alloy-family selector (austenitic by default, which keeps every earlier result); for duplex and nickel alloys removal is still checked and the measured Cr/Fe and oxide depth are reported, not judged. For austenitic and superaustenitic coupons the Cr/Fe minimum is the E-3.2-1 value for the test method, never below H-4.3-1's — 1.0 by AES or GD-OES (GD-OES is new to the method list), 1.3 by XPS/ESCA — and oxide depth 15 Å. - Fixtures spray-flow.json and ep-passivation.json: existing cases unchanged. Added a multi-axis horizontal case (24 ft × 0.8–1.2 = 19.2–28.8 gpm, 72.680–109.020 L/min), an XPS case (Cr/Fe 1.2 < 1.3, fail) and a duplex case (Cr/Fe 0.8 and 10 Å not judged, removal 6.25 ≥ 5 µm, pass); arithmetic in each fixture's description. Engine tests pin the subparagraph and table attribution, the N/A handling and the behavior when the data service refuses a dataset (the engine asks for the project's value rather than judging against nothing); data-service tests pin every value and citation, and check the six U.S. bands against the SI bands printed beside them; an end-to-end test pins both cards' citations on the free tier and their report source rows (Pro).
2026-10-02 — Polymer thermal-expansion coefficients served as cited data, with a units check on α
The 2026-09-23 correction put the right PM-4.2.3 coefficients on the Polymer Thermal Expansion card, but compiled them into the calculation engine — outside the data service that gates and cites embedded standard data — and the embedded-data inventory on /trust/sources.html did not list them. Both are closed here. No calculated number changes for any α a user can pick.
- PM-4.2.3 coefficients move into the data service (
bpe.polymer-thermal-expansion). PVDF 6.6, PFA 7.0 and PP 8.33 × 10^−5 in./in./°F — the typical room-temperature U.S. Customary values ASME BPE-2026 PM-4.2.3 lists — now ship as a cited dataset, and the engine no longer carries them (BPE_POLYMER_CTEis removed from @pcp/calc-core); α is always an input. Picking a preset prints "ASME BPE-2026, PM-4.2.3" with the material and value beside the control, and a report carries it as a source row. The card and its landing page now say what the clause says: these are typical room-temperature values, and the manufacturer's figure for the actual compound governs. The card works in U.S. Customary units only; the SI coefficients printed alongside are not used. The trust page's embedded-data table gains the PM-4.2.3 row. - Units check on α (
bpe.polymer-thermal-expansion). A coefficient below 2 × 10^−5 or above 2 × 10^−4 in./in./°F — outside the band thermoplastic piping occupies, from PVC to HDPE — now raises a warning naming the likely slip: a metal's or a glass-reinforced FRP's coefficient, a per-°C value, or one in mm/m/°C. The number is still computed as entered; the band is engineering judgment, not a code value. - Fixture polymer-thermal-expansion.json unchanged (0.6336, 0.7286 and 0.7997 in, hand calculation in its description). The engine test now pins the units band, the data-service test pins the three coefficients and their citation, and an end-to-end test pins the card's presets, citation and report source row on the free tier.
2026-09-23 — Independent audit corrections: DNV Part B factor, EJMA squirm, BPE polymer coefficients, current B31.1/B31.3 equation forms, ASCE 7-22 wind and seismic, support bending span
An independent review of the live calculators raised eighteen items. Each was checked against the edition text before anything changed; the ones that held are corrected below, every changed fixture is re-derived by hand (arithmetic in each fixture's description), and the landing pages, app cards and worked examples now say what the engines do. Items the edition text did not support were left as they were: B31.3 Eq. (24) carries no ceiling on ST/S in the 2016, 2020, 2022 or 2024 texts; the site's B31.3 table names (A-1C, A-2, A-3) are the 2024 edition's own; and the spring-variability rule lives in MSS SP-58 §6.16 / Table 5, not the clause the review named.
- DNV-RP-F101 safe working pressure used one factor where Part B uses two (
pipeline.dnv-f101-defect). Part B's safe working pressure is Psw = F·Pf with F = F1·F2 — a modelling factor F1 = 0.9 fixed by the recommended practice and an operational usage factor F2 normally equal to the pipeline's design factor. The engine multiplied the capacity by one entered factor, so entering the design factor directly overstated Psw by 1/0.9 (11.1 %, unconservative). Both factors are now inputs — F1 (0.9 in Part B) and F2, entered from the user's own copy with no default, since no DNV value is embedded — and F1, F2 and F reported; the old single-factor input is still accepted as the combined F, with a deprecation warning, so existing callers do not silently change. Worked example: 2,236.194 → 2,012.576 psi, utilization 0.64395 → 0.71550 (still passes, with less margin). The capacity equation was already correct. - EJMA column-squirm screen overstated the limiting pressure about 0.8·N times (
general.ejma-rating). EJMA 10th Ed. Eq. (4-43) is Psc = 0.34π·Cθ·fi/(N²·q) with fi the per-convolution rate; with the engine's whole-bellows Kax (fi = Kax·N, q = Lb/N) that is 0.34π·Cθ·Kax/Lb — N does not appear. The engine computed 0.87·Kax·N/Lb. The shipped worked example (150 psi against a reported 870 psi, "ok") is corrected to 89.012 psi and now fails as an instability risk; optional Cθ (default 1) added, with a warning that the screen assumes unreinforced U-shaped bellows. The PiperEXJ bellows engine already used the correct form. - Polymer thermal-expansion presets now match PM-4.2.3 (
bpe.polymer-thermal-expansion). The card offered PVDF 7.9, PFA 6.7 and PP 4.8 × 10^−5 in./in./°F while citing ASME BPE-2026 PM-4.2.3, which lists 6.6, 7.0 and 8.33 × 10^−5 — PP growth was understated by 42 %. The presets now live in the engine (BPE_POLYMER_CTE) and are pinned by a unit test; the warning cites PM-4.2.4.1 for support distances and no longer suggests expansion joints, which PM-4.2.3 advises against. Fixture re-derived (PVDF 0.6336 in) with a new PP case (0.7997 in). - Tube weld limits have no default values (
bpe.tube-weld-acceptance). Owner decision on the 2026-09-22 open item: every limit is entered from the user's own copy of Table MJ-8.4-1 and a missing one throws; the card opens with the three limit fields blank and computes nothing until they are filled. Only the basis (the O.D. form of each criterion) keeps a default. - Multi-code comparison uses the current B31.1 and B31.3 displacement forms (
general.analysis-set). The B31.1 row computed the pre-2020 single-i resultant form; it now computes B31.1-2024 Figure 104.8-1 Eq. (17), and the B31.3 row gains the axial term of B31.3-2024 Eq. (17). New optional inputs Fa, Ap, it. Case 0: B31.1 SE 8,324.34 → 7,640.76 psi, governing check B31.8 combined 0.51823 → 0.49653; new case 2 exercises the axial and torsional terms. - Weld joint strength reduction factor W added where the equations carry it (
piping.b311-wall-thickness,piping.bend-thickness,piping.miter-allowable-pressure). B31.1 ¶104.1.2 Eq. (7) has read tm = PDo/(2(SEW + Py)) + A since the 2018 edition, and B31.3 bends (Eq. (3c)) and miters (Eqs. (4a)–(4c)) carry SEW. W defaults to 1.0, so existing results are unchanged; each fixture gains a W < 1 case. - Displacement stress range takes the axial term (
piping.displacement-stress). Optional Sa (default 0): SE = √((|Sa| + Sb)² + (2St)²), B31.3-2024 ¶319.4.4 Eq. (17). New case with Sa = 3,000 psi. - Leak test ratio cap is optional and the pneumatic ceiling is checked (
piping.leak-test-pressure). Eq. (24) sets no ceiling on ST/S, so a cap is now applied only when entered (the card leaves it blank) and a binding cap is reported as below the code minimum. New optional pneumatic upper-bound factor warns past B31.3 ¶345.5.4 (1.33 × P) or B31.1 ¶137.5.5 (1.5 × P). The B31.1 card now computes the flat ¶137.4.5 1.5 × P form with no ratio fields. New hot-service cases: uncapped 3,600 psi; with a 6.5 specification cap, 2,925 psi and a warning. - Wind velocity pressure follows the edition (
aux.wind-asce). ASCE 7-22 Eq. (26.10-1) removed Kd from qz and applies it in the force equation (Eq. (29.4-1)); the engine takes an edition input (7-16 default) and reports qz per edition. The line load is identical either way. - Seismic design force supports ASCE 7-22 (
aux.b31e-seismic). Adds the 7-22 §13.3.1 form, Fp = 0.4·SDS·Ip·Wp·(Hf/Rμ)·(CAR/Rpo) with the same 0.3/1.6 bounds (Hf, Rμ, CAR, Rpo entered by the user), alongside the 7-16 form, and a warning that a B31E §3.4 check requires ap = 2.5 and Rp ≤ 3.5 (B31Ea-2010). Retitled to name ASCE 7 §13.3.1 — B31E takes Fp as an input and does not define it. Two new 7-22 cases. - Occasional-load ASD factors default to 1.0 (
aux.asce-occasional). New piping-code input; B31.1-2024 ¶101.5.2/¶101.5.3 say the ASCE 7 ASD reduction factor shall not be applied, so the 0.6/0.7 defaults are gone and a B31.1-2024 run with a factor below 1.0 warns. B31.3-2024 states no such factor; applying 0.6/0.7 there is practice and is entered deliberately. - Support span reports the bending-stress span and which limit governs (
nonmetallic.support-span). With an allowable bending stress S entered, L = √(k·Z·S/w) with k matched to the deflection boundary condition (8 simple, 12 fixed-fixed — the combination B31.1-2024 Table 121.5-1 Note (c) uses); the shorter span governs. Without S the result is marked "bending not checked". Two new cases (deflection governs; bending governs). - Nozzle check notes the PIP RECE002 design-stage margin (
connections.nozzle-load-check). Informational warning above a 0.5 ratio: where the owner invokes RECE002, vital/sensitive machinery is laid out to 50 % of the allowable loads (§4.2.2.3). Status is unchanged. - Citations and labels only (no calculation change). Spring variability and maximum spring rate now cite MSS SP-58 §6.16 / Table 5 (B31.3-2024 references the 2018 edition), and 6 % is described as the constant-support criterion it is. The pipeline cards label B31.11 as absorbed into ASME B31.4 Chapter XI (¶C403.2 for slurry design; the "Ch. IX" label was wrong) with option values unchanged. API 610 is cited as the 13th Edition.
- Verified by hand calculation against the edition texts;
npm run verify(310/310),npm run test:coreand the full Playwright suite green.
2026-09-22 — BPE tube weld acceptance and the BN2 ferrite criterion: corrected to the edition's own basis
Two BPE engines computed their acceptance criteria on the wrong basis. Both are corrected against ASME BPE-2026, both fixtures are re-derived by hand, and both landing pages, app cards and diagrams now say what the engines do.
- Tube weld acceptance — each limit now carries its own basis (
bpe.tube-weld-acceptance, Table MJ-8.4-1 / Fig. MJ-8.4-1). The engine checked outside-surface measurements with misalignment against a fixed absolute limit for every tube size and convexity against a fraction of the wall. For the outside (non-process-contact) surface the table states misalignment as a fraction of the nominal wall Tw — switching to an absolute limit only for the largest tube sizes — and convexity as an absolute height. A default run on 3/4 in × 0.065 in tube therefore passed a 0.010 in mismatch (ratio 0.67) that the edition of record rejects at 0.15 × 0.065 = 0.00975 in (ratio 1.03). Convexity and misalignment now take a basis input (fraction of Tw or absolute); the defaults follow the outside-surface forms, and the older inputs keep their meaning (misalignmentLimitalone is absolute,convexityFracalone is a fraction). New outputs:convexityBasis,misalignmentBasis; allowables now carry five decimals. - Reweld disposition now follows MJ-8.4.2. A failing concavity or convexity reports the single reflow attempt MJ-8.4.2 permits; a failing misalignment reports that it is not among the reweld-eligible defects. The engine previously raised the same reweld warning for all three.
- BN2 is now evaluated on its own equivalents (
bpe.ferrite-number, App. G, G-3(d) and its footnote). The 0.91 coefficient and the limit belong to the BN2 pair — Cr(eq) = Cr + 1.5Si + Mo + 2Ti, Ni(eq) = Ni + 0.5Mn + 30C + 30(N − 0.02) — not to the WRC-1992 pair App. G uses for the constitution diagram, which the engine had been subtracting. On a typical 316L heat the two read 6.883 and 6.633; on a higher-silicon heat the WRC-based number (7.033) qualified a heat the BN2 criterion rejects (7.947). BN2 now needs silicon and manganese (new inputs Si, Mn and optional Ti) and returns no verdict without them, because a missing silicon would flatter the heat. The WRC-1992 Cr_eq and Ni_eq outputs are unchanged. New outputsbn2CrEq,bn2NiEq;bn2Valueandbn2Qualifiesmay be null. - Fixtures.
tube-weld-acceptance.jsonre-derived (0.7179 pass / 1.0256 fail, both governed by misalignment);ferrite-number.jsonre-derived with Si and Mn and a third case pinning the pair difference. New unit tests cover the defaults, legacy inputs, basis switching, the MJ-8.4.2 split and the not-evaluated BN2 path. Verified by hand calculation against the ASME BPE-2026 text;npm run verifyandnpm run test:coregreen. - App cards and pages. The tube weld card gains limit and basis inputs (it previously showed none and ran on its defaults); the ferrite card gains Si, Mn and Ti. Both landing pages, their worked examples, FAQ answers and diagrams are rewritten to match — including a new worked example showing the BN2 pair difference.
2026-09-19 — Dependency and security maintenance: PDF and Excel export libraries
Maintenance release; no calculation behavior changes. No engine, fixture or dataset was touched.
- jsPDF 2.5.2 → 4.2.1 (PiperISO sheet PDF, PiperSTR Design Summary PDF). Picks up the upstream security fixes published against every jsPDF release through 4.2.0, and with them a patched DOMPurify (2.5.9 → 3.4.15). The advisories concern jsPDF's HTML-rendering, embedded-JavaScript and form features; both tools draw vector sheets only (text, lines, one optional logo image) and call none of them, so this closes an audit finding rather than a reachable hole.
- Output verified identical, not assumed. Every PDF the suite can produce was generated before and after the upgrade — from the dev server and again from the production bundle — and compared: PiperISO Letter and 11x17, single- and multi-sheet, with and without a title-block logo; PiperSTR for both CSA standard details; the PiperEXJ GA sheet and EJ design package; and the Report Manager print view. Page count, page size (MediaBox), every text string and its position, and a rasterized pixel comparison of every page all match. Text carrying "&" and the non-WinAnsi characters the exporters clamp (●, ≤) is unchanged.
- One behavior difference found and fixed: logo file size. jsPDF 3 and later decode every PNG and, by default, embed the raw pixels; 2.x passed an opaque PNG's compressed data straight through. Left alone, a 1600-pixel-wide PNG title-block logo would have grown a PiperISO PDF from about 79 KB to 3.4 MB. The exporter now asks jsPDF to deflate the image, which restores the old size (83 KB) and also shrinks transparent PNG logos, which 2.x had always stored raw (4.6 MB → 101 KB for the same test image). Rendering is pixel-identical across RGB, RGBA, palette, grayscale and JPEG logos.
- SheetJS (xlsx) 0.18.5 → 0.20.3, installed from the SheetJS CDN. The npm registry copy of xlsx stopped at 0.18.5 and carries two unpatched advisories (prototype pollution, regular-expression denial of service) in its file-parsing code; SheetJS publishes fixed builds only from its own CDN, so the dependency is pinned to that tarball and integrity-hashed in the lockfile. The app only ever writes workbooks — it never parses one — so the advisories were not reachable. The PiperISO 7-tab Excel export (BOM, Cut List, Weld TQC, Supports, Quote, Datasheet, Revisions) is byte-for-byte identical before and after.
- hono 4.12.27 → 4.13.8 and @hono/node-server 1.19.14 → 1.19.17 in the development-only API server, which is not deployed.
- Production dependency audit: 5 advisories (1 critical, 1 high, 3 moderate) → 0.
- New unit tests run the real libraries instead of stand-ins: PiperISO and PiperSTR PDFs are generated with the shipped jsPDF and read back (page count, the custom landscape page size on every sheet, WinAnsi text, the bold face, the logo embedded once and deflated), the workbook is written with the shipped SheetJS and read back, and a version floor fails the suite if xlsx ever falls back to the registry build.
2026-09-19 — Dry-run findings: numeric entry, ASSUMED defaults, PiperBRC/PiperEXJ corrections
One input-handling defect that could change a calculated number, plus eight display and sample-data corrections. No engine formula changed; every fixture is unchanged and green.
- Numeric entry no longer drops a trailing zero mid-typing (all tools). Typing
0.102into any numeric field stored 0.12: the shared input re-rendered the box from the parsed number after each keystroke, so "0.10" was redrawn as "0.1" and the next digit landed after it. In PiperOCC that turned SDS 0.102 into 0.12 and overstated the seismic force by 18 %. The field now keeps exactly what was typed for as long as it still means the value being computed ("0.10", "1.050", "1e-3" all survive), and still yields to a value set from outside the field (autofill, preset, import). Affected module ids: none — the defect was in the shared input component (useNumberDraft/NumberField, also the PiperEXJ and PiperSTR table cells), upstream of every engine. Locked bye2e/dry-run-findings.spec.ts(#1), which types the value key by key and checks the result tile. - PiperOCC marks untouched defaults ASSUMED. Every numeric input starts as a tool default that produces a plausible load. Each now carries an ASSUMED badge until a value is typed or the badge is clicked to accept the default, the results pane lists what is still assumed, and that list is written into the Report Manager entry (an input row and the first warning) and into the PiperBRC handoff.
- PiperBRC prints the Cp delta to coefficient precision. Vendor Cp 0.036 against project Cp 0.051 showed a delta of "0" beside a warning that they differ; it now reads "+0.015 (project − vendor)". The two deltas are also captured to the Report Manager.
- PiperBRC reference-tool chip. The banner image is replaced by the owner-supplied trimmed mark with the tool named in plain text.
- PiperEXJ sample data is fictional and round. The pre-filled metallic and non-metallic samples no longer name a real manufacturer, drawing or catalog style, the NPS 8 sample no longer carries an 18 in bellows, and the material values are obviously not tabulated ones. Both samples still PASS, the results list says sample data is loaded, and a browser that had persisted the old sample untouched is moved to the new one (edited work is kept).
- PiperEXJ result notes are listed once, not once per movement condition; a note that applies to only some conditions names them. The same list feeds the Report Manager entry.
- PiperEXJ usage label reads Σ(n/N). The tile's uppercase styling had turned applied-over-allowable cycles into "N/N".
- PiperEXJ titleblock date and input pane. The date was saved with the rest of the design and so froze on the day the tool was first opened; it now follows today (local calendar date) until a date is typed. The wide load-condition table scrolls inside its own frame instead of making the whole input pane scroll sideways.
- Visible confirmations, and the PiperOCC → PiperBRC load basis. "Send load basis to PiperBRC", "Export DXF" and both "Add to Report Manager" buttons now raise an announced confirmation that stays long enough to read. The load-basis confirmation offers "Open PiperBRC", which imports the seismic force on arrival; opened on its own, PiperBRC shows the waiting load basis (edition, forces, location, time sent) with a one-click import.
2026-09-19 — PiperSTR report prints E, electrode strength and f'c in full
Report-display fix. No calculation changed: the engine reads the numeric inputs, never the printed strings, so every ratio, reaction and verdict in an affected report was already correct. Every fixture is unchanged and green.
- Whole-number values ending in zero were truncated in the PiperSTR report. The report's number formatter dropped trailing zeros even when the value had no decimal point, so it ate the integer's own zeros. On the default CSA Type 1 model the Design Basis table read "Elastic modulus E (ksi) 29" and "Electrode FEXX (ksi) 7", and Assembly Geometry read "E7XX" and "f'c 4 psi". They now read 29000, 70, E70XX and f'c 4000 psi. Both outputs were affected — the Design Summary PDF and the Report Manager document (its flat summary rows included) — because they share the formatter. Only the three values printed to zero decimal places were exposed: E, the electrode strength FEXX (every standard electrode, E60XX to E110XX, is a multiple of ten) and the concrete strength f'c. Values printed with decimals (loads, reactions, demands, capacities, ratios) were never affected.
- A value that rounds to zero prints "0". The same formatter printed a tiny negative (−0.0001 at three places) as "-0", and at zero places as a bare "-", which is the report's placeholder for a missing value.
- A PiperSTR report captured or exported before this date may carry the truncated strings. Re-capture or re-export to correct the printed values; the design itself does not need to be re-run.
Affected module ids: none — the defect was in the report formatter (apps/web/src/tools/piperstr/exporters.js), downstream of the engine. Locked by apps/web/src/tools/piperstr/test/report-format.test.js (the formatter directly, plus the default model through the real engine into the Report Manager document, the flat entry and the PDF draw calls, across every standard electrode and f'c value) and by e2e/piperstr.spec.ts ("the captured document prints E, FEXX, the electrode and f'c in full").
2026-09-13 — Reference-tool buttons in PiperOCC and PiperBRC
UI-only release; no calculation behavior changes.
- PiperOCC opens the ASCE Hazard Tool from the input pane. From the owner's mock-up, the rail now has a "Location (Address, LAT/LONG)" field directly under the ASCE edition, and beside it an ASCE-logo button that opens ascehazardtool.org in a new tab so the site's wind and seismic map values can be looked up for that location and entered (and cited) here. Nothing is fetched from ASCE; the tool still embeds no maps, figures or tables. The location text travels with the load basis — it is a row on the Report Manager entry and a field of the PiperBRC handoff.
- PiperBRC opens ASC SeisBrace® from the reconciliation section. The "SeisBrace reconciliation" heading now carries an ASC SeisBrace button that opens seisbrace.com (ASC Engineered Solutions' free seismic bracing tool) in a new tab, next to the existing "Import SeisBrace PDF" control that reads its report back in.
- Both buttons are plain links (new tab,
noopener), so middle-click and copy-link work and the vendor page never gets a handle on the app window. The vendor marks are shown for identification only. The Playwright suite stubs both vendor origins and asserts the popup actually opens at the expected URL, that the app stays put, and that the location round-trips into the report entry and the handoff.
2026-09-13 — PiperHGR, PiperPSV, PiperSIF and PiperOCC get their own marks
UI-only release; no calculation behavior changes.
- PiperHGR no longer borrows the Pipe Supports A-frame. Its icon is now a variable-spring hanger in elevation, from the owner's mark: beam clip at the top with the rod through it, the spring coil drawn as one red zigzag on the rod, and the supported pipe as a ring underneath. It is a 24-grid, stroke-2 mark in the existing icon language (apps/web/src/components/icons.tsx) and appears everywhere the tool is listed in-app — the launcher tile, the Tools menu and the pill bar. The free Pipe Supports line keeps the A-frame, so the two no longer share a symbol. An unused placeholder hanger mark from the July icon set was retired at the same time.
- PiperPSV and PiperSIF likewise. PiperPSV had borrowed the General toolbox; its icon is now an angle relief valve from the owner's mark — inlet riser with an end cap, the two-triangle valve body in red, outlet running right to an end cap. PiperSIF had borrowed the dataset-table glyph; its icon is now a tee with end caps on the run and the branch, and the run/branch intersection the SIF describes drawn as a red ring. With these, every paid tool in the Tools menu carries a distinct mark, and the Tools menu e2e spec now asserts it.
- PiperOCC too, and the free Occasional mark turned right way up. PiperOCC had shared the Occasional icon. From the owner's mock it now carries the Occasional family — ground line, two supports, seismic trace — with the lateral demand drawn as a red double-headed arrow between trace and supports. The free Occasional mark itself was re-oriented to the same mock (ground at the bottom, trace above; it had been drawn inverted). With this, no two entries anywhere in the Tools menu share a mark, and the e2e spec asserts that across every group, not just the paid ones.
2026-09-12 — Hover-activated Tools menu, tier-star sweep, PiperBRC and PiperEXJ marks
UI-only release; no calculation behavior changes.
- Tools menu redesigned as a hover-activated, two-pane group flyout. The chrome-bar Tools button now opens on hover (and still toggles on click and keyboard for touch and assistive use). The left rail lists the toolset groups in tier order — Piping Codes, Piping Tools, Pro, Pro Plus, Ultimate, Setup (Settings, Help, Utilities) — with an Applications home row above them; hovering, focusing or tapping a group fills the right pane with that group's tools, so the whole catalog is browsable from one hover without a navigation. The pane opens on the group that owns the current route with that route highlighted. Esc closes and refocuses the trigger; arrow keys walk the rail and the tools. Below 640 px the panel anchors to the bar's full rail width instead of the button. Pinned by a new Playwright spec (e2e/tools-menu.spec.ts: group order, per-item tier stars, hover / click / keyboard activation, navigation, the paid-tool gate, outside-click close).
- Tier-star sweep. Every paid item in the app — the launcher tiles, the Tools menu, the pill bar, the upsell modal and the autofill pickers — was checked for its tier marker. One gap: the Report Manager row in the Tools menu had shipped without its Pro star since the menu was introduced; it now carries it, and the e2e spec asserts it. The crawler-facing catalog in the HTML shell marks tiers by section heading only, as before.
- PiperBRC and PiperEXJ get their own marks. PiperBRC no longer borrows the Pipe Supports A-frame: its icon is a four-way brace — riser in a two-band clamp with a strut to the structure on each side, from the owner's reference photo. PiperEXJ no longer borrows the General toolbox: its icon is an expansion joint in elevation — pipe stubs, end plates and the bellows convolutions as one red zigzag, from the owner's linework. Both are 24-grid, stroke-2 marks in the existing icon language (apps/web/src/components/icons.tsx).
2026-09-12 — PiperEXJ expansion joint design package
New paid-tool release (Pro Plus). Metallic bellows verification, non-metallic rubber-joint rating, movement equivalence, and anchor/guide loads are fixture-locked; no ASME, EJMA, or manufacturer table values are embedded beyond the coefficient/fatigue tables listed below — every other dimension, rating, and coefficient remains engineer-entered from the vendor bellows data sheet or the manufacturer's catalog.
- PiperEXJ — Expansion Joint Design Package (Pro Plus). Five calc-core modules.
ej.bellows-verifyverifies a vendor metallic bellows design (U-shaped unreinforced, reinforced, and toroidal forms) per ASME BPVC VIII-2-2025 §4.19, invoked by VIII-1-2025 Part UEB — pressure and deflection stresses, fatigue life, column/in-plane/squirm stability, test-pressure checks, spring rates, and thrust.ej.movement-equivalentconverts assembly movement to total equivalent axial displacement per convolution, both single-bellows (VIII-2-2025 4.19.8) and universal dual-bellows joints (EJMA 10th Ed. eq. (4-6)), including the cold-spring range.ej.rubber-ratingis a non-metallic elastomeric-joint concurrent-movement rating check — there is no code stress method for elastomeric joints, so it reproduces the Proco Concurrent Movement Calculator method, verified against report PR_232 (2026-09-12), pending Proco's written confirmation; rated values are entered per project from the maker's tables/BOM and nothing from Proco is embedded.ej.anchor-loadsderives main and intermediate anchor and guide loads per B31.3-2024 Appendix X X301.2.2 and B31.1-2024 ¶119.5.1, with EJMA "A Practical Guide to Expansion Joints" B-1.3/B-1.4.1 guide-spacing limits.ej.package-summarycollates the design-package manifest and enforces its traceability gate — cumulative fatigue usage Σ(nᵢ/Nᵢ) ≤ 1 per VIII-2 4.19.3.2(a) / EJMA 4.12.1.5, blocking package assembly on a missing edition or an uncited allowable. Fixtures:fixtures/ej-bellows-verify.json,fixtures/ej-movement-equivalent.json,fixtures/ej-rubber-rating.json,fixtures/ej-anchor-loads.json,fixtures/ej-package-summary.json(15 hand-derived cases). Verified by hand calculation, reconciliation against a Triad Bellows EJMA-10 sample sheet (S1, thrust, and Kax/Klat/Kang spring-rate proportions reproduce; the sheet's printed Nalw reflects an EJMA Figure 4.20 mean curve rather than the VIII-2 Table 4.19.6 design curve implemented here — recorded as a finding, not a fixture edit), and reconciliation against Proco report PR_232 for the rubber-joint rating check. - Embedded data. ASME BPVC VIII-2-2025 Tables 4.19.3/4.19.4/4.19.5 (Cp/Cf/Cd polynomial coefficients) and Tables 4.19.6/4.19.8/4.19.11 (allowable-cycle fatigue constants, USC units); Table 4.19.10's B1/B2/B3 rational functions are implemented as code, not a table lookup. Derived catalogs (U.S. Bellows Expansion Joint Catalog, 2nd Ed.): single-joint ratings and spring rates (pp. 45–75, 237 rows NPS 3–156), stainless 85 psig ratings (p. 76, 35 rows), and the guide-spacing table (p. 27).
- Outputs. Calculation report captured into Report Manager; GA sheet PDF (pdf-lib, titleblocked) with a DXF twin; merged design package PDF (cover + report + GA + engineer-selected vendor-appendix pages from the browser-local source store, 25 MB client-side guard) — the same submittal posture as PiperHGR.
- UI fix. PiperOCC and PiperBRC tool-mode layouts no longer split the screen in thirds between header, workspace and status strip (
styles.css.tool-fullbleed > .piper-tool-head, .tool-fullbleed > .tool-status { flex: 0 0 auto }), matching PiperFLG.
2026-09-12 — PiperOCC, PiperBRC and configured PiperHGR submittals
New paid-tool release. The ASCE and brace engines are fixture-locked; no ASCE, MSS, or manufacturer table values are embedded. Map values, component factors, capacities, spacing limits, and their citations remain engineer-entered.
- PiperOCC — ASCE Site Hazards (Pro Plus).
aux.asce-site-hazardsmakes ASCE/SEI 7-10, 7-16, and 7-22 selection explicit for static wind and nonstructural piping-component seismic demand, alongside an explicit ASME B31.1-2024 or B31.3-2024 piping basis. It imports, plots, and re-exports response-spectrum CSV values without discarding the zero-period point, and hands a local, source-cited static-load basis to PiperBRC. Fixtures:fixtures/asce-site-hazards.json. - PiperBRC — Pipe Brace Demand & Selection (Pro Plus; DXF in Ultimate).
supports.pipe-bracescreens a rigid lateral or longitudinal brace by axial geometry, vertical reaction, 30 degree minimum brace angle, L/r, and user-entered capacity and MSS SP-127-2014a spacing checks. Local SeisBrace PDF text import is a reconciliation aid only; it does not treat an imported vendor result as the design basis. DXF export uses PiperISO's ASCII DXF approach. No DWG generation is included. Fixtures:fixtures/pipe-brace.json. - PiperHGR configured submittals (Pro Plus). The existing URL remains
/ptp-support-tool/, now built as a Vite entry. Its 3D assembly workspace uses a white background and a persisted, keyboard-operable vertical divider. A complete configured PDF starts with the assembly datasheet and BOM, then appends one configured record and only the engineer-selected original PDF pages for every BOM item. Source PDFs remain in browser IndexedDB; the v3.pcpproject records source label, hash, selected pages and identity but never silently redistributes a catalog PDF. A package cannot be created if any BOM component lacks selected source pages.
2026-09-12 — Governing code on every card and report, deliberate edition choices, checkout recovery, trial-offer copy
Suite release from the 2026-09-11 revenue and acquisition re-audit. No engine equation or fixture changed; two cards now refuse to compute until an edition choice is made, which changes what a fresh card shows (an instruction instead of a defaulted number).
- Governing code / edition on every calculator card. Each card carries a *Governing code* line under its description stating the code, edition and paragraph/table its engine implements and which values are embedded versus user-supplied (e.g. *ASME B31.3-2024 ¶304.1.2 eq. (3a) — equation form; S from Table A-1C, E from Table A-3 / 302.3.4-1 / 302.3.3-1, W from Table 302.3.5-1, Y from Table 304.1.1-1 — 2024 tables when autofilled, else user-supplied*). Report capture prints it as the first input row, *Governing code / edition*, so no captured number appears without its edition. Where an engine's edition is not embedded, the line says so and defers to the project's code of record.
- Design basis on the report. The Report Manager titleblock gained a Design Basis block — code of record (with edition), allowable-stress source, material / grade / product form, design temperature, units, load case(s), assumptions — printed under the titleblock on every report. Blank fields print *— not stated —* rather than an empty cell. Older
.pcpfiles open unchanged (the fields are optional). - Fatigue factor: no default edition. The *Fatigue Factor & Equivalent Cycles* card (
piping.fatigue-factor) used to open on the legacy form (f = 6·N^(−0.2), Σ Ni·ri⁵). It now opens on a placeholder and reports an instruction until the code of record is chosen: B31.3-2022 and later (f = 20·N^(−0.333) ≤ fm, Σ Ni·ri³, ¶302.3.5(d) eqs. (1c)/(1d)) or B31.3-2020 and earlier / every B31.1 edition. The engine and its fixture (fixtures/fatigue-factor.json) are unchanged; only the card's default is. - Displacement stress range: SIF source is a deliberate choice. The *Displacement Stress Range (319.4.4)* card (
piping.displacement-stress) now requires the source of ii / io — ASME B31J-2023 Table 1-1, the retired Appendix D closed forms (B31.3-2018 and earlier / B31.1-2022 and earlier), or the flexibility analysis — and prints the choice as a result row. B31.3 deleted Appendix D in the 2020 edition and B31.1 in 2024; the two factor sets are not equated. The card's basis line also states that the axial term Sa (in the SE equation since B31.3-2016) is taken as zero. - Checkout recovery. A Checkout return now stores its session reference on the device before verifying, retries transient failures in page (0 / 1.5 / 4 s), keeps the reference across reloads and retries it on every launch until Stripe confirms it, and shows a persistent banner with *Retry now* instead of a vanishing "refresh in a minute". Signing in links a still-pending reference to the account (link-purchase now accepts the card-less trial's
no_payment_requiredstatus, as the webhook and verify-checkout already did). - Back to the calculator after checkout. Checkout carries the originating hash route (
return_to, validated on both sides), so success and cancel both land on the calculator the buyer left, with the unlocked action named. - Trial offer copy. The pricing card, the PiperFLG product page and its FAQ said a card was required; the checkout has been card-less since 2026-09-09 and the pricing FAQ already said so. All surfaces now say no card is needed to start; the build derives the card line from create-checkout's
payment_method_collectionsetting and fails on any surface that contradicts it, and the browser suite asserts the rendered pages. - Activation funnel events.
checkout_session_created,checkout_create_failed,checkout_return,trial_verified,purchase_verified(plus GA4purchasefor paid),checkout_verify_pending,calc_result(first own-input recompute per card),report_captureandreport_export, each stampedfirst_in_session.begin_checkoutis unchanged and still measures intent. - Browser journey suite (
e2e/checkout-journey.spec.ts): anonymous card-less trial → return → entitlement → back on the calculator → first captured output → exported report; delayed verification (failed verify, reload, retry, later launch); cancellation; account link of a pending trial; lapsed-subscription downgrade; trial-copy on the rendered pages. Stripe is mocked at the browser's network edge only.
2026-09-11 — Five B31.1 FAQ pages, the B31 load-case guide, content-audit corrections, homepage footer and favicon
Content and site-surface release. No calculation behavior changes in this entry; the two engine changes the same audit produced are recorded in their own sections below (welding-tee SIF base entry; fatigue factor 2022+ form).
- Five B31.1-2024 FAQ pages — a new page type. Code topics without a calculator of their own had no home on the site: the /faq/ hub was derived purely from the calculators' FAQ arrays. Stand-alone /faq/ pages now exist (FAQPage + BreadcrumbList structured data, a governing-paragraphs table, curated related links validated against built paths, grouped on the hub under *Power Piping — ASME B31.1*): leak test pressure (¶137.3, ¶137.4.5, ¶137.5.5, ¶102.3.3(b), ¶137.8); stress intensification factors (¶104.8.1–.4, Figure 104.8-1, ¶119.7.3, the Appendix D deletion); safety valve reaction forces (¶101.5.5, ¶122.6, Nonmandatory Appendix II); pipe support spacing (¶121.5, Table 121.5-1 general notes); occasional loads (¶104.8.2 k = 1.15 / 1.2, ¶102.3.3, ¶101.5). Every clause was read from the 2024 text before it was cited; no table values are reproduced.
- New guide — Load Cases: ASME B31 Flexibility (Stress) Analysis Requirements. The SUS / OCC / EXP / operating / installed / test case set for B31.1 and B31.3, ASCE 7 wind (Eq. 26.10-1 → lb/ft) and Chapter 13 seismic (Fp, vertical ±0.2·SDS·Wp, §13.3.2 anchor motion) applied to a pipe model, the B31E overlay, relief and surge cases, and a stress-program case-list checklist.
- About page. Sector table refreshed with recent stress work — reheat valve replacement, a steam-crossover shutdown, an oilseed-processing plant, an FRP ferric-chloride seismic scope, API 618 compressor-piping qualification — plant type and scope only, no client names.
- Content audit — 26 confirmed corrections across the landing pages, guides and trust pages (18 reviewers, two skeptic lenses per critical or high finding, then hand re-verification against the licensed text). The ones that change engineering copy are listed next; the rest are wording.
- Audit — B31.3 leak test: the "ST/S ≤ 6.5 cap per note to Eq. (24)" is not in the 2016, 2022 or 2024 text. The calculator's cap is now described as a specification input; the Code's own ceilings are ¶345.2.1(a).
- Audit — B31.3 Eq. (17): the displacement-stress-range page shows the (|Sa| + Sb)² form and says the card takes Sa = 0. The fatigue-factor card is labelled as the legacy f = 6·N^(−0.2) form, with the 2022+ 20·N^(−0.333) form and cube rule now an engine option (entry below).
- Audit — Welding-tee SIF: h = 4.4·T/r2 is the Table D300 / Table D-1 Note (7) form; the unconditional entry is 3.1·T/r2, now an engine option (entry below). Copy states the (4.4/3.1)^(2/3) scaling.
- Audit — Miter FAQ: cut spacing is a B31J / Appendix D SIF question, not a ¶304.2.3 one; olets cite ¶304.3.2(a); Category M examination is 100% (M341.4(b)), not 20%.
- Audit — B31J guide: the B31.1 Appendix D timeline (2016 primary → 2022 retained with B31J permitted → 2024 deleted); the ¶320.1(b) sustained-index change described per B31J General Note (d), by component type.
- Audit — Multi-code comparison: the B31.1 expansion row is labelled as the 2016-and-earlier resultant form.
- Audit — Wind and seismic pages: B31.1-2024 ¶101.5.2 and ¶101.5.3 take the ASCE 7 loads without the ASD reduction — enter 1.0 on the occasional-load card for power piping.
- Audit — Equipment nozzle page: API 610 13th ed. §6.5; VIII-1 Appendix 2 ¶2-3 → VIII-2 Part 4.16; ¶319.4.2; the nozzle-check and PiperSIF tiers stated consistently (Pro Plus).
- Audit — B31.1 wall page: B31.9 has its own y-free equation (¶904.1.1); the cast-iron y value is no longer quoted.
- Audit — Trust sources: B16.5 hub-dimension provenance and the API 610 embedded-tables carve-out. BPE guide: dead-leg measurement errors run in opposite directions. Minor: 24% → 20% span note, MSS SP-58 title, loop-leg arithmetic, dent Q value, ¶302.4 citation, Appendix F-3 spelling.
- Homepage footer. The five B31.1 FAQ pages are listed under *Power Piping — B31.1* as a "B31.1 FAQ" group, and the build's footer drift guard and the browser smoke test now assert that every stand-alone FAQ page has a footer link, as they already did for every calculator. Trust, Legal and Connect share the far-right column; the site hubs (calculators, tools, guides, FAQ index, worked examples, pricing) ride one strip under the brand band; the seven columns are rebalanced to roughly even height; the tagline is shortened to one line.
- Favicon. The brand mark — ink square, red grid elbow — is redrawn at every size: SVG, 48 / 192 / 512 PNG, a maskable PWA icon, a real multi-resolution /favicon.ico at the site root (replacing the Netlify rewrite to the 512 PNG), and the Apple touch icon, which had been a mostly white legacy render and was the image Google's result page was showing. The service-worker cache version is bumped so returning installs drop the old marks.
2026-09-11 — Welding-tee SIF closed form: Table D300 base entry (3.1·T/r2) alongside the Note (7) form
The same content audit read the legacy Appendix D tables directly (B31.3-2016 Table D300; B31.1-2016 Table D-1) and found that piping.b31-sif computed the welding-tee flexibility characteristic as h = 4.4·T/r2 — which both tables carry only in Note (7), for a tee whose crotch radius rx ≥ Db/8 and crotch thickness Tc ≥ 1.5T. The unconditional entry for a B16.9 welding tee in both tables is h = 3.1·T/r2, and because io varies as h^(−2/3) it gives SIFs (4.4/3.1)^(2/3) = 1.263 times higher.
piping.b31-sifgains ateeForminput —"note7"(h = 4.4·T/r2; the default when omitted, so every recorded input and the PVP-selftest fixture case compute exactly as before) or"base"(h = 3.1·T/r2). Ignored for elbows. The output gainsform, a report-ready statement of the entry applied (SIF_FORM_LABEL), and every Note (7) result now carries a warning naming its geometric condition. The default was deliberately left on Note (7) pending the owner's call; switching it is a one-line change with a fixture update.- Fixture
b31-sif.json— two cases added: the base entry for the NPS 6 Sch 40 tee (h = 0.27360, io = 2.13549, ii = 1.85162; hand-derived from the licensed table text) and the Note (7) form named explicitly (must equal the default). - The closed-form cards were retired from the UI on 2026-08-19 (B31J-2023 via PiperSIF is the current factor source), so the option is reached through the batch runner and the API tier; the two landing pages (welding-tee SIF, B31.3 SIF & flexibility factors) document both forms, and the welding-tee page publishes the base entry as a second fixture-locked worked example.
2026-09-11 — Fatigue factor: B31.3-2022+ equation form, cube-rule equivalent cycles, 0.15 floor
The site-wide content audit of 2026-09-11 confirmed against the licensed text that piping.fatigue-factor implemented only the pre-2022 B31.3 form — f = 6·N^(−0.2) with fifth-power equivalent cycles — which is also the form every B31.1 edition uses (¶102.3.2(b) eq. (1C) and eq. (2)). ASME B31.3-2022 and 2024 ¶302.3.5(d) changed both: eq. (1c) is f = 20·N^(−0.333) ≤ fm, with fm = 1.2 for ferrous materials of SMTS ≤ 517 MPa (75 ksi) at metal temperatures ≤ 371 °C (700 °F) and 1.0 otherwise, and eq. (1d) weights each partial range by the cube of its stress ratio, N = NE + Σ ri³·Ni. The two forms cross near N ≈ 7,000 and diverge materially above 10⁵ cycles.
piping.fatigue-factorgains an explicitequationinput —"legacy"(the existing form; the default when omitted, so every recorded input and the two PVP-selftest fixture cases compute exactly as before) or"b313-2022"(the 2022+ form with the cube rule). The output gainsequation, a report-ready statement of the form applied (FATIGUE_EQUATION_LABEL), so an f value never travels unlabeled. Both forms now apply the code minimum f = 0.15 (footnote to ¶302.3.5(d)) with a warning when it engages; the former "N > 2e6" advisory, which paraphrased a limit the current editions do not state, is retired. A second warning fires when the legacy form is run with a cap above 1.0, since B31.1 caps f at 1.0.- Fixture
fatigue-factor.json— four cases added: the legacy form named explicitly (must equal the default), and three 2022+ cases hand-derived from the 2024 text: f(22,500) = 0.71081 at fm = 1.2; 1,000 full cycles + 8,000 at half range → NE = 2,000 and f = 1.59143 capped at 1.2; N = 7,000 → 1.04861 capped at 1.0. Verified: hand calculation. - Fatigue line card — a "f equation (code of record)" picker whose option text is the edition statement, captured verbatim into the report; the cap field is relabelled as fm for the 2022+ form.
- Landing copy: the B31.3 displacement-stress-range FAQ now points at the picker instead of telling the reader to compute the 2022+ value by hand.
2026-09-10 — PiperSTR: pipe-frame horizontal loads reach the column base; "lateral load at top" retired; cloud designs; dock divider
Calculation behavior changed in structural.support-assembly (analyzeAssembly), locked by support-assembly.test.ts (13 → 18 cases). Every PiperSTR result that carries a horizontal pipe load moves; a support carrying vertical load only is unchanged.
- Horizontal pipe loads are defined in the pipe's frame and carried to the base with their elevation lever.
transverseis the load across the pipe (guide / lateral) andlongitudinalthe load along it (friction, line stop, anchor). Pipes cross the arm at 90°, so a transverse load acts along the arm — arm axial force, in-plane column moment T·EL — and a longitudinal load acts across it — arm weak-axis moment L·x, out-of-plane column moment L·EL, column torsion L·x. Before this the two fields were documented relative to the arm,transverseproduced weak-axis arm bending and column shear only, and neither component ever overturned the column: the CSA Type 1 default (0.45 kip of guide load at EL 96 in) reported a base moment of 36.6 kip·in; it now reports 79.8 kip·in (36.6 gravity + 43.2 from the guide loads). Horizontal loads combine as magnitudes — none is allowed to relieve another. Verified: hand statics on one pipe (1.0 kip transverse at EL 96 → 105.6 kip·in in plane; 0.5 kip longitudinal at offset 8 → 48 kip·in out of plane and 4 kip·in of torsion).
- The "Lateral load at top" input is retired from the tool. The lateral load on the column is derived from the pipe loads above and shown read-only in the Column section (
output.lateral). The engine still honourslateralLoadin an older payload — wind or seismic on the support steel itself — so saved numbers reproduce.
- The out-of-plane moment reaches the base stages as the elastic superposition M_eq = Mx + My·(N/B) about the plate's N axis — exact for the corner anchor of a four-anchor pattern (Mx/2sN + My/2sB) and for the corner bearing pressure of a rectangular area, conservative otherwise. Applied with the anchor spacings for the base plate / anchorage stage, the pier plan dimensions for the pier stage, and d/bf for the column-to-base weld. Column torsion Σ L·x is reported in the base reactions and named in a warning; AISC 360 H3 is not checked.
- Column shear is split into its in-plane (Vx) and out-of-plane (Vy) components for the AISC G checks instead of one resultant on the major axis; the arm sees the longitudinal component as minor-axis shear (Vy) as well, and its weld takes both horizontal components as one parallel shear resultant (no directional increase on them — the conservative side).
- New outputs:
baseReactions.momentY,baseReactions.torsion,output.lateral = { transverse, longitudinal }. Report Manager entries and the Design Summary PDF print all of them, plus a "Load Frame" note stating the convention.
- Tool (no further calculation change): a Longitudinal (kip) field on every pipe row; the remove-pipe button is a small red ×; the input dock takes the PiperISO divider (drag, ← → / Home, double-click reset, hide/show chevron, persisted per browser); File ▾ saves the design to the cloud (
piperstr_projects— owner-only RLS, additive migration inservices/supabase/piperstr_projects.sql, applied 2026-09-10) and reopens it later. Inputs only are stored: results re-derive on open, so a reopened design edits, re-saves and captures into the Report Manager exactly like a fresh one.
2026-09-10 — Report capture names what was picked; schedule verdict on the wall-thickness cards; picker labels; PiperISO dock divider
Found while recording the B31.3 calculator videos. No engine, module id, or fixture value changes — every number a calculator produced yesterday it produces today. What changed is what the sheet says and what the screen shows.
- Report capture prints the picked row, not its key. "Add to report" scraped each dropdown's internal value — the NPS list index (
11), the material row id (Table A-1C-33-6), the W/Y grid cell (0-0) — so a reviewer could not tell which material, product form, or table row an S, W, or Y came from. The capture now records the option text the engineer saw ("NPS 6 — OD 6.625″", "A106 B", "Ferritic steels @ ≤900°F — Y=0.4") and carries each picker's citation line into the sheet as its own *source* row ("ASME B31.3-2024, Table A-1C — Line 33 · S(450°F) = 19.10 ksi (interpolated 400–500°F) · …"). An untouched picker no longer prints its placeholder. This is one change in the shared capture, so it covers every calculator line — the B31.1 E/y pickers and the Building line's temperature column included.
- Schedule verdict on the four wall-thickness cards (B31.3, B31.1, Building & HVAC, Pipeline). Two new result rows name the lightest B36.10M / B36.19M schedule at the entered OD whose nominal wall covers the order thickness (tn on the pipeline card, which the pipeline codes apply to nominal wall directly), and the next-lighter schedule that does not — the Sch 40 vs 80 check a reviewer makes by hand. A pure table lookup on the existing output; the order thickness already carries the allowances and the mill gross-up. Locked by
apps/web/src/lib/pipe-dimensions.test.tsand the browser smoke test on the B31.3 card's default case (NPS 6 @ 2000 psi, c = 1/16 in, 12.5% mill: order t 0.435 in → Sch 120 at 0.562 in is the lightest pass; XS (80) at 0.432 in misses by 0.003 in).
- Picker labels. Coefficient Y/y columns now print the tables' band semantics — "≤900°F" for the "900 and below" column, "≥1250°F" for "1,250 and above" (Tables 304.1.1-1 and 104.1.2-1) — so a 450°F design reads as the row it is. The B31.3 quality-factor picker gains a seamless pipe/tube row, Ej = 1.00, cited to Table A-3 (the per-specification basic factor table in the 2024 edition; the picker's label had named the pre-2022 "A-1B", which this edition does not contain), and the B31.1 picker gains the matching Appendix A seamless line (E = 1.00, the "E or F" column already embedded with the allowable-stress rows). Values unchanged; only labels and one definitional row added.
- Picker/card start state. Every card that mounts the pipe-size picker now seeds its OD/wall from the same B36.10 row the picker starts on and cites it from the first paint. The Allowable Pressure card opens on NPS 6 STD (6.625 × 0.280) instead of NPS 6 selected over NPS 8 numbers; six more cards (pipeline allowable pressure, bend thickness, branch header, B31.1 wall, building wall, steel span, trapeze group A) had the same split.
- PiperISO. The left input dock gets a drag-to-resize divider (keyboard ← → / Home, double-click to reset) and a hide/show chevron, persisted per browser — the PiperSTR rail pattern.
2026-09-01 — BPE fitting-dimension lookup: registered engine, fixture, landing page
The ASME BPE Part DT-4.1 fitting-dimension card has shipped on the BPE line since 2026-07-04, reading the bpe-fitting-dimensions dataset directly. It was the one BPE card with no registered calculator, no fixture and no public URL. This promotes it to a first-class method.
- New module
bpe.fitting-dimensions(bpeFittingDimensions) locked bybpe-fitting-dimensions.json(9 cases). It returns the tabulated nominal dimensions for a fitting type and size — elbows DT-4.1.1-1/-3/-4/-6, tees and crosses DT-4.1.2-1, instrument tees DT-4.1.2-10, reducers DT-4.1.3-1, ferrules DT-4.1.4-1, solid end caps DT-4.1.5-2 — and derives two geometric terms: the weld-elbow tangent A − R·tan(θ/2) (the straight length from the weld end to the bend tangent point; A − R for a 90° elbow) and the eccentric-reducer centreline offset (OD_large − OD_small)/2, using BPE tube OD = nominal size. An unlisted size returnslisted: 0, status fail, naming the tabulated sizes. Verified: hand calculation (2 in 90°: 4.75 − 3.0 = 1.75; 6 in 45°: 6.25 − 9.0·tan 22.5° = 2.522; 2 × 1 eccentric: 0.5).
- Label correction, no value changed. The dataset's 90° and 45° weld-elbow dimension A was labelled "Face-to-tangent" in the card; it is the center-to-end dimension, consistent with the tee row's "Center-to-end A" and with the 45° and 90° columns sharing one tangent length once R·tan(θ/2) is removed. The label now reads "Center-to-end A (in)". Every tabulated value is unchanged and the dataset tests are untouched.
- New page
/calculators/bpe-fitting-dimensions/with method, limitations, four fixture-verified worked examples and FAQ; the eleventh BPE-line page (calculator pages 48 → 49).
2026-09-01 — Six BPE landing pages (material, surface, weld, polymer)
Content-only. Six BPE calculation engines that have shipped since 2026-07-04 had no public URL — they were reachable in the app and invisible to search. This adds the landing page, sample report and worked examples for each, closing the last gap between what the BPE line computes and what it publishes.
- No calculation behavior changed. The six engines, their fixtures and their acceptance thresholds are untouched; the "Method last updated" stamp on each new page therefore still reads 2026-07-04, the date the engines shipped. The module ids are named in plain text below rather than in backticks precisely so this entry cannot bump that stamp — a page shipping is not a method changing.
- New pages (
scripts/seo/content/bpe.mjs), each with method, limitations, fixture-verified worked examples and FAQ: PREN / alloy classification (bpe.pre-pren, App. F-3); ferrite and weldability (bpe.ferrite-number, WRC-1992 equivalents, the BN2 discriminant and the MM-5.2.1.1(a) autogenous sulfur window); Ra surface finish (bpe.ra-finish, SF designations); electropolish removal and passivation acceptance (bpe.ep-passivation, App. H / App. E); tube weld acceptance (bpe.tube-weld-acceptance, Table MJ-8.4-1); and polymer thermal expansion (bpe.polymer-thermal-expansion, PM-4.2.3).
- Every published number is fixture-locked. Each worked example is bound to a named case in the module's own fixture file and the build's drift guard fails if a displayed result does not round from a fixture value. Thirteen fixture cases across the six files back the thirteen worked examples.
- Data posture unchanged and stated on the pages. The WRC-1992 diagram plate, the SF grade-to-Ra mapping and the Table MJ-8.4-1 acceptance values are not embedded: each arrives as a user-supplied input read from the reader's own licensed copy, and each page says so in its Method section and its limitations. The pages state only what is embedded — the public closed forms — cited to clause.
- Six purpose-drawn diagrams (
scripts/seo/diagrams.mjs): a PREN band scale, the WRC-1992 equivalents plane with the sulfur window, a surface profile trace against a grade ceiling, an electropolished coupon section, the three MJ-8.4-1 weld discontinuities, and an anchored thermoplastic run. Thebpefamily default is a dead leg at a tee — correct for the L/d, slope and CIP cards and wrong for all six of these, so each is mapped explicitly in DIAGRAM_SLUG_OVERRIDES rather than falling back to it.
- Line placement. Five pages sit on the BPE line. Polymer thermal expansion is published on the Non-Metallic line because that is where its live card actually is, so the page's CTA lands on the calculator rather than a dead deep link; the page still cites BPE PM-4.2.3, which is its governing reference. FAMILY_ORDER's thermal-flexibility group was widened to cover the nonmetallic line so the page is not orphaned from the calculator index.
2026-08-31 — Flange Bolt-Up Sequence (General line)
New free calculator on the General line — the second tool out of the same r/pipefitter calculator thread that produced the trapeze tool: field crews tracing end-of-day flange leaks to bad tightening patterns, not torque values ("the sequence matters more than the number"). A phone-sized star-pattern chart by bolt count, with pass percentages for the crews that torque.
- Calculation behavior — new module
connections.bolt-sequence(packages/calc-core/src/connections/bolt-sequence.ts). Generates the legacy cross (star) tightening order for any even bolt count 4–68 by two rules: every bolt is followed by its diametric opposite (i → i + N/2), and pair leads are ordered by applying the same crossing recursively to the half-count, so consecutive pairs rotate quadrants. For 4, 8, 12, 16, 24 and 32 bolts the output is digit-for-digit the published chart on gasket manufacturers' assembly cards — pinned exactly inbolt-sequence.test.ts(15 tests: published charts, permutation and opposite-pair properties for every even count, quadrant rotation for every multiple of 4, torque splits, validation). Pass schedule: snug, then cross passes at editable ascending percentages (default 30 / 70 / 100, up to six), then always a final circular pass; an entered target torque (job spec / gasket sheet — deliberately never computed here) is split into per-pass wrench settings rounded to a tenth, unit label (ft·lb / N·m) passed through. Warnings on non-multiple-of-4 counts, counts above 48 (alternative-pattern advisory), and schedules that never reach 100%. No copyrighted table values embedded: the pattern and pass practice are standard bolted-joint assembly trade practice (ASME PCC-1 legacy-pattern guidance). Locked bypackages/calc-core/fixtures/bolt-sequence.json(9 cases; case 0 is the card's default 12-bolt state, case 1 the 200 ft·lb split 60/140/200) and ane2e/smoke.spec.tscase. - Site — General line card (after the trapeze card) with a live numbered SVG star chart (tightening step at each hole, red crossing path), the written order, and the pass table; landing page
/calculators/flange-bolt-tightening-sequence/with a purpose-drawn 8-bolt star diagram, a 4–32 bolt sequence chart table read at build time from the CI fixture file (one source of truth — a missing case fails the build), two fixture-locked worked examples, cross-links with the flange pages, and footer/General-line copy updated in the static shell.
2026-08-30 — Trapeze / Strongback Sizing (General line)
New free calculator on the General line, built from a working request in the r/pipefitter calculator thread (four 30" sch 10 cooling-tower headers on rod-hung back-to-back channel strongbacks): channel size, rod size and count, and maximum strongback spacing, in one pass.
- Calculation behavior — new module
structural.trapeze-hanger(packages/calc-core/src/structural/trapeze-hanger.ts). Rack load built from up to three pipe groups (annulus metal + contents weight) plus an extra lb/ft allowance; pipes laid across the rod-to-rod width at equal centres, heaviest nearest midspan (conservative for mixed racks); each rod-to-rod segment analysed as a simple span with exact point-load statics (Mmax under a load point, end-reaction shear, midspan deflection by superposition). The channel — back-to-back pair (half demand per channel, no composite action assumed) or single — runs through the existingstructural.aisc-memberAISC 360-22 ASD check with Lb = the rod-to-rod span and Cb = 1.0; auto-select sweeps the C then MC families ofaisc.shapes-v16lightest-first (candidates injected, so calc-core keeps no dataset dependency). Rod capacity on the classic coarse-thread root area 0.7854·(D − 1.3/n)² at an editable allowable (default 11.6 ksi — the B31.9 ¶921.2.2 / Table 921.2.2-1 practice basis of one-fifth of A36's 58 ksi minimum tensile; computed capacities reproduce the published 3/8"–1 1/4" table loads, and larger rods are flagged as beyond that table's range). Two rods take exact simple-span reactions; 3–4 rods take tributary width with a 1.25 interior-rod continuity factor. Maximum strongback spacing = min(weakest pipe's own span from the classic fixed-beam screening basis — 2,300 psi bending / 0.1 in sag, both editable — and the entered spacing divided by the worst hardware utilization, every demand being linear in spacing); the output names the governor. Every run carries the building-structure hand-off warning (bar joists / EOR sign-off) and a thin-wall bearing advisory below t/OD = 0.015. Verified by hand statics intrapeze-hanger.test.ts(root areas held to ±0.0012 in² of the published hanger-rod rows, exact reactions, hand LTB anchor for the C9X15 pick). Locked bypackages/calc-core/fixtures/trapeze-hanger.json(case 0 is the thread's rack: 1,579.7 lb/ft, C9X15 pair at 0.882, 1 1/8" rod at 0.983, spacing rod-governed at 10.18 ft) and thee2e/smoke.spec.tstrapeze case. - B36.10 size table extension —
apps/web/src/lib/pipe-dimensions.tsgains NPS 26–36 (appended, so every existing index is untouched; B36.19M stops at NPS 30, so only that size carries 5S/10S labels). The free Pipe Section Properties card and every PipeSizePicker card now reach large-OD sizes; no existing schedule value changed. - Site — General line card (first on the route), landing page
/calculators/pipe-trapeze-strongback-sizing/with a purpose-drawn trapeze diagram, cross-links with the support-spacing page, and footer/General-line copy updated in the static shell.
2026-08-29 — PiperISO 45° routing, equipment symbols, cloud-save fix; site accessibility and caching
PiperISO (owner redlines, PRJ-0001):
- 45° routing — the dock gains a signed Δ pad (N/S · E/W · UP/DN, stress-model element-delta convention: N/E/UP positive) that extrudes one compound-direction run per gesture, alongside the existing one-click axis buttons. Direction changes now insert the elbow the actual bend angle calls for: 45° and 90° are B16.9 catalog fittings; any other angle is drawn and flagged for review. The Fittings menu adds an explicit 45° elbow next to the 90°.
- Calculation behavior — new B16.9 45° LR elbow center-to-end column B in
asme-data.js(ELBOW_B45; NPS ≥ 4 equals the standard's 0.625 × NPS inches, smaller sizes transcribed with their manufacturing tangents — confirm-against- the-standard posture, same as the VALVE_FTF 600/900 note). Cut-list take-out at a 45° bend uses column B; 3D-radius 45s derive R·tan(22.5°) from the 3D column where A = R; non-catalog angles take out R·tan(θ/2) and carry a review flag. BOM rows name the angle (ELBOW 45° LR 4"). Existing drawings are untouched: a fitting with no angle field computes exactly the old 90° path. Locked byapps/web/src/tools/isodraft/test/isodraft.test.js(45°/3D/odd-angle take-outs, 45°-bend cut list and BOM naming) and thee2e/isodraft.spec.tsΔ-pad case. - Equipment symbols — pump, vessel, heat exchanger and nozzle now draw as recognizable single-line shapes (volute on a baseplate, vertical drum with a flanged side nozzle, shell with channel-end flange pair, flanged stub) instead of the diamond placeholder — identically on the canvas, the PDF sheet and the DXF (new EQUIPMENT layer), from one primitive source (
skeys.js). Pump and vessel stay sheet-vertical, like upright supports. BOM SKEY stays blank for equipment — they are tie-ins, not piping components. - Cloud save keeps the drawing open — the first save of a new drawing used to remount the editor blank and re-raise the project-info modal (the drawing survived only in the cloud row). Saving no longer remounts; opening a drawing remains the one deliberate remount. Regression-locked in
e2e/isodraft.spec.ts.
Site (content/infrastructure only; no other calculation behavior changed):
- Accessibility — the shared page shell's breadcrumb, topbar, footer and
<summary>targets were sized by their small fonts alone (~19–21 px) and failed the 24 px target-size minimum on every generated page; padding now grows the hit areas without changing the type. The /pricing/ trial line (--accenton white, 4.2:1) moves to--accent-deep(7.2:1) — the new color-contrast failure on the subscription cards. - Caching — content-hashed
/assets/*bundles (plus version-pinned/vendor/*and the font files) now shipCache-Control: public, max-age=31536000, immutablevia_headers; they had ridden the platform defaultmax-age=0since launch (flagged 2026-07-31). - /tools/pipe-stress-fea/ — the page
<title>no longer claims "in Browser": meshing and solving run on the managed solver worker, as the page itself discloses. Title now matches the h1. - /tools/relief-valve-sizing/ — the standard's own §5.6.3.2 worked example (the tool's default state, fixture
packages/calc-core/fixtures/ api520-sizing.json) now renders above the fold ahead of any CTA, so the calculator-intent visitor sees the computed case — A = 6.50573 in² — before the tier pitch.
2026-08-19 — Source policy, terms and homepage copy refresh
Content-only release; no calculation behavior changed and no module ids are affected.
/trust/sources§3 retitled Embedded standard data, in full — the complete inventory of embedded reference tables, each row naming the standard and edition, what ships embedded, and the tool that consumes it. §4 adds purchased codes and standards to the validation-source list: embedded standard data is cross-checked to the source documentation.- Homepage intro rewritten to state the suite's full code coverage rather than the original B31.1/B31.3/BPE subset: the B31 family (B31.1 power, B31.3 process, B31.4/B31.8/B31.11 pipelines, B31.5/B31.9 refrigeration and building services, B31.12 hydrogen), BPE hygienic design, BPVC Section VIII and App. 2 flange design, Section IX weld-metal A-Numbers, B31J-2023 SIFs and flexibility factors, B31E seismic, B31G remaining strength, B16.5 and B36.10 dimensional data, NM.1/NM.2 non-metallic catalogs, API 520/521 relief sizing, API 610/560/620/650/660/661 and NEMA SM-23 nozzle loads, WRC-107 shell stresses, AISC and ACI support-structure compliance in LRFD or ASD, ASCE 7 wind and occasional-load combinations, EJMA expansion joints, and ISO 14692 for FRP/GRP.
/legal/terms§6 simplified;/aboutlede widened to match. In-app Help, Settings and tool card descriptions re-worded so every surface states the same source policy: published equations are implemented in code, copyrighted table values are either embedded reference data cited to their table and line or values you supply from your own copy of the standard.
2026-08-18 — Section IX A-Numbers reference + §4.5.15 method-scope correction
qw442-a-numbers(embedded dataset) — ASME BPVC Section IX-2025 Table QW-442, the ferrous weld-metal A-number classification, as a Pro Plus reference card on the General line. Dual-verified transcription (independent blind pass, zero value disagreements). First slice of the §3.8 welding data service; F-numbers (QW-432) and the versioned P-number DB (QW/QB-422) phase in next.- Roadmap correction: VIII-2-2025 §4.5.15 is a method POINTER to WRC 537/297/STP-PT-074 — it does not codify the STP-PT-074 coefficient tables (Part 4.5 carries only Tables 4.5.1/4.5.2). The planned nozzle local-stress engine therefore depends on the STP-PT-074 / WRC coefficient sets and is deferred to a later phase. No shipped calculator is affected; the WRC-terms calculators (user-supplied curve values) remain the correct shipped surface for 4.5.15's method list.
2026-08-18 — PiperPSV v1: relief sizing, discharge reaction, scenario router (Ultimate)
New product line at #/psv (Ultimate; free tier unaffected — the route's tools never mount below the tier).
New calculation engines
psv.api520-sizing— API 520 Part I 10th Ed. orifice sizing as published equations: gas/vapor critical flow (Eq. 6, C per Eq. 12, Pcf per Eq. 5), subcritical flow (Eq. 16 with F2 per Eq. 22) — the regime is selected automatically from Pcf and reported; steam (Eq. 25) with the Napier correction (Eq. 27/28, valid to 3,200 psia); certified-valve liquid sizing (Eq. 32). Fluid properties (k, MW, Z), Table 11 C, KSH and Kv stay user-entered — the API 520 coefficient tables are not embedded. Fixtures include the standard's own §5.6.3.2 worked example (6.51 in²), reproduced to full precision (6.50573).psv.b311-reaction— ASME B31.1-2024 Nonmandatory App. II open-discharge reaction: exit state per II-2.2.1 (V1, P1 from stagnation enthalpy), F1 = ṁV1/gc + (P1 − Pa)A1 per II-2.3.1.1 with ṁ = 1.11 × stamped capacity and a user-supplied DLF (II-3.5.1.3). Hand-derived fixture.
New datasets
b311-appii-steam-constants(embedded dataset) — Table II-2.2.1-1 values of a and b with their printed applicability limits; autofills the reaction calculator via the steam-condition picker with the citation on the card.api521-scenario-index(derived, citation map) — the 26 overpressure contingencies of API 521 §4.4 with the governing section for each. Names and section numbers only: no relieving-rate guidance or standard text is embedded, and required relief loads remain the engineer's determination from their own copy of the standard.
Also on the route: the Section XIII device-type part guide (Parts 3–8 map; set-pressure/accumulation limits stay with the referencing code per XIII 2.3/2.4 — a per-referencing-code limits card follows once those rules pass the verification gate).
2026-08-18 — Material Property Autofill v1: B31.3/B31.1 allowable-stress first slice
The flagship Pro-tier picker: material line + design temperature autofills the allowable stress into the Process and Power calculators, interpolated per the tables' own rules, with the table and line number cited on the card and in the report. First-slice specs (the >90%-of-BOMs set): A53, A105, A106, A182, A193, A234, A312, A335 in the slice grades. Free tier keeps every hand-keyed input.
New datasets (served via getDataset(), citations included)
b313-allowable-stresses-2024— ASME B31.3-2024 Table A-1C first slice. Per-line: section, product form, spec/grade/UNS/class, size, P-No., note markers, min-temp, SMTS/SMYS, max temp, and S at each tabulated temperature with the table's italic markers carried per cell (italic = exceeds two-thirds of expected yield at temperature; bold italic = 90%-of-yield basis).b313-bolting-stresses-2024— Table A-4C bolting design stresses (A193 B7/B7M/B16 size-range lines).b311-allowable-stresses-2024— ASME B31.1-2024 App. A Tables A-1/A-2/A-3 first slice. Tabulated values are SE (joint efficiency/casting factor INCLUDED — the autofill sets Factor E to 1.0 in the same pick so S·E is never double-counted); italics = time-dependent (creep-governed) values, carried per cell and badged on autofill.b311-bolting-stresses-2024— Table A-10 bolting (B7/B7M/B16 by diameter).
New shared engine
stressAtTempinterpolation in @pcp/code-data-service — straight-line between tabulated columns, first-column verbatim at/below its temperature, hard stop (never extrapolate) above a line's last tabulated value or inside an untabulated gap, italic/creep flags propagate when either bracketing value is flagged. Fixture-covered (interpolate.test.ts).
Where it autofills
B31.3 wall thickness (S), B31.3 allowable pressure (S), displacement stress range (Sc and Sh, two pickers), sustained + occasional stress (Sh), B31.1 wall thickness (SE with E→1.0), B31.1 allowable pressure (SE with E→1.0).
Verified: deterministic font-aware extraction, two independent blind visual transcriptions of 600 dpi page rasterizations, per-cell adjudication, plus a page sweep for slice rows outside the extraction. /trust/sources §3 inventory updated in the same change.
2026-08-18 — Code-data expansion: B31J-2023 engine, factor pickers, MDMT tool, API nozzle presets, 2025-edition datasets
Embedded reference data expanded to ASME B31J-2023, B31.9-2025, B16.5-2025 (current edition), NM.1-2022, and the API nozzle-load tables (610 Tables 5a/5b · 660 Table 2 · 661 Table 4 + §7.1.10 · 560 Tables 7–10). Every dataset in this release was transcribed dual-blind from the printed standards with per-cell adjudication, and formula/sign ambiguities were settled against 600 dpi rasterizations of the printed pages. /trust/sources §3 carries the complete embedded-data inventory.
New calculation engines
piping.b31j-sif— ASME B31J-2023 Table 1-1 in full: bends/miters, all six branch-connection sketches, reducer, welds, flanges, threaded joints, with the Note (7) cap/floor rules, Table 1-2 stiffnesses, Table 1-3 flanged-end corrections, Note (4) pressure correction, and General Note (d) sustained factors. Verified: independent Python derivation of every fixture case (fixtures/b31j-sif.json); the 6-in sch 40 elbow reproduces the PVP-suite App D anchors exactly. The legacy App D card remains for checking pre-2020/2024 calculations.connections.api610-annexf— API 610 13th Ed. Annex F pump-nozzle criteria (F.1–F.11): per-nozzle screen, resolution to the pump center, interaction checks, and the vertical in-line principal-stress path. Verified: hand derivations recorded in fixtures/api610-annexf.json.vessel.ucs66-mdmt— VIII-1-2025 UCS-66 impact-test exemption: Table UCS-66 tabular lookup (curves A–D), coincident-ratio reduction (Figure UCS-66.1 reduction is a user-read, range-validated input — the 2025 edition prints it as a curve only, and no eyeballed curve values ship), UCS-66(b)(3)/(d) paths, and the UCS-68.2 PWHT credit (the 2025 designator of the legacy UCS-68(c) rule).aux.app2-flange-integralgainshubFactorMethod: "fit-4165"— the VIII-2-2025 Table 4.16.5 published curve-fit equations for F/V/f as a selectable alternative to the exact §2-7.6 constant chain (which stays the default; outputs unchanged unless selected). The two methods agree within curve-fit accuracy (~1%) and the module warns if they ever differ by more than 2%. Verified: fixtures/app2-flange-integral.json fit-4165 cases with independently derived expectations.
Calculation-affecting data correction
- Gasket factor correction (PiperFLG / App 2 tools): the "Flat metal jacketed, iron or soft steel" selection previously carried m = 3.5 / y = 8,000 psi — the table's MONEL line — instead of the iron/soft-steel line's m = 3.75 / y = 7,600 psi (VIII-2-2025 Table 4.16.1; identical in the legacy Table 2-5.1 lineage). Operating bolt loads computed with the old values were slightly unconservative (m low by 6.7%); seating loads slightly high. A new cross-check test now pins every curated gasket row to the VIII-2-2025 Table 4.16.1 dataset so a wrong-line copy cannot recur.
Reference data now embedded (paid-tier pickers; free tier keeps hand-keyed inputs everywhere)
- B31.3-2024 factor pickers: Ej (Table 302.3.4-1), Ec (302.3.3-1), W (302.3.5-1), Y (304.1.1-1).
- B31.1-2024: weld joint efficiency E (Table 102.4.3-1), y coefficients (104.1.2-1), suggested support spans (121.5-1).
- B31.9-2025: threaded-rod capacities (Table 921.2.2-1) and the Table I-1 allowable-stress library (79 material lines).
- B16.5-2025 pressure–temperature ratings (groups 1.1/2.1/2.2/2.3) as a current-edition selection beside the retained 2017 tables — 68 rating cells changed between editions, all in stainless groups 2.1/2.2.
- VIII-2-2025 Table 4.16.1 gasket factors (42 lines) as the single source for gasket m/y.
- VIII-1-2025 Table UCS-66 tabular values + Figure UCS-66 curve assignments.
- NM.1-2022: GSR, design factors, molded-fitting PR, and the Appendix IV Table IV-1 HDPE i/k factors.
- API nozzle-load presets: 610 Tables 5a/5b, 660 Table 2, 661 Table 4 with the §7.1.10 aggregate rules, 560 Tables 7–10.
2026-08-12 — Suite update: report documents in every paid tool, Pro Plus trial, three-tier packaging
Summary of tool development landed 2026-07-31 through 2026-08-12.
Tools and reports
- Report Manager v2: every Pro Plus / Ultimate tool now files its complete formatted output into the Report Manager as a navigable document — sections, tables, and a 3D snapshot of the model — instead of flat key/value pairs. Existing project files still load.
- PiperISO: full BOM / cut-list / weld-TQC / supports document with a 3D render; Letter and 11×17 PDF both in Export; click-to-select in the 3D view so edits no longer require toggling to 2D.
- PiperHGR files the complete submittal datasheet (selection data, elevation schematic, BOM, dimension tables). PiperFEA captures the solver's full ten-section report. PiperFLG captures all Appendix 2 factors, the EN 1591 screen, and the stress tables. PiperNOZ reports the six-component unity ratios with WRC terms and allowables.
- Tool GUI: shared tool-mode header chrome across the paid tools; governing-check guidance on failing PiperSTR stages; status strips wrap cleanly on phone widths.
- Demo videos: current full-pass demos are embedded on the tool pages, the PiperHGR page, and pricing; two superseded 2026-07-28 first-look demos (PiperISO modeling, PiperFEA) were retired from their pages.
Calculation record
structural.support-assembly— the CSA pipe-support preset was re-baselined (shipped 2026-08-10, recorded here). The original 16×16 pier with 9 in anchor spacing sat on the ACI 318-19 17.6.2.1.2 edge-clipping cliff, so the anchorage stage failed under any realistic load; the preset now uses a 24×24 pier, 8 in embedment, 15 in spacing, a 1.25 in base plate, and supplies a product-specific adhesive bond strength so the ACI 17.6.5 bond check runs. Equations unchanged — this is a preset-input change, verified at both the shipped default and realistic 8/10 kip loads.
Plans and access
- Pro Plus monthly carries a 30-day card-required free trial, one per customer.
- Three-tier packaging finalized — Pro ($2.99/mo), Pro Plus ($7.99/mo), Ultimate ($14.99/mo) — with annual plans repriced to two months free ($29 / $79 / $149) and cancellation copy that states exactly what happens at period end.
- Paid tools gate on arrival, not only on click.
Site and documentation
- Worked-example FAQ coverage extended across the calculator pages; internal linking between guides, tools, and calculators built out; full-text llms-full.txt published for AI/LLM consumption.
- Trust pages refreshed. The embedded-data inventory on /trust/sources remains the complete list of standard data that ships in the product.
2026-07-31 — B16.5 flange dimensions extended to Classes 400, 1500 and 2500
Closes the asymmetry between connections.b165-rating (all seven classes since 2026-07-24) and the dimensional table, which stopped at Classes 150/300/600/900 — the tool could rate a Class 1500 flange but not size one.
Added
connections.b165-dimensions(new fixtureb165-dimensions.json, 12 cases) — the dimension table, previously an exported helper outside the fixture gate, is now a registered, fixture-locked lookup.- Facing/drilling and B16.20 spiral-wound sealing-element rows for Classes 400, 1500 and 2500. Coverage follows the standard, not a uniform grid: Class 400 below NPS 4 uses Class 600 dimensions by direction of the standard, Class 2500 ends at NPS 12, and NPS 26–60 remains B16.47 and out of scope.
BOLT_ROOT_AREAextended through 3-1/2" for the new bolting. - Hub dimensions X and Y on all 43 new rows, so the Appendix 2 integral-flange path covers the new classes from day one.
Changed
- An unlisted NPS/class pair now fails with an explanatory warning naming the reason the combination is not a B16.5 flange.
Fixed
- Correction — Class 600 bolting, four sizes. Auditing all 112 rows against the standard turned up five wrong cells in the pre-existing Class 600 data:
| NPS | Field | Was | Now |
|---|---|---|---|
| 0.5 | bolt dia | 5/8" | 1/2" |
| 12 | bolt dia | 1-3/8" | 1-1/4" |
| 20 | number of bolts | 20 | 24 |
| 20 | bolt dia | 1-3/4" | 1-5/8" |
| 24 | bolt dia | 2" | 1-7/8" |
These reach the Appendix 2 bolting checks through Ab (actual bolt area). NPS 20 was the worst: oversized bolts and an undercount of them left Ab wrong by −9% overall — unconservative, a joint could have been shown adequate on bolt area when it was not. No other class was affected; every corrected cell satisfies the B16.5 para. 6.5 bolt-hole cross-check, and the fixture and unit suite lock the corrected values.
Verified: double-blind transcription of B16.5-2017 Mandatory Appendix II and B16.20-2017 Table SW-2.1-1 — 485 facing/drilling cells and 214 gasket cells re-extracted and diffed, 0 mismatches (that re-extraction pass is what caught the Class 600 defects). Hub X/Y cross-checked against three independent public reproductions, 43/43 rows agreeing, and all rows satisfy the geometric invariants (bore < X < flange OD, h = Y − t > 0, g1 ≥ g0). Bolt root areas are derived, not transcribed: π/4·(D − 1.299038/n)² reproduces all thirteen pre-existing entries exactly. Dimensional data should still be verified against the standard before use for construction.
2026-07-31 — PiperFLG pre-release audit fixes: |M| in the Kellogg term; App 2 2-8(a) hub cap
Two findings from the adversarial pre-release audit of aux.app2-flange-integral, both landed before the module shipped — no released number changes.
- Kellogg moment term now uses |M| (fixture
app2-flange-integral.json, new case). A moment's sign is an artifact of the analysis frame and can never relieve a flanged joint; previously a negative Mext lowered Peq below design pressure — unconservative. Restores parity withconnections.flange-equivalent-pressure, which has always taken |M|. Axial force stays signed (compression genuinely relieves). - Longitudinal-hub allowable caps at min(1.5·Sf, 2.5·Sn) per App 2 2-8(a) for hubs welded to pipe. New optional Sn inputs apply the cap; when absent the engine emits a standing warning naming the unchecked cap. The AutoPIPE parity fixture supplies Sn — the cap does not bind there, so every anchored expect is unchanged.
2026-07-31 — PiperFLG: Appendix 2 integral (weld-neck) flange design
New calculation. aux.app2-flange covers a loose ring without a hub and cannot analyse a weld-neck flange; aux.app2-flange-integral adds the integral/hubbed case and supersedes it for new work (the loose module stays registered and fixture-locked for the API tier and the batch runner).
New modules
aux.app2-flange-integral(fixtureapp2-flange-integral.json, 3 cases) — the full Appendix 2 sequence: gasket seating and load reaction diameter, bolt loads Wm1/Wm2 with Am against Ab, the Table 2-6 integral moment arms, the bolt-spacing correction Bsc, longitudinal-hub / radial / tangential stresses with both averages, the seating case at ambient allowables, and the App 2-14 rigidity index J.aux.app2-hub-factors(exercised through the module above plus 15 unit tests) — the §2-7.6 constant series C1…C37 → E1…E6 giving the tapered-hub factors F, V and f. Sourced from an open-source implementation and corroborated term-for-term against a published reproduction of the chain.
Two conventions this entry pins down
- π/4, not 0.785, in the hydrostatic end force — matching AutoPIPE and CAESAR II; the 0.05% gap shows up when cross-checking against either.
aux.app2-flangekeeps 0.785 and is unchanged. - Bsc applies to stress, not to rigidity. Applying it to both puts J out by exactly the value of Bsc.
Verified
Against a Bentley AutoPIPE Advanced 11.01 flange report (NPS 16 Class 150 weld neck, 500 psi at 500 °F): moment (Mo 35250.22 ft·lb), hub stress (S_H 17116 psi) and both rigidity indices (J 0.357 operating / 0.275 seating) land exactly; S_R and S_T sit 0.1–0.7% off only because the report prints two factors rounded. The straight-hub limit reproduces the Code's tabulated F/V values to six figures with no special-casing.
Supporting data (not calculation modules)
- Flange/bolt allowable-stress series vs temperature and the Table 2-5.1 gasket m/y library. The gasket factors are code data; the allowable-stress series are a curated starting library that populates editable fields and is expected to be replaced with the job's own Section II Part D values — labelled as such in the UI.
- Known gap surfaced in the UI: the attached-pipe allowable Sn has no lookup — it is an editable field, and the engine warns whenever the 2-8(a) cap goes unchecked.
2026-07-31 — B16.5 Table 9 weld-neck hub dimensions (X, Y) and derived App 2 hub geometry
connections.b165-dimensions gains the two Table 9 weld-neck columns it was missing, so an Appendix 2 integral flange no longer estimates its hub: g0, g1 and h now derive exactly (g0 = (pipe OD − B)/2, g1 = (X − B)/2, h = Y − t), and the confirmation gate in front of the aux.app2-flange-integral result was removed without ever shipping. No existing calculator's output changed; aux.app2-flange is loose-type without a hub and is unaffected.
Fixed
b165Dimensions(24, "900")threw — the Class 900 NPS 24 row specifies 2.5" bolts and the root-area table stopped at 2". Added 2.5 → 4.292 in² on the same 8-UN basis as every other entry. The row was previously unreachable, so no released number changes.
Verified
X and Y transcribed from three independent public reproductions, two of them blind, then adjudicated: all 64 X and 64 Y cells agree once the raised-face convention is resolved. The one real trap: Y in this table excludes the raised face, matching the listed minimum thickness — pairing that thickness with an RF-inclusive Y inflates h by 0.06. The AutoPIPE reference report's h = 3.56 at NPS 16 Class 150 is reproduced by both conventions independently. Locked by 18 unit cases including two all-row invariant sweeps. (Superseded the same day: the seven-class expansion above registers the table with fixture b165-dimensions.json.)
2026-07-31 — PiperSTR: AISC 360-22 + ACI 318-19 structural pipe-support design
New product line. Six modules covering the whole structural load path of a pipe support — the first calc-core surface to carry both LRFD and ASD from one nominal-strength core.
| Module id | Scope |
|---|---|
structural.aisc-member | AISC 360-22 Ch. B4 classification, D tension, E compression, F2-F10 flexure, G shear, H1 interaction, deflection |
structural.fillet-weld | AISC J2 fillet welds with the directional strength increase and a J4 base-metal rupture check |
structural.baseplate-anchorage | AISC J8 bearing, Design Guide 1 plate yielding, ACI 318-19 Ch. 17 anchorage and the 17.8 interaction |
structural.pier-soil | Soil bearing, overturning, sliding, ACI Ch. 22 punching shear |
structural.support-assembly | The cascade: pipe load → arm → weld → column → weld → base plate → anchors → pier → soil |
Fixtures: piperstr-member.json (14 cases), piperstr-weld.json (4), piperstr-baseplate.json (4), piperstr-pier.json (3), all with self-contained inputs so a fixture cannot silently change when the shapes dataset is regenerated.
Verified against published AISC Steel Construction Manual values: Table 3-2 Mp / Lp / Lr match to three significant figures for four benchmark W shapes, and the engine independently reproduces the Manual's exact ten-shape non-compact-flange footnote list from Table B4.1b arithmetic alone.
New dataset aisc.shapes-v16 (mode derived) — 1,506 shapes from AISC's freely published Shapes Database v16.0; L, HSS and Pipe computed from nominal geometry by a generator that gates itself against published AISC values and refuses to emit on a mismatch. Four defects were caught by those gates before ship (HSS corner slivers, a missing ACI 17.6.2.1.2 substitution, a base-plate yield-line over-demand, and D1/E2 slenderness now correctly advisory), and a check with an infinite ratio now sorts to the top of the governing roll-up in all modules.
Data firewall. AISC 360 and ACI 318 equations are methods and live in code. Proprietary anchor qualification data (adhesive bond stress, product-specific factors) is never embedded — it arrives from the user's ICC-ES evaluation report, and an adhesive anchor without it reports that the bond check did not run rather than passing silently. Soil bearing, friction and cohesion are likewise always user-supplied.
Supersedes general.aisc-member-check, which remains registered (ASD only) for API and batch callers.
2026-07-30 — Line-depth expansion: 13 calculators (documentation backfill)
Documentation-only entry, recorded 2026-07-31. These modules shipped 2026-07-30 in one commit without a changelog record; no calculation behavior is changed by this entry — it backfills the record so each module's landing page has a true source for its published "last updated" stamp.
pipeline.maop(fixturepipeline-maop.json, 3 cases) — MAOP/MOP as the lowest of design pressure, test-qualified pressure, and an optional cap, reporting which basis governed. Verified: hand-derived trio.aux.water-hammer(fixturewater-hammer.json, 2 cases) — Joukowsky surge with the elastic wave-speed correction and critical closure period. Verified: hand-derived steel water line.pipeline.slurry-velocity(fixtureslurry-velocity.json, 2 cases) — Durand–Condolios critical deposition velocity vs actual, PASS/FAIL. Verified: hand-derived sand-water pair.pipeline.charpy-arrest(fixturecharpy-arrest.json, 2 cases) — Battelle/AGA ductile fracture arrest energy with PASS/FAIL vs the MTR value. Verified: hand-derived pair.pipeline.dent-screening(fixturedent-screening.json, 2 cases) — plain-dent depth as %OD against a user-supplied limit. Verified: hand-derived pair.pipeline.dnv-f101-defect(fixturednv-f101-defect.json, 2 cases) — DNV-RP-F101 Part B single-defect capacity and utilization. Verified: hand-derived X52 pair.pipeline.erosional-velocity(fixtureerosional-velocity.json, 2 cases) — API RP 14E erosional velocity with the actual-velocity ratio. Verified: hand-derived pair.pipeline.hydrotest(fixturepipeline-hydrotest.json, 2 cases) — pipeline strength test pressure with the Barlow hoop check against a %SMYS cap. Verified: hand-derived pair.flexibility.expansion-interpolation(fixtureexpansion-interpolation.json, 1 case) — interpolation between two user-entered expansion-table rows, scaled to total growth; warns on extrapolation. Verified: hand-derived midpoint.aux.snow-ice-load(fixturesnow-ice-load.json, 2 cases) — radial ice annulus plus snow on the projected width. Verified: hand-derived pair.
Code-table values (design factors, C-factors, FL, ice/snow parameters) are user-supplied throughout, and each module carries its applicability warnings on every run.
2026-07-30 — Engineering Tools expansion: six PVP-Suite-parity calculators + two corrections
Five new modules, one extension, and one correction, all fixture-locked and anchored to the PVP Suite validation set where its inputs could be reverse-derived, hand-derived otherwise.
Added
general.criticality(fixturecriticality.json, 3 cases) — line/component criticality screening in the API 580/581 spirit, CLASS 1–4 with drivers.general.ejma-rating(fixtureejma-rating.json, 2 cases) — EJMA-framework bellows screening: pressure thrust, spring forces, anchor load, column-squirm screen. Effective-area anchor reproduces the PVP selftest.general.aisc-member-check(fixtureaisc-member-check.json, 2 cases) — AISC 360 ASD member check, compact non-slender members. Hand-derived.general.analysis-set(fixtureanalysis-set.json, 2 cases) — one load case compared under B31.1/B31.3/B31.4/B31.8 with per-row unity and a governing verdict; allowable factors are explicit inputs. Hand-derived.connections.en1591-screen(fixtureen1591-screen.json, 2 cases) — EN 1591-1 load-balance screening; explicitly NOT the full iterative method. Effective-area anchor reproduces the PVP selftest.
Changed
pipeline.b31g(fixtureb31g.json, +2 cases) — extended with Modified B31G and the stress-based path (S_fail, P_safe, ERF, the d/t > 0.8 rule). The legacy pressure-based form and both existing cases are unchanged. Verified: hand-derived pair on the same defect.piping.b31-sif(fixtureb31-sif.json, expected values corrected) — correction for the welding-tee branch: App D Table D300 assigns the tee io = 0.9/h^(2/3) with ii = 0.75·io + 0.25; the module previously applied the elbow assignment to tees, overstating ii and understating io (1.40904 vs the correct 1.69084 — unconservative out-of-plane). Elbow behavior unchanged; the PVP selftest's welding-tee anchor confirms the corrected assignment. Card relocations only on the UI side (enginepiping.fatigue-factorunchanged).
2026-07-24 — B16.5 flange pressure–temperature rating lookup (new module)
New module connections.b165-rating (fixture b165-rating.json, 8 cases): ASME B16.5-2017 pressure–temperature ratings for material Groups 1.1, 2.1, 2.2 and 2.3, Classes 150–2500, with linear interpolation per B16.5 Section 2 and per-group material sub-limit warnings. Rating data embedded and fixture-locked; B16.47 deliberately excluded. Verified: double-blind transcription (two independent readers per table, zero cell disagreements) plus hand-derived interpolation cases locked in the fixture.
2026-07-22 — New locked fixture cases behind published worked examples
No equation, limit, or verdict logic changed. Six hand-derived fixture cases added (and one existing case's expected values locked) so every worked example published on the calculator landing pages is CI-gated: piping.b313-wall-thickness (two new cases), piping.b311-wall-thickness, pipeline.b31g (pass path), piping.branch-reinforcement (expected values locked), noncode.thermal-growth, and bpe.cip-velocity.
2026-07-21 — PiperFEA nozzle/shell FEA goes live
Scope note: covers the FEA service, outside this file's usual calc-core scope, because it is a calculation surface users can run.
fea.nozzle-shell— nozzle-to-shell finite element analysis (shell meshing + CalculiX) on an isolated server-side worker. Reports Pl, Qb, Pl+Pb+Q and Pl+Pb+Q+F against their allowables, plus a job report in the legacy FE/Pipe layout with a 3D junction-stress plot. The fatigue allowable Sa implements the ASME VIII-2 Appendix 5 design fatigue curve with the E-ratio correction and Ke factor; the B31 and Markl bounds are reported alongside.
Verified: Sa and the B31 bound reproduce the legacy commercial-FEA reference reports to the psi on all 35 golden fixtures carrying a fatigue result. Secondary-stress ratio agreement: 19 of 24 runnable fixtures gated (15 within ±20%, 4 within ±35%); geometry outside the validated envelope is refused at submission rather than answered with a number. v1 limit: surface-maximum von Mises within a junction-local window stands in for a through-thickness linearized result — conservative.
2026-07-19 — Thermal Flexibility line
flexibility.expansion-loop(fixtureexpansion-loop.json, 5 cases) — guided-cantilever expansion loop / Z / L leg sizing, metallic and plastic families. Verified: reproduces the published coefficient rules 6.225·√(ΔL·D) and 4·√(ΔL·D) within 0.03%.
2026-07-14 — Pipe support spring selection
supports.variable-spring-select(fixturevariable-spring-select.json) andsupports.compact-spring-select(fixturecompact-spring-select.json) — variable- and compact-spring catalog selection (mode: derived data). Verified against published catalog load tables; catalog data remains mode-derivedwith attribution.
2026-07-04 — BPE line expansion + Equipment/Non-Metallic ports
Added
- BPE:
bpe.cip-velocity(SD-6.3.5.2.1),bpe.tube-weld-acceptance(MJ-8.4-1),bpe.pre-pren(App. F-3),bpe.ferrite-number(WRC-1992),bpe.ra-finish(SF-2.4.1-1),bpe.ep-passivation(App. H/E),bpe.polymer-thermal-expansion(PM-4.2.3). Fixtures: one file per module. - Equipment:
equipment.shell-nozzle-loads(WRC-107 / VIII-2 5.5 screen), ASME VIII-1vessel.ug27-shell,vessel.ug32-head,vessel.ug28-external(+UG-99),vessel.ug37-nozzle-area;aux.wrc-terms. - Non-Metallic:
nonmetallic.hdpe-n755,nonmetallic.frp-grp(NM-2 / ISO 14692 / BS 7159). - Auxiliary:
aux.app2-flange(Sec VIII App 2 loose-type),aux.asce-occasional.
Changed
- Data service: BPE Part DT-4.1 fitting dimensions and the SD-3.1.2.2 dead-leg limit ship embedded — see the source & citation policy for the complete embedded-data inventory. All other standards data stays user-supplied.
Verified
- Seventeen calculators fixture-anchored to the PVP Suite validation set (112 checks); the exact inputs behind each PVP expected value were reverse-derived and locked as fixtures.
2026-07-03 — BPE toolset full-parity port
bpe.unit-converter(App. U incl. Ra & slope units),bpe.dead-leg(SD-3.1.2.2 with small-branch advisory),bpe.slope-check+bpe.slope-report(SD-2.4.3 GSD + drainability classification),bpe.spray-flow(SD-3.9.2 device-type bands). Fixtures: one file per module. Verified: full-parity port, case-for-case against the legacy BPE toolset's results.
2026-07-03 — Phase 1 core
Added
- Piping:
piping.b313-wall-thickness,piping.b311-wall-thickness,pipeline.b31-wall-thickness,piping.b31-allowable-pressure,pipeline.b31-allowable-pressure,piping.leak-test-pressure,piping.bend-thickness,piping.miter-allowable-pressure,piping.branch-reinforcement. - Flexibility/stress:
piping.b31-sif(App. D closed forms),piping.displacement-stress,piping.sustained-stress,piping.fatigue-factor,pipeline.b31g. - Supports:
supports.spring-variability,supports.max-spring-rate; non-codenoncode.pipe-weight,noncode.pipe-section,noncode.thermal-growth,noncode.collapse-pressure,noncode.rolling-offset,noncode.interpolate. - Connections/Auxiliary:
connections.nozzle-load-check,connections.nema-sm23,connections.flange-equivalent-pressure,aux.wind-asce,aux.b31e-seismic,aux.pressure-thrust,aux.column-buckling. - Non-Metallic:
nonmetallic.hdpe-pressure-rating,nonmetallic.support-span.
Verified
- Hand-derived fixture per module (derivation recorded in each fixture's
description); stress-range and SIF modules cross-checked against the PVP Suite selftest values.