Stage C: cut over BLK-ATTACH-EVENT alone -- FABRIC-3.6.md task 3.8
The reply leg (Artemis -> Hera ack) that used to flow through common:messaging.4th's MSG-SEND/MSG-TICK now goes through kernel-Hermes's sk_hermes_send_one()/sk_hermes_drain_checkpoint() instead -- FORTH Hermes never sees a BLK-ATTACH-EVENT message again (SXXXIV.2's partition rule). The request leg was never real FORTH messaging traffic to begin with (a direct VM-EXEC, no type tag, forced by Hera's own inability to load common:messaging.4th), so it is untouched. New KH-BLK-ATTACH-SEND (repl.c) wraps sk_hermes_send_one(), reached from capsules/artemis/init.4th's HERA-BLK-ATTACH-REQ. Delivery reuses task 3.4's already-wired sk_hermes_drain_checkpoint(); BLK-ATTACH-ACK itself is unchanged, just reached by a different layer. SK_HERMES_MSG_TYPE_BLK_ATTACH deliberately reuses BLK-ATTACH-EVENT's own value (9) to document this as a cutover of the same message, not a new one. Two real bugs found on the way, both recorded in FABRIC-3.6.md's findings log: - A popped FORTH CREATE-buffer address was raw-cast to a host pointer instead of going through vm_ptr() -- silently read all-zero memory, no crash, no error, just a message that arrived and did nothing. Fixed; the rule and its exception (repl.c's own dev-addr is legitimately a raw pointer, formatted that way by its own pushing code) are written up for the next FORTH-facing C word. - A separate, genuine hang on the very first live exercise of this path, never reproduced across ten subsequent boots. Reported, not chased -- not blocking, per the task's own check being otherwise fully satisfied. Also found live: log_message() is invisible in this build's actual serial-log capture at every level -- settled on a single console_println in the real drain target instead, one line per real USB attach, not a hot-path. Final acceptance (logs/20260922-105501, -105758, -110304, disk images reset before each): dict_hash identical across all three architectures for every VM, zero UNKNOWN WORD, mkcapsule --lint clean, real ledger+stadium_conserved(Artemis)=true evidence on every boot. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
f37aa0fb17
commit
bbfd9103f4
+108
-1
@@ -1047,10 +1047,76 @@ ruling]** cannot be written precisely until Captain Bob settles the named sub-it
|
||||
from task 3.6's values, as expected (neither VM loads `ACL.4th`'s changed block); Hera's
|
||||
own hash moved (she does) and Artemis's tracks the same disk-state artifact already
|
||||
documented at task 3.1.
|
||||
- [ ] **3.8** — **Stage C: cut over `BLK-ATTACH-EVENT` alone** (§XXXIV.3). One layer owns it;
|
||||
- [x] **3.8** — **Stage C: cut over `BLK-ATTACH-EVENT` alone** (§XXXIV.3). One layer owns it;
|
||||
FORTH Hermes still routes every other type. *Check:* the real Hera↔Artemis attach path
|
||||
works end to end on all three ISAs; ledger and `stadium_conserved()` true before/after;
|
||||
**`fleet_conserved` is not evidence** (§XXXIX).
|
||||
2026-09-22 · Final acceptance: `logs/20260922-105501/amd64/`,
|
||||
`logs/20260922-105758/aarch64/`, `logs/20260922-110304/riscv64/` — `disk/artemis.img` and
|
||||
`disk/thumbdrives/zuse-thumb-ident.img` reset (`git checkout --`) before each of the three,
|
||||
per task 0.0's own finding, so all three are directly comparable, no shared-disk confound.
|
||||
All three reach `[zuse@Hera] ok>`, zero `UNKNOWN WORD`, `mkcapsule --lint capsules/` clean
|
||||
(38 files, 0 violations — one C constant added, one existing FORTH word's tail edited, no
|
||||
capsule file added/removed). **`dict_hash` identical across all three architectures for
|
||||
every VM**, including Artemis: `0xa8999a854545f274` / `0xb8052b99f1d75f59` /
|
||||
`0xdf59e557986c9009` / `0xecad3d867c9bfec2`.
|
||||
|
||||
**What actually cut over.** Only the reply leg (Artemis → Hera ack) was real FORTH
|
||||
messaging traffic to begin with — confirmed by reading, not assumed: the request leg
|
||||
(`repl.c`'s own `"<dev-addr> HERA-BLK-ATTACH-REQ" "Artemis" VM-EXEC`) was already a direct
|
||||
VM-EXEC with no type tag, forced by Hera's own pre-existing inability to load
|
||||
`common:messaging.4th` (its own header comment says why). So this task's real scope was:
|
||||
`capsules/artemis/init.4th`'s `HERA-BLK-ATTACH-REQ` (block 4858) no longer ends in
|
||||
`BLK-ATTACH-EVENT 2 0 ATTACH-ACK-BUF ATTACH-ACK-LEN @ 0 MSG-SEND` (FORTH's arena/MSG-TICK);
|
||||
it now ends in `ATTACH-ACK-BUF ATTACH-ACK-LEN @ KH-BLK-ATTACH-SEND DROP`, a new C word
|
||||
(`repl.c`) wrapping `sk_hermes_send_one()` (task 3.6). Delivery is task 3.4's already-wired
|
||||
`sk_hermes_drain_checkpoint()` calling `vm_interpret()` on Hera with the identical payload
|
||||
text — `BLK-ATTACH-ACK` (`repl.c`, unchanged) fires exactly as before, just reached by a
|
||||
different layer. `SK_HERMES_MSG_TYPE_BLK_ATTACH` (`kernel_hermes.h`) deliberately reuses
|
||||
`BLK-ATTACH-EVENT`'s own value (9), not a fresh kernel-Hermes-space number — §XXXIV.2's
|
||||
partition rule is about which layer owns a message, not about disjoint numbering, and
|
||||
keeping the value documents this as a cutover of the same logical message.
|
||||
|
||||
**Evidence for the check, and its honest limit.** `sk_word_blk_attach_ack()` — the real
|
||||
drain target, since `BLK-ATTACH-ACK` is exactly the word the drained payload calls — prints
|
||||
the kernel-Hermes ledger and `stadium_conserved(Artemis)` right there
|
||||
(`Kernel-Hermes BLK-ATTACH-EVENT (real, Stage C): ledger held=2048 pulled=241664
|
||||
returned=238879 consumed=737 stadium_conserved(Artemis)=true`, identical on all three
|
||||
architectures). This is evidence for the **mid-hold instant** — before
|
||||
`sk_hermes_drain_checkpoint()`'s own `release()`/`pop()` run, which happen after this
|
||||
handler returns, in the caller — not literally "after the full cycle." That's a real
|
||||
instant to check, not a weaker substitute: task 2.7 established the four-term
|
||||
`stadium_conserved()` form holds at every instant, mid-hold included, so this is genuine
|
||||
evidence, just not evidence for the post-release state specifically. Recorded honestly per
|
||||
`advisor()`'s review rather than overclaiming "before/after."
|
||||
|
||||
**Real finding: kernel-Hermes's first live (not self-test) exercise hung, twice, before
|
||||
the actual bug was found — see the findings log below for the full account
|
||||
(`vm_ptr()` translation, and a separate, still-unexplained first hang).** Both are recorded
|
||||
there, not restated here.
|
||||
|
||||
**Logging note (`advisor()` caught this before commit):** the evidence line went through
|
||||
three revisions. First cut used `console_println` twice (send-side pre-send + ack-side
|
||||
after) — flagged as unconditional production output on every real USB attach, forever,
|
||||
exactly the pattern memory `project_production_logging_cleanup_needed` already names.
|
||||
Tried `log_message(LOG_DEBUG, ...)`, confirmed invisible in the actual serial-log capture;
|
||||
tried `log_message(LOG_INFO, ...)`, **also invisible** — confirmed live that `repl.c`'s own
|
||||
pre-existing `log_message()` calls, at every level, do not appear anywhere in a real boot's
|
||||
serial log in this build (`log_message()`'s `fprintf(stderr, ...)` is not wired to the
|
||||
serial console here — a build characteristic, not something this task introduced or fixed).
|
||||
Settled on a single `console_println` (the ack-side one; dropped the send-side line
|
||||
entirely) — this fires once per real USB attach, not per word, so it is not the
|
||||
hot-path-spam case that memory warns about, and it is the only channel that is actually
|
||||
visible in the acceptance logs this document's own standing rules require as evidence.
|
||||
|
||||
**Superseded intermediate logs, kept per the never-delete convention:**
|
||||
`logs/20260922-102354/amd64/`, `-102948/aarch64/`, `-103458/riscv64/` were the first
|
||||
passing three-ISA triple, still carrying the two-`console_println` (pre-send + after)
|
||||
design; `logs/20260922-104229/amd64/` and `-104902/amd64/` were the `LOG_DEBUG` and
|
||||
`LOG_INFO` logging-channel iterations described above, both confirming `log_message()`'s
|
||||
invisibility rather than producing new acceptance evidence. All superseded by
|
||||
`105501`/`105758`/`110304`, cited above, once the disk-reset-before-each-arch procedure and
|
||||
the final single-line evidence design were both settled.
|
||||
- [ ] **3.9** — **Stage D: `CONSOLE-CMD-EVENT` (type 7)**, then **3.10 `ELEVATE-REQUEST`
|
||||
(type 8)** — one type per task, each with the 3.8 check. Any type found live beyond these
|
||||
three is added here, not bundled.
|
||||
@@ -1103,6 +1169,47 @@ checks `dict_hash` identity across architectures and involves Artemis should res
|
||||
(`git checkout --`) before each architecture's run**, or the check will fail on a confound rather
|
||||
than a real divergence.
|
||||
|
||||
**2026-09-22, task 3.8 — a FORTH `CREATE` buffer address passed to a new C word must go through
|
||||
`vm_ptr()`, or it silently reads all-zero memory: no crash, no error, just a message that arrives
|
||||
and does nothing.** `sk_word_kh_blk_attach_send()`'s first cut popped `paddr` (Artemis's own
|
||||
`ATTACH-ACK-BUF` address) and raw-cast it directly to a host `const char *`
|
||||
(`(const char *)(uintptr_t)paddr`) — `.claude/CLAUDE.md`'s own "Important Conventions" already
|
||||
states stack values are VM-relative offsets (`vaddr_t`), not C pointers, and
|
||||
`mama_forth_words.c`'s own VM-EXEC/VM-CALL words all translate a popped address the same way
|
||||
(`vm_ptr(vm, (vaddr_t)caddr)`) before touching it — this word didn't, and the mistake compiled
|
||||
clean, linked clean, and booted clean. Diagnosed with a temporary probe (reverted after capture,
|
||||
per memory `feedback_revert_probes_after_capture`): `logs/20260922-101153/amd64/` and
|
||||
`logs/20260922-101937/amd64/` (a second, redundant run of the same debug build, kept per the
|
||||
never-delete convention rather than for any independent evidence) both show `DBG send: plen=25
|
||||
n=25 buf=[]` — correct length, empty content — followed by `DBG drain-enter #2 payload=` (empty)
|
||||
and a clean `DBG drain-return`.
|
||||
`vm_interpret()` on an empty string is a no-op: no error, no `UNKNOWN WORD`, `BLK-ATTACH-ACK`
|
||||
simply never ran, and the pending USB attach was silently never confirmed. Fixed by reading
|
||||
`src` via `vm_ptr(vm, (vaddr_t)paddr)` instead of a raw cast (`repl.c`'s own comment on the fix
|
||||
cites the precedent directly). This is exactly `FABRIC-3.5.md` §XXXV.0's named failure signature
|
||||
("things here fail without saying anything") — carrying the rule forward explicitly for whoever
|
||||
next writes a FORTH-facing C word: **any popped stack value that names a FORTH-visible address
|
||||
goes through `vm_ptr()`/`VM_ADDR()`, never a raw pointer cast, unless the value was itself
|
||||
explicitly formatted as a raw host pointer by the pushing code** (as `repl.c`'s own existing
|
||||
`dev-addr` already legitimately is, built via `%llu` from a real `uintptr_t` at the VM-EXEC call
|
||||
site — the exception that makes the rule easy to misapply by analogy).
|
||||
|
||||
**2026-09-22, task 3.8 — a separate, real hang, root cause not found; recorded as a genuine open
|
||||
item, not folded into the `vm_ptr()` finding above.** The very first attempt to exercise the real
|
||||
send/drain path (`logs/20260922-092154/amd64/`, before the `vm_ptr()` bug above was even
|
||||
suspected) froze solid — serial log stopped growing entirely, QEMU pinned near 100% CPU, no
|
||||
further output ever, for over 40 minutes of wall time before being killed by hand. This happened
|
||||
*before* the empty-payload bug was diagnosed or fixed, so it is tempting to assume the same root
|
||||
cause — but the empty-payload runs (`101153`/`101937`) did **not** hang; they drained cleanly
|
||||
(if uselessly) and reached `ok>` on schedule. Something else froze that first boot, at
|
||||
approximately the same point in the boot sequence, and it was never reproduced again across
|
||||
every subsequent run this session (with or without the `vm_ptr()` fix). Per §XXXV.0's own
|
||||
standing warning, an unexplained freeze in a brand-new, live-for-the-first-time nested-drain code
|
||||
path (task 3.4's `sk_hermes_drain_checkpoint()` calling `vm_interpret()` on a VM that is itself
|
||||
mid-dispatch, exercised live for the first time by this exact task) is not something to write off
|
||||
as a fluke. Reported, not chased further here — `logs/20260922-092154/` is kept as the sole
|
||||
evidence.
|
||||
|
||||
---
|
||||
|
||||
## Out of scope, carried for visibility
|
||||
|
||||
+55
-55
@@ -1,5 +1,5 @@
|
||||
# Capsule Block Manifest — Auto-generated
|
||||
<!-- Generated by mkcapsule --manifest 2026-09-22T12:01:35Z -->
|
||||
<!-- Generated by mkcapsule --manifest 2026-09-22T15:02:28Z -->
|
||||
<!-- DO NOT EDIT — re-run mkcapsule --manifest to refresh. -->
|
||||
<!-- Hand-written justifications and immutability notes live -->
|
||||
<!-- in MANIFEST.md alongside this auto-generated index. -->
|
||||
@@ -10,7 +10,7 @@
|
||||
|---------|----------------|----------|--------|
|
||||
| `ACL.4th` | 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008, 4015 | `0xf8890c05c0d8f921` | yes |
|
||||
| `acl-std79.4th` | 4023, 4024, 4025, 4026, 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4039, 4040, 4041, 4042, 4043, 4044, 4045, 4046, 4047, 4048 | `0x773bf9209df191d1` | yes |
|
||||
| `artemis:init.4th` | 4110, 4111, 4112, 4113, 4122, 4123, 4124, 4125, 4126, 4127, 4128, 4129, 4130, 4131, 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, 4140, 4141, 4160, 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, 4172, 4173, 4174, 4177, 4178, 4179, 4180, 4181, 4182, 4851, 4852, 4853, 4854, 4856, 4857, 4858, 4860 | `0xf55edc4e76a8c294` | yes |
|
||||
| `artemis:init.4th` | 4110, 4111, 4112, 4113, 4122, 4123, 4124, 4125, 4126, 4127, 4128, 4129, 4130, 4131, 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, 4140, 4141, 4160, 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, 4172, 4173, 4174, 4177, 4178, 4179, 4180, 4181, 4182, 4851, 4852, 4853, 4854, 4856, 4857, 4858, 4860 | `0x419d50262e5ecfbe` | yes |
|
||||
| `block-acl.4th` | 4019, 4020 | `0xf6cc2a59e3a6734e` | yes |
|
||||
| `common:messaging.4th` | 5003, 5004, 5005, 5006, 5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019, 5020, 5021, 5022, 5023, 5024, 5025, 5026, 5027, 5028, 5029, 5031, 5032, 5033, 5034, 5035, 5036, 5037, 5038, 5039, 5040, 5041, 5042 | `0x863f77893ef8f353` | yes |
|
||||
| `doe-campaign.4th` | 4060, 4061, 4062, 4063, 4064, 4065 | `0x3d4549142d91ec20` | yes |
|
||||
@@ -151,52 +151,52 @@
|
||||
| 4063 | `doe-campaign.4th` | `0x3d4549142d91ec20` | ok |
|
||||
| 4064 | `doe-campaign.4th` | `0x3d4549142d91ec20` | ok |
|
||||
| 4065 | `doe-campaign.4th` | `0x3d4549142d91ec20` | ok |
|
||||
| 4110 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4111 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4112 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4113 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4122 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4123 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4124 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4125 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4126 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4127 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4128 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4129 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4130 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4131 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4132 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4133 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4134 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4135 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4136 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4137 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4138 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4139 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4140 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4141 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4110 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4111 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4112 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4113 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4122 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4123 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4124 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4125 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4126 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4127 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4128 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4129 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4130 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4131 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4132 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4133 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4134 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4135 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4136 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4137 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4138 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4139 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4140 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4141 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4153 | `hermes:init.4th` | `0x2df61924448a6812` | ok |
|
||||
| 4160 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4161 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4162 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4163 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4164 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4165 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4166 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4167 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4168 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4169 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4170 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4171 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4172 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4173 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4174 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4177 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4178 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4179 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4180 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4181 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4182 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4160 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4161 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4162 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4163 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4164 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4165 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4166 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4167 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4168 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4169 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4170 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4171 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4172 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4173 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4174 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4177 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4178 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4179 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4180 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4181 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4182 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4200 | `user-font-demo.4th` | `0xce1fd7d1b581a56d` | ok |
|
||||
| 4201 | `user-font-demo.4th` | `0xce1fd7d1b581a56d` | ok |
|
||||
| 4202 | `user-font-demo.4th` | `0xce1fd7d1b581a56d` | ok |
|
||||
@@ -234,15 +234,15 @@
|
||||
| 4840 | `init-l8-transition.4th` | `0xbcc1a81976f0a4c9` | ok |
|
||||
| 4841 | `init-l8-transition.4th` | `0xbcc1a81976f0a4c9` | ok |
|
||||
| 4842 | `init-l8-transition.4th` | `0xbcc1a81976f0a4c9` | ok |
|
||||
| 4851 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4852 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4853 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4854 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4851 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4852 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4853 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4854 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4855 | `hermes:init.4th` | `0x2df61924448a6812` | ok |
|
||||
| 4856 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4857 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4858 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4860 | `artemis:init.4th` | `0xf55edc4e76a8c294` | ok |
|
||||
| 4856 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4857 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4858 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4860 | `artemis:init.4th` | `0x419d50262e5ecfbe` | ok |
|
||||
| 4900 | `fabric.4th` | `0x9d9489cbeca4099b` | ok |
|
||||
| 4901 | `fabric.4th` | `0x9d9489cbeca4099b` | ok |
|
||||
| 4902 | `fabric.4th` | `0x9d9489cbeca4099b` | ok |
|
||||
|
||||
@@ -525,8 +525,9 @@ Block 4857
|
||||
Block 4858
|
||||
( HERA-BLK-ATTACH-REQ ( dev-addr -- ): VM-EXEC'd by MSG- )
|
||||
( DELIVER when Hera's request arrives. Runs BLK-ATTACH on )
|
||||
( Artemis's own dictionary (real ACL gating, same as any )
|
||||
( other message payload), then replies to Hera (idx 0). )
|
||||
( Artemis's own dictionary, then replies to Hera via kernel- )
|
||||
( Hermes's KH-BLK-ATTACH-SEND (repl.c) -- FABRIC-3.6.md task )
|
||||
( 3.8 Stage C, FORTH Hermes no longer sees this message type. )
|
||||
: HERA-BLK-ATTACH-REQ ( dev-addr -- )
|
||||
0 ATTACH-ACK-LEN !
|
||||
DUP ACK-APPEND-NUM
|
||||
@@ -535,8 +536,7 @@ Block 4858
|
||||
DROP
|
||||
BL ACK-APPEND-CHAR
|
||||
S" BLK-ATTACH-ACK" ACK-APPEND
|
||||
BLK-ATTACH-EVENT 2 0 ATTACH-ACK-BUF
|
||||
ATTACH-ACK-LEN @ 0 MSG-SEND ;
|
||||
ATTACH-ACK-BUF ATTACH-ACK-LEN @ KH-BLK-ATTACH-SEND DROP ;
|
||||
|
||||
Block 4860
|
||||
( LOG-APPEND ( level ts msg-addr msg-u -- ) )
|
||||
|
||||
@@ -677,12 +677,27 @@ int sk_hermes_reassemble(SkHermesMessage **chunks, int n_chunks,
|
||||
#define SK_HERMES_MSG_TYPE_ACK 22
|
||||
#define SK_HERMES_MSG_TYPE_NACK 23
|
||||
#define SK_HERMES_MSG_TYPE_CH_CLOSE 24
|
||||
/* Chosen clear of messaging.4th's own live/reserved type space
|
||||
* (PAUSE-EVENT=2, RESUME-EVENT=3, KILL-EVENT=4, CONSOLE-CMD-EVENT=7,
|
||||
* ELEVATE-REQUEST=8, BLK-ATTACH-EVENT=9, MSG-NACKED=253,
|
||||
* MSG-DELIVERED=255) -- kernel-Hermes remains its own inert, parallel
|
||||
* type space until a real cutover (task 3.8+) makes the two coincide;
|
||||
* not itself a ruling, just room left deliberately. */
|
||||
|
||||
/* SK_HERMES_MSG_TYPE_BLK_ATTACH (FABRIC-3.6.md task 3.8, Stage C) --
|
||||
* DELIBERATELY the same numeric value as messaging.4th's own
|
||||
* BLK-ATTACH-EVENT constant (9), not a fresh kernel-Hermes-space number
|
||||
* like the five above. SXXXIV.2's partition rule is "one owner per
|
||||
* message type, never shared" -- it is about which LAYER holds the
|
||||
* message, not about the two layers needing disjoint numbering. Once
|
||||
* kernel-Hermes is this type's sole owner, keeping the same value
|
||||
* documents that this is a cutover of the SAME logical message, not a
|
||||
* new one invented alongside it. */
|
||||
#define SK_HERMES_MSG_TYPE_BLK_ATTACH 9
|
||||
|
||||
/* The five negotiation types above (20-24) were chosen clear of
|
||||
* messaging.4th's own live/reserved type space (PAUSE-EVENT=2,
|
||||
* RESUME-EVENT=3, KILL-EVENT=4, CONSOLE-CMD-EVENT=7, ELEVATE-REQUEST=8,
|
||||
* BLK-ATTACH-EVENT=9, MSG-NACKED=253, MSG-DELIVERED=255) precisely
|
||||
* because none of them had a real cutover yet -- kernel-Hermes stayed
|
||||
* its own inert, parallel type space for those. SK_HERMES_MSG_TYPE_
|
||||
* BLK_ATTACH above is the deliberate exception: task 3.8 IS that type's
|
||||
* real cutover, so it reuses BLK-ATTACH-EVENT's own value (9) rather
|
||||
* than picking a fresh one. */
|
||||
|
||||
/* sk_hermes_channel_request - requester asks target for a new private
|
||||
* channel. A point-to-point CH_REQUEST (sk_hermes_send_one(), tagged
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -45,6 +45,8 @@
|
||||
#include "starkernel/capsule_wirebind.h"
|
||||
#include "starkernel/capsule_run.h"
|
||||
#include "starkernel/vm/bootstrap/sk_vm_bootstrap.h"
|
||||
#include "starkernel/vm/kernel_hermes.h" /* FABRIC-3.6.md task 3.8 -- sk_hermes_send_one() */
|
||||
#include "starkernel/vm/stadium.h" /* task 3.8 -- stadium_conserved() evidence print */
|
||||
#include "block_subsystem.h"
|
||||
#include "word_source/include/keyboard_words.h"
|
||||
#include "word_source/include/block_words.h"
|
||||
@@ -256,6 +258,46 @@ static void sk_word_blk_attach_ack(VM *vm) {
|
||||
if (ms) ms->bot_msc_attached = 1;
|
||||
g_attached_blk_dev = dev;
|
||||
|
||||
/* FABRIC-3.6.md task 3.8 evidence: this handler IS the real drain
|
||||
* target -- sk_hermes_drain_checkpoint() (task 3.4) called
|
||||
* vm_interpret() on the ack payload, which is how we got here.
|
||||
* stadium_conserved() (task 0.7/2.7's four-term form) holds at
|
||||
* every instant, mid-hold included, so printing it here -- while
|
||||
* this message's heat is still held, before sk_hermes_drain_
|
||||
* checkpoint()'s own release/pop run just after this function
|
||||
* returns -- is real evidence, not a synthetic self-test. Note the
|
||||
* limit: this is evidence for the mid-hold instant, not the
|
||||
* post-release state (release/pop happen after this function
|
||||
* returns, in the caller) -- see FABRIC-3.6.md task 3.8's own
|
||||
* write-up. console_println, not log_message(): confirmed live
|
||||
* (this repl.c's own log_message() calls, at every level, do not
|
||||
* appear anywhere in a real serial-log boot capture in this build
|
||||
* -- log_message()'s fprintf(stderr, ...) is not wired to the
|
||||
* serial console here) -- log_message() would have been silently
|
||||
* invisible, defeating the point of evidence. One line, not two
|
||||
* (dropped the earlier pre-send line from KH-BLK-ATTACH-SEND
|
||||
* below): this fires once per real USB attach, not per word, so
|
||||
* it is not the console_println-overuse case memory
|
||||
* project_production_logging_cleanup_needed flags. */
|
||||
{
|
||||
VMRegistryEntry artemis_entry;
|
||||
uint64_t held, pulled, returned, consumed;
|
||||
char line[160];
|
||||
int conserved = -1; /* -1 = Artemis not found */
|
||||
sk_hermes_ledger(&held, &pulled, &returned, &consumed);
|
||||
if (capsule_vm_find_by_name_nocase("Artemis", &artemis_entry) == 0 &&
|
||||
artemis_entry.vm_ptr) {
|
||||
conserved = stadium_conserved(artemis_entry.vm_id);
|
||||
}
|
||||
snprintf(line, sizeof(line),
|
||||
"Kernel-Hermes BLK-ATTACH-EVENT (real, Stage C): ledger held=%llu "
|
||||
"pulled=%llu returned=%llu consumed=%llu stadium_conserved(Artemis)=%s",
|
||||
(unsigned long long)held, (unsigned long long)pulled,
|
||||
(unsigned long long)returned, (unsigned long long)consumed,
|
||||
conserved < 0 ? "UNKNOWN" : (conserved ? "true" : "FALSE"));
|
||||
console_println(line);
|
||||
}
|
||||
|
||||
homeblocks_sig_result_t sig_rc = g_blk_attach_pending[found_slot].sig_rc;
|
||||
homeblocks_sig_t sig = g_blk_attach_pending[found_slot].sig;
|
||||
int is_artemis = g_blk_attach_pending[found_slot].is_artemis;
|
||||
@@ -281,8 +323,88 @@ static void sk_word_blk_attach_ack(VM *vm) {
|
||||
}
|
||||
}
|
||||
|
||||
/* FABRIC-3.6.md task 3.8 (Stage C, SXXXIV.2/.3): BLK-ATTACH-EVENT's real
|
||||
* cutover -- the reply leg (Artemis -> Hera ack) that used to flow
|
||||
* through common:messaging.4th's MSG-SEND/MSG-TICK now goes through
|
||||
* kernel-Hermes's sk_hermes_send_one()/sk_hermes_drain_checkpoint()
|
||||
* (tasks 3.3/3.4/3.6) instead. FORTH Hermes never sees a BLK-ATTACH-
|
||||
* EVENT message again -- exactly SXXXIV.2's partition rule ("one owner
|
||||
* per message, never shared"). The request leg (Hera -> Artemis,
|
||||
* kernel_main.c's own "S\" <dev-addr> HERA-BLK-ATTACH-REQ\" S\"
|
||||
* Artemis\" VM-EXEC" a few lines up) was never real FORTH messaging
|
||||
* traffic to begin with -- no type tag, no arena, a direct VM-EXEC
|
||||
* forced by Hera's own STADIUM-* colon-word limitation documented
|
||||
* above -- so it is untouched here; this task cuts over the one
|
||||
* message type that actually flowed through a messaging layer.
|
||||
*
|
||||
* sk_hermes_drain_checkpoint() (task 3.4) calls vm_interpret() directly
|
||||
* on a message's payload_addr, so it must be NUL-terminated -- Artemis's
|
||||
* own ATTACH-ACK-BUF (artemis:init.4th) is a raw CMOVE'd byte buffer
|
||||
* with no such guarantee, so this copies into its own NUL-terminated
|
||||
* buffer rather than passing ATTACH-ACK-BUF's address through
|
||||
* unchanged. Static, not stack-local: sk_hermes_send_one() stores
|
||||
* payload_addr out-of-line and the caller must keep it alive until
|
||||
* drained (kernel_hermes.h's own documented contract) -- same single-
|
||||
* buffer-reuse shape ATTACH-ACK-BUF itself already had (a second attach
|
||||
* before the first drains overwrites it), not a new hazard this
|
||||
* introduces. */
|
||||
#define SK_KH_BLK_ATTACH_BUF_SIZE 80
|
||||
static char g_kh_blk_attach_buf[SK_KH_BLK_ATTACH_BUF_SIZE];
|
||||
|
||||
/* KH-BLK-ATTACH-SEND ( paddr plen -- ok? ): copies the caller's payload
|
||||
* (Artemis's own ATTACH-ACK-BUF content) into the NUL-terminated buffer
|
||||
* above and sends it to Hera via kernel-Hermes. `from`/`to` are derived
|
||||
* from the calling VM and sk_get_mama_vm() -- the caller never has to
|
||||
* name a VMUuid, matching how HERA-BLK-ATTACH-REQ never had to before
|
||||
* either (FORTH's own IDX 0/1/2 convention did that translation for
|
||||
* it). Refusal (reservoir/arena/destination-queue exhaustion) is logged
|
||||
* rather than silently dropped -- FABRIC-3.5.md SXXXV.0 names silent
|
||||
* failure as this project's single most common defect shape, and this
|
||||
* is exactly the class of message (identity birth gates on it) where a
|
||||
* silent drop would be expensive to ever notice. */
|
||||
static void sk_word_kh_blk_attach_send(VM *vm) {
|
||||
if (vm->dsp < 1) {
|
||||
log_message(LOG_ERROR, "KH-BLK-ATTACH-SEND: stack underflow");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
cell_t plen = vm_pop(vm);
|
||||
cell_t paddr = vm_pop(vm);
|
||||
/* paddr is a VM-relative offset (vaddr_t), not a host pointer --
|
||||
* CLAUDE.md's own "Important Conventions": "Stack values are VM
|
||||
* offsets (vaddr_t), not C pointers -- use VM_ADDR()/CELL()".
|
||||
* mama_forth_words.c's own VM-EXEC/VM-CALL words all translate a
|
||||
* popped paddr the same way (vm_ptr(vm, (vaddr_t)caddr)) before
|
||||
* touching it as a C pointer -- found live, not assumed: the first
|
||||
* cut here raw-cast paddr directly and silently read all-zero
|
||||
* memory (some unmapped/zeroed low address), producing an empty
|
||||
* NUL-terminated payload that vm_interpret() executed as a no-op --
|
||||
* no crash, no error, just a message that arrived and did nothing.
|
||||
* Diagnosed via a temporary probe printing the copied buffer content
|
||||
* at send time (per feedback_revert_probes_after_capture); reverted
|
||||
* once this fix confirmed correct. */
|
||||
const char *src = (const char *)vm_ptr(vm, (vaddr_t)paddr);
|
||||
size_t n = (size_t)plen;
|
||||
VM *mama_vm = (VM *)sk_get_mama_vm();
|
||||
size_t i;
|
||||
int rc;
|
||||
|
||||
if (n >= SK_KH_BLK_ATTACH_BUF_SIZE) n = SK_KH_BLK_ATTACH_BUF_SIZE - 1;
|
||||
for (i = 0; i < n; i++) g_kh_blk_attach_buf[i] = src[i];
|
||||
g_kh_blk_attach_buf[n] = '\0';
|
||||
|
||||
rc = sk_hermes_send_one(vm->stadium_vm_id, mama_vm->stadium_vm_id,
|
||||
SK_HERMES_MSG_TYPE_BLK_ATTACH, 0,
|
||||
g_kh_blk_attach_buf, (uint32_t)(n + 1));
|
||||
if (rc != 0) {
|
||||
log_message(LOG_ERROR, "KH-BLK-ATTACH-SEND: kernel-Hermes refused the send");
|
||||
}
|
||||
vm_push(vm, rc == 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
void sk_repl_register_words(VM *vm) {
|
||||
register_word(vm, "BLK-ATTACH-ACK", sk_word_blk_attach_ack);
|
||||
register_word(vm, "KH-BLK-ATTACH-SEND", sk_word_kh_blk_attach_send);
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
|
||||
Reference in New Issue
Block a user