Skip to content

Commit a9ea4e1

Browse files
committed
v57: audit Synta requirements, recover owned CPU startup and journal real compute decisions
1 parent 30697bf commit a9ea4e1

13 files changed

Lines changed: 352 additions & 19 deletions

‎SYNTA_REQUIREMENTS_AUDIT.md‎

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Synta: requirement and verification audit, v57
2+
3+
This audits the visible conversation. "Implemented" means code exists and the
4+
listed checks pass, not that it has run successfully on the operator's computers.
5+
Hardware-dependent checks are separate. No real orders, spending, paid APIs,
6+
account creation or sales are authorized by this implementation.
7+
8+
| Requirement | Code / checks | Result and boundary |
9+
| --- | --- | --- |
10+
| Name Synta; distinguish user/master/controller | `mission_chat.py`, `tests/test_v100_chat_backend.py` | Implemented; controller capability/status answers are identified, not claimed as model generation. |
11+
| Chat answers; finite timeouts and no endless queue retries | `mission_chat.py`, chat/backend tests | Implemented; ordinary questions use one generation, identity probes bounded, connection retries finite, incomplete replies fail explicitly. An offline backend cannot supply a genuine model answer. |
12+
| Master executes requests instead of only writing plans | `research_tools.py`, `mission_chat.py`, action-object/resource tests | Named validated tools and receipts; plan-only implementation replies do not count as execution. Model tool choice is not guaranteed. |
13+
| Goal editable by explicit chat request | `chat_goals.py`, `planning.py`, chat-goal tests | Implemented; old experiments preserve their original goal; fetched content cannot change the operator goal. |
14+
| Dashboard accessible over LAN and updated automatically | `tools/serve-v100-dashboard.py`, `dashboard_editor.py` | Read-only host service with trusted renderer and validated passive guest layout. Host/guest publication hashes must match. |
15+
| Master edits dashboard without pasting HTML into chat | `dashboard_editor.py`, dashboard tests | Scoped read/write/repair tools; source read is separate from publication validation. Guest scripts remain disallowed; host supplies refresh. |
16+
| Clear resource, agent, plan, job and evidence sections | Dashboard renderer, activity-view tests | Implemented cards/timelines. No visual browser binary here, so aesthetic acceptance is not certified. |
17+
| Reading position and expansion survive all refresh paths | Transactional/keyed renderer, dashboard Node tests | Same DOM reader/text nodes and scroll offsets retained across repeated refreshes; live browser on operator machine remains an acceptance check. |
18+
| Show actions and results of controlled tools | `activity.py`, `research_tools.py`, `activity_browser.py` | Correlated start/result/error events and paged journal. Redaction, bounds and omitted secrets are intentional. This is not an OS-wide syscall recorder. |
19+
| Show each model's returned text/token measurements | `llamacpp.py`, `remote_helper.py`, `streaming.py`, streaming tests | Returned fragments and actual usage counters, with model/device/request provenance. Missing counters are unknown. Not every backend exposes raw token IDs. |
20+
| See model reasoning | Opt-in local returned-trace capture | Only reasoning actually returned by owned local models can be recorded. Unavailable internal reasoning is not fabricated or inferred from GPU usage. |
21+
| GPU/CPU utilization is distinct from actual useful work | Activity/resource cards; job receipts | Implemented. Readiness, loaded VRAM and idle heartbeat do not prove a task was executed. |
22+
| RTX helper survives Windows logon and recovers | `install-rtx3090-autostart.ps1`, guardian/firewall policies | Current-user logon task, existing guardian/game guard retained. Matching narrowly scoped firewall rules reused, unrelated rules unchanged. Windows runtime test required. |
23+
| Visible PowerShell monitor | `watch-rtx3090-helper.ps1`, `Synta-Helper-Monitor` task | Separate visible read-only window at logon; closing it does not stop compute. LAN binding corrected. |
24+
| Owned Windows CPU worker autostart | `install-owned-compute-autostart.ps1` | Added; existing authenticated mailbox/settings recovered; credentials/share unchanged; running worker preserved, new revision used after it exits/logon. CPU child remains 2 threads / 4 GiB. |
25+
| 50% helper target consistently | RTX autostart and `start-windows-lab.ps1` | Both use 50% active wall-time pacing, not a hard board utilization/power/temperature cap. Exact installed CPU dependencies avoid repeated network resolution. |
26+
| Use Windows RAM/disk/CPU and RTX | Owned mailbox, distributed compute, remote helper | Worker-local bounded jobs and safe artifact transfer. RAM/VRAM is not pooled into Debian; available hardware need not run dummy work to raise utilization. |
27+
| Automatically allocate useful owned CPU work | `goal_compute.py`, dispatch tests | A/B tasks queued for fresh idle workers when enough verified active-goal outcomes exist. No valid outcomes means an explicit blocker. |
28+
| Goal-oriented ML from newly discovered signals | `goal_learning.py`, `goal_compute.py`, `continuous.py` | Precommitted numeric signal/target forecasts, observed later outcomes, source-disjoint splits, verified master examples plus separate tiny CPU baselines. Tools support operator directions and model proposals. Arbitrary goals need an independently verifiable task/label definition. |
29+
| Social/news/filings evidence linked to outcomes | Public-source/JSON feed registration, `paper_agents.py`, goal observation tools | Available primitives; a measured association does not prove causality or profit. No promise of universal social-feed access or discovery of an income edge. |
30+
| Compare lawful opportunities, sports, crypto, equities | Research tools, provider registry, paper ledger | Research and bounded paper simulations; execution requires valid fees, feeds and domain settlement rules. Stale/unavailable sources remain blockers, not fabricated substitutes. |
31+
| Scalping/news/arbitrage and high leverage | Earlier assistant-generated plans | Not falsely certified as implemented profitable algorithms. These names came from model replies; placeholders and promises are not executable evidence. Leveraged live trading remains outside the authorized goal. |
32+
| Retention experiments including capacity growth | `retention.py`, `capacity_growth.py`, training/distillation, actual CPU PEFT tests | Replay, KL, reference-gradient projection, Fisher/drift constraints and optional adapter growth; residual-column/embedding extension experiments. Activation requires independent finite gates. No universal zero-forgetting guarantee or claim every published method was implemented. |
33+
| Prior weights/checkpoints and A/B histories survive | Protection, branch-lineage, activation/rollback tests | Implemented; candidates do not overwrite immutable originals. Tiny worker weights are not automatically substituted for master weights. |
34+
| Honest training progress and optimizer counters | `mission_evidence.py`, training-health tests | Attempted/global steps, completed optimizer updates and accepted versions remain separate; missing means unknown. GUI readiness is not a prerequisite for native inference/training. |
35+
| End-to-end task execution and acceptance decision | Real child-process goal test and independent local tensor validation | Observations -> frozen job -> actual optimizer -> safe weights -> host reload -> locally validated/rejected decision. Hardware sensors are simulated in sandbox; old goal labels cannot enter a new goal pool. Master activation separately tested through quality/retention/goal gates; no actual V100 training here. |
36+
| Code size / number of changed lines | Git tracked source/diff history | Reproducible with Git; temporary test directories are excluded. Line count is not a completion or quality measure. |
37+
38+
## Hardware acceptance still required
39+
40+
After installing the pinned Debian and Windows revisions, verify a real model
41+
answer, stable browser reading position, fresh Windows CPU heartbeat plus actual
42+
job receipt, RTX inference logs, and a logon recovery. Verify GPU training and
43+
accepted weights only from new run artifacts and independent gate results.
44+
Neither screenshots nor passing mocked transport tests establish these facts.
45+
46+
## Operator goal is retained
47+
48+
The financial goal is not replaced by arithmetic, dashboard maintenance or a
49+
small forecast task. Arithmetic is an auxiliary experiment. Failed trading tests,
50+
losses and rejected updates remain evidence. No result here establishes income.
51+
52+
Source-size snapshot: 46130 physical lines in 190 tracked/new Python, PowerShell and shell files under `rlm/v100`, `tools` and `tests`. Includes comments/tests, excludes temporary files.
53+
54+
Verification result: full test suite 1028 passed, 65 skipped, no deselections;
55+
ruff and upgrade shell checks pass. Windows startup policy has static contract
56+
checks, not a Windows runtime execution. Real CPU child-training/tensor-validation
57+
integration is included with simulated resource readings.

