diff --git a/whitepaper/outreach/wave28-sci-lisp-smalltalk-survey.md b/whitepaper/outreach/wave28-sci-lisp-smalltalk-survey.md new file mode 100644 index 000000000..dbbbc200f --- /dev/null +++ b/whitepaper/outreach/wave28-sci-lisp-smalltalk-survey.md @@ -0,0 +1,87 @@ +# Wave 28 — Scientific niches, Lisp/Scheme, Smalltalk, Erlang DB, Routing + +**Survey date:** 2026-04-25 +**Tool:** unmoad (9 active MOAD detectors, HIGH+ severity filter) +**Scope:** 10 projects across software-defined radio (gnuradio), particle physics (geant4), HPC package manager (spack), Lisp/Scheme (sbcl, racket), F# compiler (fsharp), Smalltalk (pharo), Erlang KV store (riak), and routing daemon (frr). + +--- + +## Summary + +Wave 28 totals 2,053 HIGH+ findings across 10 projects. **8 new clean-scan honor roll entries.** Honor roll cumulative: **192 projects** across waves 3-28. + +**No flagship CWE-407 patches ship this pass.** Lisp/Scheme projects (sbcl, racket) cluster their findings in `(member ...)` / `(memq ...)` / `(position ...)` primitives — the canonical Lisp linear-search idiom (same Wave 24 maxima pattern). HPC/scientific projects (spack, geant4) cluster theirs in intentional spec/spatial intersection algorithms. + +Two zero-finding results need caveats: +- **pharo** (Smalltalk): 0 findings because unmoad has no Smalltalk language module — `.st` files were not scanned. Joins backlog as "unverified, awaiting Smalltalk detector". +- **riak** (Erlang): 0 findings, but the cloned `riak` repo is the rebar3 wrapper (3.5MB) — actual riak_kv code lives in submodules. Noted as partial scan. + +## Clean-scan honor roll — 8 new entries + +| Project | Lang | Role | Notes | +|---------|------|------|-------| +| **fsharp** | F# | F# compiler + tooling | 10 findings: `fsihelp.fs` xpath `contains(@name, ...)` is XPath function (intentional XML query); `Source.cs` `ranges[i].GetSpan(...).Contains(caretPoint)` is WPF text-view containment (geometric); `ProjectReferenceNode.IndexOf('|')` single-char position. **clean** | +| **gnuradio** | C++/Python | Software-defined radio | 62 findings: `qsettings.contains(full_key)` is Qt QSettings.contains (O(log) hash), build-time Python tools (`cppfile_editor.py`, `blocktool/comments.py` parsing build artifacts). **clean** | +| **geant4** | C++ | Monte Carlo particle simulation | 87 findings: `liblist.c` "."/".." dirent skip (constant 2 strings), `G4StrUtil::contains(aString, "#")` substring search, `BooleanProcessor.src` `plane.distance(...)` is intentional geometry primitive. **clean** | +| **spack** | Python | HPC package manager | 459 findings: 356 M3 in test files; 72 M7 are `Spec.intersects(other)` — intentional Spack version-spec intersection (the algorithm, not a lookup). Same Wave 24 maxima Lisp-algorithm pattern. **clean** | +| **sbcl** | Common Lisp | Steel Bank Common Lisp | 741 findings: 727 M1 are Lisp `(member ...)`/`(position ...)` in `tools-for-build/ucd.lisp` (Unicode character database build), `target-package.lisp` (package internals), `meta-vmdef.lisp` (VM definitions). Lisp-tradition O(N) primitives, bounded by language input. **clean** | +| **racket** | Racket/Scheme | Racket programming language | 388 findings: 383 M1 are Scheme/Racket `memq`/`member`/`assq` in compiler bootstrap (`xform.rkt`, `s/syntax.ss`). Same Lisp-tradition pattern as sbcl/maxima. **clean** | +| **frr** | C | FRRouting (routing daemon family) | 306 findings: `ospf6d.c` per-VRF name comparison (bounded by VRF count, typically <100), `bgpd/bgp_mplsvpn.c` route-map name lookup, `bgpd/bgpd.c` peer-group name lookup. Bounded by network configuration size. **clean** | +| **riak** | Erlang | Distributed KV store (Basho) | 0 findings — the `riak` GitHub repo is the rebar3 wrapper (3.5MB). Actual `riak_kv`, `riak_core` code lives in git submodules not pulled. **partial scan** — joins honor roll on the wrapper but `riak_kv`/`riak_core` deferred. | + +Honor roll now stands at **192 projects** validated zero-real-finding under MOAD-0001 scanning. + +## Per-target findings + +| Project | Lang | Total | M1 | M3 | M4 | M5 | M6 | M7 | M9 | M11 | Triage | +|---------|------|------:|---:|---:|---:|---:|---:|---:|---:|----:|--------| +| **sbcl** | Lisp | 741 | 727 | - | 14 | - | - | - | - | - | Lisp `(member ...)` build-time + runtime primitives. **clean** | +| **spack** | Python | 459 | 24 | 356 | - | 1 | 1 | 72 | - | 5 | Test ContextValue + Spec.intersects algorithm. **clean** | +| **racket** | Racket | 388 | 383 | - | 3 | - | - | - | 2 | - | Scheme memq/member compiler bootstrap. **clean** | +| **frr** | C | 306 | 241 | 1 | 13 | - | 22 | 21 | - | 8 | Per-VRF + route-map + peer-group. **clean** | +| **geant4** | C++ | 87 | 37 | - | 1 | - | - | 49 | - | - | dirent skip + spatial geometry. **clean** | +| **gnuradio** | C++/Python | 62 | 40 | 14 | - | - | - | 7 | - | 1 | QSettings + build-time Python. **clean** | +| **fsharp** | F# | 10 | 5 | - | - | - | - | 5 | - | - | XPath + WPF text-view geometry. **clean** | +| pharo | Smalltalk | 0 | - | - | - | - | - | - | - | - | **unscanned** — no Smalltalk language module. | +| **riak** (wrapper) | Erlang | 0 | - | - | - | - | - | - | - | - | rebar3 wrapper only (3.5MB); actual app code in submodules. **partial** | + +## Investigations + +### Lisp/Scheme `(member ...)` ecosystem pattern (sbcl, racket, maxima) + +Lisp's `(member item list :test ...)` is the canonical containment primitive — O(N) linear scan returning the tail of the list at the match. Used pervasively in: +- **sbcl** Unicode character database builds, package symbol resolution, VM type definitions +- **racket** Scheme/Chez compiler bootstrap, syntax expansion, scribble doc generation +- **maxima** (Wave 24) graph isomorphism, sheaf cohomology, gentran transformations + +Replacing with hash-based membership changes Lisp semantics (member returns the matched-from-here tail, callers may rely on this). The Lisp ecosystem's idiom is to use `member` for small lists and explicit hash tables (`make-hash-table`) for large ones — the choice is intentional per call site. + +**Detector enhancement candidate** (continued from Wave 24 maxima): Lisp `member`/`memq`/`assq`/`position` algorithm awareness — these aren't to be replaced wholesale. + +### spack `Spec.intersects` — intentional algorithm + +Spack's `spack.spec.Spec.intersects(other)` is the version/variant intersection algorithm at the heart of dependency resolution. The 72 M7 hits are recursive intersection calls down the spec tree — the algorithm is the work, not a lookup that should be cached. + +### geant4 `G4StrUtil::contains(aString, "#")` substring + `plane.distance(...)` geometry + +`contains(aString, "#")` is single-char comment detection in CHEM file parsing. `BooleanProcessor.src` Constructive Solid Geometry uses `plane.distance(...)` for boolean-mesh operations — intentional geometric algorithm, not a lookup. + +### pharo Smalltalk gap + +Pharo's source is `.st` files (Smalltalk class definitions). unmoad's language detection covers ~42 languages but not Smalltalk yet. Joins the gap-list alongside Erlang's full Riak codebase. + +## Triage backlog + +1. **Scanner enhancement: Smalltalk language module** — would enable scanning Pharo + GToolkit + Squeak. +2. **Scanner enhancement: Lisp `(member ...)` algorithm awareness** (continued from Wave 24) — sbcl + racket reinforce. +3. **Scanner enhancement: Spack/conan-style intersects() algorithm awareness** — package-spec intersection is the algorithm, not a lookup. + +## Method + +Same as Waves 3-27: shallow clone, `unmoad -s high -f json`, filter test/vendor/codegen noise, manual triage of strongest source-only candidates per project. **Eight projects added to clean-scan honor roll.** Two more (pharo, riak) noted as partial-scan with caveats. No new UNDF IDs assigned (no patches shipped). + +## References + +- `unmoad` detection engine: `git.unturf.com/engineering/unmoad.com` +- Earlier surveys: `/test-harness-survey/` through `/wave27-pkg-build-script-firmware-survey/` +- Clean-scan honor roll cumulative: 192 projects across waves 3-28