RFTSystems commited on
Commit
1c2a285
·
verified ·
1 Parent(s): 71529e4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +59 -219
app.py CHANGED
@@ -1,251 +1,91 @@
1
  # ============================================================
2
- # RFT-Ω FRAMEWORK — TOTAL-PROOF API (Sprint 1, Stable Build)
3
- # Author: Liam Grinstead (RFT Systems) | All Rights Reserved
4
  # ============================================================
5
- """
6
- Deterministic, signed validation harness for the
7
- Rendered Frame Theory (RFT-Ω) harmonic-stability kernel.
8
- """
9
 
10
  import os, json, time, hashlib, zipfile, random
11
  from datetime import datetime
12
- from typing import Dict, Any, List, Tuple
13
  import numpy as np
14
  import gradio as gr
15
 
16
- try:
17
- from fastapi import FastAPI
18
- HAVE_FASTAPI = True
19
- except Exception:
20
- HAVE_FASTAPI = False
21
-
22
-
23
  # ------------------ About / Legal ---------------------------
24
  RFT_VERSION = "v4.0-total-proof-stable"
25
  RFT_DOI = "https://doi.org/10.5281/zenodo.17466722"
26
- HF_URL = "https://rftsystems-rft-omega-api.hf.space"
27
  LEGAL_NOTICE = (
28
  "All Rights Reserved — RFT-IPURL v1.0 (UK / Berne). "
29
- "Research validation use only. No reverse-engineering or derivative kernels without written consent."
30
  )
31
 
32
- ABOUT_BLOCK = {
33
- "name": "RFT-Ω Framework — Total-Proof API",
34
- "version": RFT_VERSION,
35
- "doi": RFT_DOI,
36
- "space": HF_URL,
37
- "profiles": ["AI / Neural", "SpaceX / Aerospace", "Energy / RHES", "Extreme Perturbation"],
38
- "noise_distributions": ["gauss", "uniform"],
39
- "schedules": ["single", "ramp", "random", "impulse", "step"],
40
- "metrics": ["QΩ", "ζ_sync", "status"],
41
- "integrity": ["run_id", "sha512(config+results)", "bundle(zip)"],
42
- "legal": LEGAL_NOTICE,
43
- }
44
-
45
-
46
- # ------------------ Rate-limit ------------------------------
47
- RUN_HISTORY_TS: List[float] = []
48
- MAX_RUNS_PER_MINUTE = 60
49
-
50
- def _rate_limit_ok() -> Tuple[bool, str]:
51
- now = time.time()
52
- while RUN_HISTORY_TS and now - RUN_HISTORY_TS[0] > 60:
53
- RUN_HISTORY_TS.pop(0)
54
- if len(RUN_HISTORY_TS) >= MAX_RUNS_PER_MINUTE:
55
- return False, "Rate limit exceeded (demo fairness). Please retry shortly."
56
- RUN_HISTORY_TS.append(now)
57
- return True, "ok"
58
-
59
-
60
- # ------------------ Profiles / Simulation -------------------
61
  PROFILES = {
62
- "AI / Neural": {"base": (0.86, 0.80), "w": (0.65, 0.35)},
63
- "SpaceX / Aerospace": {"base": (0.84, 0.79), "w": (0.60, 0.40)},
64
- "Energy / RHES": {"base": (0.83, 0.78), "w": (0.55, 0.45)},
65
- "Extreme Perturbation":{"base": (0.82, 0.77), "w": (0.50, 0.50)},
66
  }
67
 
68
- def _rng(seed:int)->np.random.RandomState:
69
- return np.random.RandomState(seed)
70
 
71
- def simulate_step(rng:np.random.RandomState, profile:str, sigma:float, noise_dist:str)->Dict[str,Any]:
72
  base_q, base_z = PROFILES[profile]["base"]
73
  wq, wz = PROFILES[profile]["w"]
74
- if noise_dist == "uniform":
75
- q_noise = rng.uniform(-sigma, sigma)
76
- z_noise = rng.uniform(-sigma*0.8, sigma*0.8)
77
  else:
78
- q_noise = rng.normal(0, sigma)
79
- z_noise = rng.normal(0, sigma*0.8)
80
- q = float(np.clip(base_q + wq*q_noise, 0.0, 0.99))
81
- z = float(np.clip(base_z + wz*z_noise, 0.0, 0.99))
82
- variance = abs(q_noise)+abs(z_noise)
83
  if variance > 0.15:
84
  status="critical"
85
  elif variance > 0.07:
86
  status="perturbed"
87
  else:
88
  status="nominal"
