Skip to content

Commit 09c00a1

Browse files
committed
v65: audit historical metrics, preserve dashboard reading position and adapt bounded compute
1 parent 2d5c5e0 commit 09c00a1

30 files changed

Lines changed: 641 additions & 29 deletions

‎SYNTA_RECOVERY.md‎

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,3 +261,47 @@ the reported black-screen hang, this preset uses Windows CPU and leaves RTX off;
261261
it does not promise to diagnose hardware or prevent all crashes. The V100
262262
remains the main model/GPU. N-gram memory runs as a bounded experimental candidate
263263
with paired host-scored ablation and existing independent promotion gates.
264+
265+
## v65: metric integrity, field anchoring and measured resource headroom
266+
267+
- The legacy `Odchylenie` header is corrected to maximum drawdown. This is the
268+
largest sampled equity decline from a preceding peak, not standard deviation.
269+
Double-cost net return has a separate label. The simulator uses full available
270+
cash and fees/slippage on each buy/sell leg, which can make frequent trading
271+
expensive even with constant prices. Audit receipts include that illustration.
272+
- `audit_backtests` checks recent archived hashes, valid OHLCV ranges and timing,
273+
reruns selected historical simulations and reconstructs net return/drawdown
274+
from the equity trace. Changed, malformed, gapped or extreme-jump archives are
275+
excluded from retrospective training; original files remain untouched. Every
276+
postmortem training example repeats admission checks. These examples explicitly
277+
deny future-profit and negative-return-means-corruption claims. Vendor accuracy,
278+
intrabar drawdown and unobserved liquidity are not certified by this replay.
279+
- Upgrade records an audit and gives Synta the metric/parameter contract. The
280+
existing tool selects past-only lookbacks 5/10/20 and exposes no Z-score input
281+
or lookback 100. Historical losses stay rejected. There is no test-until-profit
282+
loop and no admission of backtests as future directional/profit labels.
283+
- Refresh anchors the visible field inside the centered dashboard rather than the entire parent section. Internal scrolling panels compensate inside their own scroll container, without moving the page.
284+
Open disclosures win over draft defaults; live token panes no longer open
285+
automatically. The timeline runs chronologically, retaining expanded events
286+
that leave the bounded recent window. Reading cards retain their panel while
287+
expanded. The action archive keeps its own DOM and pagination.
288+
- Local CPU/network drone admission scales from two to one or zero slots with
289+
measured CPU/RAM headroom. Windows children use one or two affinity slots
290+
within the previous two-thread ceiling, idle priority, one job and monitored
291+
four-GiB RSS limit. Existing 40% host CPU, six-GiB free RAM and foreground media
292+
guards remain. Access-denied foreground inspection yields instead of crashing.
293+
Transient SMB failures report blocked/retry state. No clocks, board power or
294+
unrelated applications change; Windows RTX remains disabled by the operator.
295+
- The visible Windows console tails bounded new bytes from stdout, stderr and
296+
autostart logs. Failed launches show their error instead of only startup
297+
banners; retry pacing backs off. Startup banners alone do not prove a running
298+
worker. `idle/ready` means no admitted job, not performed training.
299+
- `remote_connect` prints this signed-in device's actual HTTPS dashboard/chat and
300+
SSH addresses, gateway/Serve configuration and upstream check. Login by itself
301+
does not install the private web gateway. The installer can be rerun after
302+
login and checks the final configuration without resetting other services.
303+
304+
Code tests use deterministic fixtures and DOM simulation. No Windows host,
305+
operator browser, actual market archive or phone session is available here;
306+
installation performs the real archive audit, while phone and runtime acceptance
307+
remain observable operator-device checks. No profitable strategy is claimed.

‎SYNTA_REMOTE_ACCESS.md‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,17 @@ Browser chat keeps actual saved request states and replies visible across reconn
1111
Disable the gateway with `systemctl --user disable --now synta-remote.service`. Disable only its Serve listener with `sudo tailscale serve --https=443 off`; do not reset other Tailscale services.
1212

