feat(v4.0.0): POST is the kernel's -- the boot feeds the cases, and nothing of the harness is on the node

The boot runs POST with the runner (v4/system/post.c) after the capsules:
it feeds the 538 cases to the node and judges them from outside.  A
case's printing no longer reaches the console.  What the cases define
stays in the dictionary, as in v3; the system is sealed after POST and
the boot prints PARITY:V4_SYSTEM word_count=N dict_hash=..., as v3 prints
its parity after POST.

Gone: capsules/v4/post79.4th and its blocks 7000 up; the harness words;
(CATCH) and (EMIT-HOOK), with what EMIT and the prompt loop did for them.

The generator runs v3 on the lines as the kernel sends them, without the
capsule's "T| ".  One expected result follows from that: >IN.initial
prints 6, not 9.

make -C v4 test, sanitize and hosted-check pass; amd64, aarch64 and
riscv64 boot, POST 538 of 538, word_count=411, dict_hash
0x6fb1d09418b189ee on all six: logs/20261007-105118, -105335, -105651.
T{ is unknown at the prompt; RS1 prints 42 42 before and after COLD.  A
scratch build with one expectation changed names the case and ends
PARITY:FAIL, POST: FAILED.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-07 10:59:02 -04:00
co-authored by Claude Opus 5.5
parent 2bf958ce3a
commit 4bdb210a99
20 changed files with 659 additions and 1981 deletions
+38 -4
View File
@@ -31,6 +31,7 @@
#include "v4/manage.h"
#include "v4/blocks.h"
#include "v4/message.h"
#include "v4/post.h"
#include "v4/text.h"
#include "block_subsystem.h"
#include <stdio.h>
@@ -154,7 +155,6 @@ static int host_open(void *self, const char *name, unsigned len)
(void)self;
if (len == 17 && memcmp(name, "v4:nucleus-64.f18", 17) == 0) { hera_reads.is_f18 = 1; hera_reads.cells_at = 0; return 1; }
if (len == 14 && memcmp(name, "v4:forth79.4th", 14) == 0) return read_file(&hera_reads, "forth79.4th");
if (len == 13 && memcmp(name, "v4:post79.4th", 13) == 0) return read_file(&hera_reads, "post79.4th");
return 0;
}
static int host_cell(void *self, v4_cell *w)
@@ -277,6 +277,30 @@ static const char *tell(v4_cell node, const char *text)
}
static int told(v4_cell node, const char *text) { return tell(node, text)[0] == 0 && ended == 1 && ended_how == V4_TEXT_COMPLETED; }
/* POST's host, for the node numbered 10 (v4/include/v4/post.h): a line is
* told to it from the console, and what it prints is handed to the runner. */
static int post_line(void *self, const char *text, unsigned text_len, char *out, unsigned cap, unsigned *len)
{
static char line[V4_MSG_MAX_CHARS + 1];
const char *r;
(void)self;
*len = 0;
if (text_len > V4_MSG_MAX_CHARS) return -1;
memcpy(line, text, text_len); line[text_len] = 0;
r = tell(10, line);
if (ended != 1 || ended_from != 10) return -1;
*len = printed_len;
memcpy(out, r, printed_len < cap ? printed_len : cap);
return (int)ended_how;
}
static char post_said[2048];
static unsigned post_said_len;
static void post_say(void *self, const char *text, unsigned len)
{
(void)self;
if (post_said_len + len < sizeof post_said) { memcpy(post_said + post_said_len, text, len); post_said_len += len; post_said[post_said_len] = 0; }
}
/* Every line of a capsule of FORTH blocks, told to a node from the console:
* how many lines did not complete. */
static unsigned load(v4_cell node, const char *file)
@@ -376,7 +400,16 @@ int main(void)
}
CHECK(strcmp(tell(10, "NODE-ME ."), "0 ") == 0 && refused == 0, "it asks where it is, and is answered");
CHECK(load(10, "forth79.4th") == 0, "it takes in FORTH-79");
CHECK(load(10, "post79.4th") == 0 && post_passed[10] == 1 && post_other == 0, "and passes POST");
{
v4_post_host host;
v4_post_tally tally;
host.self = 0; host.n = node_numbered(10); host.line = post_line; host.say = post_say;
CHECK(v4_post_run(&host, v4_post_cases, v4_post_case_count, &tally) && tally.tests == 538 && tally.pass == 538 && tally.fail == 0
&& strstr(post_said, "PARITY:V4_POST tests=538 pass=538 fail=0\n") != NULL && strstr(post_said, "POST FAIL") == NULL,
"and passes POST, which the kernel runs on her: %u of %u, %u failed; \"%s\"", tally.pass, tally.tests, tally.fail, post_said);
}
CHECK(strstr(tell(10, "T{"), "UNKNOWN WORD") != NULL, "nothing of POST's harness is on her: \"%s\"", printed);
CHECK(strcmp(tell(10, "RS1"), "42 42 \n") == 0, "what POST's cases defined is: \"%s\"", printed);
CHECK(load(10, "hera.4th") == 0, "and its own capsule, which makes it Hera");
CHECK(told(10, "(SEAL)"), "that is the system it comes back to");
@@ -387,9 +420,10 @@ int main(void)
CHECK(ended == 1 && ended_how == V4_TEXT_COMPLETED && ended_from == 10, "Hera births four nodes and joins them: \"%s\"", r);
}
CHECK(born_count == 4 && refused == 0, "four nodes were asked for: %u", born_count);
CHECK(post_passed[10] == 1 && post_passed[11] == 0 && post_passed[12] == 0 && post_passed[13] == 0 && post_passed[14] == 0 && post_other == 0,
"a node she births is not POSTed: POST is the kernel's, once, on Hera: %u; %u %u %u %u, %u failed",
CHECK(post_passed[10] == 0 && post_passed[11] == 0 && post_passed[12] == 0 && post_passed[13] == 0 && post_passed[14] == 0 && post_other == 0,
"a node she births is not POSTed, and no node prints a POST tally: POST is the kernel's, once, on Hera: %u %u %u %u %u, %u failed",
post_passed[10], post_passed[11], post_passed[12], post_passed[13], post_passed[14], post_other);
CHECK(strstr(tell(10, "COLD"), "Cold Start") != NULL && strcmp(tell(10, "RS1"), "42 42 \n") == 0, "COLD on Hera comes back to a system that has what POST's cases defined: \"%s\"", printed);
CHECK(parity_count == 4 && parity_number[0] == 11 && parity_number[1] == 12 && parity_number[2] == 13 && parity_number[3] == 14, "the parity of each was recorded: %u", parity_count);
CHECK(parity_hash[0] == parity_hash[1] && parity_hash[1] == parity_hash[2] && parity_hash[2] == parity_hash[3],
"and their dictionary hashes are the same: %016llx %016llx %016llx %016llx",