89
- return {"sigma": round(sigma,6),"QΩ":q,"ζ_sync":z,"status":status}
90
-
91
-
92
- # ------------------ Schedules -------------------------------
93
- def build_sigma_series(schedule_type:str, params:Dict[str,Any])->List[float]:
94
- if schedule_type=="single":
95
- return [float(params.get("sigma",0.05))]
96
- elif schedule_type=="ramp":
97
- return list(np.linspace(float(params.get("start",0.0)),
98
- float(params.get("stop",0.3)),
99
- int(params.get("steps",10))))
100
- elif schedule_type=="random":
101
- r = random.Random(int(params.get("seed",0)))
102
- return [r.uniform(float(params.get("min",0.0)),
103
- float(params.get("max",0.3)))
104
- for _ in range(int(params.get("steps",10)))]
105
- elif schedule_type=="impulse":
106
- base,spike,at,steps = float(params.get("base",0.05)), float(params.get("spike",0.25)), int(params.get("at",5)), int(params.get("steps",10))
107
- s=[base]*steps
108
- if 0<=at<len(s): s[at]=spike
109
- return s
110
- elif schedule_type=="step":
111
- before,after,at,steps = float(params.get("before",0.05)), float(params.get("after",0.2)), int(params.get("at",5)), int(params.get("steps",10))
112
- s=[before]*steps
113
- for i in range(steps):
114
- if i>=at: s[i]=after
115
- return s
116
- return [float(params.get("sigma",0.05))]
117
-
118
-
119
- # ------------------ Integrity helpers -----------------------
120
- def sha512_hex(s:str)->str:
121
- return hashlib.sha512(s.encode()).hexdigest()
122
-
123
- def make_run_id(seed:int,profile:str)->str:
124
- raw=f"{time.time_ns()}::{seed}::{profile}::{random.random()}"
125
- return hashlib.sha256(raw.encode()).hexdigest()[:16]
126
-
127
- def write_bundle(run_dir:str,config:Dict[str,Any],results:Dict[str,Any])->Tuple[str,str]:
128
- os.makedirs(run_dir,exist_ok=True)
129
- with open(os.path.join(run_dir,"run.json"),"w") as f:
130
- json.dump({"config":config,"results":results},f,indent=2)
131
- canonical=json.dumps({"config":config,"results":results},sort_keys=True)
132
- digest=sha512_hex(canonical)
133
- with open(os.path.join(run_dir,"run.sha512"),"w") as f:
134
- f.write(digest+"\n")
135
- with open(os.path.join(run_dir,"ABOUT.json"),"w") as f:
136
- json.dump(ABOUT_BLOCK,f,indent=2)
137
- with open(os.path.join(run_dir,"NOTICE.txt"),"w") as f:
138
- f.write(LEGAL_NOTICE+"\n")
139
- zip_path=os.path.join(run_dir,"rft_run_bundle.zip")
140
- with zipfile.ZipFile(zip_path,"w",zipfile.ZIP_DEFLATED) as z:
141
- for fn in ["run.json","run.sha512","ABOUT.json","NOTICE.txt"]:
142
- z.write(os.path.join(run_dir,fn),arcname=fn)
143
- return zip_path,digest
144
-
145
-
146
- # ------------------ Core runner -----------------------------
147
- def run_total_proof(profile,noise_dist,schedule_type,schedule_params_text,seed,samples):
148
- ok,msg=_rate_limit_ok()
149
- if not ok:
150
- return {"error":msg,"rft_notice":LEGAL_NOTICE},None
151
- try:
152
- params=json.loads(schedule_params_text) if schedule_params_text.strip() else {}
153
- if not isinstance(params,dict): raise ValueError
154
- except Exception as e:
155
- return {"error":f"Invalid schedule_params JSON: {e}","rft_notice":LEGAL_NOTICE},None
156
-
157
- sigma_series=build_sigma_series(schedule_type,params)
158
- rng_master=_rng(seed)
159
- results_steps=[]; trigger_count=0
160
- for i,sigma in enumerate(sigma_series):
161
- qs, zs, statuses=[],[],[]
162
- sub_seed=int(rng_master.randint(0,2**31-1))
163
- step_rng=_rng(sub_seed)
164
- for _ in range(max(1,samples)):
165
- o=simulate_step(step_rng,profile,float(sigma),noise_dist)
166
- qs.append(o["QΩ"]); zs.append(o["ζ_sync"]); statuses.append(o["status"])
167
- q_mean=float(np.mean(qs)); z_mean=float(np.mean(zs))
168
- counts={"nominal":0,"perturbed":0,"critical":0}
169
- for s in statuses: counts[s]+=1
170
- majority=max(counts.items(),key=lambda kv:(kv[1],["nominal","perturbed","critical"].index(kv[0])))[0]
171
- if majority!="nominal": trigger_count+=1
172
- results_steps.append({"index":i,"sigma":round(float(sigma),6),
173
- "QΩ_mean":round(q_mean,6),"ζ_sync_mean":round(z_mean,6),
174
- "status_majority":majority,"samples":int(samples)})
175
- statuses=[r["status_majority"] for r in results_steps]
176
- summary={"steps":len(results_steps),
177
- "nominal_count":statuses.count("nominal"),
178
- "perturbed_count":statuses.count("perturbed"),
179
- "critical_count":statuses.count("critical"),
180
- "triggers_non_nominal":trigger_count}
181
- run_id=make_run_id(seed,profile)
182
- config={"run_id":run_id,"timestamp_utc":datetime.utcnow().isoformat()+"Z",
183
- "profile":profile,"noise_distribution":noise_dist,
184
- "schedule_type":schedule_type,"schedule_params":params,
185
- "seed":int(seed),"samples_per_step":int(samples),
186
- "about_version":RFT_VERSION,"about_doi":RFT_DOI}
187
- results={"series":results_steps,"summary":summary,"rft_notice":LEGAL_NOTICE}
188
- run_dir=f"/tmp/rft_run_{run_id}"
189
- zip_path,digest=write_bundle(run_dir,config,results)
190
- head={"run_id":run_id,"sha512":digest,"sha512_short":digest[:16]+"…",
191
- "steps":summary["steps"],
192
- "counts":{"nominal":summary["nominal_count"],
193
- "perturbed":summary["perturbed_count"],
194
- "critical":summary["critical_count"]},
195
- "rft_notice":LEGAL_NOTICE}
196
- return {"config":config,"head":head,"results":results},zip_path
197
-
198
 
