Skip to content

Commit 073c9e0

Browse files
committed
v54: reuse verified firewall rules and retain dashboard reading nodes
1 parent 486bc3b commit 073c9e0

6 files changed

Lines changed: 48 additions & 10 deletions

File tree

‎V100_AUDIT.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,3 +614,14 @@ Validation: 1010 passed, 65 skipped, one resource-dependent worker integration
614614
deselected, one existing PEFT warning. Final dashboard/chat checks passed 29 tests.
615615
No Windows PowerShell runtime is available here; scheduled task operation must be
616616
confirmed on Windows.
617+
618+
## v54: reusable scoped firewall and retained reading nodes
619+
620+
The previous Windows launcher rejected its own persistent firewall rules after
621+
reboot. Matching inbound TCP port, local/remote address, action, enabled state and
622+
program rules are now reused. A mismatched rule is rejected and left unchanged;
623+
failure cleanup removes only rules created by this launch. The watchdog retains
624+
the existing game guard and 50 percent target. Windows runtime validation remains
625+
required. Dashboard keyed details and their existing text nodes are retained and
626+
updated in place, including nested text scroll and open/closed state. This replaces
627+
reconstruction of reading nodes, not just restoration of their open flags.

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

‎rlm/v100/dashboard_layout.py‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
agentView(data);
3232
$('actors').replaceChildren();
3333
for(const a of data.live?.actors||[]){
34-
const node=document.createElement('article');node.className='card';const title=document.createElement('h3');title.textContent=a.label;
34+
const node=document.createElement('article');node.className='card';node.dataset.scrollKey=a.label+'-resource-card';const title=document.createElement('h3');title.textContent=a.label;
3535
const state=document.createElement('strong');state.textContent=a.state+(a.stale?' | nieaktualne lub brak danych':'');state.style.color=a.stale?'#ffbf86':'#75c5ae';
3636
const detail=document.createElement('p');detail.textContent=a.detail||'';node.append(title,state,detail);
3737
if(a.cooldown_seconds){const p=document.createElement('p');p.textContent='Przerwa helpera: '+a.cooldown_seconds+' s';node.append(p)}
@@ -44,9 +44,10 @@
4444
}
4545
4646
function textField(parent,label,value){if(value===undefined||value===null||value==='')return;const p=document.createElement('p'),b=document.createElement('strong');b.textContent=label+': ';p.append(b,document.createTextNode(String(value)));parent.append(p)}
47-
const disclosureStates=new Map(), disclosureScroll=new Map();
48-
function rememberDisclosures(){for(const n of document.querySelectorAll('details[data-key]')){disclosureStates.set(n.dataset.key,n.open);const pre=n.querySelector?.('pre');if(pre)disclosureScroll.set(n.dataset.key,[pre.scrollTop,pre.scrollLeft])}}
49-
function restoreDisclosures(){for(const n of document.querySelectorAll('details[data-key]')){if(disclosureStates.has(n.dataset.key))n.open=disclosureStates.get(n.dataset.key);const pre=n.querySelector?.('pre'),position=disclosureScroll.get(n.dataset.key);if(pre&&position){pre.scrollTop=position[0];pre.scrollLeft=position[1]}}}
47+
const disclosureStates=new Map(), disclosureScroll=new Map(), disclosureNodes=new Map(), panelScroll=new Map();
48+
function updateNode(old,fresh){if(old.nodeType!==fresh.nodeType||old.nodeName!==fresh.nodeName){old.replaceWith(fresh);return}if(old.nodeType===3){if(old.nodeValue!==fresh.nodeValue)old.nodeValue=fresh.nodeValue;return}const a=[...old.childNodes],b=[...fresh.childNodes];for(let i=0;i<Math.max(a.length,b.length);i++){if(!b[i])a[i].remove();else if(!a[i])old.append(b[i]);else updateNode(a[i],b[i])}}
49+
function rememberDisclosures(){for(const n of document.querySelectorAll('[data-scroll-key]'))if(n.dataset.scrollKey)panelScroll.set(n.dataset.scrollKey,[n.scrollTop,n.scrollLeft]);for(const n of document.querySelectorAll('details[data-key]')){disclosureStates.set(n.dataset.key,n.open);disclosureNodes.set(n.dataset.key,n);const pre=n.querySelector?.('pre');if(pre)disclosureScroll.set(n.dataset.key,[pre.scrollTop,pre.scrollLeft])}}
50+
function restoreDisclosures(){for(const n of document.querySelectorAll('[data-scroll-key]')){const position=panelScroll.get(n.dataset.scrollKey);if(position){n.scrollTop=position[0];n.scrollLeft=position[1]}}for(let n of document.querySelectorAll('details[data-key]')){const previous=disclosureNodes.get(n.dataset.key);if(previous&&previous!==n&&n.replaceWith){updateNode(previous,n);n.replaceWith(previous);n=previous}if(disclosureStates.has(n.dataset.key))n.open=disclosureStates.get(n.dataset.key);const pre=n.querySelector?.('pre'),position=disclosureScroll.get(n.dataset.key);if(pre&&position){pre.scrollTop=position[0];pre.scrollLeft=position[1]}}}
5051
function detailsField(parent,label,value,key,open=false){if(!value)return;const d=document.createElement('details'),h=document.createElement('summary'),p=document.createElement('pre');d.dataset.key=key;d.open=open;h.textContent=label;p.textContent=String(value);d.append(h,p);parent.append(d)}
5152
function panel(id,title,after){let p=$(id);if(!p){p=document.createElement('section');p.id=id;const h=document.createElement('h2');h.textContent=title;p.append(h);after.after(p)}return p}
5253
function agentView(data){

‎tests/test_v100_live_dashboard.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ class Element {
180180
program += dashboard_layout.APP_SCRIPT
181181
program += "\nrender(sample);if(nodes.actors.children.length!==2||!nodes.goals.textContent.includes('Operator goal')||nodes.events.children.length!==1||nodes['agent-grid'].children.length!==1)throw Error('Live renderer failed');\n"
182182
program += """
183+
const textNode={nodeType:3,nodeName:'#text',nodeValue:'previous'};const reader={nodeType:1,nodeName:'PRE',childNodes:[textNode],scrollTop:77};const freshReader={nodeType:1,nodeName:'PRE',childNodes:[{nodeType:3,nodeName:'#text',nodeValue:'updated'}]};updateNode(reader,freshReader);if(reader.childNodes[0]!==textNode||textNode.nodeValue!=='updated'||reader.scrollTop!==77)throw Error('Reading node replaced');
183184
const old={dataset:{key:'reader'},open:false};let disclosures=[old];document.querySelectorAll=()=>disclosures;rememberDisclosures();
184185
const next={dataset:{key:'reader'},open:true};disclosures=[next];restoreDisclosures();if(next.open)throw Error('User-closed detail reopened');
185186
next.open=true;rememberDisclosures();const newer={dataset:{key:'reader'},open:false};disclosures=[newer];restoreDisclosures();if(!newer.open)throw Error('User-open detail lost');

‎tools/start-rtx3090-helper.ps1‎

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,25 @@ New-Item -ItemType Directory -Path $Root -Force | Out-Null
105105
New-Item -ItemType Directory -Path (Join-Path $Root 'models') -Force | Out-Null
106106
New-Item -ItemType Directory -Path (Join-Path $Root 'logs') -Force | Out-Null
107107

108-
$ExistingRule = Get-NetFirewallRule -Name $Rule -ErrorAction SilentlyContinue
109-
if ($ExistingRule -or (Get-NetFirewallRule -Name $BlockRule -ErrorAction SilentlyContinue)) { throw "Helper firewall rule already exists; inspect it before restarting." }
108+
function Confirm-HelperRule([string]$Name, [string]$Action, [string[]]$Remote, [string]$Program) {
109+
$existing = @(Get-NetFirewallRule -Name $Name -ErrorAction SilentlyContinue)
110+
if ($existing.Count -eq 0) { return $false }
111+
if ($existing.Count -ne 1) { throw "Ambiguous helper firewall rule: $Name" }
112+
$item = $existing[0]
113+
$ports = $item | Get-NetFirewallPortFilter
114+
$addresses = $item | Get-NetFirewallAddressFilter
115+
$app = $item | Get-NetFirewallApplicationFilter
116+
$expected = ($Remote | Sort-Object) -join ','
117+
$actual = (@($addresses.RemoteAddress) | Sort-Object) -join ','
118+
if ($item.Direction -ne 'Inbound' -or $item.Action -ne $Action -or $item.Enabled -ne 'True' -or
119+
[string]$ports.Protocol -notin @('TCP','6') -or [string]$ports.LocalPort -ne [string]$Port -or
120+
[string]$addresses.LocalAddress -ne $WindowsIp -or $actual -ne $expected -or
121+
($Program -and $app.Program -ne $Program)) {
122+
throw "Existing helper firewall scope differs: $Name. Nothing replaced."
123+
}
124+
Write-Host "Reusing verified helper firewall rule: $Name"
125+
return $true
126+
}
110127

111128
# The current model manifest rejects the user's installed Ollama 0.21.2.
112129
# Use the official standalone runtime, including optional NVIDIA MLX libraries,
@@ -167,13 +184,21 @@ foreach ($number in $Allowed) {
167184
}
168185
if ($First -lt 4294967295) { $Ranges += "$(Number-Ip $First)-255.255.255.255" }
169186
$Worker = $null
187+
$CreatedAllowRule = $false
188+
$CreatedBlockRule = $false
170189
Remove-Item -LiteralPath $OwnerPath -ErrorAction SilentlyContinue
171190
try {
191+
if (-not (Confirm-HelperRule $BlockRule 'Block' $Ranges '')) {
172192
New-NetFirewallRule -Name $BlockRule -DisplayName $BlockRule -Direction Inbound -Action Block `
173193
-Protocol TCP -LocalPort $Port -LocalAddress $WindowsIp -RemoteAddress $Ranges -Profile Any | Out-Null
194+
$CreatedBlockRule = $true
195+
}
196+
if (-not (Confirm-HelperRule $Rule 'Allow' @($DebianIp) $Ollama)) {
174197
New-NetFirewallRule -Name $Rule -DisplayName $Rule -Direction Inbound -Action Allow `
175198
-Protocol TCP -LocalPort $Port -LocalAddress $WindowsIp -RemoteAddress $DebianIp `
176199
-Program $Ollama -Profile Any | Out-Null
200+
$CreatedAllowRule = $true
201+
}
177202

178203
$WorkerScript = Join-Path $Root 'serve-worker.ps1'
179204
@'
@@ -353,7 +378,7 @@ $Ready = $false
353378
if ($Worker -and -not $Worker.HasExited) { $Worker.Kill() }
354379
try { Stop-HelperProcesses $RuntimeRoot }
355380
catch { Write-Warning "Helper cleanup failed: $($_.Exception.Message)" }
356-
Remove-NetFirewallRule -Name $Rule -ErrorAction SilentlyContinue
357-
Remove-NetFirewallRule -Name $BlockRule -ErrorAction SilentlyContinue
381+
if ($CreatedAllowRule) { Remove-NetFirewallRule -Name $Rule -ErrorAction SilentlyContinue }
382+
if ($CreatedBlockRule) { Remove-NetFirewallRule -Name $BlockRule -ErrorAction SilentlyContinue }
358383
throw $LaunchError
359384
}

‎tools/upgrade-v100-retention.sh‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ PY
4747
uv --no-config pip install --python "$PY" --no-deps --reinstall-package rlms \
4848
"rlms @ git+https://github.com/Mantiee/rlm.git@$REV"
4949
uv --no-config pip check --python "$PY"
50-
uv --no-config pip freeze --python "$PY" > "$AI_V100_ROOT/research/requirements.continual.v10053.txt"
50+
uv --no-config pip freeze --python "$PY" > "$AI_V100_ROOT/research/requirements.continual.v10054.txt"
5151

5252
"$PY" <<'PY'
5353
import json, os

0 commit comments

Comments
 (0)