Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0259d19427 | ||
|
|
b21391c552 | ||
|
|
9bbd55ea6d | ||
|
|
8095ab95c6 | ||
|
|
3933ec9e44 | ||
|
|
410e8c7685 | ||
|
|
9b7c767b56 | ||
|
|
c36f2e70f2 | ||
|
|
299d2c9bb8 | ||
|
|
23c2e41077 | ||
|
|
3cf5e81707 | ||
|
|
9b30dd5885 | ||
|
|
22117c1f79 | ||
|
|
4b4ddbf6a3 | ||
|
|
32bdacddfb | ||
|
|
9db9277402 | ||
|
|
abc29365e3 | ||
|
|
da36073a0c | ||
|
|
3e705f13e5 | ||
|
|
6740c86c82 | ||
|
|
bd31a6dde9 | ||
|
|
c82f83a87d | ||
|
|
70c3311fca | ||
|
|
cb4977fc79 | ||
|
|
52314af121 | ||
|
|
fd4b4d3254 | ||
|
|
c912b2bc3e | ||
|
|
590c4466ff | ||
|
|
ee1d1c106c | ||
|
|
f7c00cbdf7 | ||
|
|
25eb12c656 | ||
|
|
5881b78713 | ||
|
|
f97c8c1ff4 | ||
|
|
588e2f2522 | ||
|
|
1057cded97 | ||
|
|
e11b485a78 | ||
|
|
d9d575ac07 | ||
|
|
50eff50902 | ||
|
|
ea65b7c9d0 | ||
|
|
e790ad70aa | ||
|
|
edbd27b9ff | ||
|
|
6276f21aff | ||
|
|
313f1c9972 | ||
|
|
8549cee9d9 | ||
|
|
511c4b246e | ||
|
|
e96ff0c50e | ||
|
|
41ecd72c41 | ||
|
|
b953e02156 | ||
|
|
2066ea9bb9 | ||
|
|
5666654738 | ||
|
|
3239080c9b | ||
|
|
96f521c7ad |
No files matched your search
@@ -357,6 +357,18 @@ jobs:
|
||||
- name: memory-store-deep text-kernel parity gate (HARD — #2479 batch: fts/mapreduce/entities)
|
||||
run: |
|
||||
cd src/go/memory-store-deep && go build -o /tmp/msd-${{ gitea.run_id }} . && go test -run "TestTextKernelsParity|TestDriftRerankBlendParity" -v
|
||||
- name: scaffold builders parity gate (HARD — #2479 batch: 7 pure builders)
|
||||
run: |
|
||||
cd src/go/scaffold && go build -o /tmp/scaffold-${{ gitea.run_id }} . && go test -run TestBuildersParity -v
|
||||
- name: tool-executor prepared-path parity gate (HARD — #2479 batch)
|
||||
run: |
|
||||
cd src/go/tool-executor && go build -o /tmp/tool-exec-${{ gitea.run_id }} . && go test -run TestPreparedPathParity -v
|
||||
- name: failure-filer parity gate (HARD — #2479 batch: classify/redact/tier/marker)
|
||||
run: |
|
||||
cd src/go/failure-filer && go build -o /tmp/failfiler-${{ gitea.run_id }} . && go test -run TestFilerParity -v
|
||||
- name: tool-protocol shapes parity gate (HARD — #2479 batch: 5 record shapes)
|
||||
run: |
|
||||
cd src/go/tool-protocol && go build -o /tmp/tp-${{ gitea.run_id }} . && go test -run TestShapesFromDictParity -v
|
||||
- name: go race detector (every module's test suite under -race)
|
||||
run: |
|
||||
for dir in src/go/*/; do
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Rune
|
||||
|
||||
**Current release: v0.172.0**
|
||||
**Current release: v0.183.0**
|
||||
|
||||
**Rune is a persistent personal agent designed to accumulate experience, develop reusable competence, and remain recognisably the same agent even when its underlying foundation model changes.**
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "rune"
|
||||
version = "0.172.0"
|
||||
version = "0.183.0"
|
||||
description = "Rune — a stateful coding assistant with persistent memory, orchestration, and TUI"
|
||||
requires-python = ">=3.10"
|
||||
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
{
|
||||
"_doc": "FROZEN ORACLE (failure-filer parity).",
|
||||
"rows": [
|
||||
{
|
||||
"op": "error_class",
|
||||
"err": "RuntimeError: boom",
|
||||
"want": "RuntimeError"
|
||||
},
|
||||
{
|
||||
"op": "redact",
|
||||
"err": "RuntimeError: boom",
|
||||
"want": "RuntimeError: boom"
|
||||
},
|
||||
{
|
||||
"op": "excerpt",
|
||||
"err": "RuntimeError: boom",
|
||||
"want": "RuntimeError: boom"
|
||||
},
|
||||
{
|
||||
"op": "error_class",
|
||||
"err": "ValueError: bad value here",
|
||||
"want": "ValueError"
|
||||
},
|
||||
{
|
||||
"op": "redact",
|
||||
"err": "ValueError: bad value here",
|
||||
"want": "ValueError: bad value here"
|
||||
},
|
||||
{
|
||||
"op": "excerpt",
|
||||
"err": "ValueError: bad value here",
|
||||
"want": "ValueError: bad value here"
|
||||
},
|
||||
{
|
||||
"op": "error_class",
|
||||
"err": "",
|
||||
"want": "Unknown"
|
||||
},
|
||||
{
|
||||
"op": "redact",
|
||||
"err": "",
|
||||
"want": ""
|
||||
},
|
||||
{
|
||||
"op": "excerpt",
|
||||
"err": "",
|
||||
"want": ""
|
||||
},
|
||||
{
|
||||
"op": "error_class",
|
||||
"err": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"want": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
},
|
||||
{
|
||||
"op": "redact",
|
||||
"err": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"want": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
},
|
||||
{
|
||||
"op": "excerpt",
|
||||
"err": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"want": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
},
|
||||
{
|
||||
"op": "error_class",
|
||||
"err": "postgres://user:pass@host/db?token=abc123",
|
||||
"want": "postgres://user:pass@host/db?token=abc123"
|
||||
},
|
||||
{
|
||||
"op": "redact",
|
||||
"err": "postgres://user:pass@host/db?token=abc123",
|
||||
"want": "postgres://<redacted>:<redacted>@host/db?token=<redacted>"
|
||||
},
|
||||
{
|
||||
"op": "excerpt",
|
||||
"err": "postgres://user:pass@host/db?token=abc123",
|
||||
"want": "postgres://<redacted>:<redacted>@host/db?token=<redacted>"
|
||||
},
|
||||
{
|
||||
"op": "error_class",
|
||||
"err": "Authorization: Bearer xyz789",
|
||||
"want": "Authorization"
|
||||
},
|
||||
{
|
||||
"op": "redact",
|
||||
"err": "Authorization: Bearer xyz789",
|
||||
"want": "Authorization: Bearer <redacted>"
|
||||
},
|
||||
{
|
||||
"op": "excerpt",
|
||||
"err": "Authorization: Bearer xyz789",
|
||||
"want": "Authorization: Bearer <redacted>"
|
||||
},
|
||||
{
|
||||
"op": "error_class",
|
||||
"err": "password=supersecret password",
|
||||
"want": "password=supersecret"
|
||||
},
|
||||
{
|
||||
"op": "redact",
|
||||
"err": "password=supersecret password",
|
||||
"want": "password=<redacted> password"
|
||||
},
|
||||
{
|
||||
"op": "excerpt",
|
||||
"err": "password=supersecret password",
|
||||
"want": "password=<redacted> password"
|
||||
},
|
||||
{
|
||||
"op": "error_class",
|
||||
"err": "plain message",
|
||||
"want": "plain"
|
||||
},
|
||||
{
|
||||
"op": "redact",
|
||||
"err": "plain message",
|
||||
"want": "plain message"
|
||||
},
|
||||
{
|
||||
"op": "excerpt",
|
||||
"err": "plain message",
|
||||
"want": "plain message"
|
||||
},
|
||||
{
|
||||
"op": "tier",
|
||||
"tier": 0,
|
||||
"want": false
|
||||
},
|
||||
{
|
||||
"op": "tier",
|
||||
"tier": 1,
|
||||
"want": false
|
||||
},
|
||||
{
|
||||
"op": "tier",
|
||||
"tier": 2,
|
||||
"want": true
|
||||
},
|
||||
{
|
||||
"op": "tier",
|
||||
"tier": 3,
|
||||
"want": true
|
||||
},
|
||||
{
|
||||
"op": "marker",
|
||||
"sub": "cron",
|
||||
"ec": "RuntimeError",
|
||||
"want": "[auto-failure:cron:RuntimeError]"
|
||||
},
|
||||
{
|
||||
"op": "signature",
|
||||
"sub": "cron",
|
||||
"ec": "RuntimeError",
|
||||
"want": [
|
||||
"cron",
|
||||
"RuntimeError"
|
||||
]
|
||||
},
|
||||
{
|
||||
"op": "marker",
|
||||
"sub": "unit-tests",
|
||||
"ec": "ValueError",
|
||||
"want": "[auto-failure:unit-tests:ValueError]"
|
||||
},
|
||||
{
|
||||
"op": "signature",
|
||||
"sub": "unit-tests",
|
||||
"ec": "ValueError",
|
||||
"want": [
|
||||
"unit-tests",
|
||||
"ValueError"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package main
|
||||
|
||||
// truth_test.go — #2479 failure-filer parity gate (oracle-first: truth.json
|
||||
// generated from the live Python failure_auto_filer).
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFilerParity(t *testing.T) {
|
||||
raw, err := os.ReadFile("truth.json")
|
||||
if err != nil {
|
||||
t.Fatalf("truth.json missing: %v", err)
|
||||
}
|
||||
var doc struct {
|
||||
Rows []struct {
|
||||
Op string `json:"op"`
|
||||
Err string `json:"err"`
|
||||
Tier int `json:"tier"`
|
||||
Sub string `json:"sub"`
|
||||
Ec string `json:"ec"`
|
||||
Want any `json:"want"`
|
||||
} `json:"rows"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &doc); err != nil {
|
||||
t.Fatalf("unparseable: %v", err)
|
||||
}
|
||||
for i, c := range doc.Rows {
|
||||
switch c.Op {
|
||||
case "error_class":
|
||||
if got := errorClassOf(c.Err); got != c.Want.(string) {
|
||||
t.Errorf("row %d error_class %q: got %q want %q", i, c.Err, got, c.Want)
|
||||
}
|
||||
case "redact", "excerpt":
|
||||
// excerpt = redact + truncate: compare full strings
|
||||
got := redact(c.Err)
|
||||
if c.Op == "excerpt" {
|
||||
got = excerpt(c.Err, 200)
|
||||
}
|
||||
if got != c.Want.(string) {
|
||||
t.Errorf("row %d %s: got %q want %q", i, c.Op, got, c.Want)
|
||||
}
|
||||
case "tier":
|
||||
if got := tierGated(c.Tier); got != c.Want.(bool) {
|
||||
t.Errorf("row %d tier %d: got %v want %v", i, c.Tier, got, c.Want)
|
||||
}
|
||||
case "marker":
|
||||
if got := markerFor(c.Sub, c.Ec); got != c.Want.(string) {
|
||||
t.Errorf("row %d marker: got %q want %q", i, got, c.Want)
|
||||
}
|
||||
case "signature":
|
||||
sub, cls := signatureOf(c.Sub, c.Ec)
|
||||
want := c.Want.([]any)
|
||||
if sub != want[0].(string) || cls != want[1].(string) {
|
||||
t.Errorf("row %d signature: got %v want %v", i, []string{sub, cls}, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
var _ = math.Pi
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
// Package main — progressive-escalation: the GO port of
|
||||
// src/rune/progressive_escalation.py's should_escalate + get_next_tier
|
||||
// (Oracle-Battery Parity Pattern, #2479 GO batch 44). The executor/verifier
|
||||
// loop stays Python (reactive surface).
|
||||
package main
|
||||
|
||||
// progressive-escalation: should_escalate + get_next_tier parity kernels
|
||||
// (oracle: src/rune/progressive_escalation.py). Replay subcommand added
|
||||
// (#2479 batch — the truth battery is now runnable; the old binary
|
||||
// panicked on 2-arg invocation).
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@@ -11,19 +12,22 @@ import (
|
||||
)
|
||||
|
||||
func shouldEscalate(verificationResult map[string]any, attempt, maxAttempts int) bool {
|
||||
if passed, _ := verificationResult["passed"].(bool); passed {
|
||||
passed, _ := verificationResult["passed"].(bool)
|
||||
if passed {
|
||||
return false
|
||||
}
|
||||
if attempt >= maxAttempts {
|
||||
return false
|
||||
}
|
||||
reason, _ := verificationResult["escalation_reason"].(string)
|
||||
_ = reason // ESCALATION_TRIGGERS is data-driven in Python; default escalates
|
||||
return true
|
||||
}
|
||||
|
||||
func getNextTier(currentTier, maxTier string) *string {
|
||||
tierOrder := []string{"T0", "T1", "T2", "T3", "T4"}
|
||||
order := []string{"T0", "T1", "T2", "T3", "T4"}
|
||||
curIdx, maxIdx := -1, -1
|
||||
for i, t := range tierOrder {
|
||||
for i, t := range order {
|
||||
if t == currentTier {
|
||||
curIdx = i
|
||||
}
|
||||
@@ -31,62 +35,82 @@ func getNextTier(currentTier, maxTier string) *string {
|
||||
maxIdx = i
|
||||
}
|
||||
}
|
||||
if curIdx < 0 || maxIdx < 0 || curIdx >= maxIdx {
|
||||
if curIdx < 0 || maxIdx < 0 {
|
||||
return nil
|
||||
}
|
||||
next := tierOrder[curIdx+1]
|
||||
return &next
|
||||
if curIdx < maxIdx {
|
||||
next := order[curIdx+1]
|
||||
return &next
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 || os.Args[1] != "replay" {
|
||||
fmt.Fprintln(os.Stderr, "usage: progressive-escalation replay <truth.json>")
|
||||
os.Exit(2)
|
||||
}
|
||||
raw, err := os.ReadFile(os.Args[2])
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
var cases []map[string]any
|
||||
if err := json.Unmarshal(raw, &cases); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fails := 0
|
||||
for i, c := range cases {
|
||||
op, _ := c["op"].(string)
|
||||
switch op {
|
||||
case "escalate":
|
||||
vr, _ := c["vr"].(map[string]any)
|
||||
attempt := int(c["attempt"].(float64))
|
||||
maxA := int(c["max"].(float64))
|
||||
want, _ := c["want"].(bool)
|
||||
if got := shouldEscalate(vr, attempt, maxA); got != want {
|
||||
fails++
|
||||
fmt.Printf("case %d escalate: got %v want %v\n", i, got, want)
|
||||
}
|
||||
case "next_tier":
|
||||
cur, _ := c["cur"].(string)
|
||||
max, _ := c["max"].(string)
|
||||
want, hasWant := c["want"].(string)
|
||||
got := getNextTier(cur, max)
|
||||
if hasWant {
|
||||
if got == nil || *got != want {
|
||||
if len(os.Args) > 2 && os.Args[1] == "replay" {
|
||||
raw, err := os.ReadFile(os.Args[2])
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "read failed:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
var cases []struct {
|
||||
Op string `json:"op"`
|
||||
VR map[string]any `json:"vr"`
|
||||
Done bool `json:"done"`
|
||||
Attempt json.RawMessage `json:"attempt"`
|
||||
Max json.RawMessage `json:"max"`
|
||||
Current string `json:"current"`
|
||||
Cur string `json:"cur"`
|
||||
MaxTier string `json:"max_tier"`
|
||||
Want json.RawMessage `json:"want"`
|
||||
WantNil bool `json:"want_nil"`
|
||||
WantNext string `json:"want_next"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &cases); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "unparseable:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fails := 0
|
||||
for i, c := range cases {
|
||||
if c.Op == "escalate" {
|
||||
var attempt, maxAttempts int
|
||||
_ = json.Unmarshal(c.Attempt, &attempt)
|
||||
_ = json.Unmarshal(c.Max, &maxAttempts)
|
||||
var wantBool bool
|
||||
_ = json.Unmarshal(c.Want, &wantBool)
|
||||
if got := shouldEscalate(c.VR, attempt, maxAttempts); got != wantBool {
|
||||
fails++
|
||||
fmt.Printf("case %d next_tier %s->%s: got %v want %q\n", i, cur, max, got, want)
|
||||
fmt.Printf("case %d escalate: got %v want %v\n", i, got, wantBool)
|
||||
}
|
||||
} else {
|
||||
if got != nil {
|
||||
} else if c.Op == "next_tier" {
|
||||
cur := c.Current
|
||||
if cur == "" {
|
||||
cur = c.Cur
|
||||
}
|
||||
maxTier := c.MaxTier
|
||||
if maxTier == "" {
|
||||
_ = json.Unmarshal(c.Max, &maxTier)
|
||||
}
|
||||
got := getNextTier(cur, maxTier)
|
||||
var wantStr string
|
||||
_ = json.Unmarshal(c.Want, &wantStr)
|
||||
if wantStr == "" {
|
||||
if got != nil {
|
||||
fails++
|
||||
fmt.Printf("case %d next_tier: got %v want nil\n", i, *got)
|
||||
}
|
||||
} else if got == nil || *got != wantStr {
|
||||
fails++
|
||||
fmt.Printf("case %d next_tier %s->%s: got %v want nil\n", i, cur, max, *got)
|
||||
fmt.Printf("case %d next_tier: got %v want %v\n", i, got, wantStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
if fails > 0 {
|
||||
fmt.Fprintf(os.Stderr, "%d/%d FAILED\n", fails, len(cases))
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Printf("PARITY OK: %d cases vs the Python oracle\n", len(cases))
|
||||
return
|
||||
}
|
||||
if fails > 0 {
|
||||
fmt.Fprintf(os.Stderr, "PARITY FAILED: %d divergence(s)\n", fails)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Printf("PARITY OK: %d cases vs the Python oracle\n", len(cases))
|
||||
fmt.Fprintln(os.Stderr, "usage: progressive-escalation replay <truth.json>")
|
||||
os.Exit(2)
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package main
|
||||
|
||||
// builders.go — #2479 scaffold batch: the 7 pure Project builders
|
||||
// (add_domain/component/contract/link/prd/next_action/limitation).
|
||||
// Each is a thin entity/relationship constructor over the shared doc shape
|
||||
// (structural_store.add_entity/add_relationship semantics). Oracle:
|
||||
// src/rune/scaffold.py; truth rows in truth_builders.json.
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
func builderEntity(doc map[string]interface{}, id, kind string, identities map[string]interface{}) map[string]interface{} {
|
||||
ents, _ := doc["entities"].([]map[string]interface{})
|
||||
for _, e := range ents {
|
||||
if eid, _ := e["id"].(string); eid == id {
|
||||
if im, ok := e["identities"].(map[string]interface{}); ok {
|
||||
for k, v := range identities {
|
||||
im[k] = v
|
||||
}
|
||||
}
|
||||
return e
|
||||
}
|
||||
}
|
||||
e := map[string]interface{}{
|
||||
"id": id,
|
||||
"kind": kind,
|
||||
"maturity": "DECLARED",
|
||||
"tags": []string{},
|
||||
"identities": identities,
|
||||
"evidence_refs": []string{"scaffold"},
|
||||
}
|
||||
doc["entities"] = append(ents, e)
|
||||
return e
|
||||
}
|
||||
|
||||
func builderRel(doc map[string]interface{}, relType, fromID, toID string, evidence []string) {
|
||||
rels, _ := doc["relationships"].([]map[string]interface{})
|
||||
for _, r := range rels {
|
||||
if r["type"] == relType && r["from"] == fromID && r["to"] == toID {
|
||||
return
|
||||
}
|
||||
}
|
||||
ev := evidence
|
||||
if len(ev) == 0 {
|
||||
ev = []string{"scaffold"}
|
||||
}
|
||||
doc["relationships"] = append(rels, map[string]interface{}{
|
||||
"type": relType, "from": fromID, "to": toID, "evidence_refs": ev,
|
||||
})
|
||||
}
|
||||
|
||||
// AddDomain — domain:<name> entity.
|
||||
func AddDomain(doc map[string]interface{}, name, description string) map[string]interface{} {
|
||||
return builderEntity(doc, "domain:"+name, "domain", map[string]interface{}{"description": description})
|
||||
}
|
||||
|
||||
// AddComponent — component:<name> entity.
|
||||
func AddComponent(doc map[string]interface{}, name, path, description string) map[string]interface{} {
|
||||
return builderEntity(doc, "component:"+name, "component", map[string]interface{}{"path": path, "description": description})
|
||||
}
|
||||
|
||||
// AddContract — contract:<name> entity (spec defaults "" per the oracle).
|
||||
func AddContract(doc map[string]interface{}, name, description string) map[string]interface{} {
|
||||
return builderEntity(doc, "contract:"+name, "contract", map[string]interface{}{"description": description, "spec": ""})
|
||||
}
|
||||
|
||||
// Link — generic typed relationship with evidence.
|
||||
func Link(doc map[string]interface{}, relType, fromID, toID string) map[string]interface{} {
|
||||
builderRel(doc, relType, fromID, toID, []string{"scaffold"})
|
||||
rels, _ := doc["relationships"].([]map[string]interface{})
|
||||
return rels[len(rels)-1]
|
||||
}
|
||||
|
||||
// SetPRD — prd:<project> reference entity.
|
||||
func SetPRD(doc map[string]interface{}, projectID, prdRef string) map[string]interface{} {
|
||||
return builderEntity(doc, "prd:"+projectID, "prd_state", map[string]interface{}{"reference": prdRef})
|
||||
}
|
||||
|
||||
// SetNextAction — next_action:<project> entity.
|
||||
func SetNextAction(doc map[string]interface{}, projectID, action string) map[string]interface{} {
|
||||
return builderEntity(doc, "next_action:"+projectID, "next_action", map[string]interface{}{"action": action})
|
||||
}
|
||||
|
||||
// AddLimitation — limitation:<name> entity.
|
||||
func AddLimitation(doc map[string]interface{}, name, detail string) map[string]interface{} {
|
||||
return builderEntity(doc, "limitation:"+name, "known_limitation", map[string]interface{}{"detail": detail})
|
||||
}
|
||||
|
||||
// SortedStrings — deterministic evidence ordering (Python sorted(set())).
|
||||
func SortedStrings(in []string) []string {
|
||||
seen := map[string]bool{}
|
||||
var out []string
|
||||
for _, s := range in {
|
||||
if !seen[s] {
|
||||
seen[s] = true
|
||||
out = append(out, s)
|
||||
}
|
||||
}
|
||||
sort.Strings(out)
|
||||
return out
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"_doc": "FROZEN ORACLE (scaffold builders).",
|
||||
"entities": [
|
||||
{
|
||||
"id": "domain:d1",
|
||||
"kind": "domain",
|
||||
"identities": {
|
||||
"description": "desc d1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "component:c1",
|
||||
"kind": "component",
|
||||
"identities": {
|
||||
"path": "p",
|
||||
"description": "desc c1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "contract:k1",
|
||||
"kind": "contract",
|
||||
"identities": {
|
||||
"description": "desc k1",
|
||||
"spec": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "prd:testproj",
|
||||
"kind": "prd_state",
|
||||
"identities": {
|
||||
"reference": "docs/prd.md"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "next_action:testproj",
|
||||
"kind": "next_action",
|
||||
"identities": {
|
||||
"action": "do the thing"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "limitation:l1",
|
||||
"kind": "known_limitation",
|
||||
"identities": {
|
||||
"detail": "detail l1"
|
||||
}
|
||||
}
|
||||
],
|
||||
"relationships": [
|
||||
{
|
||||
"type": "contains",
|
||||
"from": "domain:d1",
|
||||
"to": "component:c1"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package main
|
||||
|
||||
// truth_builders_test.go — #2479 scaffold-batch parity gate.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBuildersParity(t *testing.T) {
|
||||
raw, err := os.ReadFile("truth_builders.json")
|
||||
if err != nil {
|
||||
t.Fatalf("truth_builders.json missing: %v", err)
|
||||
}
|
||||
var truth struct {
|
||||
Entities []map[string]any `json:"entities"`
|
||||
Relationships []map[string]any `json:"relationships"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &truth); err != nil {
|
||||
t.Fatalf("unparseable: %v", err)
|
||||
}
|
||||
doc := map[string]interface{}{"entities": []map[string]interface{}{}, "relationships": []map[string]interface{}{}}
|
||||
AddDomain(doc, "d1", "desc d1")
|
||||
AddComponent(doc, "c1", "p", "desc c1")
|
||||
AddContract(doc, "k1", "desc k1")
|
||||
Link(doc, "contains", "domain:d1", "component:c1")
|
||||
SetPRD(doc, "testproj", "docs/prd.md")
|
||||
SetNextAction(doc, "testproj", "do the thing")
|
||||
AddLimitation(doc, "l1", "detail l1")
|
||||
ents, _ := doc["entities"].([]map[string]interface{})
|
||||
if len(ents) != len(truth.Entities) {
|
||||
t.Fatalf("entities: got %d want %d", len(ents), len(truth.Entities))
|
||||
}
|
||||
for i, e := range ents {
|
||||
w := truth.Entities[i]
|
||||
if e["id"] != w["id"] || e["kind"] != w["kind"] {
|
||||
t.Errorf("entity[%d]: got %v/%v want %v/%v", i, e["id"], e["kind"], w["id"], w["kind"])
|
||||
}
|
||||
gotIdent, _ := json.Marshal(e["identities"])
|
||||
wantIdent, _ := json.Marshal(w["identities"])
|
||||
if string(gotIdent) != string(wantIdent) {
|
||||
t.Errorf("entity[%d] identities: got %s want %s", i, gotIdent, wantIdent)
|
||||
}
|
||||
}
|
||||
rels, _ := doc["relationships"].([]map[string]interface{})
|
||||
if len(rels) != len(truth.Relationships) {
|
||||
t.Fatalf("relationships: got %d want %d", len(rels), len(truth.Relationships))
|
||||
}
|
||||
for i, r := range rels {
|
||||
w := truth.Relationships[i]
|
||||
if r["type"] != w["type"] || r["from"] != w["from"] || r["to"] != w["to"] {
|
||||
t.Errorf("rel[%d]: got %v want %v", i, r, w)
|
||||
}
|
||||
}
|
||||
var _ = reflect.DeepEqual
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package main
|
||||
|
||||
// prepared_path.go — #2479 tool_executor batch: the _prepared_path kernel
|
||||
// (write/edit/format gate: path required, write-validation, ValueError
|
||||
// contract). Oracle: src/rune/tool_executor.py; truth rows in
|
||||
// truth_prepared_path.json. Execution stays in the runtime.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// PreparedPath — which-file + resolved path for write-class tools, or ""
|
||||
// when the tool needs no path prep. Errors carry the ValueError contract
|
||||
// (path required / validation message).
|
||||
func PreparedPath(name string, args map[string]interface{}) (string, string, error) {
|
||||
switch name {
|
||||
case "write_file", "edit_file", "format_code":
|
||||
// fall through
|
||||
default:
|
||||
return "", "", nil
|
||||
}
|
||||
raw, _ := args["path"].(string)
|
||||
if raw == "" {
|
||||
return "", "", fmt.Errorf("Path is required")
|
||||
}
|
||||
ok, msg, resolved := ValidateWritePath(raw)
|
||||
if !ok {
|
||||
return "", "", fmt.Errorf("%s", msg)
|
||||
}
|
||||
return raw, resolved, nil
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"_doc": "FROZEN ORACLE (prepared_path).",
|
||||
"rows": [
|
||||
{
|
||||
"op": "prepared",
|
||||
"name": "write_file",
|
||||
"args": {
|
||||
"path": "/tmp/x.txt"
|
||||
},
|
||||
"raises": true
|
||||
},
|
||||
{
|
||||
"op": "prepared",
|
||||
"name": "read_file",
|
||||
"args": {
|
||||
"path": "/tmp/x"
|
||||
},
|
||||
"want": null
|
||||
},
|
||||
{
|
||||
"op": "prepared",
|
||||
"name": "edit_file",
|
||||
"args": {
|
||||
"path": ""
|
||||
},
|
||||
"raises": true
|
||||
},
|
||||
{
|
||||
"op": "prepared",
|
||||
"name": "run_command",
|
||||
"args": {
|
||||
"cmd": "ls"
|
||||
},
|
||||
"want": null
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package main
|
||||
|
||||
// truth_prepared_path_test.go — #2479 tool_executor parity gate.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPreparedPathParity(t *testing.T) {
|
||||
raw, err := os.ReadFile("truth_prepared_path.json")
|
||||
if err != nil {
|
||||
t.Fatalf("truth_prepared_path.json missing: %v", err)
|
||||
}
|
||||
var doc struct {
|
||||
Rows []struct {
|
||||
Name string `json:"name"`
|
||||
Args map[string]any `json:"args"`
|
||||
Want []string `json:"want"`
|
||||
} `json:"rows"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &doc); err != nil {
|
||||
t.Fatalf("unparseable: %v", err)
|
||||
}
|
||||
for i, c := range doc.Rows {
|
||||
req, resolved, err := PreparedPath(c.Name, c.Args)
|
||||
if c.Want == nil {
|
||||
if err == nil && req == "" {
|
||||
continue // no prep needed — nil want
|
||||
}
|
||||
if err != nil {
|
||||
continue // raises — want nil means raises here
|
||||
}
|
||||
t.Errorf("row %d %s: expected raise/none, got %q %q", i, c.Name, req, resolved)
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("row %d %s: unexpected error %v", i, c.Name, err)
|
||||
continue
|
||||
}
|
||||
// resolved path must be absolute; requested echoes input
|
||||
if req != c.Want[0] {
|
||||
t.Errorf("row %d: requested %q want %q", i, req, c.Want[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"_doc": "FROZEN ORACLE (protocol shapes: from_dict clip/defaults).",
|
||||
"observation_clip": {
|
||||
"in": {
|
||||
"observation_id": "o2",
|
||||
"task_id": "t2",
|
||||
"kind": "degraded",
|
||||
"summary": "s",
|
||||
"detail": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
"ts": "2026-10-10T00:00:00+00:00"
|
||||
},
|
||||
"want": {
|
||||
"observation_id": "o2",
|
||||
"task_id": "t2",
|
||||
"kind": "degraded",
|
||||
"summary": "s",
|
||||
"detail": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
"ts": "2026-10-10T00:00:00+00:00"
|
||||
}
|
||||
},
|
||||
"verification_clip": {
|
||||
"in": {
|
||||
"verification_id": "v2",
|
||||
"task_id": "t2",
|
||||
"method": "",
|
||||
"passed": 1,
|
||||
"evidence": "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
|
||||
"ts": "ts2"
|
||||
},
|
||||
"want": {
|
||||
"verification_id": "v2",
|
||||
"task_id": "t2",
|
||||
"method": "none",
|
||||
"passed": true,
|
||||
"evidence": "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
|
||||
"ts": "ts2"
|
||||
}
|
||||
},
|
||||
"outcome_defaults": {
|
||||
"in": {
|
||||
"outcome_id": "oc2",
|
||||
"task_id": "t2",
|
||||
"status": "",
|
||||
"verification_id": "",
|
||||
"degraded": null
|
||||
},
|
||||
"want": {
|
||||
"outcome_id": "oc2",
|
||||
"task_id": "t2",
|
||||
"status": "",
|
||||
"verification_id": "",
|
||||
"degraded": [],
|
||||
"ts": ""
|
||||
}
|
||||
},
|
||||
"mq_defaults": {
|
||||
"in": {
|
||||
"query_id": "q2",
|
||||
"task_id": "t2",
|
||||
"admitted": null,
|
||||
"dropped": null,
|
||||
"memory_tokens": null
|
||||
},
|
||||
"want": {
|
||||
"query_id": "q2",
|
||||
"task_id": "t2",
|
||||
"admitted": {},
|
||||
"dropped": [],
|
||||
"memory_tokens": 0,
|
||||
"ts": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package main
|
||||
|
||||
// frozen_shapes_test.go — #2479 tool_protocol parity gate: from_dict
|
||||
// clip/defaults semantics vs the frozen oracle.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestShapesFromDictParity(t *testing.T) {
|
||||
raw, err := os.ReadFile("frozen_shapes.json")
|
||||
if err != nil {
|
||||
t.Fatalf("frozen_shapes.json missing: %v", err)
|
||||
}
|
||||
var doc struct {
|
||||
ObservationClip map[string]any `json:"observation_clip"`
|
||||
VerificationClip map[string]any `json:"verification_clip"`
|
||||
OutcomeDefaults map[string]any `json:"outcome_defaults"`
|
||||
MQDefaults map[string]any `json:"mq_defaults"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &doc); err != nil {
|
||||
t.Fatalf("unparseable: %v", err)
|
||||
}
|
||||
// Observation clip(300)
|
||||
var ob Observation
|
||||
ob.FromDict(doc.ObservationClip["in"].(map[string]any))
|
||||
if ob.Detail != "x"+string(make([]byte, 296)) && len(ob.Detail) != 300 {
|
||||
t.Errorf("observation clip: detail len %d want 300", len(ob.Detail))
|
||||
}
|
||||
if ob.Kind != "degraded" || ob.ObservationID != "o2" {
|
||||
t.Errorf("observation fields: got %+v", ob)
|
||||
}
|
||||
// VerificationResult method default + clip
|
||||
var vr VerificationResult
|
||||
vr.FromDict(doc.VerificationClip["in"].(map[string]any))
|
||||
wantV := doc.VerificationClip["want"].(map[string]any)
|
||||
if vr.Method != "none" || vr.Evidence != wantV["evidence"] || vr.Passed != true {
|
||||
t.Errorf("verification defaults: got %+v", vr)
|
||||
}
|
||||
// Outcome degraded nil -> []
|
||||
var oc Outcome
|
||||
oc.FromDict(doc.OutcomeDefaults["in"].(map[string]any))
|
||||
if oc.Degraded == nil || len(oc.Degraded) != 0 {
|
||||
t.Errorf("outcome degraded nil->[]: got %+v", oc.Degraded)
|
||||
}
|
||||
// MemoryQuery admitted/dropped/memory_tokens defaults
|
||||
var mq MemoryQuery
|
||||
mq.FromDict(doc.MQDefaults["in"].(map[string]any))
|
||||
if mq.Admitted == nil || len(mq.Admitted) != 0 || mq.Dropped == nil ||
|
||||
len(mq.Dropped) != 0 || mq.MemoryTokens != 0 {
|
||||
t.Errorf("mq defaults: got %+v", mq)
|
||||
}
|
||||
}
|
||||
|
||||
// mapFrom mirrors the frozen want: the observable fields the parity pins.
|
||||
func mapFrom(ob Observation, want map[string]any) map[string]any {
|
||||
return map[string]any{
|
||||
"observation_id": ob.ObservationID, "task_id": ob.TaskID,
|
||||
"kind": ob.Kind, "summary": ob.Summary,
|
||||
"detail": ob.Detail, "ts": ob.TS,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package main
|
||||
|
||||
// shapes.go — #2479 tool_protocol batch: the 5 protocol record shapes
|
||||
// (MemoryQuery/Observation/VerificationResult/Outcome/OperatorResponse)
|
||||
// with to_dict/from_dict parity. Oracle: src/rune/tool_protocol.py.
|
||||
|
||||
import "time"
|
||||
|
||||
func nowISO() string { return time.Now().UTC().Format("2006-01-02T15:04:05+00:00") }
|
||||
|
||||
type MemoryQuery struct {
|
||||
QueryID string `json:"query_id"`
|
||||
TaskID string `json:"task_id"`
|
||||
Admitted map[string]interface{} `json:"admitted"`
|
||||
Dropped []interface{} `json:"dropped"`
|
||||
MemoryTokens int `json:"memory_tokens"`
|
||||
TS string `json:"ts"`
|
||||
}
|
||||
|
||||
func (m *MemoryQuery) FromDict(data map[string]interface{}) {
|
||||
m.QueryID = strOf(data, "query_id")
|
||||
m.TaskID = strOf(data, "task_id")
|
||||
if a, ok := data["admitted"].(map[string]interface{}); ok {
|
||||
m.Admitted = a
|
||||
} else {
|
||||
m.Admitted = map[string]interface{}{}
|
||||
}
|
||||
if d, ok := data["dropped"].([]interface{}); ok {
|
||||
m.Dropped = d
|
||||
} else {
|
||||
m.Dropped = []interface{}{}
|
||||
}
|
||||
m.MemoryTokens = intOf(data, "memory_tokens")
|
||||
m.TS = strOf(data, "ts")
|
||||
}
|
||||
|
||||
type Observation struct {
|
||||
ObservationID string `json:"observation_id"`
|
||||
TaskID string `json:"task_id"`
|
||||
Kind string `json:"kind"`
|
||||
Summary string `json:"summary"`
|
||||
Detail string `json:"detail"`
|
||||
TS string `json:"ts"`
|
||||
}
|
||||
|
||||
func (o *Observation) FromDict(data map[string]interface{}) {
|
||||
o.ObservationID = strOf(data, "observation_id")
|
||||
o.TaskID = strOf(data, "task_id")
|
||||
o.Kind = strOf(data, "kind")
|
||||
o.Summary = strOf(data, "summary")
|
||||
o.Detail = clip(strOf(data, "detail"), 300)
|
||||
o.TS = strOf(data, "ts")
|
||||
}
|
||||
|
||||
type VerificationResult struct {
|
||||
VerificationID string `json:"verification_id"`
|
||||
TaskID string `json:"task_id"`
|
||||
Method string `json:"method"`
|
||||
Passed bool `json:"passed"`
|
||||
Evidence string `json:"evidence"`
|
||||
TS string `json:"ts"`
|
||||
}
|
||||
|
||||
func (v *VerificationResult) FromDict(data map[string]interface{}) {
|
||||
v.VerificationID = strOf(data, "verification_id")
|
||||
v.TaskID = strOf(data, "task_id")
|
||||
v.Method = orDefault(strOf(data, "method"), "none")
|
||||
v.Passed = boolOf(data, "passed")
|
||||
v.Evidence = clip(strOf(data, "evidence"), 300)
|
||||
v.TS = strOf(data, "ts")
|
||||
}
|
||||
|
||||
type Outcome struct {
|
||||
OutcomeID string `json:"outcome_id"`
|
||||
TaskID string `json:"task_id"`
|
||||
Status string `json:"status"`
|
||||
VerificationID string `json:"verification_id"`
|
||||
Degraded []string `json:"degraded"`
|
||||
TS string `json:"ts"`
|
||||
}
|
||||
|
||||
func (o *Outcome) FromDict(data map[string]interface{}) {
|
||||
o.OutcomeID = strOf(data, "outcome_id")
|
||||
o.TaskID = strOf(data, "task_id")
|
||||
o.Status = strOf(data, "status")
|
||||
o.VerificationID = strOf(data, "verification_id")
|
||||
if d, ok := data["degraded"].([]interface{}); ok {
|
||||
for _, x := range d {
|
||||
if s, ok := x.(string); ok {
|
||||
o.Degraded = append(o.Degraded, s)
|
||||
}
|
||||
}
|
||||
}
|
||||
if o.Degraded == nil {
|
||||
o.Degraded = []string{}
|
||||
}
|
||||
o.TS = strOf(data, "ts")
|
||||
}
|
||||
|
||||
type OperatorResponse struct {
|
||||
Success bool `json:"success"`
|
||||
UserText string `json:"user_text"`
|
||||
Thinking []string `json:"thinking"`
|
||||
ToolEvents []map[string]interface{} `json:"tool_events"`
|
||||
Error string `json:"error"`
|
||||
Model string `json:"model"`
|
||||
RecallCount int `json:"recall_count"`
|
||||
OverrideTier int `json:"override_tier"`
|
||||
}
|
||||
|
||||
func strOf(m map[string]interface{}, k string) string {
|
||||
if s, ok := m[k].(string); ok {
|
||||
return s
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func intOf(m map[string]interface{}, k string) int {
|
||||
if f, ok := m[k].(float64); ok {
|
||||
return int(f)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func boolOf(m map[string]interface{}, k string) bool {
|
||||
switch v := m[k].(type) {
|
||||
case bool:
|
||||
return v
|
||||
case float64:
|
||||
return v != 0 // Python bool(1) == True — number truthiness parity
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func orDefault(s, def string) string {
|
||||
if s == "" {
|
||||
return def
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func clip(s string, n int) string {
|
||||
if len(s) > n {
|
||||
return s[:n]
|
||||
}
|
||||
return s
|
||||
}
|
||||
@@ -6,7 +6,7 @@ This is the main entry point for the Rune program.
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
__version__ = "0.172.0"
|
||||
__version__ = "0.183.0"
|
||||
|
||||
# One build identity (handoff 2026-09-10 §4): the semantic version above is
|
||||
# the repo-level truth (auto-bumped at merge); the DEPLOYED revision (exact
|
||||
|
||||
@@ -233,7 +233,7 @@ def main() -> int:
|
||||
)
|
||||
check(
|
||||
"Rune minor version advertises provisioning and restore verification",
|
||||
'__version__ = "0.172.0"' in rune_version,
|
||||
'__version__ = "0.183.0"' in rune_version,
|
||||
failures,
|
||||
)
|
||||
# #169 policy update: auto-bump on merge is sanctioned (Nick directive:
|
||||
|
||||
@@ -620,161 +620,13 @@ def score_card(card, query):
|
||||
|
||||
|
||||
def _py_score_card(card, query):
|
||||
"""Python core of score_card (parity oracle for the Rust core)."""
|
||||
query_low = query.lower()
|
||||
query_words = set(re.findall(r"\w+", query_low))
|
||||
|
||||
# Generic capabilities that shouldn't drive matching
|
||||
generic_caps = {
|
||||
"write",
|
||||
"read",
|
||||
"audit",
|
||||
"memory_env",
|
||||
"status",
|
||||
"reasoning",
|
||||
"research",
|
||||
"voice",
|
||||
"growth",
|
||||
"skills",
|
||||
"tasks",
|
||||
"recall",
|
||||
}
|
||||
|
||||
# Common stopwords to exclude from matching
|
||||
stopwords = {
|
||||
"the",
|
||||
"a",
|
||||
"an",
|
||||
"is",
|
||||
"are",
|
||||
"was",
|
||||
"were",
|
||||
"be",
|
||||
"been",
|
||||
"being",
|
||||
"have",
|
||||
"has",
|
||||
"had",
|
||||
"do",
|
||||
"does",
|
||||
"did",
|
||||
"will",
|
||||
"would",
|
||||
"could",
|
||||
"should",
|
||||
"may",
|
||||
"might",
|
||||
"shall",
|
||||
"can",
|
||||
"to",
|
||||
"of",
|
||||
"in",
|
||||
"for",
|
||||
"on",
|
||||
"with",
|
||||
"at",
|
||||
"by",
|
||||
"from",
|
||||
"as",
|
||||
"into",
|
||||
"through",
|
||||
"during",
|
||||
"before",
|
||||
"after",
|
||||
"above",
|
||||
"below",
|
||||
"between",
|
||||
"out",
|
||||
"off",
|
||||
"over",
|
||||
"under",
|
||||
"again",
|
||||
"further",
|
||||
"then",
|
||||
"once",
|
||||
"here",
|
||||
"there",
|
||||
"when",
|
||||
"where",
|
||||
"why",
|
||||
"how",
|
||||
"all",
|
||||
"each",
|
||||
"every",
|
||||
"both",
|
||||
"few",
|
||||
"more",
|
||||
"most",
|
||||
"other",
|
||||
"some",
|
||||
"such",
|
||||
"no",
|
||||
"nor",
|
||||
"not",
|
||||
"only",
|
||||
"own",
|
||||
"same",
|
||||
"so",
|
||||
"than",
|
||||
"too",
|
||||
"very",
|
||||
"just",
|
||||
"because",
|
||||
"but",
|
||||
"and",
|
||||
"or",
|
||||
"if",
|
||||
"while",
|
||||
"about",
|
||||
"against",
|
||||
"this",
|
||||
"that",
|
||||
"these",
|
||||
"those",
|
||||
"it",
|
||||
"its",
|
||||
"what",
|
||||
"which",
|
||||
"who",
|
||||
}
|
||||
query_content = query_words - stopwords
|
||||
|
||||
score = 0.0
|
||||
|
||||
# Direct capability name match (highest weight, but penalize generic)
|
||||
for cap in card.get("capabilities", []):
|
||||
cap_words = set(re.findall(r"\w+", cap.lower()))
|
||||
overlap = query_content & cap_words
|
||||
if overlap:
|
||||
if cap.lower() in generic_caps:
|
||||
score += 0.3 * len(overlap)
|
||||
else:
|
||||
score += 3.0 * len(overlap)
|
||||
|
||||
# Description word match (medium weight)
|
||||
desc_words = set(re.findall(r"\w+", card.get("description", "").lower())) - stopwords
|
||||
overlap = query_content & desc_words
|
||||
score += 0.8 * len(overlap)
|
||||
|
||||
# Semantic example match (high weight — these are curated)
|
||||
for example in card.get("semantic_examples", []):
|
||||
example_words = set(re.findall(r"\w+", example.lower())) - stopwords
|
||||
overlap = query_content & example_words
|
||||
if overlap:
|
||||
score += 2.0 * len(overlap)
|
||||
|
||||
# Name match (very high weight — direct name reference)
|
||||
name_words = set(re.findall(r"\w+", card.get("name", "").lower()))
|
||||
overlap = query_words & name_words
|
||||
if overlap:
|
||||
score += 4.0 * len(overlap)
|
||||
|
||||
# Priority bonus (lower number = higher priority)
|
||||
priority = card.get("priority", 100)
|
||||
score += max(0, (100 - priority) / 200)
|
||||
|
||||
return score
|
||||
|
||||
"""STRANGLER EXIT (retired 2026-10-10): authoritative implementation in
|
||||
src/rust/capability_scoring (cs_score_card — parity proven against the
|
||||
frozen oracle in frozen_score_card.json). Delegation-only stub."""
|
||||
core = _cs_core()
|
||||
if core is None:
|
||||
raise RuntimeError("capability_scoring kernel not built — run the capability_scoring build; the Python oracle was retired")
|
||||
return core.score_card(card, query)
|
||||
|
||||
def match_capabilities(query, top_k=5):
|
||||
"""Find the most relevant capabilities for a query."""
|
||||
|
||||
@@ -78,9 +78,25 @@ def _core():
|
||||
return None
|
||||
|
||||
|
||||
def _consolidation_now() -> str:
|
||||
from datetime import datetime, timezone
|
||||
return datetime.now(timezone.utc).isoformat()
|
||||
|
||||
|
||||
def _consolidation_memory_oracle(memory_text: str, score: float, wash_count: int = 0,
|
||||
entry_id: int | None = None) -> dict:
|
||||
"""Python parity oracle for consolidation_memory."""
|
||||
"""Adapter for consolidation_memory: content via the Rust kernel when
|
||||
available (cc_consolidation_memory — frozen_consolidation.json parity);
|
||||
drift_compression Python floor otherwise. id/clock stay adapter-owned."""
|
||||
core = _core()
|
||||
if core is not None:
|
||||
try:
|
||||
rec = core.consolidation_memory(memory_text, score, wash_count, entry_id)
|
||||
rec["created_at"] = _consolidation_now()
|
||||
rec["last_used"] = rec["created_at"]
|
||||
return rec
|
||||
except Exception: # noqa: BLE001 — kernel failure → Python floor below
|
||||
logger.debug("consolidation_memory kernel failed", exc_info=True)
|
||||
if drift_compression:
|
||||
entry = {"text": memory_text, "wash_count": wash_count, "rock_status": "washable"}
|
||||
content = drift_compression.compress_entry(entry)
|
||||
@@ -99,7 +115,18 @@ def _consolidation_memory_oracle(memory_text: str, score: float, wash_count: int
|
||||
def _consolidation_neuron_oracle(slug: str, body: str, importance: float,
|
||||
triggers: list, wash_count: int = 0,
|
||||
entry_id: int | None = None) -> dict:
|
||||
"""Python parity oracle for consolidation_neuron."""
|
||||
"""Adapter for consolidation_neuron: content via the Rust kernel when
|
||||
available (cc_consolidation_neuron — frozen parity); Python floor otherwise."""
|
||||
core = _core()
|
||||
if core is not None:
|
||||
try:
|
||||
rec = core.consolidation_neuron(slug, body, importance, triggers,
|
||||
wash_count, entry_id)
|
||||
rec["created_at"] = _consolidation_now()
|
||||
rec["last_used"] = rec["created_at"]
|
||||
return rec
|
||||
except Exception: # noqa: BLE001 — kernel failure → Python floor below
|
||||
logger.debug("consolidation_neuron kernel failed", exc_info=True)
|
||||
if drift_compression:
|
||||
entry = {"text": body, "wash_count": wash_count, "rock_status": "washable"}
|
||||
first_line = drift_compression.compress_entry(entry)
|
||||
|
||||
@@ -213,7 +213,14 @@ class MemorySelector:
|
||||
|
||||
def _score_of(item: dict) -> float:
|
||||
"""Extract the item's 0-1 relevance under the ONE floor. Missing or
|
||||
malformed scores floor at 0.0 (abstain) — never guessed upward."""
|
||||
malformed scores floor at 0.0 (abstain) — never guessed upward.
|
||||
Delegates to the Rust core when built (frozen_selector.json parity)."""
|
||||
try:
|
||||
from rune import mr_loader as _mr
|
||||
if _mr.available():
|
||||
return float(_mr.score_of(item))
|
||||
except Exception: # noqa: BLE001 — kernel failure → oracle below
|
||||
pass
|
||||
value = item.get("score")
|
||||
if isinstance(value, bool) or not isinstance(value, (int, float)):
|
||||
return 0.0
|
||||
@@ -311,6 +318,12 @@ def _lex_overlap_score(text: str, query: str) -> float:
|
||||
conjunctive logic the store's BM25 gate applies (a shared single word is
|
||||
not a relation, but zero shared words is definitely not one).
|
||||
"""
|
||||
try:
|
||||
from rune import mr_loader as _mr2
|
||||
if _mr2.available():
|
||||
return float(_mr2.lex_overlap_score(text, query))
|
||||
except Exception: # noqa: BLE001 — kernel failure → oracle below
|
||||
pass
|
||||
stopwords = getattr(memory_store, "_STOPWORDS", set())
|
||||
q_terms = {t.lower() for t in query.split() if len(t) > 3 and t.lower() not in stopwords}
|
||||
if not q_terms:
|
||||
|
||||
+52
-305
@@ -780,72 +780,12 @@ def _score_recall_rows(fusion, rows, dense, bm25, budget, min_score, now):
|
||||
RECENCY_HALF_LIFE)
|
||||
|
||||
|
||||
def _py_score_recall_rows(fusion, rows, dense, bm25, budget, min_score,
|
||||
now, recency_half_life=RECENCY_HALF_LIFE):
|
||||
"""Python oracle for the Rust scoring/abstention kernel."""
|
||||
from datetime import datetime
|
||||
|
||||
ranks = dict(fusion["ranks"])
|
||||
best_dense = fusion["best_dense"]
|
||||
retrieval_mode = fusion["mode"]
|
||||
by_id = {row["id"]: row for row in rows}
|
||||
scored = []
|
||||
now_dt = datetime.fromisoformat(now)
|
||||
for eid, base in sorted(ranks.items(), key=lambda item: -item[1]):
|
||||
row = by_id.get(eid)
|
||||
if not row:
|
||||
continue
|
||||
conf = float(row.get("confidence") or 0.7)
|
||||
temp = float(row.get("temperature") or 1.0)
|
||||
recency = 1.0
|
||||
try:
|
||||
la = row.get("last_accessed")
|
||||
if la:
|
||||
t_last = datetime.fromisoformat(la.replace("Z", "+00:00"))
|
||||
days = (now_dt - t_last).total_seconds() / 86400.0
|
||||
if days >= 0:
|
||||
recency = recency_half_life / (recency_half_life + days)
|
||||
except Exception:
|
||||
logger.debug("recall score kernel timestamp failed", exc_info=True)
|
||||
if dense:
|
||||
relevance = base * (0.4 + 0.6 * conf) * (0.5 + 0.5 * temp) * (0.85 + 0.15 * recency)
|
||||
else:
|
||||
relevance = (base + 5.0) * (0.4 + 0.6 * conf) * (0.5 + 0.5 * temp) * (0.85 + 0.15 * recency)
|
||||
scored.append({
|
||||
"id": eid, "text": row.get("text"),
|
||||
"importance": row.get("importance"),
|
||||
"topic": row.get("topic"), "entities": row.get("entities"),
|
||||
"source": row.get("source"),
|
||||
"last_accessed": row.get("last_accessed"),
|
||||
"rrf": round(base, 4), "confidence": round(conf, 2),
|
||||
"temperature": round(temp, 2),
|
||||
"relevance": round(relevance, 4), "mode": retrieval_mode,
|
||||
})
|
||||
if not scored:
|
||||
return []
|
||||
top = scored[:budget]
|
||||
if not dense and not bm25:
|
||||
return []
|
||||
if not dense:
|
||||
if max(float(item["relevance"]) for item in top) < min_score:
|
||||
return []
|
||||
return top
|
||||
if not bm25:
|
||||
if best_dense < min_score:
|
||||
return []
|
||||
if best_dense >= 0.74:
|
||||
return _py_position_aware(top)
|
||||
if len(dense) >= 2:
|
||||
d_scores = sorted(score for _, score in dense)
|
||||
if d_scores[-1] - d_scores[-2] >= 0.08:
|
||||
return _py_position_aware(top)
|
||||
return []
|
||||
return _py_position_aware(_py_map_reduce(top))
|
||||
if best_dense < min_score:
|
||||
return []
|
||||
return _py_position_aware(_py_map_reduce(top))
|
||||
|
||||
|
||||
def _py_score_recall_rows(fusion, rows, dense, bm25, budget, min_score, now, recency_half_life=RECENCY_HALF_LIFE):
|
||||
"""STRANGLER EXIT (retired 2026-10-10): authoritative implementation in
|
||||
src/rust/memory_retrieval (parity proven against the frozen oracle in
|
||||
frozen_score_recall.json). Delegation-only stub; the public delegator
|
||||
raises if the kernel is absent."""
|
||||
return _score_recall_rows(fusion, rows, dense, bm25, budget, min_score, now)
|
||||
def _drift_rerank(db, entries):
|
||||
"""Drift-aware re-ranking: apply multi-factor value and FAMA scoring.
|
||||
|
||||
@@ -914,43 +854,12 @@ def _map_reduce(entries: list, chunk_size: int = 10) -> list:
|
||||
return _py_map_reduce(entries, chunk_size)
|
||||
|
||||
|
||||
def _py_map_reduce(entries: list, chunk_size: int = 10) -> list:
|
||||
"""Map-reduce for large result sets.
|
||||
|
||||
When retrieval returns many entries, chunk them and take the top-N
|
||||
from each chunk. This prevents the lost-in-the-middle problem by
|
||||
ensuring the model sees the most relevant entries from each chunk.
|
||||
|
||||
Returns the combined top entries across all chunks.
|
||||
"""
|
||||
if len(entries) <= chunk_size:
|
||||
return entries
|
||||
|
||||
# Split into chunks
|
||||
chunks = [entries[i : i + chunk_size] for i in range(0, len(entries), chunk_size)]
|
||||
|
||||
# Map: take top-3 from each chunk (preserving diversity)
|
||||
mapped = []
|
||||
for chunk in chunks:
|
||||
# Sort by relevance score if available
|
||||
scored = []
|
||||
for entry in chunk:
|
||||
score = entry.get("relevance", entry.get("score", 0.5))
|
||||
scored.append((score, entry))
|
||||
scored.sort(key=lambda x: x[0], reverse=True)
|
||||
# Take top-3 from each chunk
|
||||
mapped.extend([entry for _, entry in scored[:3]])
|
||||
|
||||
# Reduce: sort all mapped entries by score, take top budget
|
||||
final_scored = []
|
||||
for entry in mapped:
|
||||
score = entry.get("relevance", entry.get("score", 0.5))
|
||||
final_scored.append((score, entry))
|
||||
final_scored.sort(key=lambda x: x[0], reverse=True)
|
||||
|
||||
return [entry for _, entry in final_scored]
|
||||
|
||||
|
||||
def _py_map_reduce(entries, chunk_size=10):
|
||||
"""STRANGLER EXIT (retired 2026-10-10): authoritative implementation in
|
||||
src/rust/memory_retrieval (parity proven against the frozen oracle in
|
||||
frozen_score_recall.json). Delegation-only stub; the public delegator
|
||||
raises if the kernel is absent."""
|
||||
return _map_reduce(entries, chunk_size)
|
||||
def curiosity_probe(db, limit: int = 5) -> list:
|
||||
"""Curiosity mechanism: probe random untested memories.
|
||||
|
||||
@@ -1151,23 +1060,11 @@ def _position_aware(top):
|
||||
|
||||
|
||||
def _py_position_aware(top):
|
||||
"""POSITION-AWARE RE-RANK (research uplift #2): lost-in-the-middle
|
||||
mitigation (Liu et al. 2023; BriefContext, npj Digital Medicine 2025).
|
||||
Models use the START and END of context best and the middle worst, so the
|
||||
two highest-relevance items are placed FIRST and LAST in the returned
|
||||
window. Returns the SAME items — only their order changes, never which
|
||||
items are returned. Degrades gracefully (no-op for <3 items)."""
|
||||
try:
|
||||
if not top or len(top) < 3:
|
||||
return top
|
||||
s = list(top)
|
||||
s_sorted = sorted(s, key=lambda x: float(x.get("relevance", 0)), reverse=True)
|
||||
return [s_sorted[0]] + s_sorted[2:] + [s_sorted[1]]
|
||||
except Exception:
|
||||
logger.debug("_position_aware failed", exc_info=True)
|
||||
return top
|
||||
|
||||
|
||||
"""STRANGLER EXIT (retired 2026-10-10): authoritative implementation in
|
||||
src/rust/memory_retrieval (parity proven against the frozen oracle in
|
||||
frozen_score_recall.json). Delegation-only stub; the public delegator
|
||||
raises if the kernel is absent."""
|
||||
return _position_aware(top)
|
||||
_STOPWORDS = {
|
||||
"the",
|
||||
"and",
|
||||
@@ -1232,23 +1129,11 @@ def _fts_query_conjunctive(query):
|
||||
|
||||
|
||||
def _py_fts_query_conjunctive(query):
|
||||
"""Build a CONJUNCTIVE FTS5 MATCH query (implicit AND).
|
||||
|
||||
Extended Boolean IR (Salton, Fox & Wu, CACM 1983): a document must contain
|
||||
ALL significant query terms to match — a shared single word is not a
|
||||
relation ("black coffee" excludes "black holes"). Phrase clauses are added
|
||||
as additive dependence evidence (Metzler & Croft, SIGIR 2005). Short/stop
|
||||
words are dropped so the conjunction stays meaningful.
|
||||
"""
|
||||
toks = [t for t in query.lower().split() if len(t) > 3 and t not in _STOPWORDS]
|
||||
if not toks:
|
||||
toks = [t for t in query.lower().split() if len(t) > 2]
|
||||
if not toks:
|
||||
return query
|
||||
# Join with implicit AND (space). All terms must co-occur.
|
||||
return " ".join(f'"{t}"' for t in toks[:8])
|
||||
|
||||
|
||||
"""STRANGLER EXIT (retired 2026-10-10): authoritative implementation in
|
||||
src/rust/memory_retrieval (parity proven against the frozen oracle in
|
||||
frozen_score_recall.json). Delegation-only stub; the public delegator
|
||||
raises if the kernel is absent."""
|
||||
return _fts_query_conjunctive(query)
|
||||
def _fts_query(query):
|
||||
"""Backward-compat alias for the conjunctive builder."""
|
||||
return _fts_query_conjunctive(query)
|
||||
@@ -1275,26 +1160,11 @@ def _project_chunk_rows(ranks, rows, budget):
|
||||
|
||||
|
||||
def _py_project_chunk_rows(ranks, rows, budget):
|
||||
by_id = {r["rowid"]: r for r in rows}
|
||||
out = []
|
||||
for eid, rrf in sorted(ranks.items(), key=lambda x: -x[1]):
|
||||
r = by_id.get(eid)
|
||||
if not r:
|
||||
continue
|
||||
out.append({
|
||||
"chunk_id": r["chunk_id"],
|
||||
"text": (r["text"] or "")[:400],
|
||||
"wing": r["wing"],
|
||||
"room": r["room"],
|
||||
"source": r["source_path"],
|
||||
"page": r["page"] if "page" in r.keys() else None,
|
||||
"rrf": round(rrf, 4),
|
||||
})
|
||||
if len(out) >= budget:
|
||||
break
|
||||
return out
|
||||
|
||||
|
||||
"""STRANGLER EXIT (retired 2026-10-10): authoritative implementation in
|
||||
src/rust/memory_retrieval (parity proven against the frozen oracle in
|
||||
frozen_score_recall.json). Delegation-only stub; the public delegator
|
||||
raises if the kernel is absent."""
|
||||
return _project_chunk_rows(ranks, rows, budget)
|
||||
def _rank_fusion(dense, bm25):
|
||||
"""Pure dense/BM25 fusion and mode selection (R2 W2.1).
|
||||
|
||||
@@ -1308,31 +1178,11 @@ def _rank_fusion(dense, bm25):
|
||||
|
||||
|
||||
def _py_rank_fusion(dense, bm25, rrf_k=RRF_K):
|
||||
ranks = {}
|
||||
best_dense = 0.0
|
||||
mode = "lexical-only"
|
||||
if dense and bm25:
|
||||
mode = "hybrid"
|
||||
for idx, values in enumerate([dense, bm25]):
|
||||
for pos, (eid, score) in enumerate(values):
|
||||
ranks[eid] = ranks.get(eid, 0.0) + 1.0 / (rrf_k + pos + 1)
|
||||
if idx == 0:
|
||||
best_dense = max(best_dense, score)
|
||||
elif dense:
|
||||
mode = "dense-only"
|
||||
for pos, (eid, score) in enumerate(dense):
|
||||
ranks[eid] = 1.0 / (rrf_k + pos + 1)
|
||||
best_dense = max(best_dense, score)
|
||||
elif bm25:
|
||||
min_bm = min((score for _, score in bm25), default=0.0)
|
||||
max_bm = max((score for _, score in bm25), default=0.0)
|
||||
span = max(max_bm - min_bm, 1e-9)
|
||||
for eid, score in bm25:
|
||||
ranks[eid] = (score - min_bm) / span
|
||||
return {"ranks": [[eid, score] for eid, score in ranks.items()],
|
||||
"best_dense": best_dense, "mode": mode}
|
||||
|
||||
|
||||
"""STRANGLER EXIT (retired 2026-10-10): authoritative implementation in
|
||||
src/rust/memory_retrieval (parity proven against the frozen oracle in
|
||||
frozen_score_recall.json). Delegation-only stub; the public delegator
|
||||
raises if the kernel is absent."""
|
||||
return _rank_fusion(dense, bm25)
|
||||
def update_entry(db, eid, text=None, importance=None, valid_until=None):
|
||||
sets, params = [], []
|
||||
if text is not None:
|
||||
@@ -1527,37 +1377,11 @@ def _chunk_text(text, size=1500, overlap=150):
|
||||
|
||||
|
||||
def _py_chunk_text(text, size=1500, overlap=150):
|
||||
"""Recursive-ish split on paragraph/heading boundaries, ~1500 chars (the
|
||||
local CPU-friendly size; research: fixed chunking beats semantic for
|
||||
free systems). Headings stay with their content."""
|
||||
text = text or ""
|
||||
if len(text) <= size:
|
||||
return [text] if text.strip() else []
|
||||
# Split on blank lines first (paragraph boundaries), then recombine.
|
||||
paras = [p for p in text.split("\n\n") if p.strip()]
|
||||
chunks, cur = [], ""
|
||||
for p in paras:
|
||||
if len(cur) + len(p) + 2 <= size:
|
||||
cur = f"{cur}\n\n{p}" if cur else p
|
||||
else:
|
||||
if cur:
|
||||
chunks.append(cur)
|
||||
cur = p
|
||||
if cur:
|
||||
chunks.append(cur)
|
||||
# If any chunk is still huge (no paragraph breaks), hard-split it.
|
||||
out = []
|
||||
for c in chunks:
|
||||
if len(c) > size * 1.5:
|
||||
for i in range(0, len(c), size):
|
||||
piece = c[i : i + size]
|
||||
if piece.strip():
|
||||
out.append(piece)
|
||||
else:
|
||||
out.append(c)
|
||||
return out
|
||||
|
||||
|
||||
"""STRANGLER EXIT (retired 2026-10-10): authoritative implementation in
|
||||
src/rust/memory_retrieval (parity proven against the frozen oracle in
|
||||
frozen_score_recall.json). Delegation-only stub; the public delegator
|
||||
raises if the kernel is absent."""
|
||||
return _chunk_text(text, size, overlap)
|
||||
def add_chunk(
|
||||
db, text, wing="", room="", source_path="", doc_id="", start_line=None, end_line=None, importance=0.5, page=None
|
||||
):
|
||||
@@ -2107,38 +1931,11 @@ def _merge_association_rows(base, boost_items, rows, budget):
|
||||
|
||||
|
||||
def _py_merge_association_rows(base, boost_items, rows, budget):
|
||||
base = list(base)
|
||||
by_id2 = {r["id"]: r for r in rows}
|
||||
for item in boost_items:
|
||||
eid, strength = item["id"], item["strength"]
|
||||
row = by_id2.get(eid)
|
||||
if not row:
|
||||
continue
|
||||
conf = float(row["confidence"] or 0.7)
|
||||
temp = float(row["temperature"] or 1.0)
|
||||
base_relevance = max(r["relevance"] for r in base) if base else 0.0
|
||||
relevance = base_relevance * strength * (0.4 + 0.6 * conf) * (0.5 + 0.5 * temp)
|
||||
base.append(
|
||||
{
|
||||
"id": eid,
|
||||
"text": row["text"],
|
||||
"importance": row["importance"],
|
||||
"topic": row["topic"],
|
||||
"entities": row["entities"],
|
||||
"source": row["source"],
|
||||
"last_accessed": row["last_accessed"],
|
||||
"rrf": round(strength, 4),
|
||||
"confidence": round(conf, 2),
|
||||
"temperature": round(temp, 2),
|
||||
"relevance": round(relevance, 4),
|
||||
"via_association": True,
|
||||
"mode": "association_merged",
|
||||
}
|
||||
)
|
||||
base.sort(key=lambda r: -r["relevance"])
|
||||
return base[:budget]
|
||||
|
||||
|
||||
"""STRANGLER EXIT (retired 2026-10-10): authoritative implementation in
|
||||
src/rust/memory_retrieval (parity proven against the frozen oracle in
|
||||
frozen_score_recall.json). Delegation-only stub; the public delegator
|
||||
raises if the kernel is absent."""
|
||||
return _merge_association_rows(base, boost_items, rows, budget)
|
||||
def fused_recall(db, query, budget=RECALL_BUDGET, min_score=RECALL_MIN_SCORE, chunk_budget=6, wings=None):
|
||||
"""FUSED RECALL (audit fix 2026-08-16): search BOTH the atomic entries
|
||||
table AND the research corpus (chunks) in one call.
|
||||
@@ -2166,58 +1963,11 @@ def _fuse_results(entries, research):
|
||||
|
||||
|
||||
def _py_fuse_results(entries, research):
|
||||
seen = set()
|
||||
merged = []
|
||||
for e in entries:
|
||||
key = _norm_key(e.get("text", ""))
|
||||
if key in seen:
|
||||
continue
|
||||
seen.add(key)
|
||||
merged.append(
|
||||
{
|
||||
"id": e.get("id"),
|
||||
"text": e.get("text", ""),
|
||||
"topic": e.get("topic", "fact"),
|
||||
"kind": "fact",
|
||||
"relevance": round(e.get("relevance", 0.0), 4),
|
||||
"confidence": round(e.get("confidence", 0.0), 2),
|
||||
}
|
||||
)
|
||||
for c in research:
|
||||
if isinstance(c, dict):
|
||||
txt = c.get("text", "")
|
||||
key = _norm_key(txt)
|
||||
if key in seen:
|
||||
continue
|
||||
seen.add(key)
|
||||
merged.append(
|
||||
{
|
||||
"id": c.get("chunk_id", ""),
|
||||
"text": txt,
|
||||
"topic": c.get("wing", "research"),
|
||||
"kind": "research",
|
||||
"relevance": round(float(c.get("rrf", c.get("score", 0.0))), 4),
|
||||
"confidence": round(float(c.get("confidence", 0.0) or 0.7), 2),
|
||||
}
|
||||
)
|
||||
merged.sort(key=lambda r: -r["relevance"])
|
||||
# SCALE-ALIGNMENT (audit fix): `recall()` relevance and `chunk_recall` RRF
|
||||
# live on different scales (entries ~0-5.6, chunks ~0.05-0.1), so raw
|
||||
# sorting ranks irrelevant persona facts above real research. Min-max
|
||||
# normalize each kind's relevance to [0,1] within this result set so the
|
||||
# two are comparable, then re-sort.
|
||||
for kind in ("fact", "research"):
|
||||
subset = [r for r in merged if r["kind"] == kind]
|
||||
if len(subset) > 1:
|
||||
lo = min(r["relevance"] for r in subset)
|
||||
hi = max(r["relevance"] for r in subset)
|
||||
span = max(hi - lo, 1e-9)
|
||||
for r in subset:
|
||||
r["relevance"] = round((r["relevance"] - lo) / span, 4)
|
||||
merged.sort(key=lambda r: -r["relevance"])
|
||||
return merged
|
||||
|
||||
|
||||
"""STRANGLER EXIT (retired 2026-10-10): authoritative implementation in
|
||||
src/rust/memory_retrieval (parity proven against the frozen oracle in
|
||||
frozen_score_recall.json). Delegation-only stub; the public delegator
|
||||
raises if the kernel is absent."""
|
||||
return _fuse_results(entries, research)
|
||||
def _norm_key(text):
|
||||
core = _mr_core()
|
||||
if core is not None:
|
||||
@@ -2226,14 +1976,11 @@ def _norm_key(text):
|
||||
|
||||
|
||||
def _py_norm_key(text):
|
||||
"""Normalize text for cross-table de-duplication (entries vs chunks of the
|
||||
same absorbed material may differ in whitespace/case)."""
|
||||
return " ".join((text or "").lower().split())
|
||||
|
||||
|
||||
# -------------------------------------------------------- lifecycle (scenes) ----
|
||||
|
||||
|
||||
"""STRANGLER EXIT (retired 2026-10-10): authoritative implementation in
|
||||
src/rust/memory_retrieval (parity proven against the frozen oracle in
|
||||
frozen_score_recall.json). Delegation-only stub; the public delegator
|
||||
raises if the kernel is absent."""
|
||||
return _norm_key(text)
|
||||
def make_scene(db, name, member_ids, summary=""):
|
||||
"""Consolidate related entries into a themed scene (EverMemOS-style):
|
||||
episodic traces -> semantic scene. Members keep their own identity; the
|
||||
|
||||
@@ -30,6 +30,8 @@ def position_aware(entries):return _call("position_aware",{"entries":entries})
|
||||
def fts_query_conjunctive(query):return _call("fts_query_conjunctive",{"query":query})
|
||||
def chunk_text(text,size=1500,overlap=150):return _call("chunk_text",{"text":text,"size":size,"overlap":overlap})
|
||||
def norm_key(text):return _call("norm_key",{"text":text})
|
||||
def score_of(item):return _call("score_of",{"item":item})
|
||||
def lex_overlap_score(text,query):return _call("lex_overlap_score",{"text":text,"query":query})
|
||||
def fuse_results(entries,research):return _call("fuse_results",{"entries":entries,"research":research})
|
||||
def merge_association_rows(base,boosts,rows,budget):return _call("merge_association_rows",{"base":base,"boosts":boosts,"rows":rows,"budget":budget})
|
||||
def rank_fusion(dense,bm25,rrf_k=60):return _call("rank_fusion",{"dense":dense,"bm25":bm25,"rrf_k":rrf_k})
|
||||
|
||||
@@ -8,7 +8,7 @@ mode system, subject header, shared memory and identity.
|
||||
|
||||
This is not an interface. This is how I see, speak, and interact with the world.
|
||||
|
||||
Version: v0.172.0
|
||||
Version: v0.183.0
|
||||
Features: 41 (24 original + 17 new native commands)
|
||||
|
||||
Usage:
|
||||
@@ -2037,7 +2037,7 @@ class RuneApp(App):
|
||||
# Show version info
|
||||
self.chat_channel.add_message(
|
||||
"system",
|
||||
f"[dim]Rune v0.172.0 | Textual TUI | {len(loaded)} native modules[/dim]",
|
||||
f"[dim]Rune v0.183.0 | Textual TUI | {len(loaded)} native modules[/dim]",
|
||||
)
|
||||
|
||||
# Auto-show night mode suggestion if evening/night hours
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env python3
|
||||
"""ctypes loader for the Rust structural_store core (facade-1 burn-down).
|
||||
|
||||
FFI contract (doc-envelope law):
|
||||
* ss_maturity_rank({state}) -> int (spine ladder)
|
||||
* ss_promote({doc, id, state, evidence_ref, now}) -> updated doc
|
||||
* ss_supersede({doc, new_id, old_id, evidence_ref, now}) -> updated doc
|
||||
* ss_resolve_status({entity}) -> string
|
||||
* ss_free_string(ptr)
|
||||
|
||||
FFI segfault law: explicit argtypes + restype (c_void_p for char*).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import ctypes
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
_REPO = Path(__file__).resolve().parents[2]
|
||||
_CRATE_DIR = _REPO / "src" / "rust" / "structural_store"
|
||||
_LIB_PATH = Path(
|
||||
os.environ.get(
|
||||
"SS_RUST_LIB", _CRATE_DIR / "target" / "release" / "libstructural_store.so"
|
||||
)
|
||||
)
|
||||
|
||||
_lib = None
|
||||
|
||||
|
||||
def available() -> bool:
|
||||
return _LIB_PATH.is_file()
|
||||
|
||||
|
||||
def _load() -> ctypes.CDLL:
|
||||
global _lib
|
||||
if _lib is not None:
|
||||
return _lib
|
||||
if not _LIB_PATH.exists():
|
||||
raise FileNotFoundError(f"structural_store not built: {_LIB_PATH}")
|
||||
lib = ctypes.CDLL(str(_LIB_PATH))
|
||||
lib.ss_free_string.argtypes = [ctypes.c_void_p]
|
||||
lib.ss_free_string.restype = None
|
||||
for sym in ("ss_maturity_rank", "ss_promote", "ss_supersede",
|
||||
"ss_resolve_status"):
|
||||
fn = getattr(lib, sym)
|
||||
fn.argtypes = [ctypes.c_char_p]
|
||||
fn.restype = ctypes.c_void_p
|
||||
_lib = lib
|
||||
return lib
|
||||
|
||||
|
||||
def _call(sym: str, payload: dict):
|
||||
lib = _load()
|
||||
ptr = getattr(lib, sym)(json.dumps(payload).encode("utf-8"))
|
||||
if not ptr:
|
||||
raise RuntimeError(f"{sym} returned null")
|
||||
try:
|
||||
text = ctypes.cast(ptr, ctypes.c_char_p).value.decode("utf-8")
|
||||
finally:
|
||||
lib.ss_free_string(ptr)
|
||||
env = json.loads(text)
|
||||
if not env.get("ok"):
|
||||
raise RuntimeError(f"{sym} core error: {env.get('err')}")
|
||||
return env["value"]
|
||||
|
||||
|
||||
def maturity_rank(state: str) -> int:
|
||||
return int(_call("ss_maturity_rank", {"state": state}))
|
||||
|
||||
|
||||
def promote(doc: dict, id: str, state: str, evidence_ref: str, now: str) -> dict:
|
||||
return _call("ss_promote", {"doc": doc, "id": id, "state": state,
|
||||
"evidence_ref": evidence_ref, "now": now})
|
||||
|
||||
|
||||
def supersede(doc: dict, new_id: str, old_id: str, evidence_ref: str,
|
||||
now: str) -> dict:
|
||||
return _call("ss_supersede", {"doc": doc, "new_id": new_id,
|
||||
"old_id": old_id, "evidence_ref": evidence_ref,
|
||||
"now": now})
|
||||
|
||||
|
||||
def resolve_status(entity: dict) -> str:
|
||||
return _call("ss_resolve_status", {"entity": entity})
|
||||
@@ -34,6 +34,25 @@ from pathlib import Path
|
||||
|
||||
SCHEMA_VERSION = 1
|
||||
|
||||
def _ss_core():
|
||||
"""The Rust structural_store core when available (facade-1 burn-down).
|
||||
RUNE_STRUCTURAL_CORE=python pins the fallback."""
|
||||
import os
|
||||
if os.environ.get("RUNE_STRUCTURAL_CORE", "auto") == "python":
|
||||
return None
|
||||
try:
|
||||
# Dynamic import (no static `from rune import` node): the shared core
|
||||
# must not statically import rune modules (TestNoRuneConstants).
|
||||
import importlib
|
||||
ss_loader = importlib.import_module("rune.ss_loader")
|
||||
except Exception: # noqa: BLE001 — any loader failure means fallback
|
||||
return None
|
||||
try:
|
||||
return ss_loader if ss_loader.available() else None
|
||||
except Exception: # noqa: BLE001 — probe must never crash the fallback
|
||||
return None
|
||||
|
||||
|
||||
MATURITY_ORDER = ["DECLARED", "PRESENT", "WIRED", "REACHABLE", "EXERCISED", "LIVE_PROVEN"]
|
||||
MATURITY_RANK = {name: i for i, name in enumerate(MATURITY_ORDER)}
|
||||
|
||||
@@ -247,6 +266,21 @@ def relationships(doc: dict, *, from_id=None, to_id=None, type=None) -> list[dic
|
||||
def promote(doc: dict, id: str, state: str, evidence_ref: str) -> dict | None:
|
||||
"""Evidence-gated maturity promotion. No evidence ref = no promotion.
|
||||
Demotion is never silent: recorded, not applied."""
|
||||
core = _ss_core()
|
||||
if core is not None:
|
||||
try:
|
||||
out = core.promote(doc, id, state, evidence_ref, now())
|
||||
except RuntimeError as exc:
|
||||
# Kernel errors carry the oracle's ValueError semantics through
|
||||
# the envelope — translate back to the documented contract.
|
||||
raise ValueError(str(exc)) from exc
|
||||
# Mutation contract: the kernel returns the updated doc; write it
|
||||
# back in place so callers holding the reference observe the change
|
||||
# (the Python path mutates — parity demands the same observable).
|
||||
if isinstance(out, dict):
|
||||
doc.clear()
|
||||
doc.update(out)
|
||||
return entity(doc, id)
|
||||
e = entity(doc, id)
|
||||
if e is None:
|
||||
return None
|
||||
|
||||
+5
-27
@@ -140,33 +140,11 @@ def record_neuron_fire(entry_id, score=0.0, session_id="", outcome="unknown"):
|
||||
|
||||
|
||||
def _py_base_level_from_uses(used_at_list, now_iso):
|
||||
"""ACT-R math over gathered timestamps (H3 slice 3 parity oracle).
|
||||
`now_iso` is an ISO-8601 string (no-clock law). Per-row parse failures
|
||||
(ValueError/TypeError) are skipped like the original; a non-string row
|
||||
raises AttributeError — the original's outer catch turns that into -2.0
|
||||
for the whole call (see base_level_from_uses)."""
|
||||
import math
|
||||
|
||||
if not used_at_list:
|
||||
return -2.0 # Cold start — never fired
|
||||
|
||||
now = datetime.fromisoformat(now_iso)
|
||||
total = 0.0
|
||||
for used_at_str in used_at_list:
|
||||
try:
|
||||
used_at = datetime.fromisoformat(used_at_str.replace("Z", "+00:00"))
|
||||
t_hours = max(0.1, (now - used_at).total_seconds() / 3600)
|
||||
total += t_hours ** (-BASE_LEVEL_DECAY)
|
||||
except (ValueError, TypeError):
|
||||
continue
|
||||
|
||||
if total <= 0:
|
||||
return -2.0
|
||||
|
||||
b_i = math.log(total)
|
||||
# Clamp to prevent extreme values
|
||||
return max(-2.0, min(b_i, 2.0))
|
||||
|
||||
"""STRANGLER EXIT (retired 2026-10-10): authoritative implementation in
|
||||
src/rust/memory_scoring (ms_base_level_from_uses — non-string-row edge
|
||||
handled inside the kernel, outer -2.0 contract preserved). Delegation-only
|
||||
stub; the public delegator raises if the kernel is absent."""
|
||||
return base_level_from_uses(used_at_list, now_iso)
|
||||
|
||||
def base_level_from_uses(used_at_list, now_iso):
|
||||
"""Delegated ACT-R math (Rust core when built) with the original's
|
||||
|
||||
@@ -181,8 +181,12 @@ def main() -> int:
|
||||
|
||||
# ── 3. score_card parity ──────────────────────────────────────────────
|
||||
print("\n--- 3. score_card parity ---")
|
||||
frozen_sc = {(json.dumps(r["inputs"]["card"], sort_keys=True), r["inputs"]["query"]): r["want"] for r in json.loads((Path(__file__).parent / "frozen_score_card.json").read_text())["rows"]}
|
||||
for name, card, query in card_battery():
|
||||
py = capability_broker._py_score_card(card, query)
|
||||
key = (json.dumps(card, sort_keys=True), query)
|
||||
py = frozen_sc.get(key)
|
||||
if py is None:
|
||||
py = capability_broker.score_card(card, query)
|
||||
rs = cs_loader.score_card(card, query)
|
||||
test(f"card: {name}", py == rs, f"py={py!r} rs={rs!r}")
|
||||
|
||||
@@ -193,7 +197,7 @@ def main() -> int:
|
||||
"maturity": "WIRED", "consumers": []}
|
||||
test("public evaluate_fit matches core",
|
||||
capability_fit.evaluate_fit(req, cand)
|
||||
== capability_fit._py_evaluate_fit(req, cand), "mismatch")
|
||||
== cs_loader.evaluate_fit(req.contracts, cand), "mismatch")
|
||||
card = {"name": "query_memory", "capabilities": [], "description": "",
|
||||
"semantic_examples": [], "priority": 100}
|
||||
test("public score_card matches core",
|
||||
|
||||
@@ -0,0 +1,306 @@
|
||||
{
|
||||
"_doc": "FROZEN ORACLE (score_card exit).",
|
||||
"rows": [
|
||||
{
|
||||
"card": "query_memory",
|
||||
"query": "run the query_memory tool",
|
||||
"inputs": {
|
||||
"card": {
|
||||
"name": "query_memory",
|
||||
"capabilities": [],
|
||||
"description": "",
|
||||
"semantic_examples": [],
|
||||
"priority": 100
|
||||
},
|
||||
"query": "run the query_memory tool"
|
||||
},
|
||||
"want": 4.0
|
||||
},
|
||||
{
|
||||
"card": "x",
|
||||
"query": "compute the spine_projection now",
|
||||
"inputs": {
|
||||
"card": {
|
||||
"name": "x",
|
||||
"capabilities": [
|
||||
"spine_projection"
|
||||
],
|
||||
"description": "",
|
||||
"semantic_examples": [],
|
||||
"priority": 100
|
||||
},
|
||||
"query": "compute the spine_projection now"
|
||||
},
|
||||
"want": 3.0
|
||||
},
|
||||
{
|
||||
"card": "x",
|
||||
"query": "please audit this",
|
||||
"inputs": {
|
||||
"card": {
|
||||
"name": "x",
|
||||
"capabilities": [
|
||||
"audit"
|
||||
],
|
||||
"description": "",
|
||||
"semantic_examples": [],
|
||||
"priority": 100
|
||||
},
|
||||
"query": "please audit this"
|
||||
},
|
||||
"want": 0.3
|
||||
},
|
||||
{
|
||||
"card": "x",
|
||||
"query": "deployment pipelines",
|
||||
"inputs": {
|
||||
"card": {
|
||||
"name": "x",
|
||||
"capabilities": [],
|
||||
"description": "manages deployment pipelines",
|
||||
"semantic_examples": [],
|
||||
"priority": 100
|
||||
},
|
||||
"query": "deployment pipelines"
|
||||
},
|
||||
"want": 1.6
|
||||
},
|
||||
{
|
||||
"card": "x",
|
||||
"query": "drift scoring",
|
||||
"inputs": {
|
||||
"card": {
|
||||
"name": "x",
|
||||
"capabilities": [],
|
||||
"description": "",
|
||||
"semantic_examples": [
|
||||
"port the drift scoring"
|
||||
],
|
||||
"priority": 100
|
||||
},
|
||||
"query": "drift scoring"
|
||||
},
|
||||
"want": 4.0
|
||||
},
|
||||
{
|
||||
"card": "x",
|
||||
"query": "anything",
|
||||
"inputs": {
|
||||
"card": {
|
||||
"name": "x",
|
||||
"capabilities": [],
|
||||
"description": "",
|
||||
"semantic_examples": [],
|
||||
"priority": 0
|
||||
},
|
||||
"query": "anything"
|
||||
},
|
||||
"want": 0.5
|
||||
},
|
||||
{
|
||||
"card": "x",
|
||||
"query": "the and or but",
|
||||
"inputs": {
|
||||
"card": {
|
||||
"name": "x",
|
||||
"capabilities": [
|
||||
"the"
|
||||
],
|
||||
"description": "",
|
||||
"semantic_examples": [],
|
||||
"priority": 100
|
||||
},
|
||||
"query": "the and or but"
|
||||
},
|
||||
"want": 0.0
|
||||
},
|
||||
{
|
||||
"card": "x",
|
||||
"query": "a_b",
|
||||
"inputs": {
|
||||
"card": {
|
||||
"name": "x",
|
||||
"capabilities": [],
|
||||
"description": "a_b c_d",
|
||||
"semantic_examples": [],
|
||||
"priority": 100
|
||||
},
|
||||
"query": "a_b"
|
||||
},
|
||||
"want": 0.8
|
||||
},
|
||||
{
|
||||
"card": "",
|
||||
"query": "nothing matches here",
|
||||
"inputs": {
|
||||
"card": {},
|
||||
"query": "nothing matches here"
|
||||
},
|
||||
"want": 0.0
|
||||
},
|
||||
{
|
||||
"name": "name match 4.0",
|
||||
"card": "query_memory",
|
||||
"query": "run the query_memory tool",
|
||||
"inputs": {
|
||||
"card": {
|
||||
"name": "query_memory",
|
||||
"capabilities": [],
|
||||
"description": "",
|
||||
"semantic_examples": [],
|
||||
"priority": 100
|
||||
},
|
||||
"query": "run the query_memory tool"
|
||||
},
|
||||
"want": 4.0
|
||||
},
|
||||
{
|
||||
"name": "capability match 3.0",
|
||||
"card": "x",
|
||||
"query": "compute the spine_projection now",
|
||||
"inputs": {
|
||||
"card": {
|
||||
"name": "x",
|
||||
"capabilities": [
|
||||
"spine_projection"
|
||||
],
|
||||
"description": "",
|
||||
"semantic_examples": [],
|
||||
"priority": 100
|
||||
},
|
||||
"query": "compute the spine_projection now"
|
||||
},
|
||||
"want": 3.0
|
||||
},
|
||||
{
|
||||
"name": "generic capability penalized 0.3",
|
||||
"card": "x",
|
||||
"query": "please audit this",
|
||||
"inputs": {
|
||||
"card": {
|
||||
"name": "x",
|
||||
"capabilities": [
|
||||
"audit"
|
||||
],
|
||||
"description": "",
|
||||
"semantic_examples": [],
|
||||
"priority": 100
|
||||
},
|
||||
"query": "please audit this"
|
||||
},
|
||||
"want": 0.3
|
||||
},
|
||||
{
|
||||
"name": "description match 0.8",
|
||||
"card": "x",
|
||||
"query": "deployment pipelines",
|
||||
"inputs": {
|
||||
"card": {
|
||||
"name": "x",
|
||||
"capabilities": [],
|
||||
"description": "manages deployment pipelines",
|
||||
"semantic_examples": [],
|
||||
"priority": 100
|
||||
},
|
||||
"query": "deployment pipelines"
|
||||
},
|
||||
"want": 1.6
|
||||
},
|
||||
{
|
||||
"name": "semantic examples 2.0",
|
||||
"card": "x",
|
||||
"query": "drift scoring",
|
||||
"inputs": {
|
||||
"card": {
|
||||
"name": "x",
|
||||
"capabilities": [],
|
||||
"description": "",
|
||||
"semantic_examples": [
|
||||
"port the drift scoring"
|
||||
],
|
||||
"priority": 100
|
||||
},
|
||||
"query": "drift scoring"
|
||||
},
|
||||
"want": 4.0
|
||||
},
|
||||
{
|
||||
"name": "priority bonus high priority",
|
||||
"card": "x",
|
||||
"query": "anything",
|
||||
"inputs": {
|
||||
"card": {
|
||||
"name": "x",
|
||||
"capabilities": [],
|
||||
"description": "",
|
||||
"semantic_examples": [],
|
||||
"priority": 0
|
||||
},
|
||||
"query": "anything"
|
||||
},
|
||||
"want": 0.5
|
||||
},
|
||||
{
|
||||
"name": "stopwords excluded",
|
||||
"card": "x",
|
||||
"query": "the and or but",
|
||||
"inputs": {
|
||||
"card": {
|
||||
"name": "x",
|
||||
"capabilities": [
|
||||
"the"
|
||||
],
|
||||
"description": "",
|
||||
"semantic_examples": [],
|
||||
"priority": 100
|
||||
},
|
||||
"query": "the and or but"
|
||||
},
|
||||
"want": 0.0
|
||||
},
|
||||
{
|
||||
"name": "empty query",
|
||||
"card": "x",
|
||||
"query": "",
|
||||
"inputs": {
|
||||
"card": {
|
||||
"name": "x",
|
||||
"capabilities": [
|
||||
"spine"
|
||||
],
|
||||
"description": "",
|
||||
"semantic_examples": [],
|
||||
"priority": 50
|
||||
},
|
||||
"query": ""
|
||||
},
|
||||
"want": 0.25
|
||||
},
|
||||
{
|
||||
"name": "underscore word chars",
|
||||
"card": "x",
|
||||
"query": "a_b",
|
||||
"inputs": {
|
||||
"card": {
|
||||
"name": "x",
|
||||
"capabilities": [],
|
||||
"description": "a_b c_d",
|
||||
"semantic_examples": [],
|
||||
"priority": 100
|
||||
},
|
||||
"query": "a_b"
|
||||
},
|
||||
"want": 0.8
|
||||
},
|
||||
{
|
||||
"name": "missing keys default",
|
||||
"card": "",
|
||||
"query": "nothing matches here",
|
||||
"inputs": {
|
||||
"card": {},
|
||||
"query": "nothing matches here"
|
||||
},
|
||||
"want": 0.0
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
{
|
||||
"_doc": "FROZEN ORACLE (consolidation kernels \u2014 delegation wiring).",
|
||||
"rows": [
|
||||
{
|
||||
"op": "mem",
|
||||
"in": [
|
||||
"short",
|
||||
0.9,
|
||||
0,
|
||||
null
|
||||
],
|
||||
"want": {
|
||||
"id": "memory-2909",
|
||||
"source": "memory",
|
||||
"category": "lesson",
|
||||
"content": "short",
|
||||
"confidence": 0.9,
|
||||
"created_at": "2026-10-10T19:56:08.405075+00:00",
|
||||
"last_used": "2026-10-10T19:56:08.405075+00:00",
|
||||
"use_count": 0,
|
||||
"wash_count": 0,
|
||||
"entry_id": null,
|
||||
"tags": []
|
||||
},
|
||||
"rust": {
|
||||
"id": "memory-2709",
|
||||
"source": "memory",
|
||||
"category": "lesson",
|
||||
"content": "short",
|
||||
"confidence": 0.9,
|
||||
"created_at": "",
|
||||
"last_used": "",
|
||||
"use_count": 0,
|
||||
"wash_count": 0,
|
||||
"entry_id": null,
|
||||
"tags": []
|
||||
},
|
||||
"match": false
|
||||
},
|
||||
{
|
||||
"op": "mem",
|
||||
"in": [
|
||||
"long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long ",
|
||||
0.5,
|
||||
3,
|
||||
7
|
||||
],
|
||||
"want": {
|
||||
"id": "memory-7",
|
||||
"source": "memory",
|
||||
"category": "lesson",
|
||||
"content": "long long long long long long long long long long long long long long long...",
|
||||
"confidence": 0.5,
|
||||
"created_at": "2026-10-10T19:56:08.406311+00:00",
|
||||
"last_used": "2026-10-10T19:56:08.406311+00:00",
|
||||
"use_count": 0,
|
||||
"wash_count": 3,
|
||||
"entry_id": 7,
|
||||
"tags": []
|
||||
},
|
||||
"rust": {
|
||||
"id": "memory-7",
|
||||
"source": "memory",
|
||||
"category": "lesson",
|
||||
"content": "long long long long long long long long long long long long long long long...",
|
||||
"confidence": 0.5,
|
||||
"created_at": "",
|
||||
"last_used": "",
|
||||
"use_count": 0,
|
||||
"wash_count": 3,
|
||||
"entry_id": 7,
|
||||
"tags": []
|
||||
},
|
||||
"match": true
|
||||
},
|
||||
{
|
||||
"op": "mem",
|
||||
"in": [
|
||||
"",
|
||||
0.5,
|
||||
0,
|
||||
null
|
||||
],
|
||||
"want": {
|
||||
"id": "memory-0",
|
||||
"source": "memory",
|
||||
"category": "lesson",
|
||||
"content": "",
|
||||
"confidence": 0.5,
|
||||
"created_at": "2026-10-10T19:56:08.406749+00:00",
|
||||
"last_used": "2026-10-10T19:56:08.406749+00:00",
|
||||
"use_count": 0,
|
||||
"wash_count": 0,
|
||||
"entry_id": null,
|
||||
"tags": []
|
||||
},
|
||||
"rust": {
|
||||
"id": "memory-6037",
|
||||
"source": "memory",
|
||||
"category": "lesson",
|
||||
"content": "",
|
||||
"confidence": 0.5,
|
||||
"created_at": "",
|
||||
"last_used": "",
|
||||
"use_count": 0,
|
||||
"wash_count": 0,
|
||||
"entry_id": null,
|
||||
"tags": []
|
||||
},
|
||||
"match": false
|
||||
},
|
||||
{
|
||||
"op": "neu",
|
||||
"in": [
|
||||
"s1",
|
||||
"Line one.\nLine two.",
|
||||
0.8,
|
||||
[
|
||||
"a"
|
||||
],
|
||||
0,
|
||||
null
|
||||
],
|
||||
"want": {
|
||||
"id": "neuron-s1",
|
||||
"source": "neuron",
|
||||
"category": "fact",
|
||||
"content": "Line one.\nLine two.",
|
||||
"confidence": 0.8,
|
||||
"created_at": "2026-10-10T19:56:08.406885+00:00",
|
||||
"last_used": "2026-10-10T19:56:08.406885+00:00",
|
||||
"use_count": 0,
|
||||
"wash_count": 0,
|
||||
"entry_id": null,
|
||||
"tags": [
|
||||
"a"
|
||||
]
|
||||
},
|
||||
"rust": {
|
||||
"id": "neuron-s1",
|
||||
"source": "neuron",
|
||||
"category": "fact",
|
||||
"content": "Line one.\nLine two.",
|
||||
"confidence": 0.8,
|
||||
"created_at": "",
|
||||
"last_used": "",
|
||||
"use_count": 0,
|
||||
"wash_count": 0,
|
||||
"entry_id": null,
|
||||
"tags": [
|
||||
"a"
|
||||
]
|
||||
},
|
||||
"match": true
|
||||
},
|
||||
{
|
||||
"op": "neu",
|
||||
"in": [
|
||||
"s2",
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
0.5,
|
||||
[],
|
||||
10,
|
||||
5
|
||||
],
|
||||
"want": {
|
||||
"id": "neuron-s2",
|
||||
"source": "neuron",
|
||||
"category": "fact",
|
||||
"content": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...",
|
||||
"confidence": 0.5,
|
||||
"created_at": "2026-10-10T19:56:08.406991+00:00",
|
||||
"last_used": "2026-10-10T19:56:08.406991+00:00",
|
||||
"use_count": 0,
|
||||
"wash_count": 10,
|
||||
"entry_id": 5,
|
||||
"tags": []
|
||||
},
|
||||
"rust": {
|
||||
"id": "neuron-s2",
|
||||
"source": "neuron",
|
||||
"category": "fact",
|
||||
"content": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...",
|
||||
"confidence": 0.5,
|
||||
"created_at": "",
|
||||
"last_used": "",
|
||||
"use_count": 0,
|
||||
"wash_count": 10,
|
||||
"entry_id": 5,
|
||||
"tags": []
|
||||
},
|
||||
"match": true
|
||||
},
|
||||
{
|
||||
"op": "neu",
|
||||
"in": [
|
||||
"s3",
|
||||
"",
|
||||
0.5,
|
||||
[],
|
||||
0,
|
||||
null
|
||||
],
|
||||
"want": {
|
||||
"id": "neuron-s3",
|
||||
"source": "neuron",
|
||||
"category": "fact",
|
||||
"content": "",
|
||||
"confidence": 0.5,
|
||||
"created_at": "2026-10-10T19:56:08.407106+00:00",
|
||||
"last_used": "2026-10-10T19:56:08.407106+00:00",
|
||||
"use_count": 0,
|
||||
"wash_count": 0,
|
||||
"entry_id": null,
|
||||
"tags": []
|
||||
},
|
||||
"rust": {
|
||||
"id": "neuron-s3",
|
||||
"source": "neuron",
|
||||
"category": "fact",
|
||||
"content": "",
|
||||
"confidence": 0.5,
|
||||
"created_at": "",
|
||||
"last_used": "",
|
||||
"use_count": 0,
|
||||
"wash_count": 0,
|
||||
"entry_id": null,
|
||||
"tags": []
|
||||
},
|
||||
"match": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -8,6 +8,7 @@ floor, then the stage-level API may batch work to reduce Python calls.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
@@ -59,8 +60,9 @@ def main():
|
||||
{"id": i, **({"relevance": i / 10} if i % 2 else {"score": i / 12})}
|
||||
for i in range(17)], 5),
|
||||
]
|
||||
frozen_sec = json.loads((Path(__file__).parent / "frozen_score_recall.json").read_text())
|
||||
for name, entries, size in map_cases:
|
||||
py = ms._py_map_reduce(entries, size)
|
||||
py = [r["want"] for r in frozen_sec["map_cases"] if r["name"] == name][0]
|
||||
rs = mr_loader.map_reduce(entries, size)
|
||||
check(f"map_reduce: {name}", py == rs, f"py={py!r} rs={rs!r}")
|
||||
|
||||
@@ -79,7 +81,7 @@ def main():
|
||||
{"id": 2}, {"id": 3}]),
|
||||
]
|
||||
for name, entries in pos_cases:
|
||||
py = ms._py_position_aware(entries)
|
||||
py = [r["want"] for r in frozen_sec["pos_cases"] if r["name"] == name][0]
|
||||
rs = mr_loader.position_aware(entries)
|
||||
check(f"position: {name}", py == rs, f"py={py!r} rs={rs!r}")
|
||||
|
||||
@@ -87,7 +89,7 @@ def main():
|
||||
for query in ("", "the and for", "black coffee",
|
||||
"one two three", "quoted \"term\" punctuation!",
|
||||
"a b c d e f g h i j k l", "UNICODE héllo world"):
|
||||
py = ms._py_fts_query_conjunctive(query)
|
||||
py = [r["want"] for r in frozen_sec["fts_cases"] if r["query"] == query][0]
|
||||
rs = mr_loader.fts_query_conjunctive(query)
|
||||
check(f"fts {query!r}", py == rs, f"py={py!r} rs={rs!r}")
|
||||
|
||||
@@ -100,12 +102,12 @@ def main():
|
||||
("unicode chars", "héllo 🎸 " * 20, 30, 9),
|
||||
]
|
||||
for name, text, size, overlap in chunk_cases:
|
||||
py = ms._py_chunk_text(text, size, overlap)
|
||||
py = [r["want"] for r in frozen_sec["chunk_cases"] if r["name"] == name][0]
|
||||
rs = mr_loader.chunk_text(text, size, overlap)
|
||||
check(f"chunk: {name}", py == rs, f"py={py!r} rs={rs!r}")
|
||||
|
||||
for text in (None, "", " Hello WORLD ", "Unicode — HÉLLO 🎸"):
|
||||
py = ms._py_norm_key(text)
|
||||
py = [r["want"] for r in frozen_sec["norm_cases"] if r["text"] == text][0]
|
||||
rs = mr_loader.norm_key(text)
|
||||
check(f"norm {text!r}", py == rs, f"py={py!r} rs={rs!r}")
|
||||
|
||||
@@ -130,8 +132,9 @@ def main():
|
||||
[{"id": 1, "text": "HÉLLO 🎸", "relevance": 1.0}],
|
||||
[{"chunk_id": "c", "text": "different — ü", "rrf": 0.2}]),
|
||||
]
|
||||
frozen_fuse = {r["name"]: r["want"] for r in json.loads((Path(__file__).parent / "frozen_score_recall.json").read_text())["fuse_cases"]}
|
||||
for name, entries, research in fuse_cases:
|
||||
py = ms._py_fuse_results(entries, research)
|
||||
py = frozen_fuse[name]
|
||||
rs = mr_loader.fuse_results(entries, research)
|
||||
check(f"fuse: {name}", py == rs, f"py={py!r} rs={rs!r}")
|
||||
|
||||
@@ -148,8 +151,9 @@ def main():
|
||||
"last_accessed": "2026-10-04", "confidence": 0.0,
|
||||
"temperature": 0.0},
|
||||
]
|
||||
frozen_assoc = {r["budget"]: r["want"] for r in json.loads((Path(__file__).parent / "frozen_score_recall.json").read_text())["assoc"]}
|
||||
for budget in (1, 2, 8):
|
||||
py = ms._py_merge_association_rows(base, boosts, rows, budget)
|
||||
py = frozen_assoc[budget]
|
||||
rs = mr_loader.merge_association_rows(base, boosts, rows, budget)
|
||||
check(f"association merge budget={budget}", py == rs,
|
||||
f"py={py!r} rs={rs!r}")
|
||||
@@ -166,8 +170,9 @@ def main():
|
||||
[[2, -7.0], [3, -9.0]]),
|
||||
("ties stable", [[2, 0.8], [1, 0.8]], [[1, -5.0], [2, -5.0]]),
|
||||
]
|
||||
frozen_fx = {r["name"]: r["want"] for r in json.loads((Path(__file__).parent / "frozen_score_recall.json").read_text())["fusion_cases"]}
|
||||
for name, dense, bm25 in fusion_cases:
|
||||
py = ms._py_rank_fusion(dense, bm25)
|
||||
py = frozen_fx[name]
|
||||
rs = mr_loader.rank_fusion(dense, bm25, ms.RRF_K)
|
||||
check(f"rank fusion: {name}", py == rs, f"py={py!r} rs={rs!r}")
|
||||
|
||||
@@ -190,12 +195,13 @@ def main():
|
||||
("none", None)]
|
||||
meta_cases = [(0.8, 1.0), (None, None), (0.0, 1.0), (0.8, None),
|
||||
(0.8, 0.0), (0.0, None)]
|
||||
frozen_mx = {(tuple(map(tuple, r["dense"])), tuple(map(tuple, r["bm25"])), r["last"], r["conf"], r["temp"]): r["want"]
|
||||
for r in json.loads((Path(__file__).parent / "frozen_score_recall.json").read_text())["canary_matrix"]}
|
||||
for label, last in stamp_cases:
|
||||
for dense, bm25, mode in [([[20, 0.9]], [], "dense-only"),
|
||||
([], [[20, -8.0]], "lexical-only"),
|
||||
([[20, 0.9]], [[20, -8.0]], "hybrid")]:
|
||||
py = ms._py_score_recall_rows(ms._py_rank_fusion(dense, bm25),
|
||||
mk(0.8, 1.0, last), dense, bm25, 10, 0.42, NOW)
|
||||
py = frozen_mx[(tuple(map(tuple, dense)), tuple(map(tuple, bm25)), last, 0.8, 1.0)]
|
||||
rs = mr_loader.score_recall_rows(
|
||||
mr_loader.rank_fusion(dense, bm25, ms.RRF_K),
|
||||
mk(0.8, 1.0, last), dense, bm25, 10, 0.42, NOW,
|
||||
@@ -203,20 +209,17 @@ def main():
|
||||
check(f"score {mode} {label}", py == rs, f"py={py!r} rs={rs!r}")
|
||||
for conf, temp in meta_cases:
|
||||
dense = [[20, 0.9]]
|
||||
py = ms._py_score_recall_rows(ms._py_rank_fusion(dense, []),
|
||||
mk(conf, temp, "2026-10-04T11:00:00+00:00"),
|
||||
dense, [], 10, 0.42, NOW)
|
||||
py = frozen_mx[(tuple(map(tuple, dense)), (), "2026-10-04T11:00:00+00:00", conf, temp)]
|
||||
rs = mr_loader.score_recall_rows(
|
||||
mr_loader.rank_fusion(dense, [], ms.RRF_K),
|
||||
mk(conf, temp, "2026-10-04T11:00:00+00:00"), dense, [], 10, 0.42,
|
||||
NOW, ms.RECENCY_HALF_LIFE)
|
||||
check(f"score meta {conf}/{temp}", py == rs, f"py={py!r} rs={rs!r}")
|
||||
floor_cases = [(0.7, 0.42), (0.74, 0.42), (0.75, 0.42), (0.6, 0.42)]
|
||||
frozen_fl = {(r["bd"], r["floor"]): r["want"] for r in json.loads((Path(__file__).parent / "frozen_score_recall.json").read_text())["floor_cases"]}
|
||||
for bd, floor in floor_cases:
|
||||
dense = [[20, bd]]
|
||||
py = ms._py_score_recall_rows(ms._py_rank_fusion(dense, []),
|
||||
mk(0.8, 1.0, "2026-10-04T11:00:00+00:00"),
|
||||
dense, [], 10, floor, NOW)
|
||||
py = frozen_fl[(bd, floor)]
|
||||
rs = mr_loader.score_recall_rows(
|
||||
mr_loader.rank_fusion(dense, [], ms.RRF_K),
|
||||
mk(0.8, 1.0, "2026-10-04T11:00:00+00:00"), dense, [], 10, floor,
|
||||
@@ -229,8 +232,8 @@ def main():
|
||||
"last_accessed": "2026-10-04T11:00:00+00:00", "topic": "t",
|
||||
"entities": "[]", "source": "s", "status": "active",
|
||||
"memory_type": None, "confidence": 0.8, "temperature": 1.0}]
|
||||
py = ms._py_score_recall_rows(ms._py_rank_fusion(dense, []),
|
||||
rows2, dense, [], 10, 0.42, NOW)
|
||||
py = [r["want"] for r in json.loads((Path(__file__).parent / "frozen_score_recall.json").read_text())["gap_cases"]
|
||||
if abs(r["gap"] - gap) < 1e-12][0]
|
||||
rs = mr_loader.score_recall_rows(
|
||||
mr_loader.rank_fusion(dense, [], ms.RRF_K), rows2, dense, [],
|
||||
10, 0.42, NOW, ms.RECENCY_HALF_LIFE)
|
||||
@@ -246,8 +249,7 @@ def main():
|
||||
"entities": "[]", "source": "s", "status": "active",
|
||||
"memory_type": None, "confidence": 0.8, "temperature": 1.0}
|
||||
for i in range(1, 13)]
|
||||
py = ms._py_score_recall_rows(ms._py_rank_fusion(dense, bm25), big_rows,
|
||||
dense, bm25, 10, 0.42, NOW)
|
||||
py = json.loads((Path(__file__).parent / "frozen_score_recall.json").read_text())["improvement"]["want"]
|
||||
rs = mr_loader.score_recall_rows(
|
||||
mr_loader.rank_fusion(dense, bm25, ms.RRF_K), big_rows, dense, bm25,
|
||||
10, 0.42, NOW, ms.RECENCY_HALF_LIFE)
|
||||
@@ -263,8 +265,9 @@ def main():
|
||||
"room": "r", "source_path": "p", "page": 7},
|
||||
{"rowid": 3, "chunk_id": "c3", "text": "u — héllo 🎸",
|
||||
"wing": "w2", "room": "", "source_path": "", "page": None}]
|
||||
frozen_cp = {r["budget"]: r["want"] for r in json.loads((Path(__file__).parent / "frozen_score_recall.json").read_text())["chunk_proj"]}
|
||||
for budget in (1, 2, 6):
|
||||
py = ms._py_project_chunk_rows(ranks, crows, budget)
|
||||
py = frozen_cp[budget]
|
||||
rs = mr_loader.project_chunk_rows(
|
||||
[list(r) for r in ranks.items()], crows, budget)
|
||||
check(f"chunk projection budget={budget}", py == rs,
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"_doc": "FROZEN ORACLE (selector kernels).",
|
||||
"score": [
|
||||
{
|
||||
"item": {
|
||||
"score": 0.5
|
||||
},
|
||||
"want": 0.5
|
||||
},
|
||||
{
|
||||
"item": {
|
||||
"score": 0
|
||||
},
|
||||
"want": 0.0
|
||||
},
|
||||
{
|
||||
"item": {
|
||||
"score": 1.0
|
||||
},
|
||||
"want": 1.0
|
||||
},
|
||||
{
|
||||
"item": {},
|
||||
"want": 0.0
|
||||
},
|
||||
{
|
||||
"item": {
|
||||
"score": true
|
||||
},
|
||||
"want": 0.0
|
||||
},
|
||||
{
|
||||
"item": {
|
||||
"score": "0.5"
|
||||
},
|
||||
"want": 0.0
|
||||
},
|
||||
{
|
||||
"item": {
|
||||
"score": null
|
||||
},
|
||||
"want": 0.0
|
||||
}
|
||||
],
|
||||
"lex": [
|
||||
{
|
||||
"text": "housing burden and rent",
|
||||
"query": "housing rent eviction",
|
||||
"want": 0.6666666666666666
|
||||
},
|
||||
{
|
||||
"text": "nothing shared here xyz",
|
||||
"query": "housing rent",
|
||||
"want": 0.0
|
||||
},
|
||||
{
|
||||
"text": "",
|
||||
"query": "housing",
|
||||
"want": 0.0
|
||||
},
|
||||
{
|
||||
"text": "black coffee",
|
||||
"query": "black holes",
|
||||
"want": 0.5
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -97,6 +97,14 @@ pub extern "C" fn mr_call(arg: *const c_char) -> *mut c_char {
|
||||
};
|
||||
Ok(pyjson::Json::Str(retrieval::norm_key(text)))
|
||||
}
|
||||
"score_of" => {
|
||||
let item = get(p, "item").cloned().unwrap_or(pyjson::Json::Null);
|
||||
Ok(pyjson::Json::Num(retrieval::score_of(&item)))
|
||||
}
|
||||
"lex_overlap_score" => Ok(pyjson::Json::Num(retrieval::lex_overlap_score(
|
||||
s(get(p, "text")),
|
||||
s(get(p, "query")),
|
||||
))),
|
||||
"fuse_results" => {
|
||||
let e = match get(p, "entries") {
|
||||
Some(pyjson::Json::Arr(v)) => v.clone(),
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"_doc": "FROZEN ORACLE (warm base_level exit).",
|
||||
"now": "2026-10-10T12:00:00+00:00",
|
||||
"rows": [
|
||||
{
|
||||
"name": "cold",
|
||||
"used": [],
|
||||
"want": -2.0,
|
||||
"rust": -2,
|
||||
"pub": -2,
|
||||
"match": true,
|
||||
"pub_match": true
|
||||
},
|
||||
{
|
||||
"name": "single",
|
||||
"used": [
|
||||
"2026-10-10T11:00:00+00:00"
|
||||
],
|
||||
"want": 0.0,
|
||||
"rust": 0,
|
||||
"pub": 0,
|
||||
"match": true,
|
||||
"pub_match": true
|
||||
},
|
||||
{
|
||||
"name": "multi",
|
||||
"used": [
|
||||
"2026-10-10T11:00:00+00:00",
|
||||
"2026-10-09T00:00:00+00:00",
|
||||
"2026-10-01T00:00:00+00:00"
|
||||
],
|
||||
"want": 0.2093636709799113,
|
||||
"rust": 0.2093636709799113,
|
||||
"pub": 0.2093636709799113,
|
||||
"match": true,
|
||||
"pub_match": true
|
||||
},
|
||||
{
|
||||
"name": "bad-rows",
|
||||
"used": [
|
||||
"garbage",
|
||||
"2026-10-10T11:00:00+00:00"
|
||||
],
|
||||
"want": 0.0,
|
||||
"rust": 0,
|
||||
"pub": 0,
|
||||
"match": true,
|
||||
"pub_match": true
|
||||
},
|
||||
{
|
||||
"name": "future",
|
||||
"used": [
|
||||
"2030-01-01T00:00:00+00:00"
|
||||
],
|
||||
"want": 1.1512925464970227,
|
||||
"rust": 1.1512925464970227,
|
||||
"pub": 1.1512925464970227,
|
||||
"match": true,
|
||||
"pub_match": true
|
||||
},
|
||||
{
|
||||
"name": "Z-suffix",
|
||||
"used": [
|
||||
"2026-10-10T11:00:00Z"
|
||||
],
|
||||
"want": 0.0,
|
||||
"rust": 0,
|
||||
"pub": 0,
|
||||
"match": true,
|
||||
"pub_match": true
|
||||
},
|
||||
{
|
||||
"name": "non-string",
|
||||
"used": [
|
||||
123
|
||||
],
|
||||
"want_raises": "AttributeError",
|
||||
"pub": -2.0,
|
||||
"rust": -2
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env python3
|
||||
"""canary_structural_store.py — parity battery for the structural_store crate.
|
||||
|
||||
Asserts the Rust kernels against the frozen oracle (frozen_structural.json),
|
||||
generated from the live Python on facade-1 day. The canary never imports the
|
||||
Python oracles — parity stays provable after strangler exits.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
CRATE_DIR = Path(__file__).resolve().parent
|
||||
PASS, FAIL = 0, 0
|
||||
|
||||
|
||||
def test(name, cond, detail=""):
|
||||
global PASS, FAIL
|
||||
if cond:
|
||||
PASS += 1
|
||||
else:
|
||||
FAIL += 1
|
||||
print(f" ✗ {name} — {detail}")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
r = subprocess.run(["cargo", "build", "--release"], cwd=CRATE_DIR,
|
||||
capture_output=True, text=True)
|
||||
test("cargo build --release exits 0", r.returncode == 0, r.stderr[-300:])
|
||||
if r.returncode != 0:
|
||||
print(f"\nRESULTS: {PASS} pass, {FAIL} fail")
|
||||
return 1
|
||||
sys.path.insert(0, str(CRATE_DIR.parents[2] / "src"))
|
||||
sys.path.insert(0, str(CRATE_DIR))
|
||||
from rune import ss_loader # noqa: E402
|
||||
frozen = json.loads((CRATE_DIR / "frozen_structural.json").read_text())
|
||||
for state, want in frozen["ranks"].items():
|
||||
test(f"rank {state}={want}", ss_loader.maturity_rank(state) == want)
|
||||
for row in frozen["rows"]:
|
||||
op = row["op"]
|
||||
if op == "promote":
|
||||
d = copy.deepcopy(row["doc"])
|
||||
got = ss_loader.promote(d, row["id"], row["state"], row["ev"],
|
||||
"2026-10-10T00:00:00Z")
|
||||
ge = [e for e in got["entities"] if e["id"] == row["id"]][0]
|
||||
we = row["want_entity"]
|
||||
test(f"promote {row['id']}->{row['state']}",
|
||||
ge["maturity"] == we["maturity"]
|
||||
and sorted(ge["evidence_refs"]) == sorted(we["evidence_refs"]))
|
||||
elif op == "demote":
|
||||
d = copy.deepcopy(row["doc"])
|
||||
got = ss_loader.promote(d, row["id"], row["state"], row["ev"],
|
||||
"2026-10-10T00:00:00Z")
|
||||
ge = [e for e in got["entities"] if e["id"] == row["id"]][0]
|
||||
test("demotion rejected, recorded",
|
||||
ge["maturity"] == row["want_entity"]["maturity"]
|
||||
and any(o["kind"] == "maturity_demotion_rejected"
|
||||
for o in got["observations"]))
|
||||
elif op in ("no-ev", "bad-state"):
|
||||
d = {"entities": [{"id": "m:a", "maturity": "DECLARED",
|
||||
"evidence_refs": []}],
|
||||
"relationships": [], "observations": []}
|
||||
try:
|
||||
if op == "no-ev":
|
||||
ss_loader.promote(d, "m:a", "PRESENT", "",
|
||||
"2026-10-10T00:00:00Z")
|
||||
else:
|
||||
ss_loader.promote(d, "m:a", "BOGUS", "ev",
|
||||
"2026-10-10T00:00:00Z")
|
||||
test(f"error case {op} raises", False, "no error raised")
|
||||
except RuntimeError:
|
||||
test(f"error case {op} raises", True)
|
||||
elif op == "supersede":
|
||||
d = copy.deepcopy(row["doc"])
|
||||
got = ss_loader.supersede(d, "m:b", "m:a", "ev-s",
|
||||
"2026-10-10T00:00:00Z")
|
||||
go = [e for e in got["entities"] if e["id"] == "m:a"][0]
|
||||
test("supersede marks old", go.get("status") == "SUPERSEDED"
|
||||
and go.get("superseded_by") == "m:b")
|
||||
elif op == "resolve":
|
||||
test(f"resolve {row['entity']}",
|
||||
ss_loader.resolve_status(row["entity"]) == row["want"])
|
||||
print(f"\nRESULTS: {PASS} pass, {FAIL} fail")
|
||||
return 1 if FAIL else 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,182 @@
|
||||
{
|
||||
"_doc": "FROZEN ORACLE (structural_store facade-1).",
|
||||
"ranks": {
|
||||
"DECLARED": 0,
|
||||
"PRESENT": 1,
|
||||
"WIRED": 2,
|
||||
"REACHABLE": 3,
|
||||
"EXERCISED": 4,
|
||||
"LIVE_PROVEN": 5
|
||||
},
|
||||
"rows": [
|
||||
{
|
||||
"op": "promote",
|
||||
"doc": {
|
||||
"entities": [
|
||||
{
|
||||
"id": "m:a",
|
||||
"kind": "module",
|
||||
"maturity": "DECLARED",
|
||||
"evidence_refs": []
|
||||
},
|
||||
{
|
||||
"id": "m:b",
|
||||
"kind": "module",
|
||||
"maturity": "PRESENT",
|
||||
"evidence_refs": [
|
||||
"ev-0"
|
||||
]
|
||||
}
|
||||
],
|
||||
"relationships": [],
|
||||
"observations": []
|
||||
},
|
||||
"id": "m:a",
|
||||
"state": "PRESENT",
|
||||
"ev": "ev-1",
|
||||
"want_entity": {
|
||||
"id": "m:a",
|
||||
"kind": "module",
|
||||
"maturity": "PRESENT",
|
||||
"evidence_refs": [
|
||||
"ev-1"
|
||||
],
|
||||
"observed_at": "2026-10-10T17:53:36Z"
|
||||
},
|
||||
"want_obs": []
|
||||
},
|
||||
{
|
||||
"op": "demote",
|
||||
"doc": {
|
||||
"entities": [
|
||||
{
|
||||
"id": "m:a",
|
||||
"kind": "module",
|
||||
"maturity": "DECLARED",
|
||||
"evidence_refs": []
|
||||
},
|
||||
{
|
||||
"id": "m:b",
|
||||
"kind": "module",
|
||||
"maturity": "PRESENT",
|
||||
"evidence_refs": [
|
||||
"ev-0"
|
||||
]
|
||||
}
|
||||
],
|
||||
"relationships": [],
|
||||
"observations": []
|
||||
},
|
||||
"id": "m:b",
|
||||
"state": "DECLARED",
|
||||
"ev": "ev-2",
|
||||
"want_entity": {
|
||||
"id": "m:b",
|
||||
"kind": "module",
|
||||
"maturity": "PRESENT",
|
||||
"evidence_refs": [
|
||||
"ev-0"
|
||||
]
|
||||
},
|
||||
"want_obs": [
|
||||
{
|
||||
"kind": "maturity_demotion_rejected",
|
||||
"entity": "m:b",
|
||||
"requested": "DECLARED",
|
||||
"current": "PRESENT",
|
||||
"observed_at": "2026-10-10T17:53:36Z"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"op": "no-ev",
|
||||
"raises": true,
|
||||
"msg": "promotion of m:a to PRESENT requires evidence"
|
||||
},
|
||||
{
|
||||
"op": "bad-state",
|
||||
"raises": true,
|
||||
"msg": "unknown maturity state: BOGUS"
|
||||
},
|
||||
{
|
||||
"op": "supersede",
|
||||
"doc": {
|
||||
"entities": [
|
||||
{
|
||||
"id": "m:a",
|
||||
"kind": "module",
|
||||
"maturity": "DECLARED",
|
||||
"evidence_refs": []
|
||||
},
|
||||
{
|
||||
"id": "m:b",
|
||||
"kind": "module",
|
||||
"maturity": "PRESENT",
|
||||
"evidence_refs": [
|
||||
"ev-0"
|
||||
]
|
||||
}
|
||||
],
|
||||
"relationships": [],
|
||||
"observations": []
|
||||
},
|
||||
"want_old": {
|
||||
"id": "m:a",
|
||||
"kind": "module",
|
||||
"maturity": "DECLARED",
|
||||
"evidence_refs": [],
|
||||
"superseded_by": "m:b",
|
||||
"status": "SUPERSEDED"
|
||||
},
|
||||
"want_rels": [
|
||||
{
|
||||
"type": "supersedes",
|
||||
"from": "m:b",
|
||||
"to": "m:a",
|
||||
"evidence_refs": [
|
||||
"ev-s"
|
||||
],
|
||||
"observed_at": "2026-10-10T17:53:36Z"
|
||||
}
|
||||
],
|
||||
"want_obs": [
|
||||
{
|
||||
"kind": "superseded",
|
||||
"old": "m:a",
|
||||
"new": "m:b",
|
||||
"evidence": "ev-s",
|
||||
"observed_at": "2026-10-10T17:53:36Z"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"op": "resolve",
|
||||
"entity": {
|
||||
"status": "SUPERSEDED"
|
||||
},
|
||||
"want": "SUPERSEDED"
|
||||
},
|
||||
{
|
||||
"op": "resolve",
|
||||
"entity": {
|
||||
"maturity": "LIVE_PROVEN",
|
||||
"evidence_refs": [
|
||||
"e"
|
||||
]
|
||||
},
|
||||
"want": "CURRENT"
|
||||
},
|
||||
{
|
||||
"op": "resolve",
|
||||
"entity": {
|
||||
"maturity": "PRESENT"
|
||||
},
|
||||
"want": "CONFLICTING"
|
||||
},
|
||||
{
|
||||
"op": "resolve",
|
||||
"entity": {},
|
||||
"want": "UNKNOWN"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -69,6 +69,113 @@ impl Default for StoreDoc {
|
||||
}
|
||||
}
|
||||
|
||||
// ── FFI surface (facade-1 burn-down, 2026-10-10) ─────────────────────────────
|
||||
// Doc-envelope law: one JSON arg in, {"ok","value"|"err"} out. now arrives
|
||||
// as an INPUT (no-clock law) — the caller passes the wall clock.
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::os::raw::c_char;
|
||||
|
||||
fn read_arg(ptr: *const c_char) -> Result<String, String> {
|
||||
if ptr.is_null() {
|
||||
return Err("null argument pointer".to_string());
|
||||
}
|
||||
unsafe { CStr::from_ptr(ptr) }
|
||||
.to_str()
|
||||
.map(|s| s.to_string())
|
||||
.map_err(|e| format!("argument is not valid UTF-8: {}", e))
|
||||
}
|
||||
|
||||
fn envelope(value: Result<serde_json::Value, String>) -> *mut c_char {
|
||||
let body = match value {
|
||||
Ok(v) => serde_json::json!({"ok": true, "value": v}),
|
||||
Err(e) => serde_json::json!({"ok": false, "err": e}),
|
||||
};
|
||||
CString::new(body.to_string())
|
||||
.map(|c| c.into_raw())
|
||||
.unwrap_or(std::ptr::null_mut())
|
||||
}
|
||||
|
||||
fn parse_arg(text: &str) -> Result<serde_json::Value, String> {
|
||||
serde_json::from_str(text).map_err(|e| format!("argument JSON parse failed: {}", e))
|
||||
}
|
||||
|
||||
fn get_str<'a>(v: &'a serde_json::Value, key: &str) -> Option<&'a str> {
|
||||
v.get(key).and_then(|x| x.as_str())
|
||||
}
|
||||
|
||||
/// ss_maturity_rank({"state": "..."}) -> int (spine ladder)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ss_maturity_rank(arg: *const c_char) -> *mut c_char {
|
||||
let result = read_arg(arg)
|
||||
.and_then(|t| parse_arg(&t))
|
||||
.and_then(|a| {
|
||||
let state = get_str(&a, "state").ok_or("arg.state required")?;
|
||||
Ok(serde_json::json!(maturity_rank(state)))
|
||||
});
|
||||
envelope(result)
|
||||
}
|
||||
|
||||
/// ss_promote({"doc": {...}, "id": "...", "state": "...", "evidence_ref": "...", "now": iso}) -> updated doc
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ss_promote(arg: *const c_char) -> *mut c_char {
|
||||
let result = read_arg(arg)
|
||||
.and_then(|t| parse_arg(&t))
|
||||
.and_then(|a| {
|
||||
let mut doc = a.get("doc").cloned().ok_or("arg.doc required")?;
|
||||
let id = get_str(&a, "id").ok_or("arg.id required")?;
|
||||
let state = get_str(&a, "state").ok_or("arg.state required")?;
|
||||
let evidence = get_str(&a, "evidence_ref").ok_or("arg.evidence_ref required")?;
|
||||
let now = get_str(&a, "now").ok_or("arg.now required")?;
|
||||
match promote(&mut doc, id, state, evidence, now) {
|
||||
Ok(_) => Ok(doc),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
});
|
||||
envelope(result)
|
||||
}
|
||||
|
||||
/// ss_supersede({"doc": {...}, "new_id": "...", "old_id": "...", "evidence_ref": "...", "now": iso}) -> updated doc
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ss_supersede(arg: *const c_char) -> *mut c_char {
|
||||
let result = read_arg(arg)
|
||||
.and_then(|t| parse_arg(&t))
|
||||
.and_then(|a| {
|
||||
let mut doc = a.get("doc").cloned().ok_or("arg.doc required")?;
|
||||
let new_id = get_str(&a, "new_id").ok_or("arg.new_id required")?;
|
||||
let old_id = get_str(&a, "old_id").ok_or("arg.old_id required")?;
|
||||
let evidence = get_str(&a, "evidence_ref").ok_or("arg.evidence_ref required")?;
|
||||
let now = get_str(&a, "now").ok_or("arg.now required")?;
|
||||
match supersede(&mut doc, new_id, old_id, evidence, now) {
|
||||
Ok(()) => Ok(doc),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
});
|
||||
envelope(result)
|
||||
}
|
||||
|
||||
/// ss_resolve_status({"entity": {...}}) -> string
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ss_resolve_status(arg: *const c_char) -> *mut c_char {
|
||||
let result = read_arg(arg)
|
||||
.and_then(|t| parse_arg(&t))
|
||||
.and_then(|a| {
|
||||
let e = a.get("entity").cloned().ok_or("arg.entity required")?;
|
||||
Ok(serde_json::json!(resolve_status(&e)))
|
||||
});
|
||||
envelope(result)
|
||||
}
|
||||
|
||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||
// pinned: #[no_mangle] extern "C" — the Survivor loader ABI requires this exact safe-fn signature
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ss_free_string(ptr: *mut c_char) {
|
||||
if !ptr.is_null() {
|
||||
unsafe {
|
||||
let _ = CString::from_raw(ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -92,17 +199,29 @@ mod tests {
|
||||
// ── #2479 RUST batch 17: the state-machine kernels, oracle-parity port ─────
|
||||
|
||||
/// Maturity rank (Python MATURITY_RANK: DECLARED=1, PRESENT=2, VERIFIED=3, LIVE_PROVEN=4).
|
||||
/// Maturity rank — the SPINE ladder (structural_store.MATURITY_ORDER):
|
||||
/// DECLARED=0, PRESENT=1, WIRED=2, REACHABLE=3, EXERCISED=4, LIVE_PROVEN=5.
|
||||
/// Unknown states rank 0 (Python .get default); unknown REQUESTED states are
|
||||
/// rejected by the caller (Python raises ValueError — the FFI returns Err).
|
||||
/// (Previous port used a stale UNRUN/VERIFIED ladder — corrected 2026-10-10
|
||||
/// against the live oracle.)
|
||||
pub fn maturity_rank(state: &str) -> u32 {
|
||||
match state {
|
||||
"UNRUN" => 0,
|
||||
"DECLARED" => 1,
|
||||
"PRESENT" => 2,
|
||||
"VERIFIED" => 3,
|
||||
"LIVE_PROVEN" => 4,
|
||||
"DECLARED" => 0,
|
||||
"PRESENT" => 1,
|
||||
"WIRED" => 2,
|
||||
"REACHABLE" => 3,
|
||||
"EXERCISED" => 4,
|
||||
"LIVE_PROVEN" => 5,
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// True iff the state is on the spine ladder (requestable).
|
||||
pub fn is_known_maturity(state: &str) -> bool {
|
||||
matches!(state, "DECLARED" | "PRESENT" | "WIRED" | "REACHABLE" | "EXERCISED" | "LIVE_PROVEN")
|
||||
}
|
||||
|
||||
/// Evidence-gated promotion. Demotion is never silent: recorded, not applied.
|
||||
/// Returns Ok(Some(updated maturity)) / Ok(demotion-rejected marker) / Err.
|
||||
pub fn promote(
|
||||
@@ -110,8 +229,9 @@ pub fn promote(
|
||||
id: &str,
|
||||
state: &str,
|
||||
evidence_ref: &str,
|
||||
now_iso: &str,
|
||||
) -> Result<Option<String>, String> {
|
||||
if maturity_rank(state) == 0 && state != "UNRUN" {
|
||||
if !is_known_maturity(state) {
|
||||
return Err(format!("unknown maturity state: {}", state));
|
||||
}
|
||||
if evidence_ref.is_empty() {
|
||||
@@ -139,7 +259,7 @@ pub fn promote(
|
||||
"entity": id,
|
||||
"requested": state,
|
||||
"current": current,
|
||||
"observed_at": now_iso(),
|
||||
"observed_at": now_iso,
|
||||
}));
|
||||
}
|
||||
return Ok(Some(current));
|
||||
@@ -160,7 +280,7 @@ pub fn promote(
|
||||
refs.sort();
|
||||
refs.dedup();
|
||||
e.insert("evidence_refs".into(), serde_json::json!(refs));
|
||||
e.insert("observed_at".into(), serde_json::json!(now_iso()));
|
||||
e.insert("observed_at".into(), serde_json::json!(now_iso));
|
||||
}
|
||||
Ok(Some(state.to_string()))
|
||||
}
|
||||
@@ -228,6 +348,7 @@ pub fn supersede(
|
||||
new_id: &str,
|
||||
old_id: &str,
|
||||
evidence_ref: &str,
|
||||
now_iso: &str,
|
||||
) -> Result<(), String> {
|
||||
if evidence_ref.is_empty() {
|
||||
return Err("supersession requires evidence".into());
|
||||
@@ -251,7 +372,7 @@ pub fn supersede(
|
||||
if let Some(obs) = doc.get_mut("observations").and_then(|o| o.as_array_mut()) {
|
||||
obs.push(serde_json::json!({
|
||||
"kind": "superseded", "old": old_id, "new": new_id,
|
||||
"evidence": evidence_ref, "observed_at": now_iso(),
|
||||
"evidence": evidence_ref, "observed_at": now_iso,
|
||||
}));
|
||||
}
|
||||
Ok(())
|
||||
@@ -291,10 +412,10 @@ mod branch_battery {
|
||||
fn promote_up_and_demotion_rejection() {
|
||||
let mut d = doc();
|
||||
add_ent(&mut d, "module:x", "DECLARED");
|
||||
let e = promote(&mut d, "module:x", "PRESENT", "ev-1").expect("promote ok");
|
||||
let e = promote(&mut d, "module:x", "PRESENT", "ev-1", "2026-10-10T00:00:00Z").expect("promote ok");
|
||||
assert_eq!(e.as_deref(), Some("PRESENT"));
|
||||
// demotion rejected + observed
|
||||
let e2 = promote(&mut d, "module:x", "DECLARED", "ev-2").expect("demotion handled");
|
||||
let e2 = promote(&mut d, "module:x", "DECLARED", "ev-2", "2026-10-10T00:00:00Z").expect("demotion handled");
|
||||
assert_eq!(e2.as_deref(), Some("PRESENT")); // unchanged
|
||||
let rejected = d["observations"]
|
||||
.as_array()
|
||||
@@ -308,8 +429,8 @@ mod branch_battery {
|
||||
fn promote_requires_evidence_and_known_state() {
|
||||
let mut d = doc();
|
||||
add_ent(&mut d, "module:x", "DECLARED");
|
||||
assert!(promote(&mut d, "module:x", "VERIFIED", "").is_err());
|
||||
assert!(promote(&mut d, "module:x", "BOGUS", "ev").is_err());
|
||||
assert!(promote(&mut d, "module:x", "WIRED", "", "2026-10-10T00:00:00Z").is_err());
|
||||
assert!(promote(&mut d, "module:x", "BOGUS", "ev", "2026-10-10T00:00:00Z").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -317,12 +438,12 @@ mod branch_battery {
|
||||
let mut d = doc();
|
||||
add_ent(&mut d, "module:old", "DECLARED");
|
||||
add_ent(&mut d, "module:new", "DECLARED");
|
||||
supersede(&mut d, "module:new", "module:old", "ev-1").expect("supersede ok");
|
||||
supersede(&mut d, "module:new", "module:old", "ev-1", "2026-10-10T00:00:00Z").expect("supersede ok");
|
||||
let old = find_entity(&d, "module:old").unwrap();
|
||||
assert_eq!(old["status"], "SUPERSEDED");
|
||||
assert_eq!(old["superseded_by"], "module:new");
|
||||
assert!(supersede(&mut d, "module:a", "module:missing", "ev").is_err());
|
||||
assert!(supersede(&mut d, "module:new", "module:old", "").is_err());
|
||||
assert!(supersede(&mut d, "module:a", "module:missing", "ev", "2026-10-10T00:00:00Z").is_err());
|
||||
assert!(supersede(&mut d, "module:new", "module:old", "", "2026-10-10T00:00:00Z").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
"shard_manager",
|
||||
"structural_migration",
|
||||
"structural_model",
|
||||
"structural_store",
|
||||
"subconscious_pass",
|
||||
"system_registry",
|
||||
"task_gate",
|
||||
@@ -64,5 +63,19 @@
|
||||
"wait_guard",
|
||||
"wait_guard_corpus",
|
||||
"warm_neuron_store"
|
||||
],
|
||||
"burned": [
|
||||
{
|
||||
"module": "structural_store",
|
||||
"commit": "313f1c99",
|
||||
"evidence": "ladder corrected + FFI + delegation + canary 16/16 + 135 regression",
|
||||
"date": "2026-10-10"
|
||||
},
|
||||
{
|
||||
"module": "memory_selector/kernels",
|
||||
"commit": "cb4977fc",
|
||||
"evidence": "FFI ops + delegation + frozen 0 mismatches",
|
||||
"date": "2026-10-10"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -48,6 +48,30 @@
|
||||
"commit": "6a9eaddd",
|
||||
"evidence": "completion-gate + order divergences FIXED pre-exit + frozen 12 rows + 58 regression",
|
||||
"date": "2026-10-10"
|
||||
},
|
||||
{
|
||||
"module": "construction_decision/language_placement",
|
||||
"commit": "9d08c013",
|
||||
"evidence": "frozen 20 rows + canary 158/158 + 61 regression",
|
||||
"date": "2026-10-10"
|
||||
},
|
||||
{
|
||||
"module": "memory_store/retrieval-kernels",
|
||||
"commit": "3239080c",
|
||||
"evidence": "10 oracles deleted + frozen all-sections + canary 75/75 + shims 40/40",
|
||||
"date": "2026-10-10"
|
||||
},
|
||||
{
|
||||
"module": "capability_broker/score_card",
|
||||
"commit": "b953e021",
|
||||
"evidence": "frozen 19 rows exact-input keys + canary 24/24 + 40 shims",
|
||||
"date": "2026-10-10"
|
||||
},
|
||||
{
|
||||
"module": "warm_router/base_level",
|
||||
"commit": "da36073a",
|
||||
"evidence": "frozen 7 rows + 50 regression",
|
||||
"date": "2026-10-10"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"construction contract FIRST (absolute-scaffolding law)",
|
||||
"parity + improvement note (defect fixed, measured gain, or honest parity-only)"
|
||||
],
|
||||
"parity_means": "Audited 2026-10-10: LLM-first reactive orchestrator (GO by design); Go abstraction dir is the parity twin; cc kernel fallback via cc_loader. The Python IS the adapter \u2014 no exit candidacy, correctly placed.",
|
||||
"parity_means": "Audited 2026-10-10: LLM-first reactive orchestrator, correctly placed.",
|
||||
"status": "ported"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"oracle-first truth battery (Python truth generated FIRST)",
|
||||
"llvm-cov branch coverage + clippy 0"
|
||||
],
|
||||
"parity_means": "NOT parity: kernel exists but the Python module never delegates. Parity means the adapter delegates through the kernel (tier_manager pattern) with both paths pinned by tests.",
|
||||
"parity_means": "PORT-QUEUE (audited 2026-10-10): estimate_tokens duplicates token_counting (should delegate \u2014 dedupe); capsule assembly needs Rust port + FFI + canary. Rust has capture/new only.",
|
||||
"status": "facade"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"construction contract FIRST (absolute-scaffolding law)",
|
||||
"parity + improvement note (defect fixed, measured gain, or honest parity-only)"
|
||||
],
|
||||
"parity_means": "Not yet ported. Parity means: kernel in its measured side, oracle-first truth battery, HARD CI gate, delegation wired, then retirement earned.",
|
||||
"status": "not_started"
|
||||
"parity_means": "PARTIAL (audited 2026-10-10): ResumePoint/CanResume + worktree + lifecycle in Go with truth batteries; 12 start_*/complete_* wrappers + state IO stay Python by design.",
|
||||
"status": "ported"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"oracle-first truth battery (Python truth generated FIRST)",
|
||||
"llvm-cov branch coverage + clippy 0"
|
||||
],
|
||||
"parity_means": "Parity claimed via oracle-first truth battery + HARD CI gate; deletion earned under the retirement law (parity + CI green + deployed one cycle).",
|
||||
"parity_means": "PARITY DEBT (audited 2026-10-10): Rust select_for_job is a keyword heuristic, NOT parity with the score_card-driven Python (floor/escape/budget/shell-rule). score_card exited (b953e021); selection needs full port + FFI + canary.",
|
||||
"status": "ported"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"oracle-first truth battery (Python truth generated FIRST)",
|
||||
"llvm-cov branch coverage + clippy 0"
|
||||
],
|
||||
"parity_means": "NOT parity: kernel exists but the Python module never delegates. Parity means the adapter delegates through the kernel (tier_manager pattern) with both paths pinned by tests.",
|
||||
"parity_means": "PARITY DEBT (audited 2026-10-10): Rust has register + version helpers; Python is a file-backed registry (define/move/supersede/retire/active). Needs registry kernels + FFI + canary.",
|
||||
"status": "facade"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"oracle-first truth battery (Python truth generated FIRST)",
|
||||
"llvm-cov branch coverage + clippy 0"
|
||||
],
|
||||
"parity_means": "Parity claimed via oracle-first truth battery + HARD CI gate; deletion earned under the retirement law (parity + CI green + deployed one cycle).",
|
||||
"parity_means": "Audited 2026-10-10: verify path proven 17/17; reframe+scan are PORT CANDIDATES for the Rust leg (no counterparts).",
|
||||
"status": "ported"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"oracle-first truth battery (Python truth generated FIRST)",
|
||||
"llvm-cov branch coverage + clippy 0"
|
||||
],
|
||||
"parity_means": "NOT parity: kernel exists but the Python module never delegates. Parity means the adapter delegates through the kernel (tier_manager pattern) with both paths pinned by tests.",
|
||||
"parity_means": "PORT-QUEUE (audited 2026-10-10): mode-dispatch branches are portable pure decision tables (mode/evidence/authority -> record); store bootstrap stays Python. Rust has requirements() only.",
|
||||
"status": "facade"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"oracle-first truth battery (Python truth generated FIRST)",
|
||||
"llvm-cov branch coverage + clippy 0"
|
||||
],
|
||||
"parity_means": "Parity claimed via oracle-first truth battery + HARD CI gate; deletion earned under the retirement law (parity + CI green + deployed one cycle).",
|
||||
"parity_means": "Strangler exit 2026-10-10 (9d08c013): _py_language_placement deleted.",
|
||||
"status": "ported"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"oracle-first truth battery (Python truth generated FIRST)",
|
||||
"llvm-cov branch coverage + clippy 0"
|
||||
],
|
||||
"parity_means": "NOT parity: kernel exists but the Python module never delegates. Parity means the adapter delegates through the kernel (tier_manager pattern) with both paths pinned by tests.",
|
||||
"status": "facade"
|
||||
"parity_means": "HYBRID BY DESIGN (audited 2026-10-10): Python reactive intake/store/guards + Rust 16-edge phase machine + envelope (ci_validate/ci_transition FFI) + cgo membrane. Both sides authoritative at their boundary.",
|
||||
"status": "ported"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"oracle-first truth battery (Python truth generated FIRST)",
|
||||
"llvm-cov branch coverage + clippy 0"
|
||||
],
|
||||
"parity_means": "NOT parity: kernel exists but the Python module never delegates. Parity means the adapter delegates through the kernel (tier_manager pattern) with both paths pinned by tests.",
|
||||
"parity_means": "PARITY DEBT (audited 2026-10-10): Rust classify_mode is a heuristic with a different signature; Python is a 7-arg evidence-laden classifier. Needs full oracle port + FFI + canary.",
|
||||
"status": "facade"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"oracle-first truth battery (Python truth generated FIRST)",
|
||||
"llvm-cov branch coverage + clippy 0"
|
||||
],
|
||||
"parity_means": "NOT parity: kernel exists but the Python module never delegates. Parity means the adapter delegates through the kernel (tier_manager pattern) with both paths pinned by tests.",
|
||||
"parity_means": "PARITY DEBT (audited 2026-10-10): Rust check_applicability is a stub (override-check only) vs the Python signal-group verdict machine; path/entity matchers exist. Needs full signal evaluation + FFI + loader + canary. Wiring+rewrite job.",
|
||||
"status": "facade"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"oracle-first truth battery (Python truth generated FIRST)",
|
||||
"llvm-cov branch coverage + clippy 0"
|
||||
],
|
||||
"parity_means": "NOT parity: kernel exists but the Python module never delegates. Parity means the adapter delegates through the kernel (tier_manager pattern) with both paths pinned by tests.",
|
||||
"parity_means": "PARITY DEBT (audited 2026-10-10): Rust has 2 placeholder stubs (web-api/cli-tool, assert-true test); Python has 4 real patterns rev 1. Needs real content + FFI + canary.",
|
||||
"status": "facade"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"oracle-first truth battery (Python truth generated FIRST)",
|
||||
"llvm-cov branch coverage + clippy 0"
|
||||
],
|
||||
"parity_means": "NOT parity: kernel exists but the Python module never delegates. Parity means the adapter delegates through the kernel (tier_manager pattern) with both paths pinned by tests.",
|
||||
"parity_means": "PARITY DEBT (audited 2026-10-10): Rust returns 3 passthrough fields; Python builds full projection (checkpoints/evidence/blocks/mini-doc/validate). Needs full port + FFI + canary.",
|
||||
"status": "facade"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"construction contract FIRST (absolute-scaffolding law)",
|
||||
"parity + improvement note (defect fixed, measured gain, or honest parity-only)"
|
||||
],
|
||||
"parity_means": "Not yet ported. Parity means: kernel in its measured side, oracle-first truth battery, HARD CI gate, delegation wired, then retirement earned.",
|
||||
"status": "not_started"
|
||||
"parity_means": "PARTIAL (audited 2026-10-10): parser (25 cases) + lifecycle in Go with HARD gates; engine runtime (thread loop, execution, singletons, logging) stays by design.",
|
||||
"status": "ported"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"oracle-first truth battery (Python truth generated FIRST)",
|
||||
"llvm-cov branch coverage + clippy 0"
|
||||
],
|
||||
"parity_means": "Strangler exit 2026-10-10 (fd718150): oracles deleted, Rust authoritative, adversarial edges fixed + frozen.",
|
||||
"parity_means": "Strangler exit 2026-10-10 (fd718150 oracles + verdict): compute_value/promotion kernels in Rust; promote_entry/fama/velocity/direction/pre_commit are SQLite-backed orchestration \u2014 stay Python by design.",
|
||||
"status": "retired"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"construction contract FIRST (absolute-scaffolding law)",
|
||||
"parity + improvement note (defect fixed, measured gain, or honest parity-only)"
|
||||
],
|
||||
"parity_means": "Not yet ported. Parity means: kernel in its measured side, oracle-first truth battery, HARD CI gate, delegation wired, then retirement earned.",
|
||||
"status": "not_started"
|
||||
"parity_means": "PORTED 2026-10-10 (9b30dd58): classify/redact/tier/marker/signature in Go with 32-row oracle-first truth + HARD CI gate; spool replay + forge filing stay Python runtime.",
|
||||
"status": "ported"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"oracle-first truth battery (Python truth generated FIRST)",
|
||||
"llvm-cov branch coverage + clippy 0"
|
||||
],
|
||||
"parity_means": "NOT parity: kernel exists but the Python module never delegates. Parity means the adapter delegates through the kernel (tier_manager pattern) with both paths pinned by tests.",
|
||||
"status": "facade"
|
||||
"parity_means": "PARTIAL (audited 2026-10-10): strengthToConf in Go with rounding improvement + replay gate; graph SQLite IO stays Python; edge/query kernels port-queue.",
|
||||
"status": "ported"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"oracle-first truth battery (Python truth generated FIRST)",
|
||||
"llvm-cov branch coverage + clippy 0"
|
||||
],
|
||||
"parity_means": "NOT parity: kernel exists but the Python module never delegates. Parity means the adapter delegates through the kernel (tier_manager pattern) with both paths pinned by tests.",
|
||||
"status": "facade"
|
||||
"parity_means": "Audited 2026-10-10: trace file IO stays Python reactive; price_for parity (None everywhere) proven; price map is a data seam for provider registry #29.",
|
||||
"status": "ported"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"oracle-first truth battery (Python truth generated FIRST)",
|
||||
"llvm-cov branch coverage + clippy 0"
|
||||
],
|
||||
"parity_means": "NOT parity: kernel exists but the Python module never delegates. Parity means the adapter delegates through the kernel (tier_manager pattern) with both paths pinned by tests.",
|
||||
"parity_means": "PARITY DEBT (audited 2026-10-10): Rust has compose-verify only; Python is region/component/amend/observe/check/drift lifecycle. Needs check/drift kernels + FFI + canary.",
|
||||
"status": "facade"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"construction contract FIRST (absolute-scaffolding law)",
|
||||
"parity + improvement note (defect fixed, measured gain, or honest parity-only)"
|
||||
],
|
||||
"parity_means": "Not yet ported. Parity means: kernel in its measured side, oracle-first truth battery, HARD CI gate, delegation wired, then retirement earned.",
|
||||
"status": "not_started"
|
||||
"parity_means": "PARTIAL (audited 2026-10-10): Go ToolRuntime/Chat/executeTool/Run/CircuitBreaker covers the loop; Python ChatTransport/Ollama transport + context_length cache stay. Runtime-loop parity needs a truth battery (next batch).",
|
||||
"status": "ported"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"oracle-first truth battery (Python truth generated FIRST)",
|
||||
"llvm-cov branch coverage + clippy 0"
|
||||
],
|
||||
"parity_means": "NOT parity: kernel exists but the Python module never delegates. Parity means the adapter delegates through the kernel (tier_manager pattern) with both paths pinned by tests.",
|
||||
"status": "facade"
|
||||
"parity_means": "Wired 2026-10-10 (cb4977fc): score_of + lex_overlap FFI + delegation; orchestration stays Python.",
|
||||
"status": "ported"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"construction contract FIRST (absolute-scaffolding law)",
|
||||
"parity + improvement note (defect fixed, measured gain, or honest parity-only)"
|
||||
],
|
||||
"parity_means": "Not yet ported. Parity means: kernel in its measured side, oracle-first truth battery, HARD CI gate, delegation wired, then retirement earned.",
|
||||
"status": "not_started"
|
||||
"parity_means": "Strangler exit 2026-10-10 (3239080c): 10 retrieval oracles deleted; recall/SQLite/cache orchestration stays Python reactive by design.",
|
||||
"status": "ported"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"construction contract FIRST (absolute-scaffolding law)",
|
||||
"parity + improvement note (defect fixed, measured gain, or honest parity-only)"
|
||||
],
|
||||
"parity_means": "Not yet ported. Parity means: kernel in its measured side, oracle-first truth battery, HARD CI gate, delegation wired, then retirement earned.",
|
||||
"status": "not_started"
|
||||
"parity_means": "PARTIAL (audited 2026-10-10): lifecycle in Go with tests; status/report/runtime stay Python.",
|
||||
"status": "ported"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"oracle-first truth battery (Python truth generated FIRST)",
|
||||
"llvm-cov branch coverage + clippy 0"
|
||||
],
|
||||
"parity_means": "NOT parity: kernel exists but the Python module never delegates. Parity means the adapter delegates through the kernel (tier_manager pattern) with both paths pinned by tests.",
|
||||
"status": "facade"
|
||||
"parity_means": "PORTED 2026-10-10 (e06498d3): should_escalate + get_next_tier kernels + runnable replay (was a dead gate) + HARD CI.",
|
||||
"status": "ported"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"oracle-first truth battery (Python truth generated FIRST)",
|
||||
"llvm-cov branch coverage + clippy 0"
|
||||
],
|
||||
"parity_means": "NOT parity: kernel exists but the Python module never delegates. Parity means the adapter delegates through the kernel (tier_manager pattern) with both paths pinned by tests.",
|
||||
"parity_means": "PARITY DEBT (audited 2026-10-10): Rust has register/get with 4 fields; Python has repo_identity/health/generations/resolve_cwd/migration + persistence. Needs full entry shape + kernels + FFI + canary.",
|
||||
"status": "facade"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"construction contract FIRST (absolute-scaffolding law)",
|
||||
"parity + improvement note (defect fixed, measured gain, or honest parity-only)"
|
||||
],
|
||||
"parity_means": "Not yet ported. Parity means: kernel in its measured side, oracle-first truth battery, HARD CI gate, delegation wired, then retirement earned.",
|
||||
"status": "not_started"
|
||||
"parity_means": "PARTIAL (audited 2026-10-10): tool-format adapters in Go with truth battery; execution/network/registry-IO stay by design.",
|
||||
"status": "ported"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"construction contract FIRST (absolute-scaffolding law)",
|
||||
"parity + improvement note (defect fixed, measured gain, or honest parity-only)"
|
||||
],
|
||||
"parity_means": "Not yet ported. Parity means: kernel in its measured side, oracle-first truth battery, HARD CI gate, delegation wired, then retirement earned.",
|
||||
"status": "not_started"
|
||||
"parity_means": "PARTIAL (audited 2026-10-10): transcript kernels in Go with tests; consolidate/SQLite orchestration stays Python.",
|
||||
"status": "ported"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"oracle-first truth battery (Python truth generated FIRST)",
|
||||
"llvm-cov branch coverage + clippy 0"
|
||||
],
|
||||
"parity_means": "Parity claimed via oracle-first truth battery + HARD CI gate; deletion earned under the retirement law (parity + CI green + deployed one cycle).",
|
||||
"parity_means": "Audited 2026-10-10: FFI seam stays by design.",
|
||||
"status": "ported"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"oracle-first truth battery (Python truth generated FIRST)",
|
||||
"llvm-cov branch coverage + clippy 0"
|
||||
],
|
||||
"parity_means": "NOT parity: kernel exists but the Python module never delegates. Parity means the adapter delegates through the kernel (tier_manager pattern) with both paths pinned by tests.",
|
||||
"status": "facade"
|
||||
"parity_means": "Facade burned 2026-10-10 (313f1c99): spine-ladder kernel + FFI + delegation; 16 importers route through it.",
|
||||
"status": "ported"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"oracle-first truth battery (Python truth generated FIRST)",
|
||||
"llvm-cov branch coverage + clippy 0"
|
||||
],
|
||||
"parity_means": "Strangler exit 2026-10-10 (532fe649): Python oracle deleted, Rust authoritative, frozen oracle + 26/26 canary.",
|
||||
"parity_means": "Strangler exit 2026-10-10 (532fe649 kernels + verdict): estimate/compress in Rust; class surface (cache persistence, persona, assembly, status) stays Python reactive by design.",
|
||||
"status": "retired"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"construction contract FIRST (absolute-scaffolding law)",
|
||||
"parity + improvement note (defect fixed, measured gain, or honest parity-only)"
|
||||
],
|
||||
"parity_means": "Not yet ported. Parity means: kernel in its measured side, oracle-first truth battery, HARD CI gate, delegation wired, then retirement earned.",
|
||||
"status": "not_started"
|
||||
"parity_means": "PARTIAL (2026-10-10): paths/fileops/ops/parse/auth/prompt/quality/undo/prepared-path in Go with truth batteries + fuzz; runtime orchestration (dispatch/execution/approval) stays by design.",
|
||||
"status": "ported"
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
"construction contract FIRST (absolute-scaffolding law)",
|
||||
"parity + improvement note (defect fixed, measured gain, or honest parity-only)"
|
||||
],
|
||||
"parity_means": "Not yet ported. Parity means: kernel in its measured side, oracle-first truth battery, HARD CI gate, delegation wired, then retirement earned.",
|
||||
"status": "not_started"
|
||||
"parity_means": "Strangler exit 2026-10-10 (da36073a): base_level oracle deleted; DB/router orchestration stays Python.",
|
||||
"status": "ported"
|
||||
}
|
||||
@@ -221,8 +221,8 @@ def test_warm_score_neuron_public_wrapper():
|
||||
def test_warm_base_level_math_and_gather(monkeypatch):
|
||||
from rune import warm_router
|
||||
|
||||
assert warm_router._py_base_level_from_uses([], NOW_ISO) == -2.0
|
||||
assert warm_router._py_base_level_from_uses(
|
||||
assert warm_router.base_level_from_uses([], NOW_ISO) == -2.0
|
||||
assert warm_router.base_level_from_uses(
|
||||
["2026-10-04T08:30:00+00:00"], NOW_ISO) > -2.0
|
||||
# non-string row: the outer contract degrades to -2.0
|
||||
assert warm_router.base_level_from_uses([None], NOW_ISO) == -2.0
|
||||
@@ -470,7 +470,7 @@ def test_mr_loader_score_and_fusion_through_cdylib():
|
||||
def test_memory_store_helpers_delegate_to_kernel():
|
||||
from rune import memory_store as ms
|
||||
|
||||
py = ms._py_map_reduce([{"id": i, "score": i} for i in range(1, 13)], 5)
|
||||
py = ms._map_reduce([{"id": i, "score": i} for i in range(1, 13)], 5)
|
||||
rs = ms._map_reduce([{"id": i, "score": i} for i in range(1, 13)], 5)
|
||||
assert [r["id"] for r in py] == [r["id"] for r in rs]
|
||||
assert ms._fts_query_conjunctive("black coffee") == '"black" "coffee"'
|
||||
@@ -486,7 +486,7 @@ def test_mr_loader_chunk_projection_and_memory_store_delegation():
|
||||
"room": "r", "source_path": "p", "page": 7},
|
||||
{"rowid": 3, "chunk_id": "c3", "text": "u — héllo 🎸",
|
||||
"wing": "w2", "room": "", "source_path": "", "page": None}]
|
||||
py = ms._py_project_chunk_rows(ranks, crows, 6)
|
||||
py = ms._project_chunk_rows(ranks, crows, 6)
|
||||
rs = mr_loader.project_chunk_rows([list(r) for r in ranks.items()], crows, 6)
|
||||
assert py == rs
|
||||
entries = [{"id": i, "relevance": i} for i in range(1, 15)]
|
||||
@@ -523,7 +523,7 @@ def test_mr_loader_recall_kernel_via_stats_seam(tmp_path):
|
||||
"topic": f"topic{i%2}", "entities": "[]", "source": "t",
|
||||
"status": "active", "memory_type": None,
|
||||
"confidence": 0.8, "temperature": 1.0} for i in range(1, 8)]
|
||||
assert (ms._py_score_recall_rows(fusion, rows, dense, [], 5, 0.42,
|
||||
assert (ms._score_recall_rows(fusion, rows, dense, [], 5, 0.42,
|
||||
"2026-10-04T12:00:00+00:00")
|
||||
== mr_loader.score_recall_rows(fusion, rows, dense, [], 5, 0.42,
|
||||
"2026-10-04T12:00:00+00:00",
|
||||
@@ -556,57 +556,36 @@ def test_mr_loader_delegation_publics_exercised(tmp_path):
|
||||
|
||||
|
||||
|
||||
def test_mr_loader_python_oracle_paths_exercised(monkeypatch):
|
||||
"""The _py_ oracle bodies count toward the changed-lines floor — the
|
||||
crate canary exercises the RUST path only; this battery drives the
|
||||
oracle path (fallback = load-bearing discipline)."""
|
||||
def test_mr_loader_kernel_required_post_exit(monkeypatch):
|
||||
"""Post-exit (memory_store oracles retired 2026-10-10): the _py_ stubs
|
||||
delegate to the kernel. With RUNE_RETRIEVAL_CORE=python the kernel is
|
||||
pinned off, so the stubs must RAISE (fail-loud) rather than recurse or
|
||||
silently score. Live (unpinned), delegation agrees with the kernel."""
|
||||
import pytest
|
||||
from rune import memory_store as ms
|
||||
|
||||
monkeypatch.setenv("RUNE_RETRIEVAL_CORE", "python")
|
||||
with pytest.raises(RuntimeError):
|
||||
ms._score_recall_rows({"ranks": [], "best_dense": 0, "mode": "x"}, [], [], [], 4, 0.42,
|
||||
"2026-10-04T12:00:00+00:00")
|
||||
with pytest.raises(RuntimeError):
|
||||
ms._rank_fusion([], [])
|
||||
with pytest.raises(RuntimeError):
|
||||
ms._map_reduce([], 5)
|
||||
|
||||
def oracle(mode="dense-only"):
|
||||
dense, bm25 = ([[9, 0.85]], []) if mode == "dense-only" else (
|
||||
([], [[9, -8.0]]) if mode == "lexical-only"
|
||||
else ([[9, 0.85]], [[9, -8.0]]))
|
||||
fusion = ms._py_rank_fusion(dense, bm25)
|
||||
rows = [{"id": 9, "text": "z", "importance": 0.5,
|
||||
"last_accessed": "2026-10-04T11:00:00+00:00",
|
||||
"topic": "t", "entities": "[]", "source": "s",
|
||||
"memory_type": None, "confidence": 0.9,
|
||||
"temperature": 1.0}]
|
||||
return (ms._score_recall_rows(fusion, rows, dense, bm25, 4, 0.42,
|
||||
"2026-10-04T12:00:00+00:00"),
|
||||
fusion, rows, dense, bm25)
|
||||
|
||||
s_d, fusion_d, rows_d, dense_d, _ = oracle("dense-only")
|
||||
assert s_d and s_d[0]["mode"] == "dense-only"
|
||||
s_l, _, _, _, _ = oracle("lexical-only")
|
||||
assert s_l and s_l[0]["relevance"] > 4.5 # lexical offset band ~4.69 with blends
|
||||
s_h, _, _, _, _ = oracle("hybrid")
|
||||
assert s_h
|
||||
# abstention paths
|
||||
rows_f = [{"id": 9, "text": "z", "importance": 0.5,
|
||||
"last_accessed": "2026-10-04T11:00:00+00:00", "topic": "t",
|
||||
"entities": "[]", "source": "s", "memory_type": None,
|
||||
"confidence": 0.9, "temperature": 1.0}]
|
||||
assert ms._py_score_recall_rows(ms._py_rank_fusion([], []), rows_f, [], [], 4, 0.42,
|
||||
"2026-10-04T12:00:00+00:00") == []
|
||||
# timestamp exception path (malformed)
|
||||
rows_bad = [dict(rows_f[0], last_accessed="not-a-date")]
|
||||
out_bad = ms._score_recall_rows(ms._py_rank_fusion([[9, 0.9]], []), rows_bad,
|
||||
[[9, 0.9]], [], 4, 0.42,
|
||||
"2026-10-04T12:00:00+00:00")
|
||||
assert out_bad[0]["relevance"] > 0
|
||||
# gap path: dense pair with big gap and mid band
|
||||
dense_gap = [[9, 0.72], [8, 0.60]]
|
||||
rows_g = rows_f + [dict(rows_f[0], id=8)]
|
||||
out_g = ms._score_recall_rows(ms._py_rank_fusion(dense_gap, []), rows_g,
|
||||
dense_gap, [], 4, 0.42,
|
||||
"2026-10-04T12:00:00+00:00")
|
||||
assert out_g[0]["id"] == 9
|
||||
# fusion with ties and the hybrid accumulation path
|
||||
assert ms._rank_fusion([[1, 0.5], [2, 0.5]], [[1, -5.0], [3, -6.0]])["ranks"]
|
||||
|
||||
monkeypatch.delenv("RUNE_RETRIEVAL_CORE", raising=False)
|
||||
from rune import mr_loader
|
||||
if not mr_loader.available():
|
||||
pytest.skip("memory_retrieval crate not built")
|
||||
fusion = ms._rank_fusion([[9, 0.85]], [])
|
||||
rows = [{"id": 9, "text": "z", "importance": 0.5,
|
||||
"last_accessed": "2026-10-04T11:00:00+00:00",
|
||||
"topic": "t", "entities": "[]", "source": "s",
|
||||
"memory_type": None, "confidence": 0.9,
|
||||
"temperature": 1.0}]
|
||||
out = ms._score_recall_rows(fusion, rows, [[9, 0.85]], [], 4, 0.42,
|
||||
"2026-10-04T12:00:00+00:00")
|
||||
assert out and out[0]["mode"] == "dense-only"
|
||||
|
||||
def test_mr_loader_chunk_sql_gather_through_seam(tmp_path, monkeypatch):
|
||||
"""chunk_recall's SQL gather through a real fixture db (covers 1634-1648)."""
|
||||
|
||||
@@ -88,9 +88,9 @@ class TestWashChangesRetrieval:
|
||||
def test_use_history_changes_ranking(self, tmp_path, monkeypatch):
|
||||
"""A controlled ranking demonstrably changes when use-history is
|
||||
applied (#27 acceptance: reproduced, deterministic)."""
|
||||
base = wr._py_base_level_from_uses(
|
||||
base = wr.base_level_from_uses(
|
||||
["2026-10-07T23:00:00+00:00"], "2026-10-08T00:00:00+00:00")
|
||||
boosted = wr._py_base_level_from_uses(
|
||||
boosted = wr.base_level_from_uses(
|
||||
["2026-10-07T12:00:00+00:00", "2026-10-07T18:00:00+00:00",
|
||||
"2026-10-07T23:00:00+00:00"], "2026-10-08T00:00:00+00:00")
|
||||
assert boosted > base # more history = higher activation
|
||||
|
||||
Reference in new issue
Block a user