1313
Official references: [Serve and identity headers](https://tailscale.com/docs/features/tailscale-serve), [packages](https://pkgs.tailscale.com/stable/), [SSH access](https://tailscale.com/docs/features/tailscale-ssh).
14+
15+
After login, rerun the pinned installer if its earlier terminal was closed. It
16+
skips login for an already-running Tailscale session and completes the gateway.
17+
To print actual connection addresses and blockers without changing services:
18+
19+
```bash
20+
"$HOME/ai-v100/venvs/v100-continual/bin/python" -m rlm.v100.remote_connect --root "$HOME/ai-v100"
21+
```
22+
23+
On phone/laptop, enable Tailscale under the same account and open the printed
24+
HTTPS `dashboard` or `chat` URL. For SSH use the printed command and existing
25+
Debian credentials. No LAN address or router forwarding is needed for these
26+
services. A configured Serve route is not proof of a successful remote browser
27+
session; its status is separate from the upstream HTTP check.

‎pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "rlms"
33
authors = [
44
{name = "Alex Zhang", email = "altzhang@mit.edu"},
55
]
6-
version = "0.1.3+v100.64"
6+
version = "0.1.3+v100.65"
77
description = "Recursive Language Models."
88
readme = "README.md"
99
license = "MIT"

‎rlm/v100/backtest_audit.py‎

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"""Bounded reproducibility audit; never confuse a losing strategy with bad data."""
2+
3+
import hashlib
4+
import json
5+
import time
6+
from pathlib import Path
7+
8+
from rlm.v100.common import atomic_json
9+
10+
11+
def inspect_report(path: Path) -> dict:
12+
from rlm.v100.backtest_learning import verified
13+
14+
result = {
15+
"report": str(path),
16+
"state": "quarantined",
17+
"postmortem_training_admitted": False,
18+
"forecast_training_admitted": False,
19+
"scope": "Archived source checksums, chronology, OHLCV ranges and simulator replay. This cannot certify vendor accuracy, causality or a future edge.",
20+
}
21+
try:
22+
record = verified(path)
23+
stored = json.loads(path.read_text())
24+
fee = stored["parameters"]["fee_bps"] / 10000
25+
slip = stored["parameters"]["slippage_bps"] / 10000
26+
pairs = stored["development_test"]["fills"] / 2
27+
flat_return = (((1 - fee) * (1 - slip)) / ((1 + fee) * (1 + slip))) ** pairs - 1
28+
result.update(
29+
state="reproduced",
30+
report_sha256=hashlib.sha256(path.read_bytes()).hexdigest(),
31+
postmortem_training_admitted=True,
32+
verified_sample=json.loads(record["messages"][-1]["content"]),
33+
flat_price_cost_only_return=flat_return,
34+
cost_explanation="Illustration for the reported number of full-capital buy/sell pairs at constant prices. Actual return also depends on price changes. Fee and slippage apply to each leg; these remain assumptions, not certified fees.",
35+
)
36+
except (ValueError, OSError, KeyError, TypeError, IndexError, ZeroDivisionError) as error:
37+
result["reason"] = str(error)[:400]
38+
return result
39+
40+
41+
def run(root: Path, limit: int = 20) -> dict:
42+
if type(limit) is not int or not 1 <= limit <= 20:
43+
raise ValueError("Audit 1-20 recent stored reports")
44+
paths = sorted(
45+
(root / "research/backtests").glob("run-*/report.json"),
46+
key=lambda path: path.stat().st_mtime_ns,
47+
reverse=True,
48+
)[:limit]
49+
result = {
50+
"updated": time.time(),
51+
"reports": [inspect_report(path) for path in paths],
52+
"metric_correction": "max_sampled_drawdown is peak-to-trough equity loss, not standard deviation. Double-cost net return is a different metric. Loss alone is not evidence of a data glitch.",
53+
"originals": "retained unchanged",
54+
"scope": "Recent reports only; every historical training record is checked again at admission. Unverified reports are excluded, including profitable ones.",
55+
}
56+
atomic_json(root / "research/backtests/audit-status.json", result)
57+
return result
58+
59+
60+
if __name__ == "__main__":
61+
import argparse
62+
63+
parser = argparse.ArgumentParser(description=__doc__)
64+
parser.add_argument("--root", type=Path, required=True)
65+
print(json.dumps(run(parser.parse_args().root), indent=2))

‎rlm/v100/backtest_learning.py‎

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,27 @@
44
import json
55
from pathlib import Path
66

7-
from rlm.v100.backtesting import bars_from_source, simulate
7+
from rlm.v100.backtesting import bars_from_source, simulate, source_quality
88
from rlm.v100.paper import sha, timestamp
99

1010

1111
def verified(path: Path) -> dict:
12+
if path.is_symlink() or path.stat().st_size > 2 * 2**20:
13+
raise ValueError("Unsafe or oversized historical report")
1214
report = json.loads(path.read_text())
1315
bodies = []
1416
for index, source in enumerate(report["sources"]):
15-
body = (path.parent / f"source-{index}.json").read_text()
17+
archive = path.parent / f"source-{index}.json"
18+
if archive.is_symlink() or archive.stat().st_size > 2 * 2**20:
19+
raise ValueError("Unsafe or oversized archived source")
20+
body = archive.read_text()
1621
if hashlib.sha256(body.encode()).hexdigest() != source["sha256"]:
1722
raise ValueError("Backtest archived source changed")
1823
bodies.append(body)
1924
bars = bars_from_source(report["sources"][0]["url"], bodies[0], timestamp(report["fetched_at"]))
25+
quality = source_quality(bars)
26+
if quality["gaps"] or quality["large_opening_jumps"]:
27+
raise ValueError("Archived bars require source review; excluded from postmortem training")
2028
events = None
2129
if len(bodies) > 1:
2230
events = []
@@ -65,19 +73,36 @@ def verified(path: Path) -> dict:
6573
bars, split, len(bars), "buy_hold", chosen, arguments["fee_bps"], arguments["slippage_bps"]
6674
)
6775
if (
68-
report["selected_lookback_on_training_only"] != chosen
76+
report["bars"] != len(bars)
77+
or report["split_index"] != split
78+
or report["selected_lookback_on_training_only"] != chosen
6979
or report["development_test"] != test
7080
or report.get("double_cost_stress") != stress
7181
or report.get("buy_hold_baseline") != baseline
7282
):
7383
raise ValueError("Historical report differs from independently rerun simulator")
7484
outcome = test["net_return"]
85+
for value in (test, stress, baseline):
86+
peak, drawdown = 1.0, 0.0
87+
for point in value["trace"]:
88+
equity = point["marked_equity"]
89+
if point["signal_available_at"] > point["fill_at"]:
90+
raise ValueError("Future information in historical trace")
91+
peak = max(peak, equity)
92+
drawdown = max(drawdown, 1 - equity / peak)
93+
if (
94+
abs(value["net_return"] - (value["trace"][-1]["marked_equity"] - 1)) > 1e-10
95+
or abs(value["max_sampled_drawdown"] - drawdown) > 1e-10
96+
):
97+
raise ValueError("Historical equity trace does not reproduce reported metrics")
7598
label = {
7699
"sample_result": "profit" if outcome > 0 else "loss" if outcome < 0 else "flat",
77100
"beats_cash_in_sample": outcome > 0,
78101
"beats_buy_hold_in_sample": outcome > baseline["net_return"],
79102
"positive_at_double_assumed_cost": stress["net_return"] > 0,
80103
"repeatable_income_established": False,
104+
"drawdown_is_standard_deviation": False,
105+
"negative_return_proves_data_corruption": False,
81106
"next_evidence": "independent forward paper observations with documented costs",
82107
}
83108

