Development

Historical validation records

Dated November 2026 test results and review findings, each tied to its recorded candidate.

Source snapshot 60c72c2bView original
On this page

These are historical results for the baselines and candidate manifests identified below. References to local logs and planned reviews describe the record at the time it was written; ignored VM evidence is not shipped with the repository. Older protocol entries do not describe the current authentication policy.

Paired authentication, psh/3 (2026-11-11)

Baseline: 727fd760628aae436addd788d2e72428d9ee38b4. The 35-file candidate manifest is tools/vm/.state/auth-v3-candidate.sha256, SHA-256 247b859fd6d9b0598cc2560717da2f9277d44112b6528dfb56404e44be375df1. It covers every implementation/test change and the protocol/crypto documentation; this accumulating validation record is excluded to avoid a self-referential hash.

Separate Sol 6.1 high and Astra high design reviews accepted the bound-proof construction before implementation. They required explicit complete-pair trust, independent broker user authorization, irreversible phases, strict PEM parsing, and the worker-exporter trust-boundary qualification. The existing 65-second outer authentication deadline remains a tighter bound on late challenges.

CheckResult
Complete normal make test, including 12 adversarial real-client casesPassed
Complete make test-sanitize, 11 suites and 100,000 parser mutationsPassed
Extended normal broker crypto-failure checksPassed
Instrumented real client/daemon authentication, PQ transport, input/PTY, trust racesPassed; authentication rerun on final candidate
Compiler diagnostics on the final full build/test/sanitizer runsZero warnings
Fresh independent GPT-6.1 Sol high verificationFinal clearance; no remaining findings
Fresh independent GPT-6 Astra high verificationFinal clearance; no remaining findings

All compilation and runtime testing use only tools/vm/vm.sh and the disposable KVM guest. No host packages, networking or services are changed. Pinned OpenSSL and YAML sources are unchanged. Sanitizers instrument project-owned C; vendored static crypto libraries are not instrumented. Unit leak detection is enabled; credential-dropping application tests disable LeakSanitizer tracing only.

Key/trust regressions cover paired object order, missing/duplicate/third objects, unsupported ML parameters, garbage, truncation, NULs, mixed encryption modes, different passphrases, independent PBES2 salts/IVs, exact digest preimages, component substitution, canonical SHA512 padding bits, and legacy pin migration. Strict decoding adds 48 malformed-DER cases with six valid controls, covering SPKI, plaintext PKCS#8, encrypted envelopes, decrypted PKCS#8, and embedded private-key encodings in both components; six malformed nested-BEGIN cases exercise PEM armor validation.

The actual broker is tested for both proof components, full-pair authorization from one file, split components from two authorized files, CID/exporter/nonce/host and exact-OPEN bindings, host signing limits, phase ordering, replay, expiry, and missing PQ generation/signing or nonce-generation failures. Test-only linker wrappers include accepting controls when one verification is bypassed, followed by rejection when the other component is invalid. No bypass exists in production.

An independent adversarial UDP/DTLS peer keeps itself alive until the production client has rejected missing, short, tampered, incorrectly bound or substituted host proofs. Every negative case asserts zero OPEN disclosure and no persisted pin. Substituted-component proofs first pass cryptographic verification and then fail complete-pair provisioning. Baseline and maximum-size OPEN cases separately verify both user signatures and reject either corrupted or omitted component. The live-peer missing-proof deadline is approximately 15 seconds.

Both independent initial reviews withheld clearance after reproducing extra DER accepted inside PEM objects. Follow-up review also reproduced an embedded Ed25519 OCTET STRING suffix accepted by the provider importer. The loader now requires complete ASN.1 consumption at each layer and the exact Ed25519 seed encoding. Both issues were format-validation defects; no signature bypass was demonstrated. Both independent reviewers rejected their original malformed fixtures on the final candidate, with valid controls still accepted. Sol also rejected additional nonminimal-length and constructed nested Ed25519 encodings.

The reviews also caught a validation workflow defect: source sync could overlay old host build artifacts onto tested guest executables. Initial stale-binary results were discarded and affected checks explicitly rebuilt and reran. Sync now excludes root build/; 12 VM-only regressions cover literal exclusions, nested source preservation, and preservation of guest build artifacts.

The normal test run completed all 30 sequential and 16 concurrent paired sessions:

Connections / concurrencyHello-to-ready p50 / p95Client + daemon CPUSampled aggregate peak RSSMean UDP payload bytes/session
30 / 167.78 / 72.21 ms0.527 s119,001,08821,590
16 / 16152.60 / 219.82 ms0.249 s343,388,16021,482

Maximum observed UDP payload remained 1,200 bytes. Readiness includes user authentication and shell launch, not just cryptographic handshake time. RSS is sampled summed process resident sets, including shared pages and overlapping closing connections; it is not unique physical memory or a hard allocation cap. Wire totals exclude IP/UDP headers and include admission/application/closure. These loopback measurements provide no production latency guarantee.

