Files
LithosAnanake/include/starkernel/vm/parity.h
T
Robert Allan JamesandClaude Opus 5.5 ee3db96ea8 Stage S-1a: parity hashing covers the whole dictionary; failures are logged, counted and marked INCOMPLETE (FABRIC-3.9.0 §8.1)
- MAX_DICT_ENTRIES (2048) removed: the entry list is allocated to the
  dictionary's size; a cyclic chain is detected (Floyd) instead of capped.
- Colon-body walk bounded by vm->here, not a 1024-cell cap.
- Every failure prints PARITY:INCOMPLETE #n with its full reason, logs at
  LOG_ERROR, bumps sk_parity_incomplete_count(), and the record reads
  hash=INCOMPLETE / PARITY:FAIL code=4 rather than a plausible hash.
- Pre-existing #GP fixed: the walker dereferenced inline body data (S"
  bytes, offsets); it now follows only known dictionary entries.
- LIT operands that are entry pointers are hashed by word_id, not address,
  so a mature dictionary hashes identically across ISAs.

Probe (reverted): 563 -> 2563 words hashed, identical on amd64/aarch64/
riscv64; cyclic chain -> INCOMPLETE, counter 2. Boot parity unchanged
(531, 0x572daac83b797332). 3-ISA acceptance passes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 12:51:34 -04:00

194 lines
6.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* parity.h - Parity packet for VM validation
*
* Defines structures and functions for comparing hosted vs kernel VM state.
* Parity is verified via canonical dictionary hash, not raw memory comparison.
*
* M7 Normative Rules:
* - word_id is monotonic creation index starting at 0
* - Dictionary traversal is creation order (oldest to newest)
* - Hash excludes pointers, padding, runtime fields
* - Colon bodies are hashed as word_id sequences, not addresses
*/
#ifndef STARKERNEL_PARITY_H
#define STARKERNEL_PARITY_H
#include <stdint.h>
#include <stddef.h>
/**
* Bootstrap result codes
*/
#define SK_BOOTSTRAP_OK 0
#define SK_BOOTSTRAP_ARENA_FAIL 1
#define SK_BOOTSTRAP_INIT_FAIL 2
#define SK_BOOTSTRAP_DICT_FAIL 3
/* FABRIC-3.9.0.md §8.1 (Stage S-1a, 2026-09-24): the canonical dictionary
* hash could not cover the whole dictionary (a cyclic/corrupt link chain,
* the entry list could not be allocated, or a colon body ran off the end
* of VM memory without EXIT). The M7.1a line prints hash=INCOMPLETE and the
* result line PARITY:FAIL with this code -- never a plausible-looking hash
* computed over part of the dictionary. */
#define SK_BOOTSTRAP_PARITY_INCOMPLETE 4
/**
* ParityPacket - Summary of VM state for comparison
*
* M7.1a fields are sufficient for bootstrap validation.
* M7.1b fields are added for POST validation.
*/
typedef struct {
/* === M7.1a: Bootstrap Parity === */
uint32_t word_count; /* Number of dictionary entries */
uint32_t here_offset; /* vm->here (bytes used in dictionary) */
uint32_t latest_word_id; /* vm->latest->word_id (stable ID) */
uint64_t header_hash64; /* Canonical dictionary hash (FNV-1a) */
int hash_complete; /* 1 if header_hash64 covers the whole dictionary;
* 0 = INCOMPLETE, header_hash64 meaningless (S-1a) */
/* === M7.1b: POST Parity === */
uint32_t tests_total; /* Total tests executed */
uint32_t tests_passed; /* Tests passed */
uint32_t tests_failed; /* Tests failed */
uint32_t tests_skipped; /* Tests skipped */
uint32_t tests_errors; /* Tests with errors */
/* === Optional: Rolling Window Hash === */
uint64_t window_hash64; /* Hash of execution history (if deterministic) */
/* === Status === */
int bootstrap_result; /* SK_BOOTSTRAP_* code */
} ParityPacket;
/**
* Forward declaration of VM struct
*/
struct VM;
/*
* sk_parity_collect - Collect parity data from VM
*
* Traverses dictionary in creation order, computes canonical hash.
* Does NOT include runtime fields (execution_heat, physics, etc.).
*
* @param vm Pointer to VM instance
* @param out Pointer to ParityPacket to fill
*/
void sk_parity_collect(struct VM *vm, ParityPacket *out);
/*
* sk_parity_print - Print parity packet to console
*
* Output format:
* PARITY:M7.1a word_count=N here=0xHHHH latest_id=N hash=0xHHHHHHHHHHHHHHHH
* PARITY:M7.1b tests=N pass=N fail=N skip=N err=N
*
* @param pkt Pointer to ParityPacket to print
*/
void sk_parity_print(const ParityPacket *pkt);
/*
* sk_dict_canonical_hash - Compute canonical dictionary hash
*
* Hashes structural fields only:
* - flags, name_len, name[], acl_default, word_id
* - For colon words: body as word_id sequence
*
* Excludes:
* - link (pointer)
* - func (function pointer)
* - execution_heat (runtime)
* - physics (runtime)
* - transition_metrics (pointer)
*
* FABRIC-3.9.0.md §8.1 (Stage S-1a, 2026-09-24): covers the WHOLE
* dictionary -- no fixed cap on entries (was 2048) or on a colon body's
* cells (was 1024). *complete is set to 1 if every entry and every colon
* body was hashed; to 0 if the link chain is cyclic (corrupt), the entry
* list could not be allocated, or a colon body runs off the end of VM
* memory without EXIT. On 0 the returned value is meaningless, the failure
* is logged at LOG_ERROR, and sk_parity_incomplete_count() is bumped.
*
* @param vm Pointer to VM instance
* @param complete Out: 1 = complete, 0 = incomplete (must not be NULL)
* @return 64-bit FNV-1a hash (valid only when *complete == 1)
*/
uint64_t sk_dict_canonical_hash(struct VM *vm, int *complete);
/*
* sk_dict_word_count - Count dictionary entries
*
* Traverses from vm->latest to NULL -- the whole chain, no cap (S-1a). A
* cyclic (corrupt) chain is detected rather than walked forever: it is
* logged, counted, and 0 is returned.
*
* @param vm Pointer to VM instance
* @return Number of dictionary entries (0 on a cyclic chain)
*/
uint32_t sk_dict_word_count(struct VM *vm);
/* Number of times a dictionary walk or canonical hash has come out
* incomplete since boot (S-1a) -- 0 in any healthy run. */
uint32_t sk_parity_incomplete_count(void);
/**
* FNV-1a constants
*/
#define FNV1A_64_OFFSET_BASIS 0xCBF29CE484222325ULL
#define FNV1A_64_PRIME 0x100000001B3ULL
/*
* fnv1a_64 - FNV-1a 64-bit hash function
*
* @param data Pointer to data to hash
* @param len Length of data
* @param hash Current hash value (use FNV1A_64_OFFSET_BASIS for initial)
* @return Updated hash value
*/
uint64_t fnv1a_64(const uint8_t *data, size_t len, uint64_t hash);
#endif /* STARKERNEL_PARITY_H */