# SCRAM server-final validation experiment S00-017 fixture-only remediation of S00-003. No network connection or production adapter. Public RFC example credentials are used only in memory. Requires the accepted Node 24.21.0 / npm 11.19.0 runtime; installs enforce exact engines and TLS. From the project root, use the isolated runtime already verified by S00-002: ```sh export PATH=/private/tmp/luma-stack-runtime/node-v24.21.0-darwin-arm64/bin:$PATH node --version npm --version npm ci --prefix experiments/0002-xmpp-library/sasl-validation --ignore-scripts --no-audit --no-fund --cache /private/tmp/luma-sasl-review-cache --fetch-retries=0 --fetch-timeout=15000 npm test --prefix experiments/0002-xmpp-library/sasl-validation ``` On another host, obtain the official exact Node runtime with verified HTTPS and checksum; do not change system configuration or disable certificates. Use a fresh cache directory for an independent clean-install check. The original parent experiment manifest remains incomplete and is not used by these commands. The 44 tests use Stanza's actual Client, XML parse/registry, named SASL feature handler, feature negotiation dispatcher and SCRAM implementation. Outgoing sends, restart and disconnect are captured fixture effects, not server evidence. Tests first reproduce stock 12.22.1 accepting missing/forged premature success, then verify rejection with the replacement. RFC 5802 §5 / RFC 7677 §3 client-first, client-proof and verified server-final are checked byte-for-byte for SHA-1/256. No real credentials or key material are printed. A passing stock reproduction means the defect was observed, not safe authentication. `validated-sasl.mjs` installs through the public plugin and feature APIs: ```js // Illustrative integration for a fresh Client, BEFORE any connect/features. client.use(validatedSasl); ``` The plugin calls `registerFeature('sasl', 100, handler)`. Stanza's feature registry uses one handler per name, so this replaces the stock callback. Registration also adds another order entry; the real dispatcher exits on restart/disconnect, and our integrated tests verify only one negotiation/completion, including after reset. Do not install after authentication has started or alongside another SASL replacement. The stock handler must never have an active event listener. State is bounded to initial credentials/send, server-first, proof send, server-final and closed. Success is allowed only after completed proof send, strict final syntax, `processSuccess` and `finalize` reporting both authenticated and mutuallyAuthenticated. Invalid input disconnects once, removes listeners and never requests authenticated restart. Reset closes the old attempt before awaited work resumes. Crypto remains entirely in the installed library, backed by Node crypto in this run; no hash, HMAC, KDF or proof implementation is authored. No credential cache/update is persisted by the replacement. This is a deliberately limited non-PLUS SHA-256/SHA-1 experiment. It rejects other mechanisms, supplied TLS binding bytes, extensions, extra challenges and server-final delivered separately as a challenge. It accepts only server-final additional-data on success. It checks nonce extension and bounds decoded data at 4096 bytes and iterations at 100000; these are experiment limits, not shared contracts/product policy. Racing success before a send promise resolves is rejected conservatively. A final timeout/lifecycle policy belongs to the original integration; this experiment does not claim one. Exact dependency graph and preserved licenses: LICENSE_INVENTORY.md and THIRD_PARTY_NOTICES.md. All eight locked packages are MIT; lock entries retain HTTPS registry URLs and SHA512 integrity. Node/npm notices stay with their runtime. Security review must inspect the state transitions and actual library calls, repeat clean install/tests, check the diff, licenses and executor evidence, then approve/reject through the task workflow. No browser build/execution, live WSS, independent server, parser resource-limit certification, TLS channel binding, constant-time verification audit, advisory/provenance audit, production SASL policy or release readiness is claimed. Stanza's verifier uses ordinary string equality; these tests prove rejection correctness, not a timing guarantee. Browser Stanza uses its bundled synchronous hash/HMAC code and browser RNG/WS; that backend is not exercised here. S00-003 retains its library selection, browser/WSS/parser/extension experiment and stronger-mechanism policy work.