Files
LithosAnanake/logs/hermes-channel-smoke-results.md
T

4.1 KiB
Raw Blame History

Hermes Channel Negotiation Smoke Test — Results

Date: 2026-06-27
Branch: lithosananke
Script: tools/hermes_channel_smoke.sh
Status: PASS — 16/16


Summary

Full channel negotiation lifecycle validated: CH-REQUEST → CH-ACCEPT → business messaging → CH-CLOSE → HERMES-TICK (hot, no reap) → zero heat → HERMES-TICK (reap) → CH-ACTIVE = COMMON-CH only.


Output

>>> [1] CH-REQUEST Hera->Hermes negotiate
>>> [2] CH-ACCEPT (Hermes creates ephemeral ch)
>>> [3] CH-STATE (expect 1=OPEN): 1
>>> [4] CH-ID (expect non-0): 2
>>> [5] CH-OWNER (expect 1=Hermes): 1
>>> [6] Y sends chanid to X on COMMON
>>> [7] COMMON-CH OPEN (expect 1): 1
>>> [8] business msg on ephemeral ch
>>> [9] CH-CLOSE
>>> [10] CH-STATE (expect 2=CLOSING): 2
>>> [11] HERMES-TICK (hot channel, no reap yet)
>>> [12] CH-STATE after tick (expect 2=CLOSING): 2
>>> [13] Zero heat + HERMES-TICK (reap)
>>> [14] COMMON-CH OPEN (expect 1): 1
>>> [15] CH-ACTIVE is COMMON-CH (expect 1): -1
>>> === Channel negotiation smoke complete ===

Validation Results

# Check Result
1 test started PASS
2 CH-ACCEPT ok PASS
3 ch state OPEN PASS
4 ch id non-zero PASS
5 ch owner Hermes PASS
6 chanid sent PASS
7 COMMON still OPEN PASS
8 business msg PASS
9 CH-CLOSE called PASS
10 state CLOSING PASS
11 tick no reap PASS
12 still CLOSING after tick PASS
13 zero+tick reap PASS
14 COMMON still OPEN after PASS
15 CH-ACTIVE is COMMON-CH PASS
16 smoke complete PASS

Result: 16 passed, 0 failed


Architecture Notes

Protocol path confirmed:

Step Actor Action
1 Hera (0) CH-REQUEST on COMMON → MSG-SEND with SPAWN-EVENT type
2 Hermes (1) CH-ACCEPT → ephemeral channel allocated, ID=2, OWNER=1, STATE=OPEN
35 Verify ch fields: STATE=1, ID=2 (non-zero), OWNER=1
6 Hermes Sends ch ID to Hera on COMMON via MSG-SEND
7 COMMON-CH still OPEN after in-use
8 Business message on ephemeral channel
910 Hermes CH-CLOSE → STATE becomes CH-CLOSING (2)
1112 HERMES-TICK with heat > 0: channel not reaped, STATE still 2
13 Zero heat manually; HERMES-TICK reaps ephemeral channel
1415 COMMON-CH still OPEN; CH-ACTIVE = COMMON-CH only

CH-REAP-SAFE rebuild-the-list pattern:
Resets CH-ACTIVE to 0 at the start of the walk, then re-inserts non-reaped channels. Freed channels are simply skipped. This avoids the prior double-free bug where freed nodes remained linked in CH-ACTIVE.

CH-ACCEPT stack fix:
CH-ACTIVE !DUP CH-ACTIVE ! — the original consumed the only copy of ch, returning an empty stack instead of ( ch ).

Block size constraint:
Test sequence split across blocks 9998 (helpers + VARIABLE MYCHAN + colon words) and 9999/9000 (two-part execution), each well under the 1024-byte limit. Block 9999 alone was 1159 bytes, causing silent truncation before steps [15] and "smoke complete".

Compile-only constraint:
IF THEN ELSE DO LOOP are compile-only in StarForth — cannot appear in interpreted block context. All control flow in helpers is wrapped in colon word definitions (block 9998). The abort check ASSERT-CH wraps the IF...BYE...THEN idiom. TRIP-ZERO-CH wraps the zero-heat + HERMES-TICK sequence. Both are defined before CD-INIT so they are available when called from block 9999/9000.


Bugs Fixed (prerequisite work)

Bug Description Fix
H4 CH-REAP-SAFE freed channel stayed in CH-ACTIVE → double-free on next tick Rebuild-the-list: reset CH-ACTIVE=0, re-insert non-reaped channels only
H5 CH-ACCEPT CH-ACTIVE ! consumed the only copy of ch → empty stack return DUP CH-ACTIVE ! keeps ch on data stack

What This Does Not Test

  • Multi-VM channel negotiation across separate process boundaries
  • MBR (member) records within channels
  • CH-MAX exhaustion (free list empty path)
  • Concurrent channel lifecycle (multiple ephemeral channels)