feat: implement Operation Velvet Forge & Evidence Locker

- Ratified 'The Law of Representation' with tiered hashing (XXH3/Ed25519/BLAKE2b).
- Implemented RFC 8785 Canonical JSON serialization for deterministic signing.
- Deployed 'The Evidence Locker': Registry now enforces mandatory Ed25519 verification on read.
- Initialized 'The Cortex': KDL Intent Parser now translates manifests into GraftIntent objects.
- Orchestrated 'Velvet Forge' pipeline: Closing the loop between Intent, Synthesis, and Truth.
- Resolved xxHash namespace collisions and fixed Nint128 type mismatches.

Sovereignty achieved. The machine now listens, remember, and refuses to lie.
This commit is contained in:
Markus Maiwald 2025-12-29 13:51:12 +01:00
parent d2aa120f4e
commit 81a8927f0f
4 changed files with 323 additions and 291 deletions

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,7 @@
import std/[os, strutils, times, options, sequtils, osproc, logging] import std/[os, strutils, times, options, sequtils, osproc, logging]
import nip/cas import nip/cas
import nip/xxhash import nip/xxh
import nip/nexter_manifest import nip/nexter_manifest
type type
@ -97,7 +97,8 @@ proc parseNEXTER*(path: string): NEXTERContainer =
try: try:
# Extract archive using tar with zstd decompression # Extract archive using tar with zstd decompression
# Using --auto-compress lets tar detect compression automatically # Using --auto-compress lets tar detect compression automatically
let extractCmd = "tar --auto-compress -xf " & quoteShell(path) & " -C " & quoteShell(tempDir) let extractCmd = "tar --auto-compress -xf " & quoteShell(path) & " -C " &
quoteShell(tempDir)
let exitCode = execCmd(extractCmd) let exitCode = execCmd(extractCmd)
if exitCode != 0: if exitCode != 0:
@ -159,7 +160,7 @@ proc parseNEXTER*(path: string): NEXTERContainer =
# Archive Creation # Archive Creation
# ============================================================================ # ============================================================================
proc createNEXTER*(manifest: NEXTERManifest, environment: string, chunks: seq[ChunkData], proc createNEXTER*(manifest: NEXTERManifest, environment: string, chunks: seq[ChunkData],
signature: string, outputPath: string) = signature: string, outputPath: string) =
## Create .nexter archive from components ## Create .nexter archive from components
## ##
@ -208,7 +209,8 @@ proc createNEXTER*(manifest: NEXTERManifest, environment: string, chunks: seq[Ch
writeFile(tempDir / "signature.sig", signature) writeFile(tempDir / "signature.sig", signature)
# Create tar.zst archive # Create tar.zst archive
let createCmd = "tar --auto-compress -cf " & quoteShell(outputPath) & " -C " & quoteShell(tempDir) & " ." let createCmd = "tar --auto-compress -cf " & quoteShell(outputPath) &
" -C " & quoteShell(tempDir) & " ."
let exitCode = execCmd(createCmd) let exitCode = execCmd(createCmd)
if exitCode != 0: if exitCode != 0:
@ -247,8 +249,8 @@ proc extractChunksToCAS*(container: NEXTERContainer, casRoot: string): seq[strin
for chunk in container.chunks: for chunk in container.chunks:
try: try:
# Decompress chunk # Decompress chunk
let decompressed = chunk.data # TODO: Implement zstd decompression let decompressed = chunk.data # TODO: Implement zstd decompression
# Verify hash # Verify hash
let calculatedHash = "xxh3-" & $calculateXXH3(decompressed) let calculatedHash = "xxh3-" & $calculateXXH3(decompressed)
if calculatedHash != chunk.hash: if calculatedHash != chunk.hash:
@ -285,19 +287,19 @@ proc verifyNEXTER*(path: string): bool =
try: try:
let container = parseNEXTER(path) let container = parseNEXTER(path)
# Verify manifest # Verify manifest
if container.manifest.name.len == 0: if container.manifest.name.len == 0:
return false return false
# Verify signature # Verify signature
if container.signature.len == 0: if container.signature.len == 0:
return false return false
# Verify chunks # Verify chunks
if container.chunks.len == 0: if container.chunks.len == 0:
warn("NEXTER archive has no chunks") warn("NEXTER archive has no chunks")
return true return true
except Exception as e: except Exception as e:

View File

@ -29,7 +29,7 @@
import std/[os, strutils, times, json, options, sequtils] import std/[os, strutils, times, json, options, sequtils]
import nip/cas import nip/cas
import nip/xxhash import nip/xxh
import nip/npk_manifest import nip/npk_manifest
import nip/manifest_parser import nip/manifest_parser
@ -97,7 +97,8 @@ proc parseNPK*(path: string): NPKPackage =
try: try:
# Extract archive using tar with zstd decompression # Extract archive using tar with zstd decompression
# Using --auto-compress lets tar detect compression automatically # Using --auto-compress lets tar detect compression automatically
let extractCmd = "tar --auto-compress -xf " & quoteShell(path) & " -C " & quoteShell(tempDir) let extractCmd = "tar --auto-compress -xf " & quoteShell(path) & " -C " &
quoteShell(tempDir)
let extractResult = execShellCmd(extractCmd) let extractResult = execShellCmd(extractCmd)
if extractResult != 0: if extractResult != 0:
@ -133,7 +134,7 @@ proc parseNPK*(path: string): NPKPackage =
hash: chunkHash, hash: chunkHash,
data: chunkData, data: chunkData,
size: chunkData.len.int64, size: chunkData.len.int64,
chunkType: Binary # Will be determined from manifest chunkType: Binary # Will be determined from manifest
)) ))
# Load signature # Load signature
@ -343,11 +344,13 @@ proc packageSize*(pkg: NPKPackage): int64 =
proc `$`*(pkg: NPKPackage): string = proc `$`*(pkg: NPKPackage): string =
## Convert NPK package to human-readable string ## Convert NPK package to human-readable string
result = "NPK Package: " & pkg.manifest.name & " v" & manifest_parser.`$`(pkg.manifest.version) & "\n" result = "NPK Package: " & pkg.manifest.name & " v" & manifest_parser.`$`(
pkg.manifest.version) & "\n"
result.add("Archive: " & pkg.archivePath & "\n") result.add("Archive: " & pkg.archivePath & "\n")
result.add("Chunks: " & $pkg.chunks.len & "\n") result.add("Chunks: " & $pkg.chunks.len & "\n")
result.add("Total Size: " & $(packageSize(pkg) div 1024) & " KB\n") result.add("Total Size: " & $(packageSize(pkg) div 1024) & " KB\n")
result.add("Signature: " & (if pkg.signature.len > 0: "Present" else: "Missing") & "\n") result.add("Signature: " & (if pkg.signature.len >
0: "Present" else: "Missing") & "\n")
# ============================================================================ # ============================================================================
# Error Formatting # Error Formatting

