HirModel commited on
Commit
290b2ed
·
verified ·
1 Parent(s): 8602a97

Upload 7 files

Browse files

Upload a short video and run a source-bound atomization route.

This Space demonstrates Video Atomization, Trace-Stack Rehydration, and Data Hologram formation as a Substrate Mesh runtime surface. The uploaded video is not treated as a monolithic compressed payload. Instead, the runtime hashes the source, samples frame atoms, detects scene intervals, records motion deltas, applies trace capsules, stacks the traces, and returns a rehydrated review surface with an HIR × OAM receipt.

The demo shows how video can become a pressure-readable temporal mesh:

source video
→ source capsule
→ frame atoms
→ scene atoms
→ trace capsules
→ stacked trace field
→ data hologram manifest
→ rehydrated review surface
→ human validation capsule

Boundary: this is not video compression, not a replacement for codecs, and not a physical hologram generator. This v0.1 Space demonstrates the source-bound data-hologram layer. Physical hologram translation would require a later optical modulation layer.

Core claim: video does not have to be handled only as a compressed monolithic file. It can be atomized into source-bound trace units, stacked into a data hologram, pressure-read, and rehydrated into a reviewable route surface while preserving source authority and human validation.

.gitignore ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ __pycache__/
2
+ *.pyc
3
+ .DS_Store
4
+ .env
5
+ runs/
6
+ tmp/
HF_Substrate_Video_Atomization_Runtime_v0_1.zip.sha256 ADDED
@@ -0,0 +1 @@
 
 
1
+ 333da88eb4746d62725df837aef44bd47154a193bcc2005d8e7b498290263094 HF_Substrate_Video_Atomization_Runtime_v0_1.zip
README.md CHANGED
@@ -1,15 +1,49 @@
1
  ---
2
- title: Video Atomization Trace Stack Runtime
3
- emoji: 📊
4
- colorFrom: yellow
5
- colorTo: green
6
  sdk: gradio
7
- sdk_version: 6.18.0
8
- python_version: '3.13'
9
  app_file: app.py
10
  pinned: false
11
  license: cc-by-nc-sa-4.0
12
  short_description: Video atomization and trace-stack rehydration
13
  ---
14
 
15
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Substrate Video Atomization Runtime
3
+ emoji: 🎞️
4
+ colorFrom: blue
5
+ colorTo: indigo
6
  sdk: gradio
7
+ sdk_version: 4.44.0
 
8
  app_file: app.py
9
  pinned: false
10
  license: cc-by-nc-sa-4.0
11
  short_description: Video atomization and trace-stack rehydration
12
  ---
13
 
