Port the 6 audit-missing fns name-preserving into src/go/core-server (make_server, log_message, _send_json, _send_ndjson, do_GET, do_POST; main via Main/os.Args surface): the full HTTP sidecar surface with byte-identical wire bodies (vendored pyjson PyDump: json.dumps ', '/': ' separators + ensure_ascii + PyDict insertion order), CPython json scanner error messages, int()/parse_qs/truthiness/or-laws, str[:200] codepoint truncation, and the AttributeError crash-parity class. Truth: 57-case shared-harness envelope (scripts/gen_core_server_truth.py under scripts/cs_freeze_seams — pinned uuid/time on module attrs, rig-bound probe seams exercising the REAL handler methods) verified byte-identical x5; go test 9/9 (verbatim TestFrozenTruthReplay + 8 quirk tests); CI replay binary 57/57; live HTTP parity 24/24 byte-identical (scripts/check_core_server_parity.py — bodies exact under pinned id/created, not modulo-volatile); canary_rune_serve 28/28; gofmt/vet/build clean; ruff clean; shims pytest zero-delta vs stashed base (9 fresh-worktree sibling-kernel failures pre-existing). Dichotomy audit core_server 6/12 PARTIAL -> 12/12 FULL (107/192).
165 lines
8.8 KiB
Python
165 lines
8.8 KiB
Python
#!/usr/bin/env python3
|
|
"""gen_core_server_truth.py — freeze core_server oracle truth (dichotomy
|
|
wave #2479 gap port, contract factory-gap-cs).
|
|
|
|
Runs under the cs freeze rig (PYTHONPATH=scripts/cs_freeze_seams:src) so
|
|
uuid/time are pinned on the oracle module and every case is
|
|
deterministic. Covers EVERY ported function and branch: the envelope
|
|
transforms (_envelope_error, models_view, chat_completion, chat_chunks)
|
|
directly, and the handler/server layer (log_message, _send_json,
|
|
_send_ndjson, do_GET, do_POST, make_server) through the rig-bound probe
|
|
seams that exercise the REAL oracle methods against a recording fake
|
|
handler. The Go battery (src/go/core-server/truth_test.go) and the CI
|
|
replay binary rebuild every row through the ported functions.
|
|
|
|
Usage:
|
|
PYTHONPATH=scripts/cs_freeze_seams:src python3 scripts/gen_core_server_truth.py
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "scripts"))
|
|
|
|
from freeze_truth import freeze, write_envelope # noqa: E402
|
|
|
|
FROZEN_NOW = "2026-10-14T08:00:00+00:00" # int epoch 1791964800 (rig FROZEN_EPOCH)
|
|
TRUTH = Path(__file__).resolve().parents[1] / "src" / "go" / "core-server" / "truth.json"
|
|
|
|
SPEC_MODELS = {"models": [{"name": "stub-a", "size_gb": 4.1}, {"size_gb": 2}, {}]}
|
|
SPEC_STATUS = {"status": {"identity": "rune", "role": "operator", "current_task": None,
|
|
"active_model": "stub-a", "tasks_pending": 0,
|
|
"tasks_completed": 3}}
|
|
SPEC_CHAT = {"send": {"task_id": "task-1", "status": "completed",
|
|
"model": "stub-model", "user_text": "Canned reply.",
|
|
"degraded": [], "iterations_used": 1}}
|
|
SPEC_WINDOW = {"window": [{"role": "user", "content": "m1"},
|
|
{"role": "assistant", "content": "m2"},
|
|
{"role": "user", "content": "m3"}]}
|
|
SPEC_FULL = {**SPEC_MODELS, **SPEC_STATUS, **SPEC_CHAT, **SPEC_WINDOW}
|
|
|
|
|
|
def post(path, body, spec, cl="auto"):
|
|
"""do_POST probe args; cl="auto" carries the exact byte length."""
|
|
cl_val = str(len(body.encode())) if cl == "auto" else cl
|
|
return (path, cl_val, body, spec)
|
|
|
|
|
|
CASES: list = [
|
|
# ── envelope transforms ────────────────────────────────────────────
|
|
("_envelope_error", ("not_found", "no route /v1/definitely-not-here")),
|
|
("_envelope_error", ("internal_error", "x" * 250)), # no truncation at the source
|
|
("_models_view_probe", (SPEC_MODELS,)), # missing-name → "" law, order preserved
|
|
("_models_view_probe", ({"models": []},)), # empty list
|
|
("chat_completion", ({"model": "stub-model", "user_text": "hello world",
|
|
"task_id": "t1"}, None)),
|
|
("chat_completion", ({"user_text": "x"}, "fallback-model")), # result model missing
|
|
("chat_completion", ({"model": "", "user_text": "y"}, "fb")), # falsy result model
|
|
("chat_completion", ({"model": 5, "user_text": "z"}, None)), # non-string truthy
|
|
("chat_completion", ({"user_text": None}, "m")), # present-null content passes
|
|
("chat_completion", ({"model": "m"}, "fb")), # missing user_text → ""
|
|
("chat_chunks", ({"model": "stub-model", "user_text": "streamed"}, None)),
|
|
("chat_chunks", ({"user_text": "x"}, "fb")),
|
|
("chat_chunks", ({"user_text": "héllo ✓"}, "m")), # ensure_ascii bytes in NDJSON
|
|
# ── handler surface ────────────────────────────────────────────────
|
|
("_log_message_probe", ('"GET %s" %d', ["/v1/models", 200])),
|
|
("_send_json_probe", (200, {"object": "list", "data": []})), # ", "/": " law
|
|
("_send_json_probe", (404, {"error": {"code": "not_found",
|
|
"message": "no route /x"}})),
|
|
("_send_json_probe", (200, {"msg": "héllo ✓"})), # ensure_ascii
|
|
("_send_ndjson_probe", (200, [{"a": 1}, {"b": [1, 2]}])),
|
|
("_send_ndjson_probe", (200, [])), # empty body, Content-Length 0
|
|
("_make_server_probe", (SPEC_FULL,)),
|
|
# ── do_GET ─────────────────────────────────────────────────────────
|
|
("_do_get_probe", ("/v1/models", SPEC_MODELS)),
|
|
("_do_get_probe", ("/v1/status", SPEC_STATUS)),
|
|
("_do_get_probe", ("/v1/status", {"raise_status": "boom"})),
|
|
("_do_get_probe", ("/v1/status", {"raise_status": "y" * 250})), # [:200] runes
|
|
("_do_get_probe", ("/v1/conversation?channel=ops&n=2", SPEC_WINDOW)),
|
|
("_do_get_probe", ("/v1/conversation", SPEC_WINDOW)), # defaults operator/8
|
|
("_do_get_probe", ("/v1/conversation?n=abc", SPEC_WINDOW)), # int ValueError → 500
|
|
("_do_get_probe", ("/v1/conversation?channel=", SPEC_WINDOW)), # blank dropped
|
|
("_do_get_probe", ("/v1/conversation?n=99&n=abc", SPEC_WINDOW)), # first value
|
|
("_do_get_probe", ("/v1/conversation?n=+12", SPEC_WINDOW)), # '+' → ' ' → int strip
|
|
("_do_get_probe", ("/v1/conversation?n=-1", SPEC_WINDOW)), # negative slice
|
|
("_do_get_probe", ("/v1/conversation?channel=%C3%A9+d", SPEC_WINDOW)), # %XX + '+'
|
|
("_do_get_probe", ("/v1/models?x=1", SPEC_MODELS)), # full-path mismatch → 404
|
|
("_do_get_probe", ("/v1/nope", SPEC_FULL)),
|
|
# ── do_POST ────────────────────────────────────────────────────────
|
|
("_do_post_probe", post("/v1/approvals/resolve", '{"approved": true}', {})),
|
|
("_do_post_probe", post("/v1/approvals/resolve", '{"approved": 1}', {})), # truthy
|
|
("_do_post_probe", post("/v1/approvals/resolve", '{"approved": "yes"}', {})),
|
|
("_do_post_probe", post("/v1/approvals/resolve", '{"approved": 0}', {})), # falsy
|
|
("_do_post_probe", post("/v1/approvals/resolve", "", {})), # empty → {} → False
|
|
("_do_post_probe", post("/v1/approvals/resolve", '{"approved": true}', {}, cl="-5")),
|
|
("_do_post_probe", post("/v1/approvals/resolve", "not json", {})),
|
|
("_do_post_probe", post("/v1/approvals/resolve", "{}", {}, cl="x")), # CL garbage
|
|
("_do_post_probe", post("/v1/approvals/resolve", "{bad", {})),
|
|
("_do_post_probe", post(
|
|
"/v1/chat/completions",
|
|
'{"model": "m2", "messages": [{"role": "user", "content": "first"}, '
|
|
'{"role": "assistant", "content": "mid"}, {"role": "user", "content": "final"}]}',
|
|
SPEC_CHAT)), # LAST user text + model passthrough
|
|
("_do_post_probe", post(
|
|
"/v1/chat/completions",
|
|
'{"messages": [{"role": "user", "content": "streamed"}], "stream": true}',
|
|
SPEC_CHAT)),
|
|
("_do_post_probe", post(
|
|
"/v1/chat/completions",
|
|
'{"messages": [{"role": "user", "content": "x"}], "stream": false}',
|
|
SPEC_CHAT)),
|
|
("_do_post_probe", post(
|
|
"/v1/chat/completions",
|
|
'{"messages": [{"role": "user", "content": "x"}], "stream": "yes"}',
|
|
SPEC_CHAT)), # truthy string
|
|
("_do_post_probe", post(
|
|
"/v1/chat/completions",
|
|
'{"messages": [{"role": "assistant", "content": "no user here"}]}',
|
|
SPEC_CHAT)), # 400 user-role law
|
|
("_do_post_probe", post(
|
|
"/v1/chat/completions",
|
|
'{"messages": [{"role": "user", "content": 5}]}',
|
|
SPEC_CHAT)), # non-string content passes through (echo 5)
|
|
("_do_post_probe", post(
|
|
"/v1/chat/completions",
|
|
'{"messages": "abc"}',
|
|
SPEC_CHAT)), # uncaught AttributeError crash class
|
|
("_do_post_probe", post(
|
|
"/v1/chat/completions",
|
|
'{"model": "", "messages": [{"role": "user", "content": "x"}]}',
|
|
SPEC_CHAT)), # "" → None → model_arg null
|
|
("_do_post_probe", post(
|
|
"/v1/chat/completions",
|
|
'{"model": 5, "messages": [{"role": "user", "content": "x"}]}',
|
|
SPEC_CHAT)), # truthy non-string model
|
|
("_do_post_probe", post(
|
|
"/v1/chat/completions",
|
|
'{"messages": [{"role": "user", "content": "x"}]}',
|
|
{"raise_send": "boom"})), # send_task raise → 500 envelope
|
|
("_do_post_probe", post(
|
|
"/v1/chat/completions",
|
|
'{"messages": [{"role": "user", "content": "c"}],}',
|
|
SPEC_CHAT)), # trailing comma message
|
|
("_do_post_probe", post(
|
|
"/v1/chat/completions",
|
|
'{"messages": []} x',
|
|
SPEC_CHAT)), # extra data message
|
|
("_do_post_probe", post(
|
|
"/v1/chat/completions",
|
|
'{"model" "m"}',
|
|
SPEC_CHAT)), # ':' delimiter message
|
|
("_do_post_probe", post("/v1/other", "{}", SPEC_FULL)), # 404
|
|
]
|
|
|
|
|
|
def main() -> int:
|
|
truth = freeze("rune.core_server", CASES, oracle_module="rune.core_server")
|
|
write_envelope(FROZEN_NOW, truth, TRUTH)
|
|
print(f"wrote {len(truth)} cases to {TRUTH}")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|