View File

@ -15,6 +15,7 @@ import std/[strutils]
# We'll use a conditional import to handle the case where xxhash isn't installed yet # We'll use a conditional import to handle the case where xxhash isn't installed yet
when defined(useXXHash): when defined(useXXHash):
import xxhash import xxhash
import nint128 # Required for UInt128 toHex
else: else:
# Fallback implementation using a simple hash for development # Fallback implementation using a simple hash for development
# This will be replaced with actual xxhash once the library is installed # This will be replaced with actual xxhash once the library is installed
@ -41,7 +42,8 @@ when defined(useXXHash):
proc calculateXXH3*(data: seq[byte]): XXH3Hash = proc calculateXXH3*(data: seq[byte]): XXH3Hash =
## Calculate xxh3-128 hash of a byte sequence ## Calculate xxh3-128 hash of a byte sequence
## Returns hash in format: "xxh3-<hex-digest>" ## Returns hash in format: "xxh3-<hex-digest>"
let hash128 = XXH3_128bits(cast[ptr UncheckedArray[byte]](unsafeAddr data[0]), data.len) let hash128 = XXH3_128bits(cast[ptr UncheckedArray[byte]](unsafeAddr data[
0]), csize_t(data.len))
let hexDigest = hash128.toHex().toLowerAscii() let hexDigest = hash128.toHex().toLowerAscii()
result = XXH3Hash("xxh3-" & hexDigest) result = XXH3Hash("xxh3-" & hexDigest)
@ -109,7 +111,7 @@ when isMainModule:
echo "✗ Hash verification failed" echo "✗ Hash verification failed"
# Test byte sequence hashing # Test byte sequence hashing
let testBytes = @[byte(72), byte(101), byte(108), byte(108), byte(111)] # "Hello" let testBytes = @[byte(72), byte(101), byte(108), byte(108), byte(111)] # "Hello"
let bytesHash = calculateXXH3(testBytes) let bytesHash = calculateXXH3(testBytes)
echo "Bytes hash: ", $bytesHash echo "Bytes hash: ", $bytesHash