14
+ # Substrate Video Atomization Runtime v0.1
15
+
16
+ Upload a short video and run a source-bound atomization route.
17
+
18
+ This Space demonstrates Video Atomization, Trace-Stack Rehydration, and Data Hologram formation as a Substrate Mesh runtime surface. The uploaded video is not treated as a monolithic compressed payload. Instead, the runtime hashes the source, samples frame atoms, detects scene intervals, records motion deltas, applies trace capsules, stacks the traces, and returns a rehydrated review surface with an HIR × OAM receipt.
19
+
20
+ The demo shows how video can become a pressure-readable temporal mesh:
21
+
22
+ ```text
23
+ source video
24
+ → source capsule
25
+ → frame atoms
26
+ → scene atoms
27
+ → trace capsules
28
+ → stacked trace field
29
+ → data hologram manifest
30
+ → rehydrated review surface
31
+ → human validation capsule
32
+ ```
33
+
34
+ ## Boundary
35
+
36
+ This is not video compression, not a replacement for codecs, and not a physical hologram generator. This v0.1 Space demonstrates the source-bound data-hologram layer. Physical hologram translation would require a later optical modulation layer.
37
+
38
+ ## What the demo proves
39
+
40
+ - The source video is hashed and held as the canonical anchor.
41
+ - The video is atomized into source-bound frame and scene atoms.
42
+ - Each sampled atom receives a trace capsule.
43
+ - Trace capsules are stacked into a data-hologram manifest.
44
+ - The rehydrated output remains a review surface, not a source replacement.
45
+ - Human validation remains required before settlement.
46
+
47
+ ## Core claim
48
+
49
+ Video does not have to be handled only as a compressed monolithic file. It can be atomized into source-bound trace units, stacked into a data hologram, pressure-read, and rehydrated into a reviewable route surface.
app.py ADDED
@@ -0,0 +1,521 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import cv2
3
+ import json
4
+ import hashlib
5
+ import tempfile
6
+ import zipfile
7
+ from datetime import datetime, timezone
8
+ from pathlib import Path
9
+
10
+ import gradio as gr
11
+ import pandas as pd
12
+ from PIL import Image
13
+
14
+
15
+ APP_TITLE = "Substrate Video Atomization Runtime v0.1"
16
+ BOUNDARY_NOTE = (
17
+ "This demo performs source-bound video atomization and trace-stack rehydration. "
18
+ "It is not video compression, not a codec replacement, and not a physical hologram generator. "
19
+ "The output is a data-hologram review surface with receipts."
20
+ )
21
+
22
+
23
+ def sha256_file(path: str) -> str:
24
+ h = hashlib.sha256()
25
+ with open(path, "rb") as f:
26
+ for chunk in iter(lambda: f.read(1024 * 1024), b""):
27
+ h.update(chunk)
28
+ return h.hexdigest()
29
+
30
+
31
+ def sha256_bytes(data: bytes) -> str:
32
+ return hashlib.sha256(data).hexdigest()
33
+
34
+
35
+ def format_time(seconds: float) -> str:
36
+ if seconds is None:
37
+ seconds = 0.0
38
+ seconds = max(float(seconds), 0.0)
39
+ h = int(seconds // 3600)
40
+ m = int((seconds % 3600) // 60)
41
+ s = seconds % 60
42
+ return f"{h:02d}:{m:02d}:{s:06.3f}"
43
+
44
+
45
+ def safe_float(value, default=0.0):
46
+ try:
47
+ if value is None:
48
+ return default
49
+ return float(value)
50
+ except Exception:
51
+ return default
52
+
53
+
54
+ def safe_int(value, default=0):
55
+ try:
56
+ if value is None:
57
+ return default
58
+ return int(value)
59
+ except Exception:
60
+ return default
61
+
62
+
63
+ def write_json(path: Path, obj) -> None:
64
+ path.parent.mkdir(parents=True, exist_ok=True)
65
+ path.write_text(json.dumps(obj, indent=2, ensure_ascii=False), encoding="utf-8")
66
+
67
+
68
+ def make_run_dir() -> Path:
69
+ stamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
70
+ return Path(tempfile.mkdtemp(prefix=f"video_atomization_{stamp}_"))
71
+
72
+
73
+ def classify_pressure(motion_delta: float, scene_threshold: float) -> str:
74
+ if motion_delta >= scene_threshold * 1.6:
75
+ return "STRAINED_SCENE_BREAK_PRESSURE"
76
+ if motion_delta >= scene_threshold:
77
+ return "HELD_WITH_SCENE_BOUNDARY"
78
+ return "HELD"
79
+
80
+
81
+ def build_markdown_receipt(receipt: dict, source_capsule: dict, trace_stack: dict) -> str:
82
+ lines = [
83
+ "# HIR × OAM Video Atomization Receipt",
84
+ "",
85
+ f"- Receipt type: `{receipt['receipt_type']}`",
86
+ f"- Route state: `{receipt['pressure_state']}`",
87
+ f"- Source mutation: `{receipt['source_mutation']}`",
88
+ f"- Canonical anchor: `{receipt['canonical_anchor']}`",
89
+ f"- Atomization state: `{receipt['atomization_state']}`",
90
+ f"- Trace-stack state: `{receipt['trace_stack_state']}`",
91
+ f"- Data-hologram state: `{receipt['data_hologram_state']}`",
92
+ f"- Human review: `{receipt['human_review']}`",
93
+ "",
94
+ "## Source",
95
+ "",
96
+ f"- Filename: `{source_capsule.get('filename')}`",
97
+ f"- SHA-256: `{source_capsule.get('sha256')}`",
98
+ f"- Duration: `{source_capsule.get('duration_seconds')}` seconds",
99
+ f"- FPS: `{source_capsule.get('fps')}`",
100
+ f"- Frame count: `{source_capsule.get('frame_count')}`",
101
+ "",
102
+ "## Boundary",
103
+ "",
104
+ BOUNDARY_NOTE,
105
+ "",
106
+ "## Trace stack layers",
107
+ "",
108
+ ]
109
+ for layer in trace_stack.get("stack_layers", []):
110
+ lines.append(f"- `{layer}`")
111
+ lines.extend([
112
+ "",
113
+ "## Settlement",
114
+ "",
115
+ "Machine route surface only. Human retains settlement authority.",
116
+ ])
117
+ return "\n".join(lines)
118
+
119
+
120
+ def create_run_packet(run_dir: Path, packet_name: str = "video_atomization_run_packet.zip") -> str:
121
+ packet_path = run_dir / packet_name
122
+ with zipfile.ZipFile(packet_path, "w", compression=zipfile.ZIP_DEFLATED) as z:
123
+ for path in run_dir.rglob("*"):
124
+ if path == packet_path or path.is_dir():
125
+ continue
126
+ z.write(path, path.relative_to(run_dir))
127
+ return str(packet_path)
128
+
129
+
130
+ def atomize_video(video_path, sample_every_seconds=1.0, scene_threshold=32.0, max_frame_atoms=72):
131
+ if not video_path:
132
+ empty = pd.DataFrame()
133
+ return (
134
+ None,
135
+ {"error": "No video uploaded."},
136
+ empty,
137
+ empty,
138
+ {"error": "No trace stack generated."},
139
+ {"error": "No receipt generated."},
140
+ {"human_validation_state": "NOT_AVAILABLE"},
141
+ [],
142
+ None,
143
+ "Upload a video and run the route."
144
+ )
145
+
146
+ run_dir = make_run_dir()
147
+ frames_dir = run_dir / "frame_atoms"
148
+ manifests_dir = run_dir / "manifests"
149
+ receipts_dir = run_dir / "receipts"
150
+ frames_dir.mkdir(parents=True, exist_ok=True)
151
+ manifests_dir.mkdir(parents=True, exist_ok=True)
152
+ receipts_dir.mkdir(parents=True, exist_ok=True)
153
+
154
+ sample_every_seconds = max(safe_float(sample_every_seconds, 1.0), 0.1)
155
+ scene_threshold = max(safe_float(scene_threshold, 32.0), 1.0)
156
+ max_frame_atoms = max(safe_int(max_frame_atoms, 72), 1)
157
+
158
+ source_hash = sha256_file(video_path)
159
+ file_size = os.path.getsize(video_path)
160
+ filename = os.path.basename(video_path)
161
+
162
+ cap = cv2.VideoCapture(video_path)
163
+ if not cap.isOpened():
164
+ empty = pd.DataFrame()
165
+ return (
166
+ video_path,
167
+ {"error": "OpenCV could not read this video. Try MP4/H.264, WebM, or MOV."},
168
+ empty,
169
+ empty,
170
+ {"error": "No trace stack generated."},
171
+ {"error": "No receipt generated."},
172
+ {"human_validation_state": "NOT_AVAILABLE"},
173
+ [],
174
+ None,
175
+ "Could not read the video file."
176
+ )
177
+
178
+ fps = safe_float(cap.get(cv2.CAP_PROP_FPS), 0.0)
179
+ frame_count = safe_int(cap.get(cv2.CAP_PROP_FRAME_COUNT), 0)
180
+ width = safe_int(cap.get(cv2.CAP_PROP_FRAME_WIDTH), 0)
181
+ height = safe_int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT), 0)
182
+ duration = frame_count / fps if fps else 0.0
183
+
184
+ source_capsule = {
185
+ "capsule_type": "SOURCE_VIDEO_CAPSULE",
186
+ "source_id": "video_source_001",
187
+ "filename": filename,
188
+ "sha256": source_hash,
189
+ "size_bytes": file_size,
190
+ "width": width,
191
+ "height": height,
192
+ "fps": round(fps, 6),
193
+ "frame_count": frame_count,
194
+ "duration_seconds": round(duration, 6),
195
+ "route_state": "SOURCE_HASHED",
196
+ "source_mutation": "BLOCKED",
197
+ "canonical_anchor": "SOURCE_VIDEO_REMAINS_AUTHORITY",
198
+ "boundary": BOUNDARY_NOTE,
199
+ }
200
+
201
+ frame_atoms = []
202
+ scene_atoms = []
203
+ motion_atoms = []
204
+ gallery_items = []
205
+
206
+ sample_interval = max(int(round(fps * sample_every_seconds)), 1) if fps else 30
207
+ previous_gray = None
208
+ current_scene_start = 0.0
209
+ scene_index = 0
210
+ atom_index = 0
211
+ frame_idx = 0
212
+
213
+ while True:
214
+ ok, frame = cap.read()
215
+ if not ok:
216
+ break
217
+
218
+ timestamp = frame_idx / fps if fps else 0.0
219
+ gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
220
+
221
+ motion_delta = 0.0
222
+ pressure_state = "HELD"
223
+ if previous_gray is not None:
224
+ diff = cv2.absdiff(gray, previous_gray)
225
+ motion_delta = float(diff.mean())
226
+ pressure_state = classify_pressure(motion_delta, scene_threshold)
227
+
228
+ motion_atoms.append({
229
+ "motion_atom_id": f"motion_atom_{frame_idx:06d}",
230
+ "frame_index": frame_idx,
231
+ "time": format_time(timestamp),
232
+ "source_video_sha256": source_hash,
233
+ "motion_delta": round(motion_delta, 6),
234
+ "pressure_state": pressure_state
235
+ })
236
+
237
+ if motion_delta >= scene_threshold:
238
+ scene_atoms.append({
239
+ "scene_id": f"scene_atom_{scene_index:06d}",
240
+ "time_start": format_time(current_scene_start),
241
+ "time_end": format_time(timestamp),
242
+ "source_video_sha256": source_hash,
243
+ "scene_boundary_reason": f"motion_delta {motion_delta:.3f} >= threshold {scene_threshold:.3f}",
244
+ "pressure_state": "HELD_WITH_BOUNDARY",
245
+ "claim_boundary": "scene interval only; does not support identity, intent, or external-context claim",
246
+ "rehydration_state": "ELIGIBLE_SOURCE_BOUND",
247
+ "human_review": "REQUIRED_BEFORE_PUBLIC_CLAIM"
248
+ })
249
+ scene_index += 1
250
+ current_scene_start = timestamp
251
+
252
+ should_sample = frame_idx % sample_interval == 0 and atom_index < max_frame_atoms
253
+ if should_sample:
254
+ rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
255
+ img = Image.fromarray(rgb)
256
+
257
+ frame_name = f"frame_atom_{atom_index:06d}.jpg"
258
+ img_path = frames_dir / frame_name
259
+ img.save(img_path, quality=90)
260
+
261
+ local_hash = sha256_file(str(img_path))
262
+ atom = {
263
+ "atom_id": f"frame_atom_{atom_index:06d}",
264
+ "atom_type": "frame",
265
+ "frame_index": frame_idx,
266
+ "time_start": format_time(timestamp),
267
+ "time_end": format_time(timestamp + (1.0 / fps if fps else 0.0)),
268
+ "source_video_sha256": source_hash,
269
+ "local_hash": local_hash,
270
+ "sample_path": f"frame_atoms/{frame_name}",
271
+ "motion_delta": round(motion_delta, 6),
272
+ "claim_boundary": "sampled frame only; does not support full-scene, identity, intent, or external-context claim",
273
+ "pressure_state": pressure_state,
274
+ "trace_capsule_state": "CAPSULED_SOURCE_BOUND",
275
+ "rehydration_state": "ELIGIBLE_SOURCE_BOUND",
276
+ "human_review": "REQUIRED_BEFORE_PUBLIC_CLAIM"
277
+ }
278
+ frame_atoms.append(atom)
279
+ gallery_items.append((str(img_path), atom["atom_id"]))
280
+ atom_index += 1
281
+
282
+ previous_gray = gray
283
+ frame_idx += 1
284
+
285
+ cap.release()
286
+
287
+ if duration > current_scene_start or not scene_atoms:
288
+ scene_atoms.append({
289
+ "scene_id": f"scene_atom_{scene_index:06d}",
290
+ "time_start": format_time(current_scene_start),
291
+ "time_end": format_time(duration),
292
+ "source_video_sha256": source_hash,
293
+ "scene_boundary_reason": "final interval closure",
294
+ "pressure_state": "HELD",
295
+ "claim_boundary": "scene interval only; does not support identity, intent, or external-context claim",
296
+ "rehydration_state": "ELIGIBLE_SOURCE_BOUND",
297
+ "human_review": "REQUIRED_BEFORE_PUBLIC_CLAIM"
298
+ })
299
+
300
+ atom_manifest = {
301
+ "manifest_type": "VIDEO_ATOM_MANIFEST",
302
+ "source_video_sha256": source_hash,
303
+ "atom_counts": {
304
+ "frame_atoms": len(frame_atoms),
305
+ "scene_atoms": len(scene_atoms),
306
+ "motion_atoms": len(motion_atoms),
307
+ },
308
+ "sampling": {
309
+ "sample_every_seconds": sample_every_seconds,
310
+ "sample_interval_frames": sample_interval,
311
+ "max_frame_atoms": max_frame_atoms,
312
+ "scene_threshold": scene_threshold,
313
+ },
314
+ "frame_atoms": frame_atoms,
315
+ "scene_atoms": scene_atoms,
316
+ "motion_atoms_summary": {
317
+ "count": len(motion_atoms),
318
+ "note": "Full motion atom list is included as motion_atoms.json in the run packet."
319
+ }
320
+ }
321
+
322
+ trace_stack = {
323
+ "manifest_type": "TRACE_STACK_DATA_HOLOGRAM_MANIFEST",
324
+ "trace_stack_id": "trace_stack_001",
325
+ "source_video_sha256": source_hash,
326
+ "stack_layers": [
327
+ "source_capsule",
328
+ "frame_trace_capsules",
329
+ "scene_trace_capsules",
330
+ "motion_delta_atoms",
331
+ "claim_boundaries",
332
+ "pressure_states",
333
+ "rehydration_states",
334
+ "human_validation_state"
335
+ ],
336
+ "data_hologram_state": "FORMED",
337
+ "rehydration_state": "REHYDRATED_SOURCE_BOUND_REVIEW_SURFACE",
338
+ "optical_hologram_state": "NOT_GENERATED_IN_THIS_DEMO",
339
+ "source_mutation": "BLOCKED",
340
+ "canonical_anchor": "SOURCE_VIDEO_REMAINS_AUTHORITY",
341
+ "boundary": "Data hologram only. Physical hologram translation requires a later optical modulation layer."
342
+ }
343
+
344
+ receipt = {
345
+ "receipt_type": "HIR_OAM_VIDEO_ATOMIZATION_RECEIPT",
346
+ "generated_utc": datetime.now(timezone.utc).isoformat(),
347
+ "source_held": True,
348
+ "source_mutation": "BLOCKED",
349
+ "atomization_state": "ATOMIZED_SOURCE_BOUND",
350
+ "trace_capsule_state": "CAPSULED_PER_ATOM",
351
+ "trace_stack_state": "STACKED",
352
+ "data_hologram_state": "FORMED",
353
+ "rehydration_state": "REHYDRATED_REVIEW_SURFACE",
354
+ "pressure_state": "HELD_WITH_BOUNDARY",
355
+ "human_review": "REQUIRED",
356
+ "canonical_anchor": "SOURCE_VIDEO_REMAINS_AUTHORITY",
357
+ "claims_blocked": [
358
+ "not a codec",
359
+ "not monolithic compression",
360
+ "not a physical hologram generator",
361
+ "not source replacement",
362
+ "not automatic settlement"
363
+ ]
364
+ }
365
+
366
+ human_validation = {
367
+ "capsule_type": "HUMAN_VALIDATION_CAPSULE",
368
+ "human_validation_state": "REQUIRED",
369
+ "machine_route_surface": "GENERATED",
370
+ "settlement_authority": "HUMAN",
371
+ "available_actions": [
372
+ "APPROVE",
373
+ "REJECT",
374
+ "DEFER",
375
+ "REPAIR",
376
+ "FORK",
377
+ "QUARANTINE",
378
+ "REQUEST_MORE_ATOMS"
379
+ ],
380
+ "settlement_note": "Machine generated route surface only. Human retains settlement authority."
381
+ }
382
+
383
+ write_json(manifests_dir / "source_video_capsule.json", source_capsule)
384
+ write_json(manifests_dir / "atom_manifest.json", atom_manifest)
385
+ write_json(manifests_dir / "trace_stack_data_hologram_manifest.json", trace_stack)
386
+ write_json(manifests_dir / "motion_atoms.json", motion_atoms)
387
+ write_json(receipts_dir / "hir_oam_video_atomization_receipt.json", receipt)
388
+ write_json(receipts_dir / "human_validation_capsule.json", human_validation)
389
+ (receipts_dir / "HIR_OAM_VIDEO_RECEIPT.md").write_text(
390
+ build_markdown_receipt(receipt, source_capsule, trace_stack),
391
+ encoding="utf-8"
392
+ )
393
+
394
+ frame_df = pd.DataFrame(frame_atoms)
395
+ scene_df = pd.DataFrame(scene_atoms)
396
+
397
+ packet_path = create_run_packet(run_dir)
398
+
399
+ summary = (
400
+ f"Route complete. Source held. {len(frame_atoms)} frame atoms, "
401
+ f"{len(scene_atoms)} scene atoms, {len(motion_atoms)} motion atoms. "
402
+ "Trace stack formed. Data hologram review surface generated. Human validation required."
403
+ )
404
+
405
+ return (
406
+ video_path,
407
+ source_capsule,
408
+ frame_df,
409
+ scene_df,
410
+ trace_stack,
411
+ receipt,
412
+ human_validation,
413
+ gallery_items,
414
+ packet_path,
415
+ summary
416
+ )
417
+
418
+
419
+ custom_css = """
420
+ .gradio-container { max-width: 1280px !important; }
421
+ #receipt_summary textarea { font-size: 1.05rem; }
422
+ """
423
+
424
+ with gr.Blocks(title=APP_TITLE, css=custom_css) as demo:
425
+ gr.Markdown(
426
+ """
427
+ # Substrate Video Atomization Runtime v0.1
428
+
429
+ Upload a short video and run a source-bound atomization route.
430
+
431
+ This Space hashes the source video, samples frame atoms, detects scene intervals, records motion-delta pressure,
432
+ applies trace capsules, stacks the traces into a data-hologram manifest, and returns an HIR × OAM receipt.
433
+
434
+ **Boundary:** this is not video compression, not a codec replacement, and not a physical hologram generator.
435
+ This v0.1 Space demonstrates the source-bound data-hologram layer.
436
+ """
437
+ )
438
+
439
+ with gr.Row():
440
+ video_input = gr.Video(
441
+ label="Upload source video",
442
+ sources=["upload"],
443
+ type="filepath"
444
+ )
445
+ video_output = gr.Video(label="Source video preview")
446
+
447
+ with gr.Row():
448
+ sample_every_seconds = gr.Slider(
449
+ minimum=0.25,
450
+ maximum=5.0,
451
+ value=1.0,
452
+ step=0.25,
453
+ label="Sample every N seconds"
454
+ )
455
+ scene_threshold = gr.Slider(
456
+ minimum=5.0,
457
+ maximum=90.0,
458
+ value=32.0,
459
+ step=1.0,
460
+ label="Scene boundary motion threshold"
461
+ )
462
+ max_frame_atoms = gr.Slider(
463
+ minimum=4,
464
+ maximum=160,
465
+ value=72,
466
+ step=4,
467
+ label="Maximum frame atoms"
468
+ )
469
+
470
+ run_btn = gr.Button("Run Video Atomization Route", variant="primary")
471
+
472
+ route_summary = gr.Textbox(
473
+ label="Route Summary",
474
+ elem_id="receipt_summary",
475
+ interactive=False
476
+ )
477
+
478
+ with gr.Tabs():
479
+ with gr.Tab("Source Capsule"):
480
+ source_json = gr.JSON(label="Source Video Capsule")
481
+
482
+ with gr.Tab("Frame Atoms"):
483
+ frame_table = gr.Dataframe(label="Frame Trace Capsules", wrap=True)
484
+
485
+ with gr.Tab("Scene Atoms"):
486
+ scene_table = gr.Dataframe(label="Scene Trace Capsules", wrap=True)
487
+
488
+ with gr.Tab("Trace Stack / Data Hologram"):
489
+ trace_json = gr.JSON(label="Stacked Trace Field")
490
+
491
+ with gr.Tab("HIR × OAM Receipt"):
492
+ receipt_json = gr.JSON(label="Route Receipt")
493
+
494
+ with gr.Tab("Human Validation"):
495
+ validation_json = gr.JSON(label="Human Validation Capsule")
496
+
497
+ with gr.Tab("Frame Atom Strip"):
498
+ gallery = gr.Gallery(label="Sampled Frame Atoms", columns=4, height=520)
499
+
500
+ with gr.Tab("Download Run Packet"):
501
+ run_packet = gr.File(label="Download JSON receipts and sampled frame atoms")
502
+
503
+ run_btn.click(
504
+ atomize_video,
505
+ inputs=[video_input, sample_every_seconds, scene_threshold, max_frame_atoms],
506
+ outputs=[
507
+ video_output,
508
+ source_json,
509
+ frame_table,
510
+ scene_table,
511
+ trace_json,
512
+ receipt_json,
513
+ validation_json,
514
+ gallery,
515
+ run_packet,
516
+ route_summary
517
+ ]
518
+ )
519
+
520
+ if __name__ == "__main__":
521
+ demo.launch()
demo_contract.json ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "contract_type": "SUBSTRATE_VIDEO_ATOMIZATION_RUNTIME_CONTRACT",
3
+ "version": "0.1",
4
+ "route": [
5
+ "source_video_upload",
6
+ "source_hash",
7
+ "frame_atom_sampling",
8
+ "scene_interval_detection",
9
+ "motion_delta_pressure_read",
10
+ "trace_capsule_assignment",
11
+ "trace_stack_manifest",
12
+ "data_hologram_manifest",
13
+ "rehydrated_review_surface",
14
+ "hir_oam_receipt",
15
+ "human_validation_capsule"
16
+ ],
17
+ "not_claims": [
18
+ "not video compression",
19
+ "not a codec replacement",
20
+ "not an optical hologram generator",
21
+ "not source replacement",
22
+ "not automatic settlement"
23
+ ],
24
+ "canonical_anchor_rule": "SOURCE_VIDEO_REMAINS_AUTHORITY",
25
+ "source_mutation": "BLOCKED",
26
+ "human_validation": "REQUIRED"
27
+ }
packages.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ ffmpeg
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ gradio>=4.44.0
2
+ opencv-python-headless
3
+ numpy
4
+ pandas
5
+ pillow