Final full-suite evidence is auth-v3-final-build.log, auth-v3-final-test.log, and auth-v3-final-sanitize.log. All three contain zero compiler warnings. Guest evidence uses /work/results/auth-v3-*.log, plus authentication-agent.log. Build instrumented applications in build/auth-v3-sanitize with DEPS=/work/psh/build/deps, ASAN/UBSAN flags and frame pointers; build its auth_peer fixture as well. Run integration scripts with PSH_TEST_BUILD=/work/psh/build/auth-v3-sanitize and ASAN_OPTIONS=detect_leaks=0:abort_on_error=1. Normal reproduction remains make -j2 all && make test && make test-sanitize inside the VM.

Fresh final verification used separate GPT-6.1 Sol high and GPT-6 Astra high agents with no inherited design/implementation history. Each independently reviewed the source, rebuilt current executables, ran normal and ASAN/UBSAN key/trust/broker and real-client tests, reran malformed-key probes with accepting controls, and confirmed the 35-file host/guest manifest before and after. Both granted final clearance with no remaining findings. Evidence is auth-v3-sol-final-verify.log, auth-v3-sol-final-probe.log, auth-v3-astra-final.log, and auth-v3-astra-final-apps.log. The earlier design reviews and test implementation assistance are not counted as these fresh final verifications.

A separate fresh Astra high whole-project review will run after the commit and be reported against that exact commit. Its results are recorded separately from this pre-commit validation record.

Mandatory hybrid key exchange (2026-11-11)

The candidate requires X25519MLKEM768 on both endpoints under ALPN psh/2. This validates hybrid key establishment, not post-quantum Ed25519 authentication or overall security equivalence to OpenSSH. Host/user PQ identities are deferred.

Baseline: 5f4cb1e49232817387bf1889cb5cb44d6a34e12f. The nine-file candidate manifest is retained as tools/vm/.state/pq-candidate.sha256; its SHA-256 is e34c6cd05c17f9fe9ba0c6a08fac02990403984dfc3717a71b2589e8083c91cb. The manifest covers implementation, tests, and crypto/protocol documentation; this accumulating validation record is excluded to avoid a self-referential hash.

All builds, test binaries, accounts, and listeners ran only through tools/vm/vm.sh in the disposable KVM Ubuntu guest (kernel 6.8.0-147-generic, two virtual CPUs, 2 GiB RAM). No host packages, networking, or services changed. The existing guest overlay’s obsolete backing-image path was repaired after verifying its base image SHA-256. Both vendored sources remain unchanged; verification confirmed the exact 6,208-file source inventory.

CheckResult
Complete normal make testPassed
make test-sanitize, 11 suites and 100,000 parser mutationsPassed
ASAN/UBSAN real client/daemon PQ faults and admission expiryPassed
ASAN/UBSAN input-credit, blocked controls, stdin closure, PTY drainage21 checks passed
Post-review DTLS allocation/failure-injection tests, normal and ASAN/UBSANPassed
Corrected real client/daemon PQ integrationPassed
Compiler diagnosticsZero warnings
Independent GPT-6.1 Sol high review and VM verificationFinal clearance; no remaining findings
Independent GPT-6 Astra high review and VM verificationFinal clearance; no remaining findings

The complete normal and sanitizer suites passed before the review-driven test strengthening. Subsequent changes were limited to test fixtures and test-only linker flags; all affected normal, sanitized, and end-to-end checks were rerun on the final candidate. The corrected real client/daemon PQ integration also passed with the project ASAN/UBSAN binaries (pq-final-app-sanitize.log).

DTLS fixtures use production-created contexts and the envelope-adjusted MTU. Checks cover both negotiated groups, restricted broker signing, exporter equality, key updates, fragmented first-flight loss, server-flight loss, duplication, reordering, tampered client shares, and classical-only offers in either direction. Channel tests also override both offers to classical exchange and confirm that both production completion guards reject it without setting handshake confirmation or exporting authentication material. Resource tests fill both capped BIOs and exercise oversized/invalid fragment headers. Existing broker authorization, host-pinning, migration, revocation, binary streams, and backpressure regressions pass with hybrid exchange.

Real client/daemon tests observe fragmented ClientHello traffic through the full supervisor/worker path and verify recovery under deliberate faults. Tampered shares fail authentication, a subsequent legitimate session succeeds, the seventeenth pending admission is rejected, and sixteen incomplete handshakes retire in approximately sixteen seconds before valid service resumes.