@@ -111,7 +136,7 @@ def records(root: Path) -> list[dict]:
111136
for path in sorted((root / "research/backtests").glob("run-*/report.json")):
112137
try:
113138
row = verified(path)
114-
except (ValueError, KeyError, OSError, TypeError):
139+
except (ValueError, KeyError, OSError, TypeError, IndexError, ZeroDivisionError):
115140
continue # Older reports without complete artifacts are not training evidence.
116141
result.append(row)
117142
return result

‎rlm/v100/backtesting.py‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,17 @@ def bars_from_source(url: str, body: str, fetched_at: datetime) -> list[dict]:
3232
float(row[3]),
3333
float(row[4]),
3434
)
35+
low, high, volume = float(row[1]), float(row[2]), float(row[5])
36+
if (
37+
not all(math.isfinite(value) for value in (low, high, volume))
38+
or not 0
39+
< low
40+
<= min(open_price, close_price)
41+
<= max(open_price, close_price)
42+
<= high
43+
or volume < 0
44+
):
45+
raise ValueError("Invalid public Coinbase OHLCV price range or volume")
3546
else:
3647
opened, closed = (
3748
timestamp(row["open_time"]).timestamp(),
@@ -63,6 +74,24 @@ def bars_from_source(url: str, body: str, fetched_at: datetime) -> list[dict]:
6374
return bars
6475

6576

77+
def source_quality(bars: list[dict]) -> dict:
78+
gaps = sum(
79+
left["available_at"] < right["open_time"]
80+
for left, right in zip(bars, bars[1:], strict=False)
81+
)
82+
jumps = sum(
83+
abs(right["open"] / left["close"] - 1) > 0.5
84+
for left, right in zip(bars, bars[1:], strict=False)
85+
)
86+
return {
87+
"closed_bars": len(bars),
88+
"gaps": gaps,
89+
"large_opening_jumps": jumps,
90+
"state": "requires source review" if gaps or jumps else "structural checks passed",
91+
"scope": "Structural checks only. Large moves are flags, not proof of corrupt prices.",
92+
}
93+
94+
6695
def simulate(
6796
bars: list[dict],
6897
start: int,
@@ -268,6 +297,12 @@ def run(root: Path, branch: str, arguments: dict, *, source_snapshot: tuple | No
268297
{key: value for key, value in source.items() if key != "body"} for source in sources
269298
],
270299
"bars": len(bars),
300+
"source_quality": source_quality(bars),
301+
"metric_definitions": {
302+
"max_sampled_drawdown": "Largest sampled peak-to-trough equity loss, including assumed exit costs; not standard deviation",
303+
"net_return": "Final liquidated equity divided by initial equity, minus one",
304+
"double_cost_stress": "Separate simulation with doubled assumed fees and slippage; its net return is not drawdown",
305+
},
271306
"split_index": split,
272307
"selected_lookback_on_training_only": chosen,
273308
"development_test": test,

‎rlm/v100/chat_facts.py‎

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def language(message: str) -> str:
1010
return (
1111
"Polish"
1212
if re.search(
13-
r"\b(?:co|czego|czemu|jak|czy|kiedy|gdzie|uczy|naucz|zarab|zarob|znalaz|zrob|zmien|przetestuj|poszukaj|zbieraj|hej|czesc|odpowiedz)\w*\b",
13+
r"\b(?:co|czego|czemu|jak|czy|kiedy|gdzie|uczy|naucz|zarab|zarob|znalaz|zrob|zmien|przetestuj|poszukaj|zbieraj|sprawdz|zbadaj|odchylen|hej|czesc|odpowiedz)\w*\b",
1414
normalized(message),
1515
)
1616
else "English"
@@ -20,7 +20,7 @@ def language(message: str) -> str:
2020
def requested(message: str) -> bool:
2121
return bool(
2222
re.search(
23-
r"zarab|zarob|strateg|income|profit|backtest|minus|paper|opportunit|candidate|brier|kandydat",
23+
r"zarab|zarob|strateg|income|profit|backtest|minus|paper|opportunit|candidate|brier|kandydat|drawdown|obsunie|odchylen|glitch",
2424
normalized(message),
2525
)
2626
)
@@ -54,6 +54,27 @@ def response(root: Path, message: str) -> dict:
5454
if pl
5555
else "A negative backtest return is a historical simulated loss, not a Brier or benchmark score.",
5656
]
57+
lines.append(
58+
"Obsunięcie to największy spadek kapitału od wcześniejszego szczytu, nie odchylenie standardowe. Wynik netto przy podwójnych kosztach to oddzielny zwrot. Sama strata nie dowodzi błędu danych."
59+
if pl
60+
else "Drawdown is the largest equity decline from a prior peak, not standard deviation. Double-cost net return is a separate return. A loss alone does not prove corrupt data."
61+
)
62+
audit_path = root / "research/backtests/audit-status.json"
63+
if audit_path.exists() and audit_path.stat().st_size <= 2 * 2**20:
64+
import json
65+
66+
audit = json.loads(audit_path.read_text())
67+
for row in audit.get("reports", [])[:4]:
68+
lines.append(
69+
"Audit: "
70+
+ row["state"]
71+
+ " | "
72+
+ row["report"]
73+
+ " | "
74+
+ row.get("reason", "archived simulator replay only")
75+
)
76+
else:
77+
lines.append("Audit: unavailable; no source integrity claim accepted")
5778
for row in value.get("recent_exploratory_backtests", []):
5879
net = row.get("development_test", {}).get("net_return")
5980
lines.append(
@@ -96,3 +117,31 @@ def test_response(root: Path, message: str) -> dict:
96117
"responder": {"model": "controller-historical-comparison"},
97118
"scope": "Historical research executed; no future edge, verified income or orders claimed",
98119
}
120+
121+
122+
def audit_response(root: Path, message: str) -> dict:
123+
from rlm.v100.backtest_audit import run
124+
125+
value = run(root)
126+
rows = [
127+
"Audit: "
128+
+ row["state"]
129+
+ " | "
130+
+ row["report"]
131+
+ " | "
132+
+ row.get("reason", "archived replay passed")
133+
for row in value["reports"]
134+
]
135+
return {
136+
"answer": (
137+
"Obsunięcie to największy spadek kapitału od wcześniejszego szczytu, nie odchylenie standardowe. Zwrot przy podwójnych kosztach jest osobną metryką. Sama strata nie dowodzi błędu cen. Audyt poniżej odtwarza zapisane źródła i obliczenia; nie potwierdza ich u niezależnego dostawcy."
138+
if language(message) == "Polish"
139+
else value["metric_correction"]
140+
)
141+
+ "\n"
142+
+ ("\n".join(rows) or "No archived reports to audit"),
143+
"actions": [],
144+
"applied": [value],
145+
"responder": {"model": "controller-backtest-audit"},
146+
"scope": value["scope"],
147+
}

‎rlm/v100/chat_resources.py‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ def status(root: Path) -> dict:
5656
"drones": drone_status(root),
5757
"scope": "Owned job execution only. Windows RAM/disk are worker-local resources, not pooled Debian RAM or shared VRAM. No arbitrary Windows shell is exposed.",
5858
}
59+
from rlm.v100.mission_chat import preferences
60+
61+
if preferences(root).get("remote_helper_enabled", True) is False:
62+
value["helper"] = {
63+
"reachable": None,
64+
"state": "disabled by operator",
65+
"scope": "No Windows GPU probes or jobs. Accepted V100 serves model work; CPU mailbox remains available. Duty cycle cannot cap peak GPU power.",
66+
}
67+
return value
5968
try:
6069
profile = load_profile(selected_helper(root), root)
6170
if not remote_profile(profile):

0 commit comments

Comments
 (0)