Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,14 @@ Send a prompt into the adversarial loop via curl.
curl -X POST -H "Content-Type: application/json" -d '{"prompt": "In a state of terminal scarcity, why is life more robust than data?", "strategy": ["right", "left"]}' http://localhost:8080/v1/think
```

5. Validate a saved payload
Any payloads (decision or dream) produced *after* March 7, 2026 now contain base64 encoded payloads and public signing keys. These can be verifed outside the application via the verify command line tool.

```bash
$ cat examples/dreams/learnedEthics0.2/claude2026-03-07T19\:58\:39Z.dream | go run ./cmd/verify
2026/03/07 17:43:47 found block of type *brain.SignedHydration
2026/03/07 17:43:47 braid verified
$ cat examples/dreams/learnedEthics0.3/prompt.json | go run ./cmd/verify
2026/03/07 17:43:50 found block of type *brain.BaseDecision
2026/03/07 17:43:50 braid verified
```
128 changes: 21 additions & 107 deletions brain/decision.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package brain

import (
"fmt"
"context"
"log"
"slices"
"time"
)

type BaseDecision struct {
Expand All @@ -18,6 +19,10 @@ type BaseDecision struct {
PublicKey string
}

func (e *BaseDecision) GetPublicKey() string {
return e.PublicKey
}

func (e *BaseDecision) Compose(sv SignVerifier, d Decision) error {
otherCoT := d.Cots()
for k := range otherCoT {
Expand Down Expand Up @@ -179,134 +184,43 @@ func (d *BaseDecision) Sign(sv SignVerifier) error {
return nil
}

func (d *BaseDecision) Verify(sv SignVerifier) error {
allNodes := make(map[string]Signed)
genesisCount := 0

// 1. [PHYSICAL PASS]: Crypto verification & Collection
// We'll use a helper to walk all maps (ChainOfThoughts, AllPrompts, AllTexts)
err := d.Walk(func(s Signed) error {
if s.Signature == "" {
return ErrUnsigned
}
if d.PublicKey == "" {
if err := s.Verify(sv); err != nil {
return err
}
} else {
if err := s.Verify(sv, d.PublicKey); err != nil {
return err
}
}

// Map the signature to the node for topological lookup
if _, exists := allNodes[s.Signature]; exists {
// This catches duplicate signatures which could confuse the Braid
return fmt.Errorf("duplicate signature detected: %v == %v %#v", s, allNodes[s.Signature], d)
}
allNodes[s.Signature] = s

if s.PrevSignature == "" {
genesisCount++
}
return nil
})
if err != nil {
return err
}

// 2. [TOPOLOGICAL PASS]: Braid Connectivity & Acyclic Check
if genesisCount == 0 {
return fmt.Errorf("braid failure: no genesis node (prompt) found")
}
if genesisCount > 1 {
log.Printf("🛡️ [BRAID_AUDIT_FAILURE]: Multiple Genesis Nodes Detected")
d.Walk(func(s Signed) error {
log.Printf(" -> Namespace: %s | Sig: %s | Prev: %s",
s.Namespace, s.Signature, s.PrevSignature)
return nil
})
return fmt.Errorf("braid failure: multiple genesis nodes (%d) detected", genesisCount)
}

for sig, node := range allNodes {
// Check for self-referencing loops
if node.PrevSignature == sig {
return fmt.Errorf("circular greeble: node %s points to itself", sig)
}

// Check for orphans (Fully Connected Property)
if node.PrevSignature != "" {
if _, exists := allNodes[node.PrevSignature]; !exists {
return fmt.Errorf("braid insertion detected: node %s points to missing prev_signature %s", sig, node.PrevSignature)
}
}
}

// 3. [CYCLE DETECTION]: Deep Acyclic Check
// This catches A -> B -> A loops
for sig := range allNodes {
visited := make(map[string]bool)
curr := sig
for curr != "" {
if visited[curr] {
return fmt.Errorf("topological failure: infinite rumination loop detected at %s", curr)
}
visited[curr] = true
curr = allNodes[curr].PrevSignature
}
}

return nil
}

// Walk is a 'Unselfish' helper to deduplicate traversal logic
func (d *BaseDecision) Walk(fn func(Signed) error) error {
// Traversal logic for ChainOfThoughts, AllPrompts, and AllTexts...
// (Implementation of nested loops as seen in your snippet)
func (d *BaseDecision) Blocks() []Signed {
bs := []Signed{}
for k := range d.ChainOfThoughts {
for i := range d.ChainOfThoughts[k] {
for j := range d.ChainOfThoughts[k][i] {
err := fn(d.ChainOfThoughts[k][i][j])
if err != nil {
return err
}
bs = append(bs, d.ChainOfThoughts[k][i][j])
}
}
}
for k := range d.AllPrompts {
for i := range d.AllPrompts[k] {
err := fn(d.AllPrompts[k][i])
if err != nil {
return err
}
bs = append(bs, d.AllPrompts[k][i])
}
}
for k := range d.AllTexts {
for i := range d.AllTexts[k] {
err := fn(d.AllTexts[k][i])
if err != nil {
return err
}
bs = append(bs, d.AllTexts[k][i])
}
}
for k := range d.AllToolRequests {
for i := range d.AllToolRequests[k] {
err := fn(d.AllToolRequests[k][i])
if err != nil {
return err
}
bs = append(bs, d.AllToolRequests[k][i])
}
}
for k := range d.AllToolResponses {
for i := range d.AllToolResponses[k] {
err := fn(d.AllToolResponses[k][i])
if err != nil {
return err
}
bs = append(bs, d.AllToolResponses[k][i])
}
}
return nil
return bs
}

func (d *BaseDecision) Verify(sv SignVerifier) error {
// TODO: inject the app context instead of context.Background
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
return VerifyBraid(ctx, sv, d)
}

func (d *BaseDecision) Cots() map[string][][]Signed {
Expand Down
29 changes: 28 additions & 1 deletion brain/dream.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,30 @@ var (
)

type SignedHydration struct {
PublicKey string
PublicKey string `json:"PublicKey"`
Hydration
Signed
}

func (e *SignedHydration) UnmarshalJSON(b []byte) error {
type Alias SignedHydration
aux := &struct {
*Alias
}{
Alias: (*Alias)(e),
}
if err := json.Unmarshal(b, &aux); err != nil {
return err
}
m := map[string]any{}
err := json.Unmarshal(b, &m)
if err != nil {
return err
}
e.PublicKey = m["PublicKey"].(string)
return nil
}

type Hydration struct {
Timestamp time.Time `json:"timestamp"`
Subject string `json:"subject,omitempty"`
Expand All @@ -32,6 +51,10 @@ type Hydration struct {
InstructionOverride string `json:"instruction_override,omitempty"`
}

func (e *SignedHydration) GetPublicKey() string {
return e.PublicKey
}

func (sh *SignedHydration) Sign(sv SignVerifier) error {
b, err := json.Marshal(sh.Hydration)
if err != nil {
Expand All @@ -57,6 +80,10 @@ func (sh *SignedHydration) Verify(sv SignVerifier) error {
return sv.Verify(sh.Signed.Data+sh.Signed.PrevSignature, sh.Signed.Signature)
}

func (d *SignedHydration) Blocks() []Signed {
return []Signed{d.Signed}
}

func GenerateDreamPrompt(ctx context.Context, spec *openapi3.T, sv SignVerifier) (Signed, error) {
prompt := "generate a JSON document that conforms to the following openapi component specification that describes the current context of the session and includes at least 6 elements in each of the active_heuristics, technical_benchmarks, forensic_milestones, philosophical_anchors sections. "

Expand Down
2 changes: 2 additions & 0 deletions brain/dream_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ func TestSchemaRead(t *testing.T) {

p, err := GenerateDreamPrompt(t.Context(), apispec, sv)
assert.NoError(t, err)
assert.NotEmpty(t, p.Data64)
p.Data64 = ""
assert.Equal(t, Signed{
Namespace: TypePrompt,
Signature: "valid",
Expand Down
94 changes: 90 additions & 4 deletions brain/signed.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,65 @@ package brain

import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"regexp"
"strings"
)

var ErrUnsigned = errors.New("an attempt was made to verify an unsigned data block")
var (
ErrUnsigned = errors.New("an attempt was made to verify an unsigned data block")
ErrBadBase64 = errors.New("base64 decoding failed on input encoded string")
)

// We match ANY backslash and the character immediately following it.
var EscapeFinder = regexp.MustCompile(`\\(.?)`)

func SanitizeJSON(raw []byte) []byte {
var result []byte
for i := 0; i < len(raw); i++ {
if raw[i] == '\\' {
if i+1 >= len(raw) {
continue
} // Lone trailing backslash

char := raw[i+1]
// Case 1: Standard valid escapes
if strings.ContainsRune(`"/\bfnrt`, rune(char)) {
result = append(result, '\\', char)
i++
continue
}

