Skip to content

Commit a8713c3

Browse files
committed
v45: bind resource chat to real job receipts and recover misrouted plans
1 parent 56702e4 commit a8713c3

9 files changed

Lines changed: 491 additions & 7 deletions

‎V100_AUDIT.md‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,31 @@
1+
## v100.45 current-request resource contract
2+
3+
A reported v44 resource request received an unrelated trading/dashboard answer,
4+
changed short/mid plans and queued a placeholder VM script. Those receipts did not
5+
prove Windows allocation or useful execution. This revision fixes that path:
6+
7+
- Resource-only instructions do not replay unrelated dashboard conversation history.
8+
Their tool allowlist exposes actual resource status, owned compute proposals and
9+
bounded drone scheduling, without HTML edits or GUI/desktop jobs.
10+
- Unrelated plan/sandbox actions are rejected before application. The displayed
11+
answer is composed from host resource evidence and executed tool receipts, not
12+
from an unverified model success declaration. Tool receipts are retained in chat.
13+
- `compute_resources` distinguishes pinned RTX model load, CPU worker heartbeat,
14+
local worker RAM/disk budgets and actual job states. Windows RAM/VRAM is not pooled
15+
into the Debian address space. Worker readiness alone is not execution.
16+
- The stopped upgrade archives completed misrouted resource requests, restores only
17+
still-current short/mid versions they replaced, cancels only matching still-queued
18+
desktop scripts and requeues the original resource request. Later user plans and
19+
the operator long-term goal are preserved. Already executed scripts are not
20+
claimed to be undone.
21+
- Expired fee profiles retained solely as accounting history are separate from
22+
expired profiles still referenced by active instruments. Historical records stay
23+
intact; currently expired instrument fees still block paper execution.
24+
25+
This correction does not certify that a model will choose a useful CPU experiment,
26+
that its job passes independent validation, or that distributing work is faster.
27+
Those outcomes require actual job receipts and measurements.
28+
129
## v100.44 integration and observed limits
230

331
This revision connects the existing capabilities; it does not certify live hardware,
@@ -365,3 +393,11 @@ The JavaScript live renderer was executed against an older layout with missing l
365393
sections. Ruff, formatting, diff whitespace checks and both installer shell syntax
366394
checks passed. No V100/RTX hardware, LAN, Windows process or guest boot is certified
367395
by those results.
396+
397+
Validation for v100.45: 968 repository tests passed, 65 skipped, 1 deselected,
398+
with one PEFT configuration warning. The excluded owned-worker process integration
399+
requires process/RAM introspection unavailable here. Resource request tests cover
400+
history isolation, host receipts, rejection before desktop execution, archive/requeue
401+
recovery, preservation of later plans and refusal to repair a running mission.
402+
Ruff, formatting, shell syntax and diff whitespace checks passed. Hardware/LAN
403+
allocation and useful execution still require the operator's deployment receipts.

‎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.44"
6+
version = "0.1.3+v100.45"
77
description = "Recursive Language Models."
88
readme = "README.md"
99
license = "MIT"