199
  # ------------------ Gradio UI -------------------------------
200
- DEFAULT_PARAMS=json.dumps({"sigma":0.05},indent=2)
201
- HELP_TEXT=("Schedule JSON examples:\n"
202
- "- single: {\"sigma\": 0.05}\n"
203
- "- ramp: {\"start\": 0.0, \"stop\": 0.3, \"steps\": 12}\n"
204
- "- random: {\"min\": 0.01, \"max\": 0.3, \"steps\": 10, \"seed\": 0}\n"
205
- "- impulse: {\"base\":0.05,\"spike\":0.25,\"at\":5,\"steps\":12}\n"
206
- "- step: {\"before\":0.05,\"after\":0.2,\"at\":6,\"steps\":12}\n")
207
-
208
- with gr.Blocks(title="RFT-Ω Total-Proof API") as demo:
209
- gr.Markdown(f"### RFT-Ω Total-Proof API ({RFT_VERSION}) \n"
210
- f"Stable display mode — deterministic, signed validation harness. \n"
211
- f"**DOI:** {RFT_DOI} \n**Legal:** {LEGAL_NOTICE}")
212
  with gr.Row():
213
- profile=gr.Radio(list(PROFILES.keys()),label="System Profile",value="AI / Neural")
214
- noise_dist=gr.Radio(["gauss","uniform"],label="Noise Distribution",value="gauss")
215
  with gr.Row():
216
- schedule_type=gr.Radio(["single","ramp","random","impulse","step"],label="Schedule Type",value="single")
217
- seed_in=gr.Number(value=123,precision=0,label="Seed (int)")
218
- samples_in=gr.Slider(1,20,value=5,step=1,label="Samples per Step")
219
- schedule_params=gr.Code(value=DEFAULT_PARAMS,language="json",label="Schedule Parameters (JSON)")
220
- gr.Markdown(HELP_TEXT)
221
- run_btn=gr.Button("Run Deterministic Simulation & Sign Results")
222
- out_json=gr.JSON(label="Signed Run Summary")
223
- out_bundle=gr.File(label="Download Signed Bundle (zip)")
224
- def _on_run(p,nd,st,sp_json,seed,samples):
225
- return run_total_proof(p,nd,st,sp_json,int(seed),int(samples))
226
- run_btn.click(_on_run,
227
- inputs=[profile,noise_dist,schedule_type,schedule_params,seed_in,samples_in],
228
- outputs=[out_json,out_bundle])
229
- gr.Markdown("Ops endpoints: `/healthz`, `/about` (FastAPI mounted if available).")
230
-
231
-
232
- # ------------------ FastAPI Mount ---------------------------
233
- if HAVE_FASTAPI:
234
- api=FastAPI(title="RFT-Ω Total-Proof Ops")
235
- @api.get("/healthz")
236
- def healthz(): return {"ok":True,"service":"RFT-Ω Total-Proof","version":RFT_VERSION}
237
- @api.get("/about")
238
- def about(): return ABOUT_BLOCK
239
- app=gr.mount_gradio_app(api,demo,path="/")
240
- else:
241
- app=demo
242
-
243
-
244
- # ------------------ Launch (stable queue) -------------------
245
- if __name__=="__main__":
246
- demo.queue().launch(
247
- server_name="0.0.0.0",
248
- server_port=7860,
249
- show_error=True,
250
- debug=False
251
- )
 
1
  # ============================================================