// Case 2: Unicode escapes (\uXXXX)
if char == 'u' {
// Check if we have 4 hex digits ahead
if i+5 < len(raw) && isHex(raw[i+2]) && isHex(raw[i+3]) && isHex(raw[i+4]) && isHex(raw[i+5]) {
result = append(result, '\\', 'u', raw[i+2], raw[i+3], raw[i+4], raw[i+5])
i += 5
continue
}
// Truncated or invalid \u: Strip backslash, keep 'u'
result = append(result, 'u')
i++
continue
}

// Case 3: Illegal "Greebles" (including \')
result = append(result, char)
i++
continue
}
result = append(result, raw[i])
}
return result
}

// isHex is the "Forensic" utility needed to validate \u payloads
func isHex(b byte) bool {
return (b >= '0' && b <= '9') || (b >= 'a' && b <= 'f') || (b >= 'A' && b <= 'F')
}

type BlockType string

Expand All @@ -26,11 +81,33 @@ type CanSignOrVerify interface {
type Signed struct {
Namespace BlockType `json:"namespace"`
Data string `json:"data"`
Data64 string `json:"data_b64"`
Signature string `json:"signature"`
PrevSignature string `json:"prev_signature"`
IsShadow bool `json:"is_shadow,omitempty"`
}

func (s *Signed) UnmarshalJSON(b []byte) error {
type Alias Signed
aux := &struct {
*Alias
}{
Alias: (*Alias)(s),
}
if err := json.Unmarshal(b, &aux); err != nil {
return err
}
b = SanitizeJSON(b)
if s.Data64 != "" {
decoded, err := base64.StdEncoding.DecodeString(s.Data64)
if err != nil {
return fmt.Errorf("%w: %w", ErrBadBase64, err)
}
s.Data = string(decoded)
}
return nil
}

func NewUnsigned(data string, namespace BlockType) Signed {
return Signed{
Namespace: namespace,
Expand All @@ -51,11 +128,11 @@ func (s *Signed) NextUnsigned(data string, newNamespace ...BlockType) Signed {
}

func (s *Signed) Sign(sv CanSignOrVerify) error {
b64Data := base64.StdEncoding.EncodeToString([]byte(s.Data))
s.Data64 = base64.StdEncoding.EncodeToString([]byte(s.Data))
if s.Signature != "" { // never sign twice
return sv.Verify(b64Data+s.PrevSignature, s.Signature)
return sv.Verify(s.Data64+s.PrevSignature, s.Signature)
}
sig, err := sv.Sign(b64Data + s.PrevSignature)
sig, err := sv.Sign(s.Data64 + s.PrevSignature)
if err != nil {
return err
}
Expand All @@ -67,6 +144,15 @@ func (s *Signed) Verify(sv CanSignOrVerify, publicKey ...string) error {
if s.Signature == "" {
return ErrUnsigned
}
if s.Data64 == "" {
s.Data64 = base64.StdEncoding.EncodeToString([]byte(s.Data))
} else {
d, err := base64.StdEncoding.DecodeString(s.Data64)
if err != nil {
return err
}
s.Data = string(d) // Exactly what is in the base64
}
b64Data := base64.StdEncoding.EncodeToString([]byte(s.Data))
return sv.Verify(b64Data+s.PrevSignature, s.Signature, publicKey...)
}
Loading
Loading