‎rlm/v100/chat_resources.py‎

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
"""Bind resource requests to real allocation receipts, not unrelated chat history."""
2+
3+
import json
4+
import re
5+
import time
6+
from pathlib import Path
7+
8+
import requests
9+
10+
from rlm.v100.chat_goals import normalized
11+
from rlm.v100.common import atomic_json
12+
13+
RESOURCE_TOOLS = {
14+
"compute_resources",
15+
"get_plan",
16+
"mission_evidence",
17+
"drone_status",
18+
"propose_compute_trial",
19+
"compute_trial_status",
20+
"cancel_compute_trial",
21+
"schedule_drone",
22+
"cancel_drone",
23+
"calculate",
24+
"goal_learning_status",
25+
}
26+
27+
28+
def instruction(message: str) -> bool:
29+
text = normalized(message)
30+
if "?" in text or re.match(r"^(?:czy|jak|why|how|is|are)\b", text):
31+
return False
32+
if re.search(r"dashboard|\bhtml\b|pulpit|(?:ustaw|zmien)\w*\s+(?:cel|plan)", text):
33+
return False
34+
resource = re.findall(r"\b(?:rtx|windows\w*|cpu|ram\w*|dysk\w*|worker\w*|dron\w*)\b", text)
35+
return len(set(resource)) >= 2 and bool(
36+
re.search(r"uzyw|wykorzyst|przydz|deleg|udostep|wspoldziel|shared", text)
37+
)
38+
39+
40+
def filter_actions(actions: list[dict]) -> tuple[list[dict], list[dict]]:
41+
allowed = [row for row in actions if row.get("kind") in ("directive", "budget")]
42+
rejected = [row for row in actions if row not in allowed]
43+
return allowed, rejected
44+
45+
46+
def status(root: Path) -> dict:
47+
from rlm.v100.common import load_profile
48+
from rlm.v100.competition import helper_client
49+
from rlm.v100.distributed_compute import inspect
50+
from rlm.v100.drones import inspect as drone_status
51+
from rlm.v100.remote_helper import remote_profile, selected_helper
52+
53+
value = {
54+
"external_compute": inspect(root),
55+
"drones": drone_status(root),
56+
"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.",
57+
}
58+
try:
59+
profile = load_profile(selected_helper(root), root)
60+
if not remote_profile(profile):
61+
raise ValueError("Pinned RTX helper is not configured")
62+
client = helper_client(profile, root)
63+
client.timeout = 3
64+
loaded = client.remote_request("/api/ps").get("models", [])
65+
loaded = [m for m in loaded if m.get("digest") == client.model_digest]
66+
value["helper"] = {
67+
"reachable": True,
68+
"pinned_model_loaded": bool(loaded),
69+
"context": profile["runtime"]["context_window"],
70+
"batch": client.helper_batch_tokens,
71+
"active_request_target_percent": client.helper_duty_percent,
72+
"scope": "Inference/vision helper, request pacing; not a hard GPU utilization/power cap",
73+
}
74+
except (OSError, ValueError, RuntimeError, requests.RequestException) as error:
75+
value["helper"] = {"reachable": False, "error": str(error)[:300]}
76+
return value
77+
78+
79+
def answer(evidence: dict, trace: list[dict], rejected: list[dict]) -> str:
80+
helper = evidence["helper"]
81+
external = evidence["external_compute"]
82+
workers = external.get("workers", [])
83+
active = [w for w in workers if not w.get("stale", True)]
84+
text = "RTX helper: " + (
85+
"osiągalny, przypięty model załadowany."
86+
if helper.get("pinned_model_loaded")
87+
else "brak potwierdzenia załadowanego modelu."
88+
)
89+
text += f"\nWindows CPU: {len(active)} aktualnych workerów. "
90+
text += "RAM i dysk Windows są używane lokalnie przez workery; nie powiększają RAM ani VRAM Debiana."
91+
for worker in active:
92+
text += f"\n{worker.get('name', 'worker')}: {worker.get('phase', 'unknown')}, {worker.get('threads', '?')} wątki, limit RAM {worker.get('ram_limit_gib', '?')} GiB."
93+
allocations = [
94+
row for row in trace if row["tool"] in ("propose_compute_trial", "schedule_drone")
95+
]
96+
for row in allocations:
97+
result = row["result"]
98+
text += (
99+
"\nZlecenie: "
100+
+ str(result.get("id", "brak ID"))
101+
+ " | "
102+
+ str(result.get("state", result.get("status", "unknown")))
103+
)
104+
if result.get("error"):
105+
text += " | " + str(result["error"])[:200]
106+
if not allocations:
107+
text += "\nW tej odpowiedzi nie przydzielono nowego zadania. Gotowość workera nie oznacza wykonania."
108+
if rejected:
109+
text += "\nOdrzucono działania niezwiązane z przydziałem zasobów. Nie zmieniono nimi planów ani HTML."
110+
text += "\nZlecenie w kolejce nie potwierdza wykonania, przyspieszenia ani aktualizacji wag."
111+
return text
112+
113+
114+
def repair_completed(root: Path) -> dict:
115+
"""Upgrade-only recovery of misrouted completed resource commands; never overwrite later plans."""
116+
from rlm.v100.drones import connect as drone_connect
117+
from rlm.v100.mission import status as mission_status
118+
from rlm.v100.mission_chat import connect
119+
120+
if mission_status(root)["running"]:
121+
raise ValueError("Stop the mission before recovering misrouted chat plans")
122+
repaired = []
123+
with connect(root) as db:
124+
rows = db.execute("SELECT * FROM requests WHERE state='completed'").fetchall()
125+
for row in rows:
126+
if not instruction(row["message"]):
127+
continue
128+
response = json.loads(row["response"])
129+
_, rejected = filter_actions(response.get("actions", []))
130+
if not rejected or response.get("resource_contract"):
131+
continue
132+
if not re.fullmatch("[a-f0-9]{32}", row["id"]):
133+
raise ValueError("Invalid persisted request identity")
134+
archive = root / "research/state/chat-contract-repairs" / (row["id"] + ".json")
135+
atomic_json(archive, dict(row))
136+
plans_path = root / "research/plans/current.json"
137+
plans = json.loads(plans_path.read_text()) if plans_path.exists() else {}
138+
restored = []
139+
for receipt in response.get("applied", []):
140+
horizon, identity = receipt.get("horizon"), receipt.get("id", "")
141+
if horizon in ("short", "mid") and re.fullmatch("[a-f0-9]{32}", identity):
142+
if plans.get(horizon, {}).get("id") == identity:
143+
version = json.loads(
144+
(root / "research/plans" / (identity + ".json")).read_text()
145+
)
146+
plans[horizon] = version.get("previous") or {}
147+
restored.append(horizon)
148+
elif receipt.get("kind") == "desktop":
149+
with drone_connect(root) as jobs:
150+
current = jobs.execute(
151+
"SELECT payload,state FROM jobs WHERE id=?", (identity,)
152+
).fetchone()
153+
payloads = {a["text"] for a in rejected if a.get("kind") == "sandbox"}
154+
if (
155+
current
156+
and current["state"] == "queued"
157+
and current["payload"] in payloads
158+
):
159+
jobs.execute(
160+
"UPDATE jobs SET state='cancelled',updated=? WHERE id=?",
161+
(time.time(), identity),
162+
)
163+
if restored:
164+
atomic_json(
165+
archive.with_name(row["id"] + "-plans-before.json"),
166+
json.loads(plans_path.read_text()),
167+
)
168+
atomic_json(plans_path, plans)
169+
db.execute(
170+
"UPDATE requests SET state='queued',response=NULL,attempts=0,error=NULL,updated=? WHERE id=?",
171+
(time.time(), row["id"]),
172+
)
173+
repaired.append({"id": row["id"], "restored_plans": restored, "archive": str(archive)})
174+
return {"requeued_resource_requests": repaired, "long_term_goal_changed": False}