‎V100_AUDIT.md‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,3 +670,30 @@ deselected; one existing PEFT warning. Ruff, diff and upgrade shell checks pass.
670670
Tests cover the actual question route (one generation, bounded identity check,
671671
no CPU cold start/tool loop), incomplete output rejection and queue advancement
672672
after terminal connection failures.
673+
674+
## v57: complete requirement audit, CPU startup and compute action journal
675+
676+
`SYNTA_REQUIREMENTS_AUDIT.md` maps the conversation to concrete modules/checks and
677+
separates implemented mechanisms, bounded experiments, hardware acceptance and
678+
unavailable guarantees. The Windows helper installer now includes a limited
679+
current-user CPU autostart task and a separate visible read-only monitor. Existing
680+
mailbox configuration/running worker is preserved, no credentials/share are
681+
created, and the monitor uses the actual LAN binding. Both Windows helper paths
682+
use the operator's 50 percent active-time target. Installed exact CPU dependencies
683+
are checked before resolving packages over the network.
684+
685+
Owned-compute state transitions are journaled once with job IDs, artifact paths,
686+
errors and independent validation decisions. Remote metrics remain untrusted.
687+
The real subprocess integration formerly deselected for lack of /proc is now
688+
exercised with explicit simulated sensor readings; training/tensor reload remain
689+
real. A new integration uses precommitted goal observations all the way through
690+
worker training and independent host validation, preserving goal provenance.
691+
Windows Scheduled Task execution and real browser/GPU operation still require
692+
operator hardware. This audit does not replace those checks with assertions.
693+
694+
Validation: full suite 1028 passed, 65 skipped, no deselected tests; one existing
695+
PEFT warning. Ruff checks over `rlm` and `tests`, diff whitespace checks and upgrade
696+
shell syntax pass. Goal/worker integrations perform actual CPU optimizer updates
697+
and safe-tensor subprocess reload, with explicit simulated resource sensors.
698+
PowerShell execution is not available in this sandbox; startup policy checks do
699+
not certify Windows task registration/execution.

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