Both independent initial reviews found no production defect, but identified inadequate regression evidence. The incomplete-fragment integration fixture reused DTLS record number zero, allowing replay suppression to hide future-message processing. It now uses distinct record numbers. The DTLS unit suite now installs OpenSSL allocation callbacks before library initialization and identifies actual reassembly allocations in the pinned statem_dtls.c: it asserts allocation at 16,716 bytes, no allocation at 16,717 or larger, retention of the current plus ten future messages, no allocations for sequences 11–63, and no duplicate allocation. It includes a replayed-record control to guard the observation point itself.

A linker wrapper restricted to normal/sanitized DTLS test executables now injects failure of the exact required-group configuration request on both production initialization paths. Both must fail with no SSL connection, no confirmation, zero exporter, and the required-group diagnostic; restoring availability restores initialization. This adds no production test hook or fallback. The original unknown-group-only check and incomplete-input-only bounds assertions were replaced.

Production code and policy were unchanged after these reviews. The strengthened DTLS suite passed normally and with ASAN/UBSAN, and corrected integration checks passed. Both independent reviewers then verified all nine final manifest entries on host and guest, reran the normal DTLS/channel/broker/signer suites, corrected PQ integration, and the sanitized DTLS suite with leak detection, and granted final clearance with no remaining security or correctness findings. The initial manifest is retained separately as pq-candidate-initial.sha256.

Measurements from the complete normal run (all 46 connections succeeded):

Connections / concurrencyHello-to-ready p50 / p95Client + daemon CPUSampled aggregate peak RSSMean UDP payload bytes per session
30 / 135.62 / 37.17 ms0.425 s164,282,368 bytes4,819
16 / 16106.75 / 167.66 ms0.205 s299,560,960 bytes4,840

Readiness latency starts at the first observed ClientHello and includes user authentication and shell launch; it is not an isolated crypto-handshake timing. Wire totals include admission, application/control traffic, and connection closure, but exclude UDP/IP headers. RSS is a 10 ms sample of summed daemon/descendant and client resident sets, including shared pages and overlapping closing connections; it is neither unique physical memory nor a hard memory ceiling. CPU includes clients, daemon, and reaped daemon descendants, excluding the Python proxy. All observed UDP payloads were at most 1,200 bytes. These guest loopback measurements establish no production throughput or latency guarantee.

Reproduce normal, sanitizer, and PQ checks:

tools/vm/vm.sh start
tools/vm/vm.sh wait
tools/vm/vm.sh sync
tools/vm/vm.sh run 'make -j2 all && make test && make test-sanitize'

Create build/pq-app-sanitize inside the guest before building it. The focused application sanitizer build uses BUILD=/work/psh/build/pq-app-sanitize, DEPS=/work/psh/build/deps, compiler/linker -fsanitize=address,undefined, and -fno-sanitize-recover=all -fno-omit-frame-pointer. Run the PQ and remote_stdin_close.py integration scripts with that PSH_TEST_BUILD and ASAN_OPTIONS=detect_leaks=0:abort_on_error=1; process isolation prevents LeakSanitizer from tracing dropped-credential workers. Unit sanitizer checks use detect_leaks=1. Vendored static crypto libraries are not sanitizer-instrumented.

Guest evidence is under /work/results/: pq-full-build.log, pq-full-test.log, pq-sanitize.log, pq-app-sanitize-build.log, pq-app-sanitize.log, and pq-app-input-sanitize.log, pq-final-app-sanitize.log, pq-bounds-build.log, pq-bounds.log, pq-bounds-sanitize.log, and pq-bounds-integration.log.

The independent initial reports/tests are retained in pq-sol-review.log and pq-astra-review.log; supplemental probe sources are pq-sol-probe.c and pq-astra-probe.c. Final independent evidence is in pq-sol-final.log and pq-astra-final.log. The initial reviews did not see each other’s findings; guest verification was serialized with flock /work/results/pq-review.lock. Both reviewers explicitly resolved their earlier findings against the final manifest. Sol observed final incomplete-session expiry at 16.06 seconds, Astra at 16.05 seconds. Required-group unavailability was fault-injected, including Astra’s separate selective key-management-fetch denial; a separate provider build was not tested. The unchanged 64-total-connection limit was reviewed in source rather than saturated concurrently. Host copies of all these logs and manifests are retained under the ignored tools/vm/.state/ directory.

Earlier validation

Validated on 2026-11-10 in the disposable QEMU/KVM Ubuntu 24.04 x86-64 guest, using GCC 13.3, vendored OpenSSL 4.1.0, and vendored libyaml 0.2.5. Builds and all application tests ran inside the VM. The current tree, including the wildcard-listener, trust-prompt, and PTY-hangup fixes, was validated in guest /work/psh.

Results

