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 1e44dcfaf0
commit 9695382eaf
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 nip/cas
import nip/xxhash
import nip/xxh
import nip/nexter_manifest
type
@ -97,7 +97,8 @@ proc parseNEXTER*(path: string): NEXTERContainer =
try:
# Extract archive using tar with zstd decompression
# 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)
if exitCode != 0:
@ -159,7 +160,7 @@ proc parseNEXTER*(path: string): NEXTERContainer =
# Archive Creation
# ============================================================================
proc createNEXTER*(manifest: NEXTERManifest, environment: string, chunks: seq[ChunkData],
proc createNEXTER*(manifest: NEXTERManifest, environment: string, chunks: seq[ChunkData],
signature: string, outputPath: string) =
## Create .nexter archive from components
##
@ -208,7 +209,8 @@ proc createNEXTER*(manifest: NEXTERManifest, environment: string, chunks: seq[Ch
writeFile(tempDir / "signature.sig", signature)
# 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)
if exitCode != 0:
@ -247,8 +249,8 @@ proc extractChunksToCAS*(container: NEXTERContainer, casRoot: string): seq[strin
for chunk in container.chunks:
try:
# Decompress chunk
let decompressed = chunk.data # TODO: Implement zstd decompression
let decompressed = chunk.data # TODO: Implement zstd decompression
# Verify hash
let calculatedHash = "xxh3-" & $calculateXXH3(decompressed)
if calculatedHash != chunk.hash:
@ -285,19 +287,19 @@ proc verifyNEXTER*(path: string): bool =
try:
let container = parseNEXTER(path)
# Verify manifest
if container.manifest.name.len == 0:
return false
# Verify signature
if container.signature.len == 0:
return false
# Verify chunks
if container.chunks.len == 0:
warn("NEXTER archive has no chunks")
return true
except Exception as e:

View File

@ -29,7 +29,7 @@
import std/[os, strutils, times, json, options, sequtils]
import nip/cas
import nip/xxhash
import nip/xxh
import nip/npk_manifest
import nip/manifest_parser
@ -97,7 +97,8 @@ proc parseNPK*(path: string): NPKPackage =
try:
# Extract archive using tar with zstd decompression
# 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)
if extractResult != 0:
@ -133,7 +134,7 @@ proc parseNPK*(path: string): NPKPackage =
hash: chunkHash,
data: chunkData,
size: chunkData.len.int64,
chunkType: Binary # Will be determined from manifest
chunkType: Binary # Will be determined from manifest
))
# Load signature
@ -343,11 +344,13 @@ proc packageSize*(pkg: NPKPackage): int64 =
proc `$`*(pkg: NPKPackage): 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("Chunks: " & $pkg.chunks.len & "\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

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
when defined(useXXHash):
import xxhash
import nint128 # Required for UInt128 toHex
else:
# Fallback implementation using a simple hash for development
# 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 =
## Calculate xxh3-128 hash of a byte sequence
## 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()
result = XXH3Hash("xxh3-" & hexDigest)
@ -109,7 +111,7 @@ when isMainModule:
echo "✗ Hash verification failed"
# 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)
echo "Bytes hash: ", $bytesHash