# Quality assurance
## Microsim
### Live player
<div class="microsim-player">
<iframe src="https://editor.p5js.org/sciencenibber/full/mBipXOIiu" width="100%" height="620" frameborder="0" sandbox="allow-scripts allow-same-origin"></iframe>
</div>
<div class="microsim-fallback">
<img src="Microsims/thumbs/Quality_assurance.png" alt="Quality_assurance microsim poster" style="width:100%;border:1px solid #4445;border-radius:6px;">
<p><em>Live microsim (desktop) · <a href="https://editor.p5js.org/sciencenibber/sketches/mBipXOIiu">open sketch in the p5.js editor</a></em></p>
</div>
**Editor URL:** https://editor.p5js.org/sciencenibber/sketches/mBipXOIiu
**Description (100 words):**
Two coupled panels on a 720x520 canvas turn the Shewhart chart into an instrument you play. The left panel streams subgroup means onto a control chart with center line, upper and lower control limits, and a shaded in-control band; points that escape the limits flash red as out-of-control signals. The right panel draws the live sampling distribution of X-bar, sharing the chart's value axis, with the tail area beyond a limit shaded to show detection power. Three sliders set the mean shift delta (sigma), the subgroup size n, and the limit width k -- watch tighter limits trade faster detection against more false alarms. Reset and pause included.
```js
// =====================================================================
// Quality_assurance.js -- Wikitube microsim
// Article: Quality_assurance en.wikitube.io/wiki/Quality_assurance
// Room: Helium Pattern: N + H (probability over time:
// a Shewhart control chart + the live
// sampling distribution that drives it)
// ---------------------------------------------------------------------
// Idea: the canonical quality-assurance instrument is the Shewhart
// control chart. A helium-cylinder fill line targets a mass mu0 with
// common-cause spread sigma. Every period we pull a subgroup of n
// units, average them (X-bar), and plot that mean against a center
// line CL = mu0 and control limits at mu0 +/- k*sigma/sqrt(n). A point
// outside the limits is an out-of-control SIGNAL -- evidence of an
// assignable cause.
//
// The reader plays three sliders and watches the chart respond live:
// * delta -- shifts the true process mean to mu = mu0 + delta*sigma
// (the "assignable cause"); the streamed points drift and
// start escaping the band.
// * n -- subgroup size; larger n shrinks sigma_xbar = sigma/sqrt(n),
// tightening the limits and detecting a shift faster.
// * k -- limit width in sigma; the sensitivity / false-alarm dial.
//
// The right panel shows the sampling distribution of X-bar, Normal with
// mean mu and SD sigma_xbar, sharing the chart's value axis. The tail
// area that pokes past a control limit (shaded red) IS the per-subgroup
// detection power -- so the bell sliding up under a fixed UCL is the
// whole lesson in one picture.
//
// Canonical relations:
// sigma_xbar = sigma / sqrt(n)
// UCL = mu0 + k*sigma_xbar CL = mu0 LCL = mu0 - k*sigma_xbar
// power = 1 - [ Phi((UCL-mu)/sigma_xbar) - Phi((LCL-mu)/sigma_xbar) ]
// ARL = 1 / power (average # subgroups to a signal)
// In control (delta = 0): power = alpha = 2*Phi(-k); for k = 3 this is
// 0.0027, so ARL0 = 370 -- the classic "3-sigma" false-alarm rate.
//
// Layout (720 x 520 canvas):
// * top-left : HUD title + en.wikitube.io/wiki/Quality_assurance
// * top-right : control hints
// * left plot : control chart -- subgroup index (x) vs X-bar (y)
// * right plot : sampling distribution of X-bar, shared y axis
// * mid strip : three labelled sliders + reset
// * bottom : live readout (delta,n,k; limits; power; ARL) + equation
//
// Conventions (Wikitube Betterfire Standard v0):
// * single ARTICLE constant; p5.disableFriendlyErrors = true
// * frame-rate-independent: dt = min(deltaTime/1000, 0.05) accumulator
// * no allocation in draw(); fixed ring buffer for the streamed means
// * ASCII only in every text() string; Greek/symbols live in COMMENTS
// =====================================================================
const ARTICLE = 'Quality_assurance';
const TITLE = ARTICLE.replace(/_/g, ' ');
p5.disableFriendlyErrors = true;
// ----- Palette (Helium / Energy room) --------------------------------
const BG = 18;
const FG = 240;
const DIM = [240, 240, 240, 140];
const SCRATCH = [120, 120, 120, 90];
const INZONE = [90, 200, 130]; // in-control points + band
const OOC = [232, 92, 82]; // out-of-control signal
const LIMIT = [235, 150, 70]; // UCL / LCL
const CLINE = [80, 180, 230]; // center line
const DENS = [240, 210, 90]; // sampling distribution
const KNOB = [240, 220, 120];
// ----- Process constants (helium cylinder fill mass, grams) ----------
const MU0 = 100.0; // target fill mass (g)
const SIGMA = 2.0; // common-cause process SD (g)
// ----- Value axis (vertical, grams) ----------------------------------
const Y_LO = MU0 - 12; // 88 g
const Y_HI = MU0 + 12; // 112 g
// ----- Geometry (set in setup) ---------------------------------------
let cX, cY, cW, cH; // control-chart rectangle
let pX0, pX1; // distribution panel x-span (shares cY/cH)
// ----- Streamed subgroup means: fixed ring buffer (no draw alloc) ----
const CAP = 80;
let buf, bufStart, bufCount;
// ----- Animation + interaction state ---------------------------------
let acc = 0;
const INTERVAL = 0.45; // seconds between subgroups
let paused = false;
// ----- Controls: three on-canvas sliders -----------------------------
const TRK0 = 178, TRK1 = 452; // slider track x-span
const DEFAULTS = { delta: 0.0, n: 4, k: 3.0 };
const sliders = [
{ id: 'delta', label: 'mean shift delta', unit: 'sigma',
min: -3, max: 3, step: 0.1, val: 0.0, y: 352 },
{ id: 'n', label: 'subgroup size n', unit: '',
min: 1, max: 10, step: 1, val: 4, y: 382 },
{ id: 'k', label: 'limit width k', unit: 'sigma',
min: 2, max: 4, step: 0.25, val: 3.0, y: 412 }
];
let active = null; // slider being dragged
let resetBtn; // {x,y,w,h}
function setup() {
createCanvas(720, 520);
pixelDensity(2);
textFont('system-ui');
cX = 55; cY = 70; cW = 470; cH = 232;
pX0 = 560; pX1 = 690;
buf = new Float64Array(CAP);
bufStart = 0;
bufCount = 0;
resetBtn = { x: 566, y: 348, w: 132, h: 30 };
// Seed a few in-control subgroups so the chart is not empty at t = 0.
for (let i = 0; i < 18; i++) pushSubgroup(MU0, SIGMA, DEFAULTS.n);
}
function draw() {
background(BG);
// Read every control ONCE into named locals (Golden Rule 3).
const delta = sliders[0].val;
const nSub = Math.round(sliders[1].val);
const kLim = sliders[2].val;
// Derived statistics for this configuration.
const sigXbar = SIGMA / Math.sqrt(nSub);
const UCL = MU0 + kLim * sigXbar;
const LCL = MU0 - kLim * sigXbar;
const mu = MU0 + delta * SIGMA;
const beta = phiCdf((UCL - mu) / sigXbar) - phiCdf((LCL - mu) / sigXbar);
const power = 1 - beta;
const arl = power > 1e-7 ? 1 / power : Infinity;
// Advance the stream (frame-rate independent).
updateStream(mu, SIGMA, nSub);
// Render.
drawChart(UCL, LCL, sigXbar);
drawDistribution(mu, sigXbar, UCL, LCL);
drawControls();
drawHUD(delta, nSub, kLim, sigXbar, UCL, LCL, power, arl);
}
// =====================================================================
// Statistics helpers
// =====================================================================
// erf via Abramowitz-Stegun 7.1.26 (|error| < 1.5e-7).
function erf(x) {
const s = x < 0 ? -1 : 1;
const a = Math.abs(x);
const t = 1 / (1 + 0.3275911 * a);
const y = 1 - (((((1.061405429 * t - 1.453152027) * t) + 1.421413741) * t
- 0.284496736) * t + 0.254829592) * t * Math.exp(-a * a);
return s * y;
}
// Standard normal CDF.
function phiCdf(z) { return 0.5 * (1 + erf(z / Math.SQRT2)); }
// Standard normal PDF at value v for Normal(m, s).
function normPdf(v, m, s) {
const z = (v - m) / s;
return Math.exp(-0.5 * z * z) / (s * Math.sqrt(2 * Math.PI));
}
// =====================================================================
// Stream of subgroup means (ring buffer)
// =====================================================================
function pushSubgroup(mu, sd, nSub) {
let sum = 0;
for (let i = 0; i < nSub; i++) sum += randomGaussian(mu, sd);
const xbar = sum / nSub;
if (bufCount < CAP) {
buf[(bufStart + bufCount) % CAP] = xbar;
bufCount++;
} else {
buf[bufStart] = xbar;
bufStart = (bufStart + 1) % CAP;
}
}
// Oldest -> newest accessor.
function getMean(i) { return buf[(bufStart + i) % CAP]; }
function updateStream(mu, sd, nSub) {
if (paused) return;
const dt = Math.min(deltaTime / 1000, 0.05);
acc += dt;
let guard = 0;
while (acc >= INTERVAL && guard < 5) {
acc -= INTERVAL;
pushSubgroup(mu, sd, nSub);
guard++;
}
}
// =====================================================================
// Coordinate transforms (vertical value axis shared by both plots)
// =====================================================================
function valToPy(v) { return map(v, Y_LO, Y_HI, cY + cH, cY); }
function idxToPx(i) { return map(i, 0, CAP - 1, cX + 10, cX + cW - 10); }
// =====================================================================
// Left plot: the Shewhart control chart
// =====================================================================
function drawChart(UCL, LCL, sigXbar) {
push();
// Frame.
noFill();
stroke(SCRATCH);
strokeWeight(1);
rect(cX, cY, cW, cH);
// In-control band (between LCL and UCL).
noStroke();
fill(INZONE[0], INZONE[1], INZONE[2], 26);
const yU = valToPy(constrain(UCL, Y_LO, Y_HI));
const yL = valToPy(constrain(LCL, Y_LO, Y_HI));
rect(cX, yU, cW, yL - yU);
// 1- and 2-sigma_xbar zone guides (dashed, dim) for context.
stroke(SCRATCH);
strokeWeight(1);
dash([2, 5]);
for (let m = 1; m <= 2; m++) {
const a = MU0 + m * sigXbar, b = MU0 - m * sigXbar;
if (a < Y_HI) line(cX, valToPy(a), cX + cW, valToPy(a));
if (b > Y_LO) line(cX, valToPy(b), cX + cW, valToPy(b));
}
dash([]);
// Value-axis ticks (grams).
noStroke();
fill(...DIM);
textSize(10);
textAlign(RIGHT, CENTER);
for (let v = 90; v <= 110; v += 5) {
const y = valToPy(v);
stroke(SCRATCH); line(cX - 4, y, cX, y);
noStroke(); text(v, cX - 6, y);
}
// Axis titles.
textAlign(CENTER, TOP);
fill(...DIM);
textSize(11);
text('subgroup number (time) ->', cX + cW / 2, cY + cH + 8);
push();
translate(cX - 34, cY + cH / 2);
rotate(-PI / 2);
text('X-bar fill mass [g]', 0, 0);
pop();
// Center line + control limits.
drawLevel(MU0, CLINE, 1.6, 'CL');
drawLevel(UCL, LIMIT, 1.6, 'UCL');
drawLevel(LCL, LIMIT, 1.6, 'LCL');
// Streamed subgroup means; re-flagged against CURRENT limits so the
// n and k sliders re-classify points live.
let signals = 0;
let prevX = 0, prevY = 0;
for (let i = 0; i < bufCount; i++) {
const v = getMean(i);
const x = idxToPx(i);
const y = valToPy(constrain(v, Y_LO, Y_HI));
const out = (v > UCL || v < LCL);
if (out) signals++;
// connecting line
if (i > 0) {
stroke(200, 200, 210, 70);
strokeWeight(1);
line(prevX, prevY, x, y);
}
// marker
noStroke();
if (out) {
fill(...OOC);
circle(x, y, 8);
stroke(...OOC); strokeWeight(1.4); noFill();
circle(x, y, 14);
} else {
fill(...INZONE);
circle(x, y, 5.5);
}
prevX = x; prevY = y;
}
// store for HUD without re-looping
drawChart._signals = signals;
drawChart._total = bufCount;
pop();
}
// A horizontal reference level with a right-edge label.
function drawLevel(v, col, w, lab) {
if (v < Y_LO || v > Y_HI) return;
const y = valToPy(v);
push();
stroke(...col);
strokeWeight(w);
line(cX, y, cX + cW, y);
noStroke();
fill(...col);
textSize(10);
textAlign(LEFT, CENTER);
text(lab, cX + cW + 4, y);
pop();
}
function dash(arr) {
if (drawingContext.setLineDash) drawingContext.setLineDash(arr);
}
// =====================================================================
// Right plot: sampling distribution of X-bar (shared value axis)
// =====================================================================
function drawDistribution(mu, sigXbar, UCL, LCL) {
push();
// Panel frame.
noFill();
stroke(SCRATCH);
strokeWeight(1);
rect(pX0, cY, pX1 - pX0, cH);
noStroke();
fill(...DIM);
textSize(10);
textAlign(CENTER, TOP);
text('X-bar density', (pX0 + pX1) / 2, cY + cH + 8);
const peak = normPdf(mu, mu, sigXbar); // density at the mode
const wMax = (pX1 - pX0) - 12; // px available for the bell
// Helper: value -> x position of the density curve.
const densX = (v) => pX0 + 6 + (normPdf(v, mu, sigXbar) / peak) * wMax;
// Shade the in-control body and the out-of-limit tails separately.
// Body (LCL..UCL) in distribution color; tails in signal red.
fillBand(Math.max(Y_LO, LCL), Math.min(Y_HI, UCL), densX, DENS, 70);
if (UCL < Y_HI) fillBand(UCL, Y_HI, densX, OOC, 110);
if (LCL > Y_LO) fillBand(Y_LO, LCL, densX, OOC, 110);
// Curve outline.
stroke(...DENS);
strokeWeight(1.6);
noFill();
beginShape();
for (let py = cY; py <= cY + cH; py += 2) {
const v = map(py, cY, cY + cH, Y_HI, Y_LO);
vertex(densX(v), py);
}
endShape();
// Limit + center lines across the panel, aligned with the chart.
for (const [v, col] of [[MU0, CLINE], [UCL, LIMIT], [LCL, LIMIT]]) {
if (v < Y_LO || v > Y_HI) continue;
const y = valToPy(v);
stroke(col[0], col[1], col[2], 200);
strokeWeight(1);
dash([2, 4]); line(pX0, y, pX1, y); dash([]);
}
// Mean marker (where the true process sits now).
if (mu > Y_LO && mu < Y_HI) {
const y = valToPy(mu);
noStroke(); fill(...DENS);
circle(pX0 + 6, y, 6);
textAlign(LEFT, CENTER); textSize(9);
text('mu', pX0 + 12, y - 8);
}
pop();
}
// Fill the density region between values v0..v1 (v1 > v0).
function fillBand(v0, v1, densX, col, alpha) {
if (v1 <= v0) return;
noStroke();
fill(col[0], col[1], col[2], alpha);
beginShape();
const py0 = valToPy(v1), py1 = valToPy(v0); // v1 higher -> smaller py
for (let py = py0; py <= py1; py += 2) {
const v = map(py, cY, cY + cH, Y_HI, Y_LO);
vertex(densX(v), py);
}
vertex(pX0 + 6, py1);
vertex(pX0 + 6, py0);
endShape(CLOSE);
}
// =====================================================================
// Control strip: three sliders + reset
// =====================================================================
function sliderX(s) { return map(s.val, s.min, s.max, TRK0, TRK1); }
function drawControls() {
push();
// Strip background.
noStroke();
fill(255, 255, 255, 10);
rect(8, 332, 704, 104, 8);
textAlign(LEFT, CENTER);
for (const s of sliders) {
// Track.
stroke(...SCRATCH);
strokeWeight(3);
line(TRK0, s.y, TRK1, s.y);
// Knob.
const kx = sliderX(s);
noStroke();
fill(...KNOB);
circle(kx, s.y, 14);
// Label (left) and value (right).
noStroke();
fill(...DIM);
textSize(12);
text(s.label + (s.unit ? ' [' + s.unit + ']' : ''), 16, s.y);
fill(FG);
textSize(12);
const shown = s.id === 'n' ? String(Math.round(s.val))
: (s.val >= 0 && s.id === 'delta' ? '+' : '') + nf(s.val, 0, s.id === 'delta' ? 1 : 2);
text(shown, TRK1 + 16, s.y);
// Min / max ticks under the track.
fill(...DIM);
textSize(9);
textAlign(CENTER, TOP);
text(s.id === 'n' ? '1' : nf(s.min, 0, 0), TRK0, s.y + 9);
text(s.id === 'n' ? '10' : nf(s.max, 0, 0), TRK1, s.y + 9);
textAlign(LEFT, CENTER);
}
// Reset button.
const b = resetBtn;
const hover = inRect(mouseX, mouseY, b);
stroke(...DIM);
strokeWeight(1);
fill(hover ? 70 : 40);
rect(b.x, b.y, b.w, b.h, 6);
noStroke();
fill(FG);
textAlign(CENTER, CENTER);
textSize(12);
text('RESET (r)', b.x + b.w / 2, b.y + b.h / 2 + 1);
// Run / pause status.
textAlign(CENTER, TOP);
textSize(11);
fill(paused ? OOC : INZONE);
text(paused ? 'PAUSED (space)' : 'running (space pauses)',
b.x + b.w / 2, b.y + b.h + 6);
pop();
}
// =====================================================================
// HUD: title, URL, hints, live readout, canonical equation
// =====================================================================
function drawHUD(delta, nSub, kLim, sigXbar, UCL, LCL, power, arl) {
// Top-left: title + Wikitube URL.
noStroke();
fill(FG);
textAlign(LEFT, TOP);
textSize(22);
text(TITLE, 14, 12);
fill(...DIM);
textSize(12);
text('Wikitube microsim . en.wikitube.io/wiki/Quality_assurance', 14, 40);
// Top-right: control hints.
textAlign(RIGHT, TOP);
textSize(10);
text('drag sliders to set delta, n, k', width - 14, 12);
text('space = pause / resume', width - 14, 24);
text('r = reset all', width - 14, 36);
// Bottom-left: configuration + chart levels.
fill(...DIM);
textAlign(LEFT, BOTTOM);
textSize(12);
const ds = (delta >= 0 ? '+' : '') + nf(delta, 0, 1);
text('shift delta = ' + ds + ' sigma n = ' + nSub +
' k = ' + nf(kLim, 0, 2) + ' sigma', 14, height - 38);
fill(FG);
textSize(12);
text('CL = ' + nf(MU0, 0, 1) + ' UCL/LCL = ' + nf(UCL, 0, 2) + ' / ' +
nf(LCL, 0, 2) + ' g sigma_xbar = ' + nf(sigXbar, 0, 2) + ' g',
14, height - 20);
// Bottom-right: detection power / ARL / live signal count + equation.
const sig = drawChart._signals || 0;
const tot = drawChart._total || 0;
const arlStr = (arl === Infinity || arl > 99999) ? '>99999' : nf(arl, 0, 0);
fill(FG);
textAlign(RIGHT, BOTTOM);
textSize(12);
text('detect power = ' + nf(power * 100, 0, 2) + ' % ARL = ' + arlStr +
' signals ' + sig + '/' + tot, width - 14, height - 38);
fill(...DIM);
textSize(11);
text('UCL,LCL = mu0 +/- k*sigma/sqrt(n)', width - 14, height - 22);
textSize(10);
text('power = 1 - [ Phi((UCL-mu)/s) - Phi((LCL-mu)/s) ], ARL = 1/power',
width - 14, height - 8);
}
// =====================================================================
// Input
// =====================================================================
function inRect(mx, my, r) {
return mx >= r.x && mx <= r.x + r.w && my >= r.y && my <= r.y + r.h;
}
function pickSlider(mx, my) {
for (const s of sliders) {
if (my > s.y - 12 && my < s.y + 12 && mx > TRK0 - 14 && mx < TRK1 + 14) {
return s;
}
}
return null;
}
function setSliderFromMouse(s, mx) {
let v = map(mx, TRK0, TRK1, s.min, s.max);
v = s.min + Math.round((v - s.min) / s.step) * s.step;
s.val = constrain(v, s.min, s.max);
}
function mousePressed() {
if (inRect(mouseX, mouseY, resetBtn)) { resetAll(); return; }
const s = pickSlider(mouseX, mouseY);
if (s) { active = s; setSliderFromMouse(s, mouseX); }
}
function mouseDragged() {
if (active) setSliderFromMouse(active, mouseX);
}
function mouseReleased() { active = null; }
function keyPressed() {
if (key === 'r' || key === 'R') resetAll();
if (key === ' ') paused = !paused;
}
function resetAll() {
sliders[0].val = DEFAULTS.delta;
sliders[1].val = DEFAULTS.n;
sliders[2].val = DEFAULTS.k;
bufStart = 0;
bufCount = 0;
acc = 0;
paused = false;
for (let i = 0; i < 18; i++) pushSubgroup(MU0, SIGMA, DEFAULTS.n);
}
// =====================================================================
// End of Quality_assurance.js -- Wikitube microsim, Helium room.
// Pattern N+H: Shewhart SPC chart coupled to its sampling distribution.
// =====================================================================
```
## Links (Wikipedia order)
<!-- injected from _registry/childlinks/Quality_assurance.json (2026-07-30T02:09:12Z) -->
`Advanced_product_quality_planning` · `American_Society_for_Quality` · `Assembly_line` · `Best_practice` · `Calibration` · `Capability_Maturity_Model_Integration` · `Confidence` · `Construction` · `Consultant` · `DMAIC` · `Data_integrity` · `Data_quality` · `Departmentalization` · `Dimension` · `Durable_good` · [[Failure_mode_and_effects_analysis]] · [[Frederick_Winslow_Taylor]] · `Guild` · `Henry_Ford` · `Humidity` · `ISO/IEC_15504` · `ISO/IEC_9126` · `Industrial_Revolution` · `Inspection` · `Integrity` · `International_standard` · [[Maintainability]] · `Management` · `Marketing_Accountability_Standards_Board` · `Mass_production` · `Mechanization` · `Medical_device` · `Middle_Ages` · `Motivation` · `Organizational_culture` · `People` · `Picatinny_Arsenal` · `Piece_work` · `Product_(business)` · `Product_testing` · `Quality_(business)` · `Quality_control` · `Quality_engineering` · `Quality_function_deployment` · `Quality_management` · `Quality_management_system` · `Regulatory_compliance` · [[Reliability_engineering]] · `Safety` · `Sampling_(statistics)` · `Samuel_Pepys` · `Shift-left_testing` · `Six_Sigma` · [[Software_engineering]] · [[Software_quality_assurance]] · `Software_testing` · `Statistical_process_control` · `Stress_testing` · `Total_quality_management` · `Verification_and_validation` · `Vibration` · `W._Edwards_Deming` · `Walter_A._Shewhart` · [[Wayback_Machine]] · `William_Ernest_Johnson` · `World_War_I`
## From the vault media library
!Quality assurance thumb.png
*Quality Assurance — from the vault's own media holdings, placed 2026-07-09. MTN / Wikitube.io original · CC BY-SA 4.0.*
<!-- LOCAL-MEDIA-PASS:END -->
> **Room:** [[Helium]] · **Status:** ✅ shipped
## Overview
Quality assurance (QA) is the discipline of building confidence that a product or process will consistently meet its requirements. Rather than inspecting defects out after the fact, QA designs measurement and [[Feedback|feedback]] into the process itself, separating the inherent common-cause variation that every process exhibits from the assignable-cause variation that signals something has genuinely changed.
Its central instrument is the Shewhart control chart, introduced by Walter A. Shewhart at Bell Telephone Laboratories in 1924 and the foundation of statistical process control (SPC). Periodically a subgroup of n units is measured and its mean X-bar is plotted against a center line at the process target mu0 and a pair of control limits at mu0 +/- k*sigma/sqrt(n), where sigma is the common-cause standard deviation and k is conventionally 3. Because the standard error of a subgroup mean is sigma/sqrt(n), larger subgroups produce tighter limits; a point outside the limits is treated as an out-of-control [[Signal|signal]] warranting investigation.
The two governing performance numbers are detection power -- the probability a single subgroup flags a given mean shift -- and the average run length (ARL), the expected number of subgroups until a signal. With three-sigma limits the in-control false-alarm rate is 2*Phi(-3) = 0.0027, an ARL of about 370 subgroups between false alarms. In a helium cylinder or [[Balloon|balloon]] fill line, QA of this kind monitors fill mass: the chart catches a drifting regulator or a worn valve long before scrap accumulates, which is why SPC underpins helium packaging, [[Leak|leak]]-test acceptance, and downstream [[Manufacturing|manufacturing]] across the Helium room.
## See also
- Room hub: [[Helium]]
- p5.js Editor conventions: P5 JS EDITOR
- Wiki root: MAIN
---
*Built by `microsim-worklist` from row 203 of the Helium worklist; microsim published to editor.p5js.org/sciencenibber and verified FES-clean (in-editor doc SHA == disk SHA).*
<!-- LOCAL-MEDIA-PASS:START -->
<!-- CRAFT-LINK:START g12 -->
*Built to the [[WT!P5_js_Microsim_Master_Class|p5.js Master Class]].*
<!-- CRAFT-LINK:END -->
## Wikipedia : Wikitube
**Strict pair:** [Wikipedia](https://en.wikipedia.org/wiki/Quality_assurance) : [Wikitube](https://en.wikitube.io/wiki/Quality_assurance)
## Previous hub tags
Tree parent: [[Reliability_engineering]].
Legacy hubs: none.
---
*Sources: 1 legacy note. Minted wave 1, 2026-07-30 (v1.6 order).*