‎rlm/v100/mission_chat.py‎

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,9 @@ def respond(root: Path, directory: Path, request: dict, accepted_cpu=None) -> di
332332
client.sampling_args = dict(client.sampling_args)
333333
client.sampling_args["max_tokens"] = min(2048, client.sampling_args.get("max_tokens", 2048))
334334
client.activity_context = {**client.activity_context, "chat_request_id": request.get("id")}
335+
from rlm.v100 import chat_resources
336+
337+
resource_request = chat_resources.instruction(message)
335338
with connect(root) as db:
336339
history = db.execute(
337340
"SELECT message,response FROM requests WHERE state='completed' ORDER BY rowid DESC LIMIT 3"
@@ -370,11 +373,20 @@ def respond(root: Path, directory: Path, request: dict, accepted_cpu=None) -> di
370373
),
371374
}
372375
]
373-
for old in reversed(history):
376+
for old in reversed([] if resource_request else history):
374377
messages += [
375378
{"role": "user", "content": old["message"][:1500]},
376379
{"role": "assistant", "content": json.loads(old["response"])["answer"][:1500]},
377380
]
381+
if resource_request:
382+
messages[0]["content"] += (
383+
" CURRENT REQUEST: allocate operator-owned RTX/Windows CPU resources for the EXISTING goal. "
384+
"Do not change short/mid/long plans, invent trading strategies, edit HTML, run GUI or submit placeholder scripts. "
385+
"Read compute_resources and get_plan if needed. Use schedule_drone for a useful concrete bounded researcher/critic/source task, "
386+
"or propose_compute_trial only for a genuinely useful proof-domain architecture experiment. "
387+
"Report actual tool job IDs/states; do not claim work completed before independent receipts. "
388+
"A worker uses its own RAM/disk; it does not enlarge Debian RAM or V100 VRAM."
389+
)
378390
messages.append(
379391
{
380392
"role": "user",
@@ -404,6 +416,9 @@ def respond(root: Path, directory: Path, request: dict, accepted_cpu=None) -> di
404416

405417
client.research_owner = "A"
406418
client.research_tool_names = {
419+
"compute_resources",
420+
"schedule_drone",
421+
"cancel_drone",
407422
"propose_compute_trial",
408423
"compute_trial_status",
409424
"cancel_compute_trial",
@@ -424,10 +439,14 @@ def respond(root: Path, directory: Path, request: dict, accepted_cpu=None) -> di
424439
"search_memory",
425440
"read_source",
426441
}
427-
result = json.loads(
428-
research_turn(client, messages, schema(allow_long_goal), root)["content"]
429-
)
442+
if resource_request:
443+
client.research_tool_names = chat_resources.RESOURCE_TOOLS
444+
client.resource_only_chat = True
445+
research = research_turn(client, messages, schema(allow_long_goal), root)
446+
tool_receipts = research.get("research_trace", [])
447+
result = json.loads(research["content"])
430448
else:
449+
tool_receipts = []
431450
result = json.loads(
432451
native_turn(
433452
client,
@@ -437,6 +456,12 @@ def respond(root: Path, directory: Path, request: dict, accepted_cpu=None) -> di
437456
)
438457
if set(result) != {"answer", "actions"} or not isinstance(result["answer"], str):
439458
raise ValueError("Invalid chat response")
459+
if resource_request:
460+
result["actions"], rejected = chat_resources.filter_actions(result["actions"])
461+
evidence = chat_resources.status(root)
462+
result["answer"] = chat_resources.answer(evidence, tool_receipts, rejected)
463+
result["resource_contract"] = {"evidence": evidence, "rejected_actions": rejected}
464+
result["tool_receipts"] = tool_receipts
440465
result["applied"] = apply_actions(root, result["actions"], message)
441466
if dashboard_request:
442467
from rlm.v100.dashboard_editor import status as dashboard_status

‎rlm/v100/paper_reports.py‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,16 @@ def summarize_snapshot(book: PaperBook, period: str) -> dict:
105105
> state["risk"]["quote_age_seconds"]
106106
and symbol not in state["outcomes"]
107107
]
108+
active_fee_ids = {instrument["fee_profile"] for instrument in state["instruments"].values()}
108109
expired_fees = [
109110
key
110111
for key, profile in state["fee_profiles"].items()
111-
if timestamp(profile["valid_until"]) <= now
112+
if key in active_fee_ids and timestamp(profile["valid_until"]) <= now
113+
]
114+
expired_archived_fees = [
115+
key
116+
for key, profile in state["fee_profiles"].items()
117+
if key not in active_fee_ids and timestamp(profile["valid_until"]) <= now
112118
]
113119
branches = {}
114120
for branch in ("A", "B"):
@@ -154,6 +160,7 @@ def summarize_snapshot(book: PaperBook, period: str) -> dict:
154160
"price_series": price_series,
155161
"stale_symbols": stale_symbols,
156162
"expired_fee_profiles": expired_fees,
163+
"expired_archived_fee_profiles": expired_archived_fees,
157164
"audit_tail_sha256": events[-1]["event_hash"],
158165
"ledger_sequence": events[-1]["sequence"],
159166
"descriptive_leader": max(branches, key=lambda branch: Decimal(branches[branch]["equity"])),

‎rlm/v100/research_tools.py‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@
3232
}
3333

3434
TOOLS = [
35+
tool_schema(
36+
"compute_resources",
37+
"Read actual pinned helper load, owned CPU worker heartbeats and queued/running jobs. Worker RAM/disk stay worker-local; never infer pooled host RAM or actual execution from readiness.",
38+
{},
39+
),
3540
tool_schema(
3641
"dashboard_status",
3742
"Verify the guest HTML and exact host publication hash. A model declaration is not publication.",
@@ -619,6 +624,10 @@ def execute(self, name: str, arguments: dict) -> dict:
619624
"text": content[offset : offset + 6000],
620625
"remaining": max(0, len(content) - offset - 6000),
621626
}
627+
if name == "compute_resources" and not arguments:
628+
from rlm.v100.chat_resources import status
629+
630+
return status(self.root)
622631
if name in ("dashboard_status", "read_dashboard") and not arguments:
623632
from rlm.v100.dashboard_editor import status
624633

@@ -1039,6 +1048,12 @@ def research_turn(client, messages: list[dict], schema: dict, root: Path) -> dic
10391048
tool_call_id=call["id"],
10401049
)
10411050
try:
1051+
if (
1052+
getattr(client, "resource_only_chat", False)
1053+
and call["function"]["name"] == "schedule_drone"
1054+
and json.loads(call["function"]["arguments"]).get("kind") == "desktop"
1055+
):
1056+
raise ValueError("Resource request cannot schedule an unrelated GUI/desktop script")
10421057
result = tools.execute(
10431058
call["function"]["name"], json.loads(call["function"]["arguments"])
10441059
)

0 commit comments

Comments
 (0)