tidy: 18g sub-arc — DESIGN ratification, latency bench, negative coverage

Resolves the architect's drift report on the 18g sub-arc:

- DESIGN.md: ratify mode-metadata's codegen role. param_modes /
  ret_mode were already on Type::Fn since 18a; with 18d.4 / 18g
  they became load-bearing for drop-emission decisions in
  codegen. The new 'Mode metadata is load-bearing for codegen'
  subsection records the four seams (Iter A + Iter B + 18g.1 +
  18g.2) and names the let-alias-of-borrow carve-out the gates
  do not propagate through.

- bench/run.sh: post-throughput, invoke bench/latency_harness.py
  on the three canonical arms (Implicit @ gc, explicit @ rc,
  Implicit @ rc control). The Boehm-retirement bench numbers
  are now reproducible by anyone running the harness, not just
  by hand on a specific host.

- Negative coverage: examples/rc_let_implicit_returning_app
  + alloc_rc_let_binder_for_implicit_returning_app_does_not_drop
  pin the asymmetry to the (own)-ret-mode test (live=0 there,
  live=1 here). The Borrow-ret-mode case is covered by the
  language design itself — typechecker rejects 'borrow-
  passthrough' shapes with consume-while-borrowed.

JOURNAL entry records four items as deferred known debt:
emit_inlined_partial_drop dynamic-tag fallback, carve-out
diagnostics surface, bench-number stat-of-N, and the
cross-family ordering observation about CLAUDE.md's tidy-iter
rule.

The 18-arc is formally closed with this tidy. Next iter is
the orchestrator's Boehm-retirement decision (Path A vs Path B
from JOURNAL 2026-05-08 18f entry, joined by the post-18g.2
re-bench numbers).
This commit is contained in:
2026-05-08 14:37:36 +02:00
parent 97e793dd62
commit 3113258680
6 changed files with 345 additions and 0 deletions
+34
View File
@@ -166,5 +166,39 @@ for f in "${fixtures[@]}"; do
"$f" "$gc_t" "$bp_t" "$rc_t" "$gc_ratio" "$rc_ratio" "$gc_r" "$bp_r" "$rc_r"
done
# Iter 18g tidy: latency bench. The throughput table above is wall-
# time-and-RSS — the wrong metric for Decision 10's real-time claim.
# `bench/latency_harness.py` measures per-operation tail latency
# (median + p99 + p99.9 + max) on PTY-line-buffered stdout for the
# `bench_latency_*` fixtures. We invoke it for the three canonical
# arms (Boehm-fair Implicit @ gc, RC-fair explicit @ rc, control
# Implicit @ rc) and emit a second table.
#
# Skipped if the harness / fixtures aren't present (the latency bench
# was added in 18f.2 and may not exist on older branches that share
# this script).
LAT_HARNESS="$ROOT/bench/latency_harness.py"
LAT_IMPL_SRC="$ROOT/examples/bench_latency_implicit.ail.json"
LAT_EXPL_SRC="$ROOT/examples/bench_latency_explicit.ail.json"
if [[ -x "$LAT_HARNESS" && -f "$LAT_IMPL_SRC" && -f "$LAT_EXPL_SRC" ]]; then
echo
echo ">>> latency bench (PTY inter-arrival, 1000 samples per arm)"
echo
# Build the three arms. -O2 to match the throughput table.
"$AIL" build --opt=-O2 --alloc=gc "$LAT_IMPL_SRC" -o "$OUTDIR/bench_latency_implicit_gc" >/dev/null
"$AIL" build --opt=-O2 --alloc=rc "$LAT_EXPL_SRC" -o "$OUTDIR/bench_latency_explicit_rc" >/dev/null
"$AIL" build --opt=-O2 --alloc=rc "$LAT_IMPL_SRC" -o "$OUTDIR/bench_latency_implicit_rc" >/dev/null
# The harness prints a multi-line block per arm; we let it speak
# for itself. The orchestrator captures the verbatim output into a
# JOURNAL entry like the throughput table above.
"$PY" "$LAT_HARNESS" "$OUTDIR/bench_latency_implicit_gc" --label "implicit @ gc (Boehm-fair)"
echo
"$PY" "$LAT_HARNESS" "$OUTDIR/bench_latency_explicit_rc" --label "explicit @ rc (RC-fair)"
echo
"$PY" "$LAT_HARNESS" "$OUTDIR/bench_latency_implicit_rc" --label "implicit @ rc (control: leaks, no STW)"
fi
echo
echo ">>> done"