‎rlm/v100/distributed_compute.py‎

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,39 @@
1010
import uuid
1111
from pathlib import Path
1212

13+
from rlm.v100.activity import ActivityLog
1314
from rlm.v100.common import atomic_json
1415
from rlm.v100.compute_kernel import validate
1516
from rlm.v100.compute_worker import read_json
1617
from rlm.v100.protection import file_hash
1718

1819

20+
def record_state(root: Path, path: Path, state: dict) -> None:
21+
"""Journal observable job transitions once, retaining the full state artifact."""
22+
before = read_json(path) if path.exists() else {}
23+
atomic_json(path, state)
24+
fields = ("state", "worker", "attempts", "validation_job", "local_report_sha256")
25+
if any(before.get(key) != state.get(key) for key in fields):
26+
job_path = path.parent / "job.json"
27+
experiment_goal = (
28+
read_json(job_path).get("provenance", {}).get("goal_id") if job_path.exists() else None
29+
)
30+
ActivityLog(root, state.get("branch", "controller"), "owned-compute").write(
31+
"training",
32+
"compute-state-changed",
33+
{
34+
"job_id": path.parent.name,
35+
"experiment_goal_id": experiment_goal,
36+
"previous_state": before.get("state"),
37+
**{key: state[key] for key in fields if key in state},
38+
"state_file": str(path),
39+
"detail": state.get("detail"),
40+
"weights_promoted": state.get("weights_promoted", False),
41+
"scope": "Observed coordinator transition; remote metrics remain untrusted until host validation",
42+
},
43+
)
44+
45+
1946
def configure(root: Path, mailbox: Path) -> dict:
2047
from rlm.v100.mission import status
2148

