You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 88860e3
Browse filesBrowse the repository at this point in the historyBrowse files
Third audit loop. Three P0s the prior loops missed:
P0-1 — Drift-detection test was itself tautological. It constructed MentorAgentProperties
manually with the literal "pi-mentor-runner.mjs" and asserted that string equalled the
constant. The @DefaultValue was never bound; renaming it would not have failed the test.
Replaced with a real round-trip through Spring's Binder against an empty property source —
that actually exercises @DefaultValue resolution.
P0-2 — runner_post_turn_gc / runner_prewarm_ok / runner_prewarm_failed events were
write-only telemetry. The runner emitted them on every turn + every cold start; Java's
translator allow-listed them and dropped them; no consumer read them. They were added to
counter wave-24's "no observability" criticism but never wired through. Pure stdout noise.
Cut entirely. If we want production observability for GC/prewarm, that's a separate,
deliberate commit (wired to MeterRegistry, with a real consumer). Side effect: handleHello
re-entrance pollution disappears (no more bogus runner_prewarm_ok durationMs=0 on reattach).
P0-3 — handleHello idempotency: solved by P0-2 (no events emitted → nothing to pollute).
P1 — global.gc() fired on EVERY agent_end, including 1-token turns. STW major GC costs
50-200 ms on a 100 MB heap (Node 22, nodejs/node#43378+); for a "Reply: ready." turn that
allocated 100 KB the cost is all pause, no benefit. Gated on
process.memoryUsage().heapUsed >= 64 MB so the call only fires when there's genuinely
something to compact.
P1 — Marginal-RSS gate: switched from Math.abs() to Math.max(0, signed). Wave 25 introduced
abs() with the rationale "bloat AND release both trigger investigation"; loop 3 caught the
flaw: a runner whose RSS happens to drop between floor and K-opens samples (V8 GC timing,
allocator decay) is not a regression. Only growth is. The signed-delta clamped at 0 asserts
the direction we care about and avoids false-positive flakes on a normal V8 scavenge.
P1 — Allocator self-check at runner startup. PiRuntimeFactory passes
LD_PRELOAD=/usr/local/lib/libjemalloc.so.2 and the Dockerfile creates the per-arch symlink
at build time. If either drifts (symlink missing on a future image, env clobbered by
deploy config) ld.so silently falls back to glibc and the wave-25 jemalloc tuning silently
disappears. Now reads /proc/self/maps at startup and logs a single WARN line on glibc
fallback. Currently fires correctly on the host stress harness (no Docker → no LD_PRELOAD);
silent in production unless drift happens.
Translator allowlist + test entries for the dropped event types removed in lockstep.
Validated: PiRuntimeFactoryTest 29 + PiEventToUiChunkTranslatorTest 33 + all mentor unit
tests green. Live stress N=3 (cold-start 64 ms, peak RSS 165-170 MB) + N=3×K=5 (peak RSS
169-172 MB) — 0 failures, all budgets satisfied.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: server/application-server/src/main/java/de/tum/in/www1/hephaestus/agent/mentor/chat/wire/PiEventToUiChunkTranslator.java
Copy file name to clipboardExpand all lines: server/application-server/src/test/java/de/tum/in/www1/hephaestus/agent/mentor/chat/wire/PiEventToUiChunkTranslatorTest.java
Copy file name to clipboardExpand all lines: server/application-server/src/test/java/de/tum/in/www1/hephaestus/agent/mentor/live/MentorSandboxStressTest.java
0 commit comments