Captain Bob, 2026-11-13: "File the POST design as an issue for alpha.5". His design, as given, is below. Notes measured against the tree come after it, as points for him to rule on, not decisions.
Status: Design, proposed for alpha.5 → beta.0 Scope: LithosAnanke kernel (C99) and StarForth V4 Author: Captain Bob (Robert Allan James)
Names marked (proposed) are placeholders. Rename them to match the existing tree.
1. Purpose
The machine proves itself before it says ok>.
POST runs during boot and inside the kernel. It checks each layer of the system against the layer below it before that layer is trusted. The results are recorded in one table that both C and StarForth can read.
Goals
Catch integration regressions (V4 ↔ Hera ↔ Stadium ↔ Hermes) at boot, not in the field.
Reuse the red-first unit tests already being written for the V4 integration.
Give the same results on amd64, aarch64 and riscv64 (parity first).
Let anyone at the ok> prompt inspect boot health, demo users included.
Non-goals
POST does not replace the full test suite run under QEMU in CI.
POST does not benchmark. Cycle counts are recorded for diagnosis only.
2. Principles
Dependency order. A stage uses only what earlier stages have proven.
Non-destructive. POST leaves no state behind in the Stadium, the dictionary or any VM.
Deterministic. No test depends on wall-clock timing, so QEMU and silicon behave alike.
Each layer vouches for itself. The kernel proves the fabric; StarForth proves the dictionary.
Honest failure. A failure is always recorded and reported, never hidden.
3. Stages
Stage
Runs in
Proves
May depend on
S0: Platform
C99, early boot
RAM pattern test (small window), timer ticks, console output
Nothing
S1: Fabric
C99, kernel
Stadium allocator: alloc, free, bounds, no leaks
S0
S2: Messaging
C99, kernel
Hermes round-trip; ACL deny and allow cases
S0–S1
S3: Fleet
C99, kernel
Hera births one V4 VM into the Stadium, exchanges one message, tears it down
S0 to S4 run before StarForth comes up. S5 runs as the first act of the StarForth runtime, before the ok> prompt.
Smoke set and full set
Smoke set: runs on every boot. Target: well under one second on QEMU.
Full set: the complete unit suite, on demand only, through POST-FULL or a boot flag.
Each test is tagged POST_SMOKE or POST_FULL when it is registered.
4. The POST table
One fixed structure in kernel memory, written by both layers and read by both.
/* post.h (proposed) */#include<stdint.h>#define POST_MAX_RESULTS 128u
typedefenum{POST_NOT_RUN=0,POST_PASS=1,POST_FAIL=2,POST_SKIPPED=3/* skipped because a dependency failed */}post_status_t;typedefenum{POST_S0_PLATFORM=0,POST_S1_FABRIC,POST_S2_MESSAGING,POST_S3_FLEET,POST_S4_BLOCKS,POST_S5_LANGUAGE,POST_STAGE_COUNT}post_stage_t;typedefstruct{uint16_tid;/* stable test ID, never reused */uint8_tstage;/* post_stage_t */uint8_tstatus;/* post_status_t */uint32_tdetail;/* test-specific failure code, 0 = none */uint64_tcycles;/* diagnostic only, never asserted on */}post_result_t;typedefstruct{uint32_tmagic;/* 'POST' = 0x504F5354 */uint16_tversion;/* bump when the layout changes */uint16_tcount;/* number of results written */uint8_tstage_ok[POST_STAGE_COUNT];/* 1 = whole stage passed */uint8_tdegraded;/* 1 = booted with a fenced subsystem */uint8_t_pad[1];uint64_tdict_hash;/* parity hash recorded in S5 */post_result_tresults[POST_MAX_RESULTS];}post_table_t;externpost_table_tg_post;
Rules
Test IDs are stable. A retired ID is never reused, so logs stay comparable across releases.
The layout carries magic and version, so StarForth can refuse a table it does not understand.
cycles is recorded but never used as a pass/fail condition (principle 3).
5. Registering tests (C99)
Tests register themselves into a dedicated linker section. No central list needs editing.
staticpost_status_tt_stadium_alloc_free(uint32_t*detail){void*p=stadium_alloc(64);/* proposed API name */if(p==NULL){*detail=1;returnPOST_FAIL;}stadium_free(p);if(stadium_in_use()!=0){*detail=2;returnPOST_FAIL;}returnPOST_PASS;}POST_TEST(0x0101,POST_S1_FABRIC,POST_SMOKE|POST_FULL,"stadium alloc/free",t_stadium_alloc_free);
The red-first unit tests for the V4 integration move into this form as they go green. The same test function serves both CI and POST.
6. The runner
/* post.c (proposed) */voidpost_run(uint8_tflags){externconstpost_test_t__post_tests_start[];externconstpost_test_t__post_tests_end[];for(uint8_ts=POST_S0_PLATFORM;s<POST_S5_LANGUAGE;++s){intstage_ok=1;intdeps_ok=post_deps_ok(s);/* all earlier stages passed? */for(constpost_test_t*t=__post_tests_start;t<__post_tests_end;++t){if(t->stage!=s||!(t->flags&flags))continue;post_result_t*r=post_next_slot();r->id=t->id;r->stage=s;r->detail=0;if(!deps_ok){r->status=POST_SKIPPED;stage_ok=0;continue;}uint64_tc0=cpu_cycles();r->status=(uint8_t)t->fn(&r->detail);r->cycles=cpu_cycles()-c0;if(r->status!=POST_PASS){stage_ok=0;console_post_line(t,r);/* report right away */}}g_post.stage_ok[s]=(uint8_t)stage_ok;}post_apply_policy();}
The linker script gains __post_tests_start and __post_tests_end around .post_tests. That section, and the test code itself, live in the init region (Section 9).
7. Failure policy
Stage failed
Action
S0 Platform
Halt. Print the failure to the console and stop. Nothing above can be trusted.
S1 Fabric
Halt. The Stadium is the foundation of everything above.
S2 Messaging
Halt. Without trusted Hermes and ACL checks, isolation cannot be guaranteed.
S3 Fleet
Degraded boot. Fence Hera: no new VMs are born. Set degraded = 1.
S4 Blocks
Degraded boot. Fence Artemis: block storage is read-only or offline. Set degraded = 1.
S5 Language
Degraded boot. Bring up ok> with a clear warning banner. Parity hash mismatch is reported loudly.
The rule: halt when security or memory integrity is in doubt. Boot degraded, and say so, when only a service is in doubt. A demo box that comes up honest beats a dead prompt.
On a degraded boot, the first line above ok> reads, for example:
POST: DEGRADED S3 Fleet FAIL (id 0x0301 detail 2) type .POST for details
ok>
8. StarForth side (S5)
S5 runs as the first act of the StarForth runtime, before the prompt. It writes into the same g_post table.
S5 tests
Core FORTH-79 words: stack, arithmetic, : and ;, IF ELSE THEN, DO LOOP, BEGIN UNTIL.
V4 engine smoke run: define, execute and forget one word, and check that the heat state returns to its baseline.
Dictionary parity hash: compute the hash and store it in g_post.dict_hash. If a reference hash is built into the image, compare against it.
New words (proposed, extensions beyond FORTH-79)
Word
Stack
Action
.POST
( -- )
Print the POST table: stage summary, then any non-PASS results.
.POST-ALL
( -- )
Print every result, including passes and cycle counts.
POST-OK?
( -- flag )
True if every stage passed and the boot is not degraded.
POST-FULL
( -- )
Run the full set on demand, then print the summary.
DICT-HASH
( -- d )
Push the current dictionary parity hash.
POST-FULL runs only tests that are safe to run while the system is live. Any test that cannot meet principle 2 at runtime is flagged POST_BOOT_ONLY and skipped.
9. Build and memory
Init section: POST code and the .post_tests table go in the init region, which is freed once the prompt is up. Runtime RAM cost: the post_table_t only.
POST-FULL exception: if POST-FULL is enabled, the full-set tests are kept resident instead. This is a build choice.
Build flags (proposed):
STARSHIP_POST=0|1|2: off / smoke only / smoke + full available at runtime.
STARSHIP_POST_HALT_ALL=1: treat every failure as a halt (for CI).
Boot flag:post=full on the boot command line runs the full set at boot.
10. Parity across ISAs
The same smoke set runs on amd64, aarch64 and riscv64.
CI compares the POST tables from all three QEMU runs. IDs, statuses and dict_hash must match. cycles is ignored.
A parity mismatch fails the build, the same way the existing dictionary-hash parity check does.
11. Integration plan
alpha.5
Add post.h and post.c, the linker section, and the empty runner.
Add S0 and S1 smoke tests.
Add .POST in StarForth so the table is visible from the prompt.
Wire the halt policy for S0 and S1.
beta.0
Move the V4 / Hera / Stadium / Hermes integration tests into POST_TEST form as they go green (S2, S3).
Add S4 (Artemis, read-only) and S5 (language and parity hash).
Add the degraded-boot policy and banner.
Add POST-FULL, POST-OK? and DICT-HASH.
Add three-ISA POST table comparison to CI.
12. Acceptance criteria
Clean boot on all three ISAs prints no POST lines and reaches ok>.
.POST shows every stage as PASS.
Forcing an S1 failure halts the boot with a readable console message.
Forcing an S3 failure boots degraded, shows the banner, and Hera refuses to birth VMs.
POST tables from amd64, aarch64 and riscv64 match on IDs, statuses and dict_hash.
Smoke set finishes well under one second under QEMU.
Runtime RAM cost with STARSHIP_POST=1 is the POST table only.
No Stadium blocks, dictionary entries or VMs remain after POST.
Notes measured against the tree (2026-11-13), for ruling
Some of it already exists.
S5: v4's POST runs on Hera at boot: PARITY:V4_POST tests=539 pass=539 fail=0, then POST: PASSED, with dict_hash in PARITY:V4_SYSTEM.
§10:scripts/nightly.sh protocol → PROTOCOL.md and scripts/check_protocol.sh already require dict_hash to match across the three architectures.
S3 is already tested, just not at boot. BIRTH → message → KILL is exactly what the mesh boot's tests run (#189, Phase 1 Task 5): v4/tests/test_mesh_boot.c on the host and births() in scripts/qemu_session.py on the boots. A birth takes a Stadium quota and KILL returns it, and conservation is checked afterwards, which meets principle 2.
S2 "Hermes round-trip". v4 has no Hermes round-trip. Messages are the fabric's wire messages (v4/message.h), and nodes are listed in the registry (v4/manage.h). In v4, S2 would test those. Kernel-Hermes remains on the v3 side.
S1 "Stadium allocator". The Stadium is not an allocator. It holds quotas and patron cells. The equivalent test is to admit a patron, return the quota (stadium_return_quota), and check conservation holds. kernel/tests/test_stadium_ops.c already does this on the host. The kernel's memory allocator is kmalloc.
§5's section attribute is a GNU extension. It is kept behind one macro, but the code standard is strict C99, so this needs a ruling. It also needs __post_tests_start and __post_tests_end in the linker script of each of amd64, aarch64 and riscv64.
§9 init region: not verified. It hasn't been checked whether the kernel has an init region that is freed after the prompt. One may have to be built.
§12 conflicts with today's acceptance. "Clean boot … prints no POST lines" conflicts with the acceptance protocol, which requires the PARITY:V4_POST … and POST: PASSED lines (scripts/qemu_session.py, check_protocol.sh). One of the two has to change.
Captain Bob, 2026-11-13: "File the POST design as an issue for alpha.5". His design, as given, is below. Notes measured against the tree come after it, as points for him to rule on, not decisions.
**Status:** Design, proposed for alpha.5 → beta.0
**Scope:** LithosAnanke kernel (C99) and StarForth V4
**Author:** Captain Bob (Robert Allan James)
> Names marked *(proposed)* are placeholders. Rename them to match the existing tree.
## 1. Purpose
The machine proves itself before it says `ok>`.
POST runs during boot and inside the kernel. It checks each layer of the system against the layer below it before that layer is trusted. The results are recorded in one table that both C and StarForth can read.
### Goals
- Catch integration regressions (V4 ↔ Hera ↔ Stadium ↔ Hermes) at boot, not in the field.
- Reuse the red-first unit tests already being written for the V4 integration.
- Give the same results on amd64, aarch64 and riscv64 (parity first).
- Let anyone at the `ok>` prompt inspect boot health, demo users included.
### Non-goals
- POST does not replace the full test suite run under QEMU in CI.
- POST does not benchmark. Cycle counts are recorded for diagnosis only.
## 2. Principles
1. **Dependency order.** A stage uses only what earlier stages have proven.
2. **Non-destructive.** POST leaves no state behind in the Stadium, the dictionary or any VM.
3. **Deterministic.** No test depends on wall-clock timing, so QEMU and silicon behave alike.
4. **Each layer vouches for itself.** The kernel proves the fabric; StarForth proves the dictionary.
5. **Honest failure.** A failure is always recorded and reported, never hidden.
## 3. Stages
| Stage | Runs in | Proves | May depend on |
|---|---|---|---|
| **S0: Platform** | C99, early boot | RAM pattern test (small window), timer ticks, console output | Nothing |
| **S1: Fabric** | C99, kernel | Stadium allocator: alloc, free, bounds, no leaks | S0 |
| **S2: Messaging** | C99, kernel | Hermes round-trip; ACL deny and allow cases | S0–S1 |
| **S3: Fleet** | C99, kernel | Hera births one V4 VM into the Stadium, exchanges one message, tears it down | S0–S2 |
| **S4: Blocks** | C99, kernel | Artemis: read back a known block (read-only) | S0–S2 |
| **S5: Language** | StarForth | Core FORTH-79 words, V4 engine smoke run, dictionary parity hash | S0–S4 |
S0 to S4 run before StarForth comes up. S5 runs as the first act of the StarForth runtime, before the `ok>` prompt.
### Smoke set and full set
- **Smoke set:** runs on every boot. Target: well under one second on QEMU.
- **Full set:** the complete unit suite, on demand only, through `POST-FULL` or a boot flag.
Each test is tagged `POST_SMOKE` or `POST_FULL` when it is registered.
## 4. The POST table
One fixed structure in kernel memory, written by both layers and read by both.
```c
/* post.h (proposed) */
#include <stdint.h>
#define POST_MAX_RESULTS 128u
typedef enum {
POST_NOT_RUN = 0,
POST_PASS = 1,
POST_FAIL = 2,
POST_SKIPPED = 3 /* skipped because a dependency failed */
} post_status_t;
typedef enum {
POST_S0_PLATFORM = 0,
POST_S1_FABRIC,
POST_S2_MESSAGING,
POST_S3_FLEET,
POST_S4_BLOCKS,
POST_S5_LANGUAGE,
POST_STAGE_COUNT
} post_stage_t;
typedef struct {
uint16_t id; /* stable test ID, never reused */
uint8_t stage; /* post_stage_t */
uint8_t status; /* post_status_t */
uint32_t detail; /* test-specific failure code, 0 = none */
uint64_t cycles; /* diagnostic only, never asserted on */
} post_result_t;
typedef struct {
uint32_t magic; /* 'POST' = 0x504F5354 */
uint16_t version; /* bump when the layout changes */
uint16_t count; /* number of results written */
uint8_t stage_ok[POST_STAGE_COUNT]; /* 1 = whole stage passed */
uint8_t degraded; /* 1 = booted with a fenced subsystem */
uint8_t _pad[1];
uint64_t dict_hash; /* parity hash recorded in S5 */
post_result_t results[POST_MAX_RESULTS];
} post_table_t;
extern post_table_t g_post;
```
**Rules**
- Test IDs are stable. A retired ID is never reused, so logs stay comparable across releases.
- The layout carries `magic` and `version`, so StarForth can refuse a table it does not understand.
- `cycles` is recorded but never used as a pass/fail condition (principle 3).
## 5. Registering tests (C99)
Tests register themselves into a dedicated linker section. No central list needs editing.
```c
/* post.h (continued, proposed) */
typedef post_status_t (*post_fn_t)(uint32_t *detail);
typedef struct {
uint16_t id;
uint8_t stage;
uint8_t flags; /* POST_SMOKE | POST_FULL */
const char *name;
post_fn_t fn;
} post_test_t;
#define POST_SMOKE 0x01u
#define POST_FULL 0x02u
/* GCC/Clang extension: section attribute.
* Keep it behind this one macro so the rest stays plain C99. */
#define POST_TEST(id_, stage_, flags_, name_, fn_) \
static const post_test_t post_test_##id_ \
__attribute__((used, section(".post_tests"))) = \
{ (id_), (stage_), (flags_), (name_), (fn_) }
```
Example:
```c
static post_status_t t_stadium_alloc_free(uint32_t *detail)
{
void *p = stadium_alloc(64); /* proposed API name */
if (p == NULL) { *detail = 1; return POST_FAIL; }
stadium_free(p);
if (stadium_in_use() != 0) { *detail = 2; return POST_FAIL; }
return POST_PASS;
}
POST_TEST(0x0101, POST_S1_FABRIC, POST_SMOKE | POST_FULL,
"stadium alloc/free", t_stadium_alloc_free);
```
The red-first unit tests for the V4 integration move into this form as they go green. The same test function serves both CI and POST.
## 6. The runner
```c
/* post.c (proposed) */
void post_run(uint8_t flags)
{
extern const post_test_t __post_tests_start[];
extern const post_test_t __post_tests_end[];
for (uint8_t s = POST_S0_PLATFORM; s < POST_S5_LANGUAGE; ++s) {
int stage_ok = 1;
int deps_ok = post_deps_ok(s); /* all earlier stages passed? */
for (const post_test_t *t = __post_tests_start;
t < __post_tests_end; ++t) {
if (t->stage != s || !(t->flags & flags)) continue;
post_result_t *r = post_next_slot();
r->id = t->id; r->stage = s; r->detail = 0;
if (!deps_ok) { r->status = POST_SKIPPED; stage_ok = 0; continue; }
uint64_t c0 = cpu_cycles();
r->status = (uint8_t)t->fn(&r->detail);
r->cycles = cpu_cycles() - c0;
if (r->status != POST_PASS) {
stage_ok = 0;
console_post_line(t, r); /* report right away */
}
}
g_post.stage_ok[s] = (uint8_t)stage_ok;
}
post_apply_policy();
}
```
The linker script gains `__post_tests_start` and `__post_tests_end` around `.post_tests`. That section, and the test code itself, live in the init region (Section 9).
## 7. Failure policy
| Stage failed | Action |
|---|---|
| S0 Platform | **Halt.** Print the failure to the console and stop. Nothing above can be trusted. |
| S1 Fabric | **Halt.** The Stadium is the foundation of everything above. |
| S2 Messaging | **Halt.** Without trusted Hermes and ACL checks, isolation cannot be guaranteed. |
| S3 Fleet | **Degraded boot.** Fence Hera: no new VMs are born. Set `degraded = 1`. |
| S4 Blocks | **Degraded boot.** Fence Artemis: block storage is read-only or offline. Set `degraded = 1`. |
| S5 Language | **Degraded boot.** Bring up `ok>` with a clear warning banner. Parity hash mismatch is reported loudly. |
The rule: halt when **security or memory integrity** is in doubt. Boot degraded, and say so, when only a **service** is in doubt. A demo box that comes up honest beats a dead prompt.
On a degraded boot, the first line above `ok>` reads, for example:
```
POST: DEGRADED S3 Fleet FAIL (id 0x0301 detail 2) type .POST for details
ok>
```
## 8. StarForth side (S5)
S5 runs as the first act of the StarForth runtime, before the prompt. It writes into the same `g_post` table.
### S5 tests
- Core FORTH-79 words: stack, arithmetic, `:` and `;`, `IF ELSE THEN`, `DO LOOP`, `BEGIN UNTIL`.
- V4 engine smoke run: define, execute and forget one word, and check that the heat state returns to its baseline.
- **Dictionary parity hash:** compute the hash and store it in `g_post.dict_hash`. If a reference hash is built into the image, compare against it.
### New words *(proposed, extensions beyond FORTH-79)*
| Word | Stack | Action |
|---|---|---|
| `.POST` | `( -- )` | Print the POST table: stage summary, then any non-PASS results. |
| `.POST-ALL` | `( -- )` | Print every result, including passes and cycle counts. |
| `POST-OK?` | `( -- flag )` | True if every stage passed and the boot is not degraded. |
| `POST-FULL` | `( -- )` | Run the full set on demand, then print the summary. |
| `DICT-HASH` | `( -- d )` | Push the current dictionary parity hash. |
`POST-FULL` runs only tests that are safe to run while the system is live. Any test that cannot meet principle 2 at runtime is flagged `POST_BOOT_ONLY` and skipped.
## 9. Build and memory
- **Init section:** POST code and the `.post_tests` table go in the init region, which is freed once the prompt is up. Runtime RAM cost: the `post_table_t` only.
- **`POST-FULL` exception:** if `POST-FULL` is enabled, the full-set tests are kept resident instead. This is a build choice.
- **Build flags *(proposed)*:**
- `STARSHIP_POST=0|1|2`: off / smoke only / smoke + full available at runtime.
- `STARSHIP_POST_HALT_ALL=1`: treat every failure as a halt (for CI).
- **Boot flag:** `post=full` on the boot command line runs the full set at boot.
## 10. Parity across ISAs
- The same smoke set runs on amd64, aarch64 and riscv64.
- CI compares the POST tables from all three QEMU runs. IDs, statuses and `dict_hash` must match. `cycles` is ignored.
- A parity mismatch fails the build, the same way the existing dictionary-hash parity check does.
## 11. Integration plan
**alpha.5**
1. Add `post.h` and `post.c`, the linker section, and the empty runner.
2. Add S0 and S1 smoke tests.
3. Add `.POST` in StarForth so the table is visible from the prompt.
4. Wire the halt policy for S0 and S1.
**beta.0**
5. Move the V4 / Hera / Stadium / Hermes integration tests into `POST_TEST` form as they go green (S2, S3).
6. Add S4 (Artemis, read-only) and S5 (language and parity hash).
7. Add the degraded-boot policy and banner.
8. Add `POST-FULL`, `POST-OK?` and `DICT-HASH`.
9. Add three-ISA POST table comparison to CI.
## 12. Acceptance criteria
- [ ] Clean boot on all three ISAs prints no POST lines and reaches `ok>`.
- [ ] `.POST` shows every stage as PASS.
- [ ] Forcing an S1 failure halts the boot with a readable console message.
- [ ] Forcing an S3 failure boots degraded, shows the banner, and Hera refuses to birth VMs.
- [ ] POST tables from amd64, aarch64 and riscv64 match on IDs, statuses and `dict_hash`.
- [ ] Smoke set finishes well under one second under QEMU.
- [ ] Runtime RAM cost with `STARSHIP_POST=1` is the POST table only.
- [ ] No Stadium blocks, dictionary entries or VMs remain after POST.
---
## Notes measured against the tree (2026-11-13), for ruling
1. **Some of it already exists.**
- **S5:** v4's POST runs on Hera at boot: `PARITY:V4_POST tests=539 pass=539 fail=0`, then `POST: PASSED`, with `dict_hash` in `PARITY:V4_SYSTEM`.
- **§10:** `scripts/nightly.sh protocol` → `PROTOCOL.md` and `scripts/check_protocol.sh` already require `dict_hash` to match across the three architectures.
2. **S3 is already tested, just not at boot.** BIRTH → message → KILL is exactly what the mesh boot's tests run (#189, Phase 1 Task 5): `v4/tests/test_mesh_boot.c` on the host and `births()` in `scripts/qemu_session.py` on the boots. A birth takes a Stadium quota and KILL returns it, and conservation is checked afterwards, which meets principle 2.
3. **S2 "Hermes round-trip".** v4 has no Hermes round-trip. Messages are the fabric's wire messages (`v4/message.h`), and nodes are listed in the registry (`v4/manage.h`). In v4, S2 would test those. Kernel-Hermes remains on the v3 side.
4. **S1 "Stadium allocator".** The Stadium is not an allocator. It holds quotas and patron cells. The equivalent test is to admit a patron, return the quota (`stadium_return_quota`), and check conservation holds. `kernel/tests/test_stadium_ops.c` already does this on the host. The kernel's memory allocator is `kmalloc`.
5. **§5's section attribute is a GNU extension.** It is kept behind one macro, but the code standard is strict C99, so this needs a ruling. It also needs `__post_tests_start` and `__post_tests_end` in the linker script of each of amd64, aarch64 and riscv64.
6. **§9 init region: not verified.** It hasn't been checked whether the kernel has an init region that is freed after the prompt. One may have to be built.
7. **§12 conflicts with today's acceptance.** "Clean boot … prints no POST lines" conflicts with the acceptance protocol, which requires the `PARITY:V4_POST …` and `POST: PASSED` lines (`scripts/qemu_session.py`, `check_protocol.sh`). One of the two has to change.
rajames
added this to the v4.0.0-alpha.5: SDK milestone 2026-11-13 16:10:56 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Captain Bob, 2026-11-13: "File the POST design as an issue for alpha.5". His design, as given, is below. Notes measured against the tree come after it, as points for him to rule on, not decisions.
Status: Design, proposed for alpha.5 → beta.0
Scope: LithosAnanke kernel (C99) and StarForth V4
Author: Captain Bob (Robert Allan James)
1. Purpose
The machine proves itself before it says
ok>.POST runs during boot and inside the kernel. It checks each layer of the system against the layer below it before that layer is trusted. The results are recorded in one table that both C and StarForth can read.
Goals
ok>prompt inspect boot health, demo users included.Non-goals
2. Principles
3. Stages
S0 to S4 run before StarForth comes up. S5 runs as the first act of the StarForth runtime, before the
ok>prompt.Smoke set and full set
POST-FULLor a boot flag.Each test is tagged
POST_SMOKEorPOST_FULLwhen it is registered.4. The POST table
One fixed structure in kernel memory, written by both layers and read by both.
Rules
magicandversion, so StarForth can refuse a table it does not understand.cyclesis recorded but never used as a pass/fail condition (principle 3).5. Registering tests (C99)
Tests register themselves into a dedicated linker section. No central list needs editing.
Example:
The red-first unit tests for the V4 integration move into this form as they go green. The same test function serves both CI and POST.
6. The runner
The linker script gains
__post_tests_startand__post_tests_endaround.post_tests. That section, and the test code itself, live in the init region (Section 9).7. Failure policy
degraded = 1.degraded = 1.ok>with a clear warning banner. Parity hash mismatch is reported loudly.The rule: halt when security or memory integrity is in doubt. Boot degraded, and say so, when only a service is in doubt. A demo box that comes up honest beats a dead prompt.
On a degraded boot, the first line above
ok>reads, for example:8. StarForth side (S5)
S5 runs as the first act of the StarForth runtime, before the prompt. It writes into the same
g_posttable.S5 tests
:and;,IF ELSE THEN,DO LOOP,BEGIN UNTIL.g_post.dict_hash. If a reference hash is built into the image, compare against it.New words (proposed, extensions beyond FORTH-79)
.POST( -- ).POST-ALL( -- )POST-OK?( -- flag )POST-FULL( -- )DICT-HASH( -- d )POST-FULLruns only tests that are safe to run while the system is live. Any test that cannot meet principle 2 at runtime is flaggedPOST_BOOT_ONLYand skipped.9. Build and memory
.post_teststable go in the init region, which is freed once the prompt is up. Runtime RAM cost: thepost_table_tonly.POST-FULLexception: ifPOST-FULLis enabled, the full-set tests are kept resident instead. This is a build choice.STARSHIP_POST=0|1|2: off / smoke only / smoke + full available at runtime.STARSHIP_POST_HALT_ALL=1: treat every failure as a halt (for CI).post=fullon the boot command line runs the full set at boot.10. Parity across ISAs
dict_hashmust match.cyclesis ignored.11. Integration plan
alpha.5
post.handpost.c, the linker section, and the empty runner..POSTin StarForth so the table is visible from the prompt.beta.0
POST_TESTform as they go green (S2, S3).POST-FULL,POST-OK?andDICT-HASH.12. Acceptance criteria
ok>..POSTshows every stage as PASS.dict_hash.STARSHIP_POST=1is the POST table only.Notes measured against the tree (2026-11-13), for ruling
PARITY:V4_POST tests=539 pass=539 fail=0, thenPOST: PASSED, withdict_hashinPARITY:V4_SYSTEM.scripts/nightly.sh protocol→PROTOCOL.mdandscripts/check_protocol.shalready requiredict_hashto match across the three architectures.v4/tests/test_mesh_boot.con the host andbirths()inscripts/qemu_session.pyon the boots. A birth takes a Stadium quota and KILL returns it, and conservation is checked afterwards, which meets principle 2.v4/message.h), and nodes are listed in the registry (v4/manage.h). In v4, S2 would test those. Kernel-Hermes remains on the v3 side.stadium_return_quota), and check conservation holds.kernel/tests/test_stadium_ops.calready does this on the host. The kernel's memory allocator iskmalloc.__post_tests_startand__post_tests_endin the linker script of each of amd64, aarch64 and riscv64.PARITY:V4_POST …andPOST: PASSEDlines (scripts/qemu_session.py,check_protocol.sh). One of the two has to change.