@@ -160,7 +187,8 @@ def queue_job(
160187
atomic_json(folder / "job.json", job)
161188
shutil.copyfile(kernel, folder / "kernel.py")
162189
(folder / "kernel.py").chmod(0o444)
163-
atomic_json(
190+
record_state(
191+
root,
164192
folder / "state.json",
165193
{
166194
"state": "queued",
@@ -209,7 +237,7 @@ def cancel(root: Path, identity: str) -> dict:
209237
path = root / "research/compute-jobs" / identity / "state.json"
210238
state = read_json(path)
211239
state.update(state="cancelled")
212-
atomic_json(path, state)
240+
record_state(root, path, state)
213241
atomic_json(mailbox_path(root) / "closed" / (identity + ".json"), {"state": "cancelled"})
214242
return state
215243

@@ -225,7 +253,7 @@ def tick(root: Path) -> None:
225253
try:
226254
scheduled = schedule(root, state["branch"], "compute-audit", identity, 0)
227255
state["validation_job"] = scheduled["id"]
228-
atomic_json(path, state)
256+
record_state(root, path, state)
229257
except ValueError:
230258
# A full bounded queue defers validation, never a completed import.
231259
pass
@@ -252,7 +280,7 @@ def tick(root: Path) -> None:
252280
if receipt is None:
253281
if time.time() - lease["heartbeat"] < 300:
254282
state.update(state="running", worker=lease["worker"])
255-
atomic_json(path, state)
283+
record_state(root, path, state)
256284
continue
257285
raise ValueError("Compute worker lease expired")
258286
if receipt.get("nonce") != lease["nonce"] or receipt.get("job_id") != identity:
@@ -286,7 +314,7 @@ def tick(root: Path) -> None:
286314
weights_promoted=False,
287315
detail="Remote metrics untrusted; queued local safe-tensor validation",
288316
)
289-
atomic_json(path, state)
317+
record_state(root, path, state)
290318
atomic_json(mailbox / "closed" / (identity + ".json"), {"state": "imported"})
291319
except (ValueError, KeyError, TypeError, OSError) as error:
292320
attempts = state["attempts"] + 1
@@ -295,7 +323,7 @@ def tick(root: Path) -> None:
295323
attempts=attempts,
296324
detail=str(error)[:400],
297325
)
298-
atomic_json(path, state)
326+
record_state(root, path, state)
299327
if attempts >= 3:
300328
atomic_json(mailbox / "closed" / (identity + ".json"), {"state": "failed"})
301329
claim = mailbox / "claims" / identity
@@ -383,5 +411,5 @@ def validate_locally(root: Path, identity: str) -> dict:
383411
weights_promoted=False,
384412
detail="Independent host loss evaluation of safe tensors; not a master promotion or proof of the user goal",
385413
)
386-
atomic_json(folder / "state.json", state)
414+
record_state(root, folder / "state.json", state)
387415
return state

‎tests/test_v100_distributed_compute.py‎

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,11 +167,24 @@ def test_owned_worker_executes_pinned_child_and_host_validates_weights(tmp_path,
167167

168168
mailbox, identity = configured(tmp_path, monkeypatch)
169169
monkeypatch.setattr(compute_worker, "available", lambda: (True, "Test CPU host ready"))
170-
available_memory = psutil.virtual_memory()
171170
monkeypatch.setattr(
172171
psutil,
173172
"virtual_memory",
174-
lambda: available_memory._replace(available=12 * 2**30),
173+
lambda: type("Memory", (), {"available": 12 * 2**30})(),
174+
)
175+
# The sandbox has no /proc. Training and validation are real subprocesses;
176+
# resource sensor readings are simulated, not asserted as hardware validation.
177+
monkeypatch.setattr(
178+
psutil,
179+
"Process",
180+
lambda pid: type(
181+
"Process",
182+
(),
183+
{
184+
"memory_info": lambda self: type("RSS", (), {"rss": 100 * 2**20})(),
185+
"children": lambda self, recursive: [],
186+
},
187+
)(),
175188
)
176189
path, lease = compute_worker.claim(mailbox, "actual-cpu")
177190
compute_worker.execute(mailbox, path, lease, Path(compute_kernel.__file__))
@@ -210,3 +223,22 @@ def full(*args):
210223
monkeypatch.setattr(drones, "schedule", actual)
211224
distributed_compute.tick(tmp_path)
212225
assert drones.inspect(tmp_path)[0]["kind"] == "compute-audit"
226+
227+
228+
def test_compute_transition_journal_is_complete_and_does_not_repeat_polling(tmp_path):
229+
path = tmp_path / "research/compute-jobs" / ("a" * 24) / "state.json"
230+
state = {"state": "queued", "branch": "A", "attempts": 0}
231+
distributed_compute.record_state(tmp_path, path, state)
232+
distributed_compute.record_state(tmp_path, path, state)
233+
state.update(state="running", worker="windows-cpu")
234+
distributed_compute.record_state(tmp_path, path, state)
235+
state.update(state="failed", attempts=3, detail="Worker failed")
236+
distributed_compute.record_state(tmp_path, path, state)
237+
events = [
238+
json.loads(line)
239+
for p in tmp_path.glob("research/logs/activity/*/timeline.jsonl")
240+
for line in p.read_text().splitlines()
241+
]
242+
assert [e["payload"]["state"] for e in events] == ["queued", "running", "failed"]
243+
assert all(e["payload"]["job_id"] == "a" * 24 for e in events)
244+
assert events[-1]["payload"]["detail"] == "Worker failed"

0 commit comments

Comments
 (0)