Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b7c767b56 | ||
|
|
c36f2e70f2 | ||
|
|
299d2c9bb8 | ||
|
|
23c2e41077 | ||
|
|
3cf5e81707 | ||
|
|
9b30dd5885 | ||
|
|
22117c1f79 | ||
|
|
4b4ddbf6a3 | ||
|
|
32bdacddfb | ||
|
|
9db9277402 | ||
|
|
abc29365e3 | ||
|
|
da36073a0c | ||
|
|
3e705f13e5 |
No files matched your search
@@ -363,6 +363,12 @@ jobs:
|
||||
- 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.178.0**
|
||||
**Current release: v0.181.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.178.0"
|
||||
version = "0.181.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
|
||||
}
|
||||
@@ -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.178.0"
|
||||
__version__ = "0.181.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.178.0"' in rune_version,
|
||||
'__version__ = "0.181.0"' in rune_version,
|
||||
failures,
|
||||
)
|
||||
# #169 policy update: auto-bump on merge is sanctioned (Nick directive:
|
||||
|
||||
@@ -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.178.0
|
||||
Version: v0.181.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.178.0 | Textual TUI | {len(loaded)} native modules[/dim]",
|
||||
f"[dim]Rune v0.181.0 | Textual TUI | {len(loaded)} native modules[/dim]",
|
||||
)
|
||||
|
||||
# Auto-show night mode suggestion if evening/night hours
|
||||
|
||||
+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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -66,6 +66,12 @@
|
||||
"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": "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 @@
|
||||
"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 @@
|
||||
"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 @@
|
||||
"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 @@
|
||||
"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 (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
|
||||
|
||||
@@ -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