This commit is contained in:
udo
2026-06-12 19:55:35 +00:00
parent 80285b7fb4
commit 961df2d542
31 changed files with 2681 additions and 7 deletions
+45
View File
@@ -0,0 +1,45 @@
# spikes/wasm-phase5 — parity, audit, and performance harness
Phase 5's production exit requires the full network suite to pass on the WASM
worker and performance numbers to be published. The production worker is not in
this branch yet, so this spike builds the Phase 5 harness and records the native
baseline that the WASM worker must match.
Run on `k-uce`:
```bash
bash spikes/wasm-phase5/run_phase5.sh
```
Expected final line:
```text
PHASE5 HARNESS: PASS
```
Artifacts are written under `/tmp/uce/wasm-phase5/`:
- `native-network.json` — full native network suite result.
- `native-starter.json` — starter-focused parity subset; this protects against
a vacuous `--match starter` exit gate.
- `site-static-audit.{json,md}` — candidate cross-request/static-state risks in
`site/` for the §3.2 semantic change audit.
- `benchmark.{json,md}` — warmed native baseline for the three Phase 5 budget
pages:
- `template-heavy-doc`: `/doc/singlepage.uce`
- `sqlite-page`: `/demo/sqlite.uce`
- `component-heavy-starter`: `/examples/uce-starter/?dashboard`
`benchmark.py` also accepts `--wasm-base-url` once a WASM worker endpoint exists.
When provided, it compares WASM medians against the Phase 5 budget of ≤2× native
page latency. Workspace birth and internal component call overhead budgets still
need worker-internal probes; this harness documents the gap rather than faking
those numbers.
Current scope:
- Native parity and baseline collection are automated.
- WASM parity/performance comparison is ready but blocked on the production WASM
worker endpoint.
- The static-state audit is heuristic and intentionally conservative; findings
must be reviewed by a human before migration work is scheduled.
+100
View File
@@ -0,0 +1,100 @@
#!/usr/bin/env python3
"""Phase 5 audit for cross-request/static state risks in site files."""
from __future__ import annotations
import json
from dataclasses import asdict, dataclass
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
SITE = ROOT / "site"
PATTERNS = [
("static local/global", "static "),
("once hook", "ONCE("),
("init hook", "INIT("),
("background task", "task_"),
]
SKIP_PARTS = {".git", "tmp", "work", "bin", "pkg", "__pycache__"}
@dataclass
class Finding:
path: str
line: int
kind: str
text: str
note: str
def iter_files() -> list[Path]:
result: list[Path] = []
for path in SITE.rglob("*"):
if not path.is_file():
continue
if any(part in SKIP_PARTS for part in path.parts):
continue
if path.suffix not in {".uce", ".h", ".txt"}:
continue
result.append(path)
return sorted(result)
def note_for(kind: str, text: str) -> str:
if kind in {"once hook", "init hook"}:
return "Audit behavior under per-request wasm workspaces; ONCE/INIT may need host-side cache semantics if used for cross-request state."
if kind == "background task":
return "Task APIs cross request lifetimes; verify they are host handles, not guest statics."
return "Check whether state is request-local, immutable, or intentionally persistent; unit statics reset per wasm workspace."
def scan() -> list[Finding]:
findings: list[Finding] = []
for path in iter_files():
try:
lines = path.read_text(encoding="utf-8").splitlines()
except UnicodeDecodeError:
continue
for lineno, line in enumerate(lines, 1):
stripped = line.strip()
if stripped.startswith("//") or stripped.startswith("# "):
continue
for kind, needle in PATTERNS:
if needle in line:
findings.append(Finding(
path=str(path.relative_to(ROOT)),
line=lineno,
kind=kind,
text=stripped[:180],
note=note_for(kind, stripped),
))
return findings
def write_reports(findings: list[Finding], out_dir: Path) -> None:
out_dir.mkdir(parents=True, exist_ok=True)
(out_dir / "site-static-audit.json").write_text(json.dumps([asdict(f) for f in findings], indent=2) + "\n")
lines = ["# Phase 5 site static-state audit", ""]
if not findings:
lines.append("No candidate cross-request/static-state patterns found.")
else:
lines.extend(["| file | line | kind | code | note |", "|---|---:|---|---|---|"])
for f in findings:
code = f.text.replace("|", "\\|")
note = f.note.replace("|", "\\|")
lines.append(f"| {f.path} | {f.line} | {f.kind} | `{code}` | {note} |")
(out_dir / "site-static-audit.md").write_text("\n".join(lines) + "\n")
def main() -> int:
out_dir = Path("/tmp/uce/wasm-phase5")
findings = scan()
write_reports(findings, out_dir)
print(f"Found {len(findings)} candidate static/cross-request patterns")
print(f"wrote {out_dir / 'site-static-audit.json'} and {out_dir / 'site-static-audit.md'}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
+153
View File
@@ -0,0 +1,153 @@
#!/usr/bin/env python3
"""Phase 5 native/WASM benchmark harness.
This runner intentionally has no third-party dependencies. It records a warmed
native HTTP baseline now and can compare against a future wasm worker by passing
--wasm-base-url. Results are written as JSON plus a small Markdown table.
"""
from __future__ import annotations
import argparse
import http.client
import json
import statistics
import time
from dataclasses import asdict, dataclass
from pathlib import Path
from urllib.parse import urlparse
@dataclass
class Target:
name: str
url: str
expected: str
@dataclass
class Measurement:
backend: str
target: str
url: str
ok: bool
status: int
samples_ms: list[float]
median_ms: float
mean_ms: float
min_ms: float
max_ms: float
note: str = ""
def request_once(base_url: str, host_header: str, path: str, timeout: float) -> tuple[int, bytes, float]:
parsed = urlparse(base_url)
if parsed.scheme not in ("http", "https") or not parsed.hostname:
raise SystemExit(f"invalid base url: {base_url}")
port = parsed.port or (443 if parsed.scheme == "https" else 80)
conn_cls = http.client.HTTPSConnection if parsed.scheme == "https" else http.client.HTTPConnection
headers = {}
if host_header:
headers["Host"] = host_header
started = time.perf_counter()
conn = conn_cls(parsed.hostname, port, timeout=timeout)
try:
conn.request("GET", path, headers=headers)
response = conn.getresponse()
body = response.read()
elapsed_ms = (time.perf_counter() - started) * 1000.0
return response.status, body, elapsed_ms
finally:
conn.close()
def measure_backend(backend: str, base_url: str, host_header: str, targets: list[Target], warmups: int, samples: int, timeout: float) -> list[Measurement]:
results: list[Measurement] = []
for target in targets:
path = urlparse(target.url).path
if "?" in target.url:
path = target.url
for _ in range(warmups):
request_once(base_url, host_header, target.url, timeout)
durations: list[float] = []
status = 0
ok = True
note = ""
for _ in range(samples):
status, body, elapsed_ms = request_once(base_url, host_header, target.url, timeout)
durations.append(elapsed_ms)
text = body.decode("utf-8", errors="replace")
if status != 200:
ok = False
note = f"HTTP {status}"
elif target.expected and target.expected not in text:
ok = False
note = f"missing marker {target.expected!r}"
results.append(Measurement(
backend=backend,
target=target.name,
url=target.url,
ok=ok,
status=status,
samples_ms=durations,
median_ms=statistics.median(durations),
mean_ms=statistics.fmean(durations),
min_ms=min(durations),
max_ms=max(durations),
note=note,
))
return results
def compare(results: list[Measurement]) -> list[str]:
native = {r.target: r for r in results if r.backend == "native"}
lines = ["| target | backend | median ms | mean ms | budget | status |", "|---|---:|---:|---:|---|---|"]
for result in results:
budget = "baseline"
status = "PASS" if result.ok else "FAIL"
if result.backend != "native" and result.target in native:
limit = native[result.target].median_ms * 2.0
budget = f"{limit:.1f} ms"
if result.median_ms > limit:
status = "FAIL"
lines.append(f"| {result.target} | {result.backend} | {result.median_ms:.1f} | {result.mean_ms:.1f} | {budget} | {status} {result.note} |")
return lines
def build_targets() -> list[Target]:
return [
Target("template-heavy-doc", "/doc/singlepage.uce", "UCE API"),
Target("sqlite-page", "/demo/sqlite.uce", "SQLite"),
Target("component-heavy-starter", "/examples/uce-starter/?dashboard", "Dashboard"),
]
def main() -> int:
parser = argparse.ArgumentParser(description="Phase 5 native/wasm benchmark harness")
parser.add_argument("--native-base-url", default="http://localhost:80")
parser.add_argument("--wasm-base-url", default="", help="optional wasm worker URL; omitted until worker exists")
parser.add_argument("--host-header", default="uce.openfu.com")
parser.add_argument("--warmups", type=int, default=2)
parser.add_argument("--samples", type=int, default=5)
parser.add_argument("--timeout", type=float, default=10.0)
parser.add_argument("--out-dir", default="/tmp/uce/wasm-phase5")
args = parser.parse_args()
targets = build_targets()
results = measure_backend("native", args.native_base_url, args.host_header, targets, args.warmups, args.samples, args.timeout)
if args.wasm_base_url:
results.extend(measure_backend("wasm", args.wasm_base_url, args.host_header, targets, args.warmups, args.samples, args.timeout))
out_dir = Path(args.out_dir)
out_dir.mkdir(parents=True, exist_ok=True)
(out_dir / "benchmark.json").write_text(json.dumps([asdict(r) for r in results], indent=2) + "\n")
md_lines = ["# Phase 5 benchmark report", "", *compare(results), ""]
if not args.wasm_base_url:
md_lines.append("WASM worker URL was not provided; this report is the native baseline that future wasm runs compare against.")
(out_dir / "benchmark.md").write_text("\n".join(md_lines) + "\n")
print("\n".join(md_lines))
print(f"wrote {out_dir / 'benchmark.json'} and {out_dir / 'benchmark.md'}")
return 0 if all(r.ok for r in results) else 1
if __name__ == "__main__":
raise SystemExit(main())
+31
View File
@@ -0,0 +1,31 @@
#!/bin/bash
# Phase 5 harness: native parity, site static audit, and native perf baseline.
# Run on k-uce from repo root.
set -euo pipefail
cd "$(dirname "$0")/../.."
OUT=/tmp/uce/wasm-phase5
mkdir -p "$OUT"
python3 tests/run_network_tests.py --include-internal --json-report "$OUT/native-network.json"
python3 tests/run_network_tests.py --include-internal --match starter --json-report "$OUT/native-starter.json"
python3 spikes/wasm-phase5/audit_site_statics.py
python3 spikes/wasm-phase5/benchmark.py --out-dir "$OUT"
python3 - <<'PY'
import json
from pathlib import Path
out = Path('/tmp/uce/wasm-phase5')
network = json.loads((out / 'native-network.json').read_text())
starter = json.loads((out / 'native-starter.json').read_text())
bench = json.loads((out / 'benchmark.json').read_text())
failures = [r for r in network if not r['ok']] + [r for r in starter if not r['ok']] + [r for r in bench if not r['ok']]
if failures:
print('PHASE5 HARNESS: FAIL')
for failure in failures:
print(failure)
raise SystemExit(1)
print('PHASE5 HARNESS: PASS')
print(f"network_cases={len(network)} starter_cases={len(starter)} benchmarks={len(bench)}")
print(f"reports={out}")
PY