# S00-017 executor evidence Agent: auto-protocol-599343cd9e3f / protocol. Date: 2026-10-15. Result: isolated fail-closed SCRAM experiment and proposed ADR; independent security review pending. ## Input, output and scope Input: assigned S00-017 card/context, S00-003 blocker/evidence/handoff, exact ACC-004/NET-003/NET-004, accepted scope/stack ADRs and direct dependency evidence/review/handoffs. Required TESTING, decisions/README and state/blockers/S00-017.md read. Read master/startup/protocol/common and architecture/contracts/workflow/automation/Git instructions. S01 contracts remain future work; no shared contract is needed/introduced here. Output: experiments/0002-xmpp-library/sasl-validation plus docs/decisions/0002-xmpp-sasl-validation.md only, with fixture tests, separate exact manifest/lock, engine/TLS settings, license inventory/notices and reproduction instructions. Workflow evidence/handoff/commit message are the allowed metadata exception. Parent exploratory manifest/lock, specs, shared interfaces, application modules and planning definitions unchanged. No Git mutations or additional task/agent launch. No secrets or real account data: only public RFC example credentials, and invented example.invalid JID, in memory without network authentication. Acceptance demonstrated locally: missing/forged/premature server-final cannot emit success or restart; valid RFC SCRAM must compute exact client proof and call the actual library verifier before setting authenticated flags. Completion of S00-017 still requires independent security review; this executor does not mark done or accept the ADR. ## Actual checks and exit codes All npm commands used PATH=/private/tmp/luma-stack-runtime/node-v24.21.0-darwin-arm64/bin:$PATH (existing accepted isolated runtime), from project root. No system runtime install or certificate override. - python3 scripts/tasks.py resume --agent auto-protocol-599343cd9e3f; show S00-017; packet S00-017 --agent auto-protocol-599343cd9e3f: exit 0 each; correct assignment/prerequisites and exact requirements, no second claim. - npm install --ignore-scripts --no-audit --no-fund --cache /private/tmp/luma-sasl-cache --fetch-retries=0 --fetch-timeout=15000 --registry=https://registry.npmjs.org/ --strict-ssl=true --prefix experiments/0002-xmpp-library/sasl-validation: exit 0; eight installed packages and independent lock generated. - npm test --prefix experiments/0002-xmpp-library/sasl-validation: exit 0 initially, 38 tests; includes actual stock defect reproduction and positive/negative replacement checks. Added further lifecycle/error coverage afterward. - npm ci --ignore-scripts --no-audit --no-fund --cache /private/tmp/luma-sasl-clean-599343cd9e3f --fetch-retries=0 --fetch-timeout=15000 --prefix experiments/0002-xmpp-library/sasl-validation: exit 0; fresh cache, eight packages, lifecycle scripts disabled, strict TLS/engines retained. - npm test --prefix experiments/0002-xmpp-library/sasl-validation after clean install: exit 0; 44 passed, zero failed/skipped/cancelled; duration 1039.675 ms. No source changes to plugin/tests afterward. - node --version; npm --version with pinned PATH: exit 0 each; v24.21.0 / 11.19.0. - Inline Python JSON/license checks: successful collector exit 0; checked eight exact installed versions/licenses against lock, all HTTPS registry URLs/SHA512 integrity, preserved installed license texts. All eight MIT. Separate post-ci assertions exit 0 verify preserved notices still match installed license texts, and Client/SASL/features/SCRAM vendor files byte-match parent installed original sources. No vendor source edit. - curl --fail --silent --show-error https://www.rfc-editor.org/rfc/rfc7677.txt (displayed §3 through sed): exit 0; canonical SHA-256 fixture obtained. RFC 5802 §5 and RFC 7677 opened through web tool; installed package declarations/source provide exact extension API and crypto behavior. - make check: exit 0; validate 282 tasks, 22 stages, 221 requirements, 211 allocated Web requirements, revision 39; 72 tooling tests passed in 17.977 s. Foundation integrity, not app readiness. - git diff --check; git status --short --untracked-files=all: exit 0 each; only scoped source and coordinator's state claim before evidence. Separate inline Python whitespace check of authored files (including untracked files): exit 0. Exploratory failures, not successful checks: cat of guessed 0001-web-stack.md and ls of guessed runtime returned exit 1 before locating actual 0001-stack.md and runtime via existing evidence; no required artifact missing. A guessed installed protocol/sasl.js read returned exit 1 (registry APIs instead inspected at actual jxt and feature paths). First license collector returned exit 1 because punycode uses LICENSE-MIT.txt; corrected filename discovery, then all eight notices verified. Some GitHub source-page requests failed in web tool; installed exact declarations/source supplied version-pinned facts, and upstream Client source was retrievable. No acceptance blocker remained; no failed command is described as passed. ## Integrated results and security boundaries Tests run the actual Client, parse and import SASL XML through the actual registry, invoke feature negotiation by emitting features, and observe resulting transport restart/disconnect, negotiated/authenticated flags and auth events. Fixture capture replaces outgoing send/transport effects only; no mechanism verifier or proof result is stubbed. Method tracing wraps and invokes real processSuccess/finalize; both RFC proofs match exactly. Stock baseline tests return success/restart on missing and forged premature final, confirming the original defect. Replacement tests reject those same categories and a valid-looking final before proof. Remaining cases: two SHA variants reject missing/forged/error/conflicting error/duplicate verifier/bad base64/oversized final after proof; wrong/unextended nonce and invalid/excessive iteration inputs rejected before proof work; duplicate challenge, pending-send premature success, failure/abort and replay are terminal; reset cancels pending credentials/proof-send continuation and allows fresh negotiation without old listeners. Credential/send rejection disconnects. PLUS/plaintext-only offers fail; strongest supported non-PLUS chosen. Success emits once only after signature verification; invalid attempts never request restart or set authenticated state. Public Client.use + registerFeature replaces the named stock handler before negotiation. No late event interception or private vendor patch. Crypto stays in existing Stanza SCRAM/Node crypto. Bounds/strict syntax restrict the experiment and prevent Stanza's permissive directive parser from ignoring conflicting attributes. Library cache is not persisted/emitted by replacement. No peer/credential/crypto log output, plaintext fallback, encryption/CORS/certificate bypass or emulated TLS binding. ## Digests and limits SHA256 package-lock.json: 6413668910ec921d7871225f22fe2753ceaf32c6c185cda6d0a5fd0e27643514. SHA256 validated-sasl.mjs: 196b16baa16fea051dc6502bae11f80ebea02f87634d90ea72778ee14557a3b9. Only success additional-data, non-PLUS SHA-256/SHA-1 and extension-free fixture profile are supported; separate final challenge and extra challenge roundtrips conservatively fail. Local bounds are 4096 decoded bytes and 100000 iterations; racing success while send is pending fails closed. No timeout policy is claimed. Stanza verifier uses string equality; no constant-time assurance. Node executes actual crypto; browser bundled hashing/RNG backend, browser build/runtime, WSS/TLS/server interoperability, full parser limits, SHA-512/complete mechanism policy, vulnerability/provenance audit and release readiness remain unverified and belong to S00-003 or later tasks. No browser availability claim is needed for this Node fixture task. Supported extension evidence is public shipped declarations and actual dispatcher behavior, not a promise of future library API stability. Separate security reviewer should follow README, inspect the actual source and pinned graph/notices, repeat clean install/tests, assess limitations and record independent acceptance/rejection. S00-003 remains separate and blocked until reviewed done of this remediation; executor does not continue it.