2
+ # RFT-Ω FRAMEWORK — TOTAL-PROOF API (Gradio Stand-Alone Build)
3
+ # Author: Liam Grinstead | RFT Systems | All Rights Reserved
4
  # ============================================================
 
 
 
 
5
 
6
  import os, json, time, hashlib, zipfile, random
7
  from datetime import datetime
 
8
  import numpy as np
9
  import gradio as gr
10
 
 
 
 
 
 
 
 
11
  # ------------------ About / Legal ---------------------------
12
  RFT_VERSION = "v4.0-total-proof-stable"
13
  RFT_DOI = "https://doi.org/10.5281/zenodo.17466722"
 
14
  LEGAL_NOTICE = (
15
  "All Rights Reserved — RFT-IPURL v1.0 (UK / Berne). "
16
+ "Research validation use only. No reverse-engineering without written consent."
17
  )
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  PROFILES = {
20
+ "AI / Neural": {"base": (0.86, 0.80), "w": (0.65, 0.35)},
21
+ "SpaceX / Aerospace": {"base": (0.84, 0.79), "w": (0.60, 0.40)},
22
+ "Energy / RHES": {"base": (0.83, 0.78), "w": (0.55, 0.45)},
23
+ "Extreme Perturbation": {"base": (0.82, 0.77), "w": (0.50, 0.50)},
24
  }
25
 
26
+ def _rng(seed:int): return np.random.RandomState(seed)
 
27
 
28
+ def simulate_step(rng, profile, sigma, dist):
29
  base_q, base_z = PROFILES[profile]["base"]
30
  wq, wz = PROFILES[profile]["w"]
31
+ if dist == "uniform":
32
+ qn = rng.uniform(-sigma, sigma)
33
+ zn = rng.uniform(-sigma*0.8, sigma*0.8)
34
  else:
35
+ qn = rng.normal(0, sigma)
36
+ zn = rng.normal(0, sigma*0.8)
37
+ q = float(np.clip(base_q + wq*qn, 0.0, 0.99))
38
+ z = float(np.clip(base_z + wz*zn, 0.0, 0.99))
39
+ variance = abs(qn)+abs(zn)
40
  if variance > 0.15:
41
  status="critical"
42
  elif variance > 0.07:
43
  status="perturbed"
44
  else:
45
  status="nominal"
46
+ return {"σ": round(sigma,6),"QΩ":q,"ζ_sync":z,"status":status}
47
+
48
+ # ------------------ Main Runner -----------------------------
49
+ def run(profile, dist, sigma, seed, samples):
50
+ rng = _rng(int(seed))
51
+ results = []
52
+ for _ in range(samples):
53
+ results.append(simulate_step(rng, profile, sigma, dist))
54
+ q_mean = np.mean([r[""] for r in results])
55
+ z_mean = np.mean([r["ζ_sync"] for r in results])
56
+ summary = {
57
+ "QΩ_mean": round(float(q_mean),6),
58
+ "ζ_sync_mean": round(float(z_mean),6),
59
+ "samples": samples,
60
+ "profile": profile,
61
+ "noise": sigma,
62
+ "dist": dist,
63
+ "status_majority": max(
64
+ ["nominal","perturbed","critical"],
65
+ key=lambda s: sum(1 for r in results if r["status"]==s)
66
+ ),
67
+ "rft_notice": LEGAL_NOTICE
68
+ }
69
+ return summary
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
  # ------------------ Gradio UI -------------------------------
72
+ with gr.Blocks(title="RFT-Ω Total-Proof Kernel") as demo:
73
+ gr.Markdown(f"### RFT-Ω Total-Proof Kernel ({RFT_VERSION}) \n"
74
+ f"DOI: [{RFT_DOI}]({RFT_DOI}) \n{LEGAL_NOTICE}")
75
+
 
 
 
 
 
 
 
 
76
  with gr.Row():
77
+ profile = gr.Dropdown(list(PROFILES.keys()), label="System Profile", value="AI / Neural")
78
+ dist = gr.Radio(["gauss","uniform"], label="Noise Distribution", value="gauss")
79
  with gr.Row():
80
+ sigma = gr.Slider(0.0, 0.3, value=0.05, step=0.01, label="Noise Scale (σ)")
81
+ seed = gr.Number(value=123, precision=0, label="Seed")
82
+ samples = gr.Slider(1, 20, value=5, step=1, label="Samples")
83
+
84
+ run_btn = gr.Button("Run Simulation")
85
+ output = gr.JSON(label="Run Summary")
86
+
87
+ run_btn.click(run, inputs=[profile, dist, sigma, seed, samples], outputs=[output])
88
+
89
+ # ------------------ Launch -------------------------------
90
+ if __name__ == "__main__":
91
+ demo.launch(server_name="0.0.0.0", server_port=7860, show_error=True, debug=False)