CheckResult
Normal build and 11 unit suitesPassed
Real client/daemon integration71 checks passed
Terminal flags and restoration9 authenticated checks passed
Closed standard descriptors17 checks passed
Input credit, stalled controls, stdin close, and PTY hangup21 checks passed
Wildcard/explicit IPv4 and IPv6 listeners8 checks passed
Trust-prompt concurrency and revalidation8 checks passed
Dependency-source regression26 tests passed
VM source-sync regression11 tests passed
ASAN + UBSAN across 11 suitesPassed with leak detection, no runtime findings
ASAN + UBSAN real client/daemon input, control, and PTY regressions21 checks passed, leak detection disabled
Deterministic parser mutation harness100,000 iterations passed
Compiler diagnosticsZero warnings in final normal and sanitizer builds
Vendored input verificationBoth release archives and all 6,208 source files verified

Unit suites cover wire framing, reliable transport, strict YAML, Ed25519 key files, the restricted host signer, DTLS negotiation/exporters/key updates, encrypted channels, host trust, session lifecycle, broker authentication, and the worker syscall filter.

Integration checks exercise actual account switching, real/effective/saved IDs, supplementary groups, home/environment, shell semantics, exit status including 255, stdout/stderr, binary I/O, PTYs and live resize, signal forwarding, encrypted private-key unlocking, terminal echo restoration after success/interruption, host trust/forget, incorrect keys/pins, account policy, and file permissions.

Network and lifecycle regressions include loss/reordering, client IP migration from 127.0.0.1 to 127.0.0.2 with a new source port, explicit client socket rebinding, simultaneous DTLS KeyUpdate and roaming, unauthenticated candidate ACKs, connection-slot reuse across 80 sessions, address-bound cookies, configuration reload, active key revocation, and host-key rotation. A guest-only negative control disabling the authenticated-control path fix fails the overlap regression, while the actual implementation passes it.

Input regressions fill a nonreading command’s stdin while keeping its transport healthy, then verify prompt signal delivery, broker CLOSE and PTY resize. A separate case fills the output IPC path while stdin is stalled and verifies CLOSE still runs. They also check the client’s local-read bound, rejection of over-credit/empty/post-EOF input and duplicate EOF, byte-exact 2 MiB delayed-reader input, ordered PTY VEOF, and a remote reader closing stdin before output/EXIT. The original pre-credit client and daemon from commit d6204bb fail the same signal-pressure regression with a five-second timeout. The fixed tree passes.

PTY hangup regressions synchronize after disabling terminal echo, then verify exact final output and exit status with empty input or 1 MiB of queued input. They cover exit statuses 0, 7, and 37, including 65,556 output bytes. The original 568dc42 reproduction returned 255 and lost final output under queued input; the fix retains the shared master for output drainage after input closes. An Astra high agent independently reviewed the fix and ran all 21 focused checks inside QEMU, confirming its original finding is resolved.

The complete combined make test and make test-sanitize passed. Focused client/daemon ASAN/UBSAN checks also passed with detect_leaks=0: LeakSanitizer cannot trace the credential-dropped, sandboxed processes. Unit sanitizer suites retain detect_leaks=1. Normal and instrumented builds produced no warnings.

Listener regressions exercise real input/output and exit status through wildcard and explicit IPv4/IPv6 listeners. Connected proxies verify COOKIE, ACCEPT, and DTLS reply sources, including a ULA server address replying to an ::1 peer. They also check client IP/port migration, rejection of session records delivered to another local server address, and recovery at the original endpoint. IPv6 link-local zone handling is reviewed in code but lacks a direct integration case.

Trust regressions leave an unknown-host prompt unanswered while a pinned batch login completes. They check concurrent approval of the same key, conflicting pins, unrelated additions, atomic deletion, and refreshed parsing, permissions, entry and byte limits after approval. Isolated baseline binaries from 1ccc5ea fail the intended wildcard-listener and pinned-login checks. An independent 6.1 sol high agent reviewed both fixes and tests without finding blockers.

Reproduce

tools/vm/vm.sh start
tools/vm/vm.sh wait
tools/vm/vm.sh sync
tools/vm/vm.sh run 'make -j2 all && make test && make test-sanitize'
tools/vm/vm.sh stop

Guest logs are under /work/results/: pty-fix-full-test.log, pty-fix-sanitize.log, pty-fix-sanitize-app-build.log, pty-fix-input-sanitize.log, and pty-fix-astra-focused.log. The original PTY failure is in review-astra-pty.log; earlier negative controls are in wildcard-baseline/regression.log and trust-concurrency-baseline.log. Review copies are under the ignored tools/vm/.state/ directory. Re-running validation requires a VM; the integration harness checks both its disposable-guest marker and actual virtualization detection.

These checks validate the implemented prototype. The mutation harness is a bounded deterministic smoke test, not a long-running coverage-guided fuzzing campaign. Sanitizers instrument project code, not the vendored OpenSSL/libyaml libraries. Internal code review and these results do not constitute an independent security audit or establish production readiness.

END OF DOCUMENT / psh/3All documentation