specimba commited on
Commit
5090ba8
·
verified ·
1 Parent(s): 4c4521d

fix: simplify creator-first generation flow

Browse files
.gitignore CHANGED
@@ -39,6 +39,7 @@ venv.bak/
39
  *.pfx
40
  .huggingface/
41
  .cache/huggingface/
 
42
  .modal.toml
43
  .netrc
44
  .pypirc
@@ -66,4 +67,3 @@ Thumbs.db
66
  .idea/
67
  .vscode/
68
  tempCodeRunnerFile.py
69
-
 
39
  *.pfx
40
  .huggingface/
41
  .cache/huggingface/
42
+ .hf-upload-cache/
43
  .modal.toml
44
  .netrc
45
  .pypirc
 
67
  .idea/
68
  .vscode/
69
  tempCodeRunnerFile.py
 
app.py CHANGED
@@ -5,6 +5,7 @@ from __future__ import annotations
5
  import os
6
  import sys
7
  import hashlib
 
8
  from pathlib import Path
9
  from typing import Any
10
  from urllib.parse import urlparse
@@ -48,6 +49,17 @@ DEFAULT_PROMPT = (
48
 
49
  MODEL_RELAY = WeaverModelRelay()
50
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
  def _default_operator_state() -> dict[str, Any]:
53
  return {
@@ -194,6 +206,9 @@ def _creator_controls(
194
  palette: str | None = None,
195
  hardware: str | None = None,
196
  locate_focus: list[str] | None = None,
 
 
 
197
  ) -> dict[str, Any]:
198
  """
199
  Create a control object combining wardrobe selections with generation policy and reasoning configuration.
@@ -220,10 +235,32 @@ def _creator_controls(
220
  "flux_primary": "black-forest-labs/FLUX.2-klein-9B",
221
  "flux_sidecar": "black-forest-labs/FLUX.2-klein-4B",
222
  "lora_policy": "attempt compatible runtime adapter; report loaded/skipped/failed",
 
 
 
223
  },
224
  }
225
 
226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  def _prompt_with_controls(prompt: str, controls: dict[str, Any]) -> str:
228
  """
229
  Augments a prompt with wardrobe control parameters.
@@ -247,7 +284,12 @@ def _prompt_with_controls(prompt: str, controls: dict[str, Any]) -> str:
247
  wardrobe.get("hardware"),
248
  ]
249
  suffix = ", ".join(str(item) for item in additions if item)
250
- return f"{prompt}\nWardrobe controls: {suffix}" if suffix else prompt
 
 
 
 
 
251
 
252
 
253
  def _generated_output_path(operator_state: dict[str, Any] | None) -> str | None:
@@ -312,6 +354,18 @@ def _wardrobe_summary(run: Any) -> str:
312
  SECTIONS = ["Forge", "Wardrobe", "Lore", "Models", "Security", "Runs"]
313
 
314
 
 
 
 
 
 
 
 
 
 
 
 
 
315
  def _dashboard_regions(
316
  run: Any | None = None,
317
  adult_mode: bool = False,
@@ -344,6 +398,9 @@ def run_weave(
344
  palette: str | None = None,
345
  hardware: str | None = None,
346
  reference_url: str | None = None,
 
 
 
347
  ) -> tuple[Any, ...]:
348
  """
349
  Execute the complete weaving workflow from prompt through image generation and evaluation.
@@ -354,6 +411,8 @@ def run_weave(
354
  Tuple containing dashboard region HTML fragments (topbar, command_rail, workflow, operations, inspector, drawer, status, artifacts, providers), catalog HTML, run data, catalog summary, scan results, operator state with generation details and judge evidence, and button state updates.
355
  """
356
  prompt = prompt.strip() or DEFAULT_PROMPT
 
 
357
  controls = _creator_controls(
358
  reasoning_mode=reasoning_mode,
359
  video_preset=video_preset,
@@ -363,6 +422,9 @@ def run_weave(
363
  footwear=footwear,
364
  palette=palette,
365
  hardware=hardware,
 
 
 
366
  )
367
  controlled_prompt = _prompt_with_controls(prompt, controls)
368
  reference_scan = scan_file(_file_path(upload))
@@ -377,7 +439,9 @@ def run_weave(
377
  )
378
  generation = generate_flux_image(
379
  run.refined_prompt.refined,
380
- seed=_checkpoint_seed(run.checkpoint.checkpoint_id),
 
 
381
  adult_mode=adult_mode,
382
  )
383
  generated_scan = scan_file(generation.output_path) if generation.output_path else scan_file(None)
@@ -392,14 +456,17 @@ def run_weave(
392
  run_packet=run.to_dict(),
393
  minicpm_result=minicpm.to_dict(),
394
  )
395
- provider_state = generation.provider_state if generation.status in {"success", "error", "missing_runtime", "no_cuda"} else "checkpointed"
396
  if generation.status == "success":
397
  provider_state = "generated"
 
 
 
 
398
  operator_state = {
399
  "provider_state": provider_state,
400
  "checkpoint": "pending_review",
401
  "export": generated_scan.get("export_gate", "pending"),
402
- "message": generation.message or "Run packet generated. Human checkpoint required before provider promotion or export.",
403
  "generation": generation.to_dict(),
404
  "creator_controls": controls,
405
  "reference_metadata": reference_metadata,
@@ -433,7 +500,7 @@ def run_weave(
433
  run,
434
  generated_scan,
435
  operator_state,
436
- gr.update(interactive=True),
437
  )
438
 
439
 
@@ -545,7 +612,7 @@ def _render_stateful(
545
  catalog_summary(adult_mode),
546
  scan,
547
  operator_state,
548
- gr.update(interactive=run is not None and operator_state.get("provider_state") not in {"idle", "stopped", "exported"}),
549
  )
550
 
551
 
@@ -613,7 +680,7 @@ def approve_checkpoint(
613
  state = operator_state or _default_operator_state()
614
  scan = _authoritative_generated_scan(state)
615
  if run is None:
616
- next_state = {**_default_operator_state(), "provider_state": "blocked", "message": "No run exists yet. Run Active Weave first."}
617
  elif not _generated_output_path(state):
618
  next_state = {
619
  **state,
@@ -632,7 +699,7 @@ def approve_checkpoint(
632
  "message": (
633
  "Checkpoint approved. Export is ready after clear ST3GG scan."
634
  if export_state == "clear"
635
- else "Checkpoint approved. ST3GG is not clear; add an override reason and click Prepare Export Packet to write an audit packet."
636
  ),
637
  }
638
  return _render_stateful(run, adult_mode, scan, active_section, next_state)
@@ -670,11 +737,11 @@ def export_packet(
670
  scan = _authoritative_generated_scan(state)
671
  override_reason = (override_reason or "").strip()
672
  if run is None:
673
- next_state = {**state, "provider_state": "blocked", "export": "blocked", "message": "Export gate active: run an active weave before preparing an export packet."}
674
  elif state.get("checkpoint") != "approved":
675
  next_state = {**state, "provider_state": "blocked", "export": "blocked", "message": "Export gate active: approve the human checkpoint before release."}
676
  elif not _generated_output_path(state):
677
- next_state = {**state, "provider_state": "blocked", "export": "blocked", "message": "Export gate active: generate an artifact before preparing evidence."}
678
  elif scan.get("export_gate") != "clear" and not override_reason:
679
  next_state = {**state, "provider_state": "blocked", "export": scan.get("export_gate", "blocked"), "message": "Export gate active: ST3GG is not clear. Add an explicit override reason to write an audit packet."}
680
  else:
@@ -716,7 +783,7 @@ def stop_provider_job(
716
  next_state = {
717
  **(operator_state or _default_operator_state()),
718
  "provider_state": "stopped",
719
- "message": "Provider handoff stopped. Local dry-run packet and evidence remain available.",
720
  }
721
  return _render_stateful(run, adult_mode, scan, active_section, next_state)
722
 
@@ -752,6 +819,8 @@ def reset_demo(
752
  scan,
753
  operator_state,
754
  gr.update(interactive=False),
 
 
755
  )
756
 
757
 
@@ -762,114 +831,116 @@ with gr.Blocks(title="NEXUS Visual Weaver") as demo:
762
  active_run_state = gr.State(None)
763
  scan_state = gr.State(scan_file(None))
764
  operator_state = gr.State(initial_operator_state)
765
- topbar_html = gr.HTML(initial_regions["topbar"], container=False)
766
 
767
- with gr.Group(elem_id="nw-inputs", elem_classes=["nw-control-panel"]):
768
- gr.HTML(render_command_header(), container=False)
769
- with gr.Row():
 
770
  prompt = gr.Textbox(
771
  value=DEFAULT_PROMPT,
772
- label="Creative Brief",
773
- lines=3,
774
  max_lines=6,
775
- scale=5,
776
  )
777
- with gr.Column(scale=2):
778
- reasoning_mode = gr.Radio(
779
- ["Strict", "Frontier"],
780
- value="Strict",
781
- label="Reasoning Mode",
 
 
782
  )
783
- video_preset = gr.Dropdown(
784
- ["Wan2.2 I2V", "LTX-2.3"],
785
- value="Wan2.2 I2V",
786
- label="Video Path Preset",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
787
  )
788
- with gr.Row():
789
- silhouette = gr.Dropdown(
790
- ["structured long coat", "fitted gothic bodice", "layered tactical silhouette"],
791
- value="structured long coat",
792
- label="Silhouette",
793
- )
794
- outerwear = gr.Dropdown(
795
- ["black patent leather long coat", "faux fur collar coat", "tailored rain slicker"],
796
- value="black patent leather long coat",
797
- label="Outerwear",
798
- )
799
- upper_body = gr.Dropdown(
800
- ["Chantilly lace neckline", "black mesh layer", "structured corset bodice"],
801
- value="Chantilly lace neckline",
802
- label="Upper Body",
803
- )
804
- footwear = gr.Dropdown(
805
- ["platform boots", "patent leather heels", "armored couture boots"],
806
- value="platform boots",
807
- label="Footwear",
808
- )
809
- with gr.Row():
810
- palette = gr.Dropdown(
811
- ["black, crimson, cyan neon", "obsidian, pearl, crimson", "graphite, magenta, cold blue"],
812
- value="black, crimson, cyan neon",
813
- label="Palette",
814
- )
815
- hardware = gr.Dropdown(
816
- ["crimson hardware", "silver occult buckles", "holographic NEXUS sigils"],
817
- value="crimson hardware",
818
- label="Hardware",
819
- )
820
- reference_url = gr.Textbox(
821
- label="Reference URL (metadata only)",
822
- placeholder="https://shop.example/reference-garment",
823
- scale=2,
824
- )
825
- with gr.Row():
826
- adult_mode = gr.Checkbox(
827
- value=False,
828
- label="Adult Mode 18+ catalog scope",
829
- info="Off by default. Enables adult-tagged catalog entries but does not disable security, consent, or export gates.",
830
- scale=2,
831
- )
832
- run_btn = gr.Button("Run Active Weave", variant="primary", scale=2)
833
- checkpoint_btn = gr.Button("Approve Checkpoint", scale=1)
834
- export_btn = gr.Button("Prepare Export Packet", scale=1)
835
- reset_btn = gr.Button("Reset Demo State", scale=1)
836
- with gr.Row(elem_id="nw-operator-actions", elem_classes=["nw-operator-actions"]):
837
- stop_btn = gr.Button("Stop Provider Job", variant="stop", interactive=False, scale=1)
838
- with gr.Accordion("Optional ST3GG file/reference scan", open=False):
839
- gr.Markdown("Upload only when you want ST3GG to inspect an external reference or output file. Generation does not require an upload.")
840
- upload = gr.File(
841
- label="Optional file for ST3GG scan",
842
- file_count="single",
843
- type="filepath",
844
- )
845
- scan_btn = gr.Button("Scan Uploaded File", scale=1)
846
- override_reason = gr.Textbox(
847
- label="ST3GG Override Reason",
848
- placeholder="Required when ST3GG is review/blocked; explain why this audit packet may be written.",
849
- lines=2,
850
- max_lines=3,
851
- )
852
 
853
- with gr.Row(elem_id="nw-workspace", elem_classes=["nw-workspace"]):
854
- with gr.Column(scale=1, min_width=150, elem_id="nw-native-rail"):
855
- section_nav = gr.Radio(
856
- SECTIONS,
857
- value="Forge",
858
- label="Command Rail",
859
- elem_id="nw-section-nav",
860
- )
861
- command_rail_html = gr.HTML(initial_regions["command_rail"], container=False)
862
- with gr.Column(scale=5, min_width=620, elem_id="nw-main-column"):
 
 
 
 
 
 
 
 
 
 
 
 
863
  artifact_html = gr.HTML(initial_regions["artifacts"], container=False)
864
- workflow_html = gr.HTML(initial_regions["workflow"], container=False)
865
- operations_html = gr.HTML(initial_regions["operations"], container=False)
866
- drawer_html = gr.HTML(initial_regions["drawer"], container=False)
867
- with gr.Column(scale=2, min_width=340, elem_id="nw-side-column"):
868
- inspector_html = gr.HTML(initial_regions["inspector"], container=False)
869
- with gr.Accordion("Optional provider lanes", open=False):
870
- provider_html = gr.HTML(initial_regions["providers"], container=False)
871
-
872
- status_html = gr.HTML(initial_regions["status"], container=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
873
 
874
  with gr.Accordion("Catalog, run record, and security evidence", open=False):
875
  catalog_html = gr.HTML(render_catalog_table(False), container=False)
@@ -894,13 +965,30 @@ with gr.Blocks(title="NEXUS Visual Weaver") as demo:
894
  scan_json,
895
  ]
896
 
897
- stateful_outputs = dashboard_outputs + [active_run_state, scan_state, operator_state, stop_btn]
898
 
899
- operator_outputs = dashboard_outputs + [operator_state, stop_btn]
900
 
901
  run_click = run_btn.click(
902
  fn=run_weave,
903
- inputs=[prompt, reasoning_mode, video_preset, adult_mode, upload, section_nav, silhouette, outerwear, upper_body, footwear, palette, hardware, reference_url],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
904
  outputs=stateful_outputs,
905
  api_name="run_active_weave",
906
  concurrency_limit=1,
@@ -908,7 +996,24 @@ with gr.Blocks(title="NEXUS Visual Weaver") as demo:
908
  )
909
  run_submit = prompt.submit(
910
  fn=run_weave,
911
- inputs=[prompt, reasoning_mode, video_preset, adult_mode, upload, section_nav, silhouette, outerwear, upper_body, footwear, palette, hardware, reference_url],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
912
  outputs=stateful_outputs,
913
  api_name=False,
914
  concurrency_limit=1,
@@ -942,7 +1047,7 @@ with gr.Blocks(title="NEXUS Visual Weaver") as demo:
942
  scan_btn.click(
943
  fn=scan_reference,
944
  inputs=[active_run_state, adult_mode, upload, section_nav, operator_state, reference_url],
945
- outputs=dashboard_outputs + [operator_state, stop_btn, scan_state],
946
  api_name="scan_reference",
947
  queue=False,
948
  )
 
5
  import os
6
  import sys
7
  import hashlib
8
+ import secrets
9
  from pathlib import Path
10
  from typing import Any
11
  from urllib.parse import urlparse
 
49
 
50
  MODEL_RELAY = WeaverModelRelay()
51
 
52
+ STYLE_MODIFIERS = {
53
+ "Balanced": "balanced editorial lighting, precise garment detail, clean composition",
54
+ "High Fashion": "haute couture editorial styling, premium material finish, runway-grade silhouette",
55
+ "Cinematic": "cinematic rain-lit atmosphere, dramatic lensing, high contrast neon reflections",
56
+ }
57
+
58
+ ASPECT_DIMENSIONS = {
59
+ "Square": (1024, 1024),
60
+ "Portrait": (832, 1216),
61
+ }
62
+
63
 
64
  def _default_operator_state() -> dict[str, Any]:
65
  return {
 
206
  palette: str | None = None,
207
  hardware: str | None = None,
208
  locate_focus: list[str] | None = None,
209
+ seed: int | None = None,
210
+ style_strength: str = "High Fashion",
211
+ aspect: str = "Portrait",
212
  ) -> dict[str, Any]:
213
  """
214
  Create a control object combining wardrobe selections with generation policy and reasoning configuration.
 
235
  "flux_primary": "black-forest-labs/FLUX.2-klein-9B",
236
  "flux_sidecar": "black-forest-labs/FLUX.2-klein-4B",
237
  "lora_policy": "attempt compatible runtime adapter; report loaded/skipped/failed",
238
+ "seed": seed,
239
+ "style_strength": style_strength,
240
+ "aspect": aspect,
241
  },
242
  }
243
 
244
 
245
+ def _resolve_seed(seed_value: Any) -> int:
246
+ """Resolve user seed input. Empty or -1 means randomize."""
247
+ try:
248
+ if seed_value is None or str(seed_value).strip() == "":
249
+ return secrets.randbelow(1_000_000_000)
250
+ seed = int(float(seed_value))
251
+ except (TypeError, ValueError):
252
+ return secrets.randbelow(1_000_000_000)
253
+ return secrets.randbelow(1_000_000_000) if seed < 0 else seed
254
+
255
+
256
+ def _generation_dimensions(aspect: str | None) -> tuple[int, int]:
257
+ return ASPECT_DIMENSIONS.get(str(aspect or "Portrait"), ASPECT_DIMENSIONS["Portrait"])
258
+
259
+
260
+ def _style_modifier(style_strength: str | None) -> str:
261
+ return STYLE_MODIFIERS.get(str(style_strength or "High Fashion"), STYLE_MODIFIERS["High Fashion"])
262
+
263
+
264
  def _prompt_with_controls(prompt: str, controls: dict[str, Any]) -> str:
265
  """
266
  Augments a prompt with wardrobe control parameters.
 
284
  wardrobe.get("hardware"),
285
  ]
286
  suffix = ", ".join(str(item) for item in additions if item)
287
+ generation = controls.get("generation", {})
288
+ if not suffix and not generation:
289
+ return prompt
290
+ style = _style_modifier(str(generation.get("style_strength", "High Fashion")))
291
+ prompt = f"{prompt}\nWardrobe controls: {suffix}" if suffix else prompt
292
+ return f"{prompt}\nStyle direction: {style}"
293
 
294
 
295
  def _generated_output_path(operator_state: dict[str, Any] | None) -> str | None:
 
354
  SECTIONS = ["Forge", "Wardrobe", "Lore", "Models", "Security", "Runs"]
355
 
356
 
357
+ def _button_updates(run: Any | None, operator_state: dict[str, Any] | None) -> tuple[Any, Any, Any]:
358
+ state = operator_state or {}
359
+ generated = bool(_generated_output_path(state)) and (state.get("generation") or {}).get("status") == "success"
360
+ checkpoint_approved = state.get("checkpoint") == "approved"
361
+ exported = state.get("provider_state") == "exported"
362
+ return (
363
+ gr.update(interactive=generated and not checkpoint_approved and not exported),
364
+ gr.update(interactive=generated and checkpoint_approved and not exported),
365
+ gr.update(interactive=False),
366
+ )
367
+
368
+
369
  def _dashboard_regions(
370
  run: Any | None = None,
371
  adult_mode: bool = False,
 
398
  palette: str | None = None,
399
  hardware: str | None = None,
400
  reference_url: str | None = None,
401
+ seed_value: Any = -1,
402
+ style_strength: str = "High Fashion",
403
+ aspect: str = "Portrait",
404
  ) -> tuple[Any, ...]:
405
  """
406
  Execute the complete weaving workflow from prompt through image generation and evaluation.
 
411
  Tuple containing dashboard region HTML fragments (topbar, command_rail, workflow, operations, inspector, drawer, status, artifacts, providers), catalog HTML, run data, catalog summary, scan results, operator state with generation details and judge evidence, and button state updates.
412
  """
413
  prompt = prompt.strip() or DEFAULT_PROMPT
414
+ resolved_seed = _resolve_seed(seed_value)
415
+ width, height = _generation_dimensions(aspect)
416
  controls = _creator_controls(
417
  reasoning_mode=reasoning_mode,
418
  video_preset=video_preset,
 
422
  footwear=footwear,
423
  palette=palette,
424
  hardware=hardware,
425
+ seed=resolved_seed,
426
+ style_strength=style_strength,
427
+ aspect=aspect,
428
  )
429
  controlled_prompt = _prompt_with_controls(prompt, controls)
430
  reference_scan = scan_file(_file_path(upload))
 
439
  )
440
  generation = generate_flux_image(
441
  run.refined_prompt.refined,
442
+ seed=resolved_seed,
443
+ width=width,
444
+ height=height,
445
  adult_mode=adult_mode,
446
  )
447
  generated_scan = scan_file(generation.output_path) if generation.output_path else scan_file(None)
 
456
  run_packet=run.to_dict(),
457
  minicpm_result=minicpm.to_dict(),
458
  )
 
459
  if generation.status == "success":
460
  provider_state = "generated"
461
+ elif generation.status in {"disabled", "missing_runtime", "no_cuda", "error"}:
462
+ provider_state = generation.provider_state
463
+ else:
464
+ provider_state = "checkpointed"
465
  operator_state = {
466
  "provider_state": provider_state,
467
  "checkpoint": "pending_review",
468
  "export": generated_scan.get("export_gate", "pending"),
469
+ "message": generation.message or "Image run complete. Human checkpoint required before export.",
470
  "generation": generation.to_dict(),
471
  "creator_controls": controls,
472
  "reference_metadata": reference_metadata,
 
500
  run,
501
  generated_scan,
502
  operator_state,
503
+ *_button_updates(run, operator_state),
504
  )
505
 
506
 
 
612
  catalog_summary(adult_mode),
613
  scan,
614
  operator_state,
615
+ *_button_updates(run, operator_state),
616
  )
617
 
618
 
 
680
  state = operator_state or _default_operator_state()
681
  scan = _authoritative_generated_scan(state)
682
  if run is None:
683
+ next_state = {**_default_operator_state(), "provider_state": "blocked", "message": "No run exists yet. Generate an image first."}
684
  elif not _generated_output_path(state):
685
  next_state = {
686
  **state,
 
699
  "message": (
700
  "Checkpoint approved. Export is ready after clear ST3GG scan."
701
  if export_state == "clear"
702
+ else "Checkpoint approved. Add an override reason and click Prepare Audit Export to write an audit packet."
703
  ),
704
  }
705
  return _render_stateful(run, adult_mode, scan, active_section, next_state)
 
737
  scan = _authoritative_generated_scan(state)
738
  override_reason = (override_reason or "").strip()
739
  if run is None:
740
+ next_state = {**state, "provider_state": "blocked", "export": "blocked", "message": "Export waits for review: generate an image before preparing an audit packet."}
741
  elif state.get("checkpoint") != "approved":
742
  next_state = {**state, "provider_state": "blocked", "export": "blocked", "message": "Export gate active: approve the human checkpoint before release."}
743
  elif not _generated_output_path(state):
744
+ next_state = {**state, "provider_state": "blocked", "export": "blocked", "message": "Export waits for review: generate an artifact before preparing evidence."}
745
  elif scan.get("export_gate") != "clear" and not override_reason:
746
  next_state = {**state, "provider_state": "blocked", "export": scan.get("export_gate", "blocked"), "message": "Export gate active: ST3GG is not clear. Add an explicit override reason to write an audit packet."}
747
  else:
 
783
  next_state = {
784
  **(operator_state or _default_operator_state()),
785
  "provider_state": "stopped",
786
+ "message": "Provider handoff stopped. Local run packet and evidence remain available.",
787
  }
788
  return _render_stateful(run, adult_mode, scan, active_section, next_state)
789
 
 
819
  scan,
820
  operator_state,
821
  gr.update(interactive=False),
822
+ gr.update(interactive=False),
823
+ gr.update(interactive=False),
824
  )
825
 
826
 
 
831
  active_run_state = gr.State(None)
832
  scan_state = gr.State(scan_file(None))
833
  operator_state = gr.State(initial_operator_state)
834
+ topbar_html = gr.HTML(initial_regions["topbar"], container=False, visible=False)
835
 
836
+ with gr.Row(elem_id="nw-creator-workbench", elem_classes=["nw-creator-workbench"]):
837
+ with gr.Column(scale=5, min_width=520, elem_id="nw-creator-panel"):
838
+ gr.Markdown("### Create Couture Image")
839
+ gr.Markdown("Describe the look, choose wardrobe controls, then generate. Reference upload is optional.")
840
  prompt = gr.Textbox(
841
  value=DEFAULT_PROMPT,
842
+ label="Describe the look",
843
+ lines=4,
844
  max_lines=6,
 
845
  )
846
+
847
+ with gr.Row():
848
+ seed_value = gr.Number(value=-1, precision=0, label="Seed (-1 randomizes)")
849
+ style_strength = gr.Dropdown(
850
+ ["Balanced", "High Fashion", "Cinematic"],
851
+ value="High Fashion",
852
+ label="Style Strength",
853
  )
854
+ aspect = gr.Dropdown(["Portrait", "Square"], value="Portrait", label="Aspect")
855
+ with gr.Row(elem_classes=["nw-primary-actions"]):
856
+ run_btn = gr.Button("Generate Image", variant="primary", scale=2)
857
+ reset_btn = gr.Button("Reset", scale=1)
858
+
859
+ with gr.Row():
860
+ silhouette = gr.Dropdown(
861
+ ["structured long coat", "fitted gothic bodice", "layered tactical silhouette"],
862
+ value="structured long coat",
863
+ label="Silhouette",
864
+ )
865
+ outerwear = gr.Dropdown(
866
+ ["black patent leather long coat", "faux fur collar coat", "tailored rain slicker"],
867
+ value="black patent leather long coat",
868
+ label="Outerwear",
869
+ )
870
+ with gr.Row():
871
+ upper_body = gr.Dropdown(
872
+ ["Chantilly lace neckline", "black mesh layer", "structured corset bodice"],
873
+ value="Chantilly lace neckline",
874
+ label="Upper Body",
875
+ )
876
+ footwear = gr.Dropdown(
877
+ ["platform boots", "patent leather heels", "armored couture boots"],
878
+ value="platform boots",
879
+ label="Footwear",
880
+ )
881
+ with gr.Row():
882
+ palette = gr.Dropdown(
883
+ ["black, crimson, cyan neon", "obsidian, pearl, crimson", "graphite, magenta, cold blue"],
884
+ value="black, crimson, cyan neon",
885
+ label="Palette",
886
+ )
887
+ hardware = gr.Dropdown(
888
+ ["crimson hardware", "silver occult buckles", "holographic NEXUS sigils"],
889
+ value="crimson hardware",
890
+ label="Hardware",
891
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
892
 
893
+ with gr.Accordion("Advanced: scan external file", open=False):
894
+ gr.Markdown("Optional. Generate directly unless you need ST3GG to inspect an uploaded reference or output file.")
895
+ with gr.Row():
896
+ reasoning_mode = gr.Radio(["Strict", "Frontier"], value="Strict", label="Reasoning Mode")
897
+ video_preset = gr.Dropdown(["Wan2.2 I2V", "LTX-2.3"], value="Wan2.2 I2V", label="Video preset (deferred)")
898
+ with gr.Row():
899
+ adult_mode = gr.Checkbox(
900
+ value=False,
901
+ label="Adult Mode 18+ catalog scope",
902
+ info="Off by default. Never disables security, consent, or export gates.",
903
+ )
904
+ reference_url = gr.Textbox(
905
+ label="Reference URL (metadata only)",
906
+ placeholder="https://shop.example/reference-garment",
907
+ )
908
+ upload = gr.File(label="Optional file for ST3GG scan", file_count="single", type="filepath")
909
+ with gr.Row():
910
+ scan_btn = gr.Button("Scan Uploaded File", scale=1)
911
+ stop_btn = gr.Button("Stop Job", variant="stop", interactive=False, scale=1)
912
+
913
+ with gr.Column(scale=4, min_width=460, elem_id="nw-output-panel"):
914
+ gr.Markdown("### Output")
915
  artifact_html = gr.HTML(initial_regions["artifacts"], container=False)
916
+ with gr.Row(elem_id="nw-checkpoint-actions", elem_classes=["nw-checkpoint-actions"]):
917
+ checkpoint_btn = gr.Button("Approve Checkpoint", scale=1, interactive=False)
918
+ export_btn = gr.Button("Prepare Audit Export", scale=1, interactive=False)
919
+ override_reason = gr.Textbox(
920
+ label="ST3GG Override Reason",
921
+ placeholder="Required only when ST3GG asks for review; explain why this audit packet may be written.",
922
+ lines=2,
923
+ max_lines=3,
924
+ )
925
+ gr.Markdown("Generation is not export. Every artifact stays behind ST3GG review and human checkpoint.")
926
+
927
+ with gr.Accordion("Run Anatomy", open=False):
928
+ with gr.Row(elem_id="nw-workspace", elem_classes=["nw-workspace"]):
929
+ with gr.Column(scale=1, min_width=160, elem_id="nw-native-rail"):
930
+ section_nav = gr.Radio(SECTIONS, value="Forge", label="Technical Section", elem_id="nw-section-nav")
931
+ command_rail_html = gr.HTML(initial_regions["command_rail"], container=False)
932
+ with gr.Column(scale=5, min_width=620, elem_id="nw-main-column"):
933
+ workflow_html = gr.HTML(initial_regions["workflow"], container=False)
934
+
935
+ with gr.Accordion("Wardrobe Evidence", open=False):
936
+ operations_html = gr.HTML(initial_regions["operations"], container=False)
937
+ drawer_html = gr.HTML(initial_regions["drawer"], container=False)
938
+
939
+ with gr.Accordion("Technical Evidence", open=False):
940
+ status_html = gr.HTML(initial_regions["status"], container=False)
941
+ inspector_html = gr.HTML(initial_regions["inspector"], container=False)
942
+ with gr.Accordion("Provider Diagnostics", open=False):
943
+ provider_html = gr.HTML(initial_regions["providers"], container=False)
944
 
945
  with gr.Accordion("Catalog, run record, and security evidence", open=False):
946
  catalog_html = gr.HTML(render_catalog_table(False), container=False)
 
965
  scan_json,
966
  ]
967
 
968
+ stateful_outputs = dashboard_outputs + [active_run_state, scan_state, operator_state, checkpoint_btn, export_btn, stop_btn]
969
 
970
+ operator_outputs = dashboard_outputs + [operator_state, checkpoint_btn, export_btn, stop_btn]
971
 
972
  run_click = run_btn.click(
973
  fn=run_weave,
974
+ inputs=[
975
+ prompt,
976
+ reasoning_mode,
977
+ video_preset,
978
+ adult_mode,
979
+ upload,
980
+ section_nav,
981
+ silhouette,
982
+ outerwear,
983
+ upper_body,
984
+ footwear,
985
+ palette,
986
+ hardware,
987
+ reference_url,
988
+ seed_value,
989
+ style_strength,
990
+ aspect,
991
+ ],
992
  outputs=stateful_outputs,
993
  api_name="run_active_weave",
994
  concurrency_limit=1,
 
996
  )
997
  run_submit = prompt.submit(
998
  fn=run_weave,
999
+ inputs=[
1000
+ prompt,
1001
+ reasoning_mode,
1002
+ video_preset,
1003
+ adult_mode,
1004
+ upload,
1005
+ section_nav,
1006
+ silhouette,
1007
+ outerwear,
1008
+ upper_body,
1009
+ footwear,
1010
+ palette,
1011
+ hardware,
1012
+ reference_url,
1013
+ seed_value,
1014
+ style_strength,
1015
+ aspect,
1016
+ ],
1017
  outputs=stateful_outputs,
1018
  api_name=False,
1019
  concurrency_limit=1,
 
1047
  scan_btn.click(
1048
  fn=scan_reference,
1049
  inputs=[active_run_state, adult_mode, upload, section_nav, operator_state, reference_url],
1050
+ outputs=dashboard_outputs + [operator_state, checkpoint_btn, export_btn, stop_btn, scan_state],
1051
  api_name="scan_reference",
1052
  queue=False,
1053
  )
docs/HANDOFF_QUOTA_EXHAUST_V4_2.md ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # NEXUS Visual Weaver v4.2 Handoff - Quota Exhaustion Coverage
2
+
3
+ Date: 2026-06-15
4
+
5
+ This handoff captures the current live state after the practical UX recovery pass. Use it if the current Codex session or quota expires.
6
+
7
+ ## Current State
8
+
9
+ - GitHub branch: `main`
10
+ - Latest GitHub commit: `4b9ab3f fix: make creation path practical and visible`
11
+ - Latest HF Space commit: `4c4521d9e88aedcbf2bd01d1394fe9fa683a01b5`
12
+ - HF Space: `build-small-hackathon/NEXUS_Visual_Weaver`
13
+ - Live URL: <https://build-small-hackathon-nexus-visual-weaver-a107340.hf.space/>
14
+ - HF runtime verified after deploy:
15
+ - `dev_mode=false`
16
+ - runtime stage `RUNNING`
17
+ - domain stage `READY`
18
+ - runtime SHA equals Space SHA: `4c4521d9e88aedcbf2bd01d1394fe9fa683a01b5`
19
+
20
+ ## Important Discovery
21
+
22
+ The live UI was stale because Hugging Face Dev Mode kept an older container running. The repository already had newer code, but the visible Space did not reflect it.
23
+
24
+ Fixed with:
25
+
26
+ ```powershell
27
+ $env:HTTP_PROXY=''; $env:HTTPS_PROXY=''; $env:ALL_PROXY=''; $env:NO_PROXY='*'
28
+ hf spaces dev-mode build-small-hackathon/NEXUS_Visual_Weaver --stop
29
+ hf spaces restart build-small-hackathon/NEXUS_Visual_Weaver --factory-reboot
30
+ ```
31
+
32
+ If future screenshots show old labels again, check `runtime.dev_mode` and `runtime.raw.sha` before editing more code.
33
+
34
+ ## Practical UX Fixes Shipped
35
+
36
+ Commit `4b9ab3f` changes:
37
+
38
+ - Moves `Artifact Preview Lane` above the workflow graph so real output is visible sooner.
39
+ - Collapses provider lanes by default under `Optional provider lanes`.
40
+ - Moves file upload into a collapsed `Optional ST3GG file/reference scan` section.
41
+ - Makes `Run Active Weave` the primary action.
42
+ - Keeps checkpoint/export/reset as immediate operator actions.
43
+ - Changes generated/export-ready states in the footer from red failure styling to green success styling.
44
+ - Enlarges the artifact preview frame so the generated image reads as the product outcome.
45
+
46
+ Files changed:
47
+
48
+ - `app.py`
49
+ - `src/nexus_visual_weaver/render.py`
50
+ - `src/nexus_visual_weaver/styles.py`
51
+ - `.gitignore` now ignores `.hf-upload-cache/`
52
+
53
+ ## What "Missing Secret" Means
54
+
55
+ `MISSING_SECRET` was not asking for more Hugging Face access. It referred to optional sponsor/provider lanes, mainly:
56
+
57
+ - OpenBMB/MiniCPM: `MINICPM_BASE_URL` plus `MINICPM_API_KEY` or `OPENBMB_API_KEY`
58
+ - NVIDIA/Nemotron: `NEMOTRON_BASE_URL` plus `NEMOTRON_API_KEY` or `NVIDIA_API_KEY`
59
+ - Other optional gateways: `FAL_KEY`, Netlify, Cloudflare
60
+
61
+ Those lanes are not the P0 demo. They should remain collapsed or framed as optional. Do not make the main flow depend on them.
62
+
63
+ ## Verification Already Run Locally
64
+
65
+ Before commit:
66
+
67
+ ```powershell
68
+ python -m compileall app.py src tests
69
+ $env:NEXUS_DISABLE_REAL_HF='1'
70
+ $env:PYTEST_DISABLE_PLUGIN_AUTOLOAD='1'
71
+ python -m pytest -q tests -p no:cacheprovider --basetemp=C:\tmp\pytest-nvw-full
72
+ git grep -n -I -E "hf_[A-Za-z0-9]{20,}|Bearer [A-Za-z0-9._-]+|sk-[A-Za-z0-9_-]{20,}|api[_-]?key\s*=" -- .
73
+ ```
74
+
75
+ Result:
76
+
77
+ - Compile clean
78
+ - `288 passed, 1 warning`
79
+ - Secret scan clean
80
+
81
+ After deploy:
82
+
83
+ ```powershell
84
+ $env:HTTP_PROXY=''; $env:HTTPS_PROXY=''; $env:ALL_PROXY=''; $env:NO_PROXY='*'
85
+ hf spaces info build-small-hackathon/NEXUS_Visual_Weaver --format json
86
+ Invoke-WebRequest -UseBasicParsing https://build-small-hackathon-nexus-visual-weaver-a107340.hf.space/
87
+ Invoke-WebRequest -UseBasicParsing https://build-small-hackathon-nexus-visual-weaver-a107340.hf.space/gradio_api/info
88
+ ```
89
+
90
+ Result:
91
+
92
+ - Space SHA and runtime SHA both `4c4521d9e88aedcbf2bd01d1394fe9fa683a01b5`
93
+ - Root returned HTTP 200
94
+ - `/gradio_api/info` returned HTTP 200
95
+
96
+ ## Deployment Commands Used
97
+
98
+ The standard upload failed once because Hugging Face Xet tried to write into a locked local cache. The successful upload disabled Xet while keeping the existing auth token:
99
+
100
+ ```powershell
101
+ $env:HTTP_PROXY=''; $env:HTTPS_PROXY=''; $env:ALL_PROXY=''; $env:NO_PROXY='*'
102
+ $env:HF_HUB_DISABLE_XET='1'
103
+ Remove-Item Env:\HF_HOME -ErrorAction SilentlyContinue
104
+ hf upload build-small-hackathon/NEXUS_Visual_Weaver C:\tmp\nvw-v422-4b9ab3f . --repo-type=space --commit-message "fix: practical creation path layout"
105
+ hf spaces restart build-small-hackathon/NEXUS_Visual_Weaver --factory-reboot
106
+ ```
107
+
108
+ ## Next Visual QA Checklist
109
+
110
+ Open the Space in a browser and verify:
111
+
112
+ - Provider cards are collapsed by default.
113
+ - Upload is inside `Optional ST3GG file/reference scan`, not dominating the main screen.
114
+ - `Artifact Preview Lane` appears before the workflow graph.
115
+ - Footer state after generation reads as success/green, not a red `Generated` block.
116
+ - The main visible path is: controls -> `Run Active Weave` -> artifact preview -> checkpoint/export.
117
+ - Optional provider lanes do not visually dominate with missing-secret labels.
118
+
119
+ If any of these fail, first confirm the browser is not cached and HF runtime SHA is still `4c4521d9e88aedcbf2bd01d1394fe9fa683a01b5`.
120
+
121
+ ## Remaining Work
122
+
123
+ P0 next:
124
+
125
+ - Browser visual inspection of the live Space after rebuild.
126
+ - One live run through `Run Active Weave`.
127
+ - Confirm export packet after checkpoint/override.
128
+
129
+ Do not spend more time on generated README images, Gamma deck polish, Modal, or video until the practical live UI is confirmed usable.
130
+
131
+ ## Demo Framing
132
+
133
+ Main proof line:
134
+
135
+ > NEXUS Visual Weaver generates a real FLUX.2 Klein artifact, keeps ST3GG review and human checkpoint visible, and writes audit evidence instead of silently exporting.
136
+
137
+ Avoid claiming:
138
+
139
+ - Sponsor judge success unless secrets are configured and a real call returns evidence.
140
+ - Video success unless a real `.mp4` is produced by the Space.
141
+ - Dynamic LoRA success unless export evidence reports `loaded`.
142
+
src/nexus_visual_weaver/render.py CHANGED
@@ -77,6 +77,8 @@ def _gate_label(export_gate: str) -> str:
77
  return "Export Blocked - Override Available"
78
  if normalized == "CLEAR":
79
  return "EXPORT CLEAR"
 
 
80
  return f"EXPORT {normalized}"
81
 
82
 
@@ -214,6 +216,7 @@ def render_trust_strip(scan: dict | None = None, operator_state: dict | None = N
214
  scan = scan or {"status": "idle", "export_gate": "pending", "findings": [], "purification_actions": []}
215
  operator_state = operator_state or {}
216
  status = str(scan.get("status", "idle")).upper()
 
217
  export_gate = str(scan.get("export_gate", "pending")).upper()
218
  checkpoint = str(operator_state.get("checkpoint", "pending")).replace("_", " ").title()
219
  raw_findings = scan.get("findings")
@@ -236,7 +239,7 @@ def render_trust_strip(scan: dict | None = None, operator_state: dict | None = N
236
  <strong>Generation is not export.</strong>
237
  <span>Every artifact must pass ST3GG scan, purification, and human checkpoint before release.</span>
238
  </div>
239
- <div class="nw-trust-card">{badge(f"ST3GG {status}", tone)}<span>{escape(str(findings[0]))}</span></div>
240
  <div class="nw-trust-card">{badge(_gate_label(export_gate), "pass" if export_gate == "CLEAR" else "warn" if export_gate == "BLOCKED" else "muted")}<span>{escape(str(actions[0]))}</span></div>
241
  <div class="nw-trust-card">{badge(f"CHECKPOINT {checkpoint.upper()}", "pass" if checkpoint == "Approved" else "muted")}<span>Adult Mode never bypasses safety, consent, provenance, or dataset gates.</span></div>
242
  <div class="nw-trust-card nw-trust-examples">{badge("FIXTURE EVIDENCE", "cyan")}<span>Clean PNG -> pass. PNG trailing bytes -> blocked.</span></div>
@@ -493,17 +496,14 @@ def render_artifact_lane(run: GenerationRun | None = None, scan: dict | None = N
493
  """
494
  scan = scan or {"status": "idle", "export_gate": "pending"}
495
  operator_state = operator_state or {}
496
- prompt_label = "Prompt proof"
497
- outfit_label = "Outfit map"
498
- locate_label = "Grounding overlay"
499
- video_label = run.video.preset if run else "Video path"
500
- active_prompt = run.refined_prompt.refined[:150] if run else "Awaiting first weave. Real output and export evidence appear here after generation."
501
  checkpoint = operator_state.get("checkpoint", getattr(run.checkpoint, "recommendation", "pending") if run else "pending")
502
  provider_state = str(operator_state.get("provider_state", "dry-run" if run else "idle"))
503
  generation = operator_state.get("generation") or {}
504
  generated_uri = _image_data_uri(generation.get("output_path")) if isinstance(generation, dict) else None
505
  generated_status = str(generation.get("status", "")) if isinstance(generation, dict) else ""
506
  generated_message = str(generation.get("message", "")) if isinstance(generation, dict) else ""
 
507
  preview_mode = {
508
  "idle": "Idle",
509
  "dry-run": "Dry Run",
@@ -512,32 +512,22 @@ def render_artifact_lane(run: GenerationRun | None = None, scan: dict | None = N
512
  "exported": "Exported",
513
  "blocked": "Export Gate Active",
514
  "stopped": "Stopped",
 
515
  }.get(provider_state, provider_state.replace("_", " ").title())
516
  demo_seed = (run.checkpoint.checkpoint_id[-4:] if run else "0000").upper()
517
- artifacts = [
518
- (prompt_label, "Taste-refined brief", "dry-run", "material-0", "01"),
519
- (outfit_label, "Wardrobe slots and locks", "checkpointed", "material-1", "02"),
520
- (locate_label, "LocateAnything region plan", "configured", "material-4", "03"),
521
- (video_label, "Checkpointed storyboard", "deferred" if scan.get("export_gate") == "blocked" or provider_state == "blocked" else "ready", "story-2", "04"),
522
- ]
523
- cards = "".join(
524
- f"""
525
- <div class="nw-artifact-card">
526
- <small>{escape(index)}</small>
527
- <i class="nw-{texture}"></i>
528
- <strong>{escape(title)}</strong>
529
- <span>{escape(body)}</span>
530
- {badge("Gated" if status == "deferred" else status.upper(), "warn" if status in {"blocked", "deferred"} else "muted")}
531
- </div>
532
- """
533
- for title, body, status, texture, index in artifacts
534
- )
535
  export_gate = str(scan.get("export_gate", "pending")).upper()
536
- continuity = ", ".join(run.video.continuity_locks[:4]) if run else "outerwear, footwear, jewelry, NEXUS sigils"
 
 
 
 
 
 
 
537
  return f"""
538
  <section class="nw-panel nw-artifacts">
539
  <div class="nw-panel-head">
540
- <div><strong>Artifact Preview Lane</strong><small>Real output and export evidence appear here</small></div>
541
  {badge(_gate_label(export_gate), "warn" if export_gate == "BLOCKED" else "pass" if export_gate == "CLEAR" else "muted")}
542
  </div>
543
  <div class="nw-preview-stage">
@@ -545,22 +535,21 @@ def render_artifact_lane(run: GenerationRun | None = None, scan: dict | None = N
545
  {'<img class="nw-preview-real-image" src="' + generated_uri + '" alt="Generated FLUX artifact" />' if generated_uri else '<i class="nw-preview-image"></i>'}
546
  <div class="nw-preview-caption">
547
  <small>PRIMARY OUTPUT STAGE / {escape(generated_status.upper() or "JUDGE-SAFE DEMO OUTPUT")} / SEED {escape(demo_seed)}</small>
548
- <strong>{'Real FLUX.2 Klein artifact' if generated_uri else 'Deterministic Raven Chronicle proof frame'}</strong>
549
  <span>{escape(generated_message or active_prompt)}</span>
550
  </div>
551
  </div>
552
  <div class="nw-preview-meta">
553
- <div><small>checkpoint</small><strong>{escape(str(checkpoint).replace("_", " ").title())}</strong></div>
554
- <div><small>export gate</small><strong>{escape(export_gate)}</strong></div>
555
- <div><small>preview mode</small><strong>{escape(preview_mode)}</strong></div>
556
  </div>
557
  </div>
558
- <div class="nw-preview-ribbon">
559
- <span>{icon("security")} ST3GG before export</span>
560
- <span>{icon("wardrobe")} continuity: {escape(continuity)}</span>
561
- <span>{icon("models")} provider call remains checkpointed; state: dry-run / configured / gated / failed / exported; current: {escape(_display_state(provider_state))}</span>
562
  </div>
563
- <div class="nw-artifact-grid">{cards}</div>
564
  </section>
565
  """
566
 
 
77
  return "Export Blocked - Override Available"
78
  if normalized == "CLEAR":
79
  return "EXPORT CLEAR"
80
+ if normalized == "PENDING":
81
+ return "Export waits for review"
82
  return f"EXPORT {normalized}"
83
 
84
 
 
216
  scan = scan or {"status": "idle", "export_gate": "pending", "findings": [], "purification_actions": []}
217
  operator_state = operator_state or {}
218
  status = str(scan.get("status", "idle")).upper()
219
+ status_label = "READY" if status == "IDLE" else status
220
  export_gate = str(scan.get("export_gate", "pending")).upper()
221
  checkpoint = str(operator_state.get("checkpoint", "pending")).replace("_", " ").title()
222
  raw_findings = scan.get("findings")
 
239
  <strong>Generation is not export.</strong>
240
  <span>Every artifact must pass ST3GG scan, purification, and human checkpoint before release.</span>
241
  </div>
242
+ <div class="nw-trust-card">{badge(f"ST3GG {status_label}", tone)}<span>{escape(str(findings[0]))}</span></div>
243
  <div class="nw-trust-card">{badge(_gate_label(export_gate), "pass" if export_gate == "CLEAR" else "warn" if export_gate == "BLOCKED" else "muted")}<span>{escape(str(actions[0]))}</span></div>
244
  <div class="nw-trust-card">{badge(f"CHECKPOINT {checkpoint.upper()}", "pass" if checkpoint == "Approved" else "muted")}<span>Adult Mode never bypasses safety, consent, provenance, or dataset gates.</span></div>
245
  <div class="nw-trust-card nw-trust-examples">{badge("FIXTURE EVIDENCE", "cyan")}<span>Clean PNG -> pass. PNG trailing bytes -> blocked.</span></div>
 
496
  """
497
  scan = scan or {"status": "idle", "export_gate": "pending"}
498
  operator_state = operator_state or {}
499
+ active_prompt = run.refined_prompt.refined[:150] if run else "Describe the look and click Generate Image."
 
 
 
 
500
  checkpoint = operator_state.get("checkpoint", getattr(run.checkpoint, "recommendation", "pending") if run else "pending")
501
  provider_state = str(operator_state.get("provider_state", "dry-run" if run else "idle"))
502
  generation = operator_state.get("generation") or {}
503
  generated_uri = _image_data_uri(generation.get("output_path")) if isinstance(generation, dict) else None
504
  generated_status = str(generation.get("status", "")) if isinstance(generation, dict) else ""
505
  generated_message = str(generation.get("message", "")) if isinstance(generation, dict) else ""
506
+ output_ready = bool(generated_uri)
507
  preview_mode = {
508
  "idle": "Idle",
509
  "dry-run": "Dry Run",
 
512
  "exported": "Exported",
513
  "blocked": "Export Gate Active",
514
  "stopped": "Stopped",
515
+ "generated": "Generated",
516
  }.get(provider_state, provider_state.replace("_", " ").title())
517
  demo_seed = (run.checkpoint.checkpoint_id[-4:] if run else "0000").upper()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
518
  export_gate = str(scan.get("export_gate", "pending")).upper()
519
+ checkpoint_label = str(checkpoint).replace("_", " ").title()
520
+ next_action = "Generate an image to unlock checkpoint review."
521
+ if output_ready and str(checkpoint) != "approved":
522
+ next_action = "Approve checkpoint to unlock audit export."
523
+ elif output_ready and str(checkpoint) == "approved" and export_gate != "CLEAR":
524
+ next_action = "Add override reason or complete ST3GG review, then prepare audit export."
525
+ elif output_ready and str(checkpoint) == "approved":
526
+ next_action = "Prepare audit export."
527
  return f"""
528
  <section class="nw-panel nw-artifacts">
529
  <div class="nw-panel-head">
530
+ <div><strong>{'Generated image ready' if output_ready else 'Output'}</strong><small>Real output and export evidence appear here</small></div>
531
  {badge(_gate_label(export_gate), "warn" if export_gate == "BLOCKED" else "pass" if export_gate == "CLEAR" else "muted")}
532
  </div>
533
  <div class="nw-preview-stage">
 
535
  {'<img class="nw-preview-real-image" src="' + generated_uri + '" alt="Generated FLUX artifact" />' if generated_uri else '<i class="nw-preview-image"></i>'}
536
  <div class="nw-preview-caption">
537
  <small>PRIMARY OUTPUT STAGE / {escape(generated_status.upper() or "JUDGE-SAFE DEMO OUTPUT")} / SEED {escape(demo_seed)}</small>
538
+ <strong>{'Real FLUX.2 Klein artifact' if generated_uri else 'No image generated yet'}</strong>
539
  <span>{escape(generated_message or active_prompt)}</span>
540
  </div>
541
  </div>
542
  <div class="nw-preview-meta">
543
+ <div><small>Output</small><strong>{'Ready' if output_ready else 'Waiting'}</strong></div>
544
+ <div><small>Checkpoint</small><strong>{escape(checkpoint_label)}</strong></div>
545
+ <div><small>Export</small><strong>{escape(_gate_label(export_gate))}</strong></div>
546
  </div>
547
  </div>
548
+ <div class="nw-run-summary">
549
+ <div><small>Current state</small><strong>{escape(preview_mode)}</strong></div>
550
+ <div><small>Security</small><strong>ST3GG review active</strong></div>
551
+ <div><small>Next action</small><strong>{escape(next_action)}</strong></div>
552
  </div>
 
553
  </section>
554
  """
555
 
src/nexus_visual_weaver/styles.py CHANGED
@@ -598,6 +598,117 @@ footer { display: none !important; }
598
  z-index: 20;
599
  box-shadow: 0 14px 32px rgba(0,0,0,.28), inset 0 1px 0 rgba(255,255,255,.04);
600
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
601
  .nw-command-header {
602
  display: grid;
603
  grid-template-columns: minmax(260px, 1fr) auto;
@@ -984,6 +1095,7 @@ footer { display: none !important; }
984
  .nw-rail-main { display: flex; }
985
  .nw-rail-foot, .nw-rail::after { display: none; }
986
  .nw-bottom { grid-template-columns: 1fr; }
 
987
  #nw-workspace { flex-direction: column; }
988
  .nw-command-header, .nw-preview-stage, .nw-preview-frame { grid-template-columns: 1fr; }
989
  .nw-command-pills { justify-content: flex-start; }
 
598
  z-index: 20;
599
  box-shadow: 0 14px 32px rgba(0,0,0,.28), inset 0 1px 0 rgba(255,255,255,.04);
600
  }
601
+ .nw-creator-workbench {
602
+ padding: 10px 8px 8px;
603
+ gap: 10px !important;
604
+ align-items: stretch;
605
+ }
606
+ #nw-creator-panel,
607
+ #nw-output-panel {
608
+ border: 1px solid var(--nw-line) !important;
609
+ border-radius: 8px !important;
610
+ background:
611
+ linear-gradient(180deg, rgba(12,17,23,.98), rgba(6,9,13,.98)) !important;
612
+ padding: 14px !important;
613
+ box-shadow: 0 16px 34px rgba(0,0,0,.22), inset 0 1px 0 rgba(255,255,255,.035);
614
+ }
615
+ #nw-creator-panel .prose h3,
616
+ #nw-output-panel .prose h3 {
617
+ margin: 0 0 2px !important;
618
+ color: var(--nw-text);
619
+ font-size: 18px !important;
620
+ letter-spacing: 0 !important;
621
+ }
622
+ #nw-creator-panel .prose p,
623
+ #nw-output-panel .prose p {
624
+ margin: 0 0 10px !important;
625
+ color: var(--nw-muted);
626
+ font-size: 12px;
627
+ }
628
+ #nw-creator-panel textarea {
629
+ min-height: 112px !important;
630
+ font-size: 14px !important;
631
+ line-height: 1.45 !important;
632
+ }
633
+ #nw-creator-panel label,
634
+ #nw-output-panel label {
635
+ color: var(--nw-text) !important;
636
+ font-size: 12px !important;
637
+ }
638
+ .nw-primary-actions button {
639
+ min-height: 46px !important;
640
+ font-weight: 760 !important;
641
+ letter-spacing: 0 !important;
642
+ }
643
+ .nw-primary-actions button.primary,
644
+ .nw-primary-actions button[variant="primary"] {
645
+ background: linear-gradient(180deg, #ff3b62, #c51a3b) !important;
646
+ border-color: rgba(255,54,95,.58) !important;
647
+ }
648
+ #nw-checkpoint-actions {
649
+ gap: 8px !important;
650
+ margin-top: 10px;
651
+ }
652
+ #nw-checkpoint-actions button {
653
+ min-height: 38px !important;
654
+ font-size: 12px !important;
655
+ font-weight: 740 !important;
656
+ letter-spacing: 0 !important;
657
+ }
658
+ #nw-output-panel .nw-artifacts {
659
+ margin: 0;
660
+ border: 0;
661
+ background: transparent;
662
+ }
663
+ #nw-output-panel .nw-panel-head {
664
+ padding: 0 0 10px;
665
+ }
666
+ #nw-output-panel .nw-preview-stage {
667
+ grid-template-columns: 1fr;
668
+ padding: 0;
669
+ }
670
+ #nw-output-panel .nw-preview-frame {
671
+ grid-template-columns: 1fr;
672
+ min-height: 500px;
673
+ }
674
+ #nw-output-panel .nw-preview-real-image,
675
+ #nw-output-panel .nw-preview-image {
676
+ min-height: 390px;
677
+ border-right: 0;
678
+ border-bottom: 1px solid rgba(255,255,255,.08);
679
+ }
680
+ #nw-output-panel .nw-preview-caption {
681
+ align-content: start;
682
+ min-height: 110px;
683
+ }
684
+ #nw-output-panel .nw-preview-meta {
685
+ grid-template-columns: repeat(3, minmax(0, 1fr));
686
+ }
687
+ .nw-run-summary {
688
+ display: grid;
689
+ grid-template-columns: 1fr;
690
+ gap: 8px;
691
+ margin-top: 10px;
692
+ }
693
+ .nw-run-summary div {
694
+ border: 1px solid var(--nw-line);
695
+ border-radius: 6px;
696
+ background: rgba(46,229,157,.035);
697
+ padding: 10px;
698
+ }
699
+ .nw-run-summary small {
700
+ display: block;
701
+ color: var(--nw-faint);
702
+ font-size: 10px;
703
+ font-weight: 760;
704
+ letter-spacing: 0;
705
+ margin-bottom: 4px;
706
+ }
707
+ .nw-run-summary strong {
708
+ color: var(--nw-text);
709
+ font-size: 12px;
710
+ line-height: 1.35;
711
+ }
712
  .nw-command-header {
713
  display: grid;
714
  grid-template-columns: minmax(260px, 1fr) auto;
 
1095
  .nw-rail-main { display: flex; }
1096
  .nw-rail-foot, .nw-rail::after { display: none; }
1097
  .nw-bottom { grid-template-columns: 1fr; }
1098
+ .nw-creator-workbench { flex-direction: column; }
1099
  #nw-workspace { flex-direction: column; }
1100
  .nw-command-header, .nw-preview-stage, .nw-preview-frame { grid-template-columns: 1fr; }
1101
  .nw-command-pills { justify-content: flex-start; }
tests/test_app_callbacks.py CHANGED
@@ -93,10 +93,12 @@ def test_run_weave_returns_stateful_dashboard_packet() -> None:
93
  "Forge",
94
  )
95
 
96
- assert len(result) == 17
97
  assert result[13].checkpoint.checkpoint_id.startswith("nw-")
98
- assert result[15]["provider_state"] == "checkpointed"
99
- assert result[16]["interactive"] is True
 
 
100
  assert result[15]["creator_controls"]["wardrobe"]["footwear"] == "platform boots"
101
  assert result[15]["generation"]["lora_status"] == "disabled"
102
 
@@ -123,6 +125,9 @@ def test_run_weave_persists_additive_creator_controls_and_reference_url_metadata
123
 
124
  assert state["creator_controls"]["reasoning_mode"] == "Frontier"
125
  assert state["creator_controls"]["wardrobe"]["footwear"] == "patent leather heels"
 
 
 
126
  assert state["reference_metadata"][0]["source"] == "url"
127
  assert state["reference_metadata"][0]["domain"] == "shop.example.test"
128
  assert "url_hash" in state["reference_metadata"][0]
@@ -227,9 +232,9 @@ def test_reference_scan_cannot_clear_blocked_generated_artifact() -> None:
227
  scanned = app.scan_reference(run, False, str(clean_reference), "Forge", state)
228
  assert scanned[13]["reference_scan"]["export_gate"] == "clear"
229
  assert scanned[13]["export"] == "blocked"
230
- assert scanned[15]["export_gate"] == "blocked"
231
 
232
- approved = app.approve_checkpoint(run, False, scanned[15], "Forge", scanned[13])
233
  assert approved[13]["provider_state"] == "checkpointed"
234
  assert approved[13]["export"] == "blocked"
235
 
@@ -257,9 +262,9 @@ def test_blocked_reference_scan_does_not_block_clear_generated_artifact() -> Non
257
  scanned = app.scan_reference(run, False, str(blocked_reference), "Forge", state)
258
  assert scanned[13]["reference_scan"]["export_gate"] == "blocked"
259
  assert scanned[13]["export"] == "clear"
260
- assert scanned[15]["export_gate"] == "clear"
261
 
262
- approved = app.approve_checkpoint(run, False, scanned[15], "Forge", scanned[13])
263
  assert approved[13]["provider_state"] == "export_ready"
264
  assert approved[13]["export"] == "clear"
265
 
@@ -517,6 +522,21 @@ def test_creator_controls_generation_specifies_flux_primary() -> None:
517
  assert "black-forest-labs/FLUX.2-klein-4B" in generation["flux_sidecar"]
518
 
519
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
520
  # --- _prompt_with_controls tests ---
521
 
522
  def test_prompt_with_controls_appends_wardrobe_suffix() -> None:
@@ -526,6 +546,7 @@ def test_prompt_with_controls_appends_wardrobe_suffix() -> None:
526
  assert result.startswith("gothic couture portrait")
527
  assert "Wardrobe controls:" in result
528
  assert "platform boots" in result
 
529
 
530
 
531
  def test_prompt_with_controls_returns_prompt_unchanged_when_no_wardrobe() -> None:
@@ -555,6 +576,36 @@ def test_prompt_with_controls_includes_all_wardrobe_fields() -> None:
555
  assert "crimson hardware" in result
556
 
557
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
558
  def test_prompt_with_controls_does_not_duplicate_prompt() -> None:
559
  controls = app._creator_controls("Strict", "Wan2.2 I2V")
560
  prompt = "gothic couture brief"
 
93
  "Forge",
94
  )
95
 
96
+ assert len(result) == 19
97
  assert result[13].checkpoint.checkpoint_id.startswith("nw-")
98
+ assert result[15]["provider_state"] == "dry-run"
99
+ assert result[16]["interactive"] is False
100
+ assert result[17]["interactive"] is False
101
+ assert result[18]["interactive"] is False
102
  assert result[15]["creator_controls"]["wardrobe"]["footwear"] == "platform boots"
103
  assert result[15]["generation"]["lora_status"] == "disabled"
104
 
 
125
 
126
  assert state["creator_controls"]["reasoning_mode"] == "Frontier"
127
  assert state["creator_controls"]["wardrobe"]["footwear"] == "patent leather heels"
128
+ assert state["creator_controls"]["generation"]["seed"] >= 0
129
+ assert state["creator_controls"]["generation"]["style_strength"] == "High Fashion"
130
+ assert state["creator_controls"]["generation"]["aspect"] == "Portrait"
131
  assert state["reference_metadata"][0]["source"] == "url"
132
  assert state["reference_metadata"][0]["domain"] == "shop.example.test"
133
  assert "url_hash" in state["reference_metadata"][0]
 
232
  scanned = app.scan_reference(run, False, str(clean_reference), "Forge", state)
233
  assert scanned[13]["reference_scan"]["export_gate"] == "clear"
234
  assert scanned[13]["export"] == "blocked"
235
+ assert scanned[17]["export_gate"] == "blocked"
236
 
237
+ approved = app.approve_checkpoint(run, False, scanned[17], "Forge", scanned[13])
238
  assert approved[13]["provider_state"] == "checkpointed"
239
  assert approved[13]["export"] == "blocked"
240
 
 
262
  scanned = app.scan_reference(run, False, str(blocked_reference), "Forge", state)
263
  assert scanned[13]["reference_scan"]["export_gate"] == "blocked"
264
  assert scanned[13]["export"] == "clear"
265
+ assert scanned[17]["export_gate"] == "clear"
266
 
267
+ approved = app.approve_checkpoint(run, False, scanned[17], "Forge", scanned[13])
268
  assert approved[13]["provider_state"] == "export_ready"
269
  assert approved[13]["export"] == "clear"
270
 
 
522
  assert "black-forest-labs/FLUX.2-klein-4B" in generation["flux_sidecar"]
523
 
524
 
525
+ def test_creator_controls_generation_persists_seed_style_and_aspect() -> None:
526
+ result = app._creator_controls(
527
+ "Strict",
528
+ "Wan2.2 I2V",
529
+ seed=123,
530
+ style_strength="Cinematic",
531
+ aspect="Square",
532
+ )
533
+ generation = result["generation"]
534
+
535
+ assert generation["seed"] == 123
536
+ assert generation["style_strength"] == "Cinematic"
537
+ assert generation["aspect"] == "Square"
538
+
539
+
540
  # --- _prompt_with_controls tests ---
541
 
542
  def test_prompt_with_controls_appends_wardrobe_suffix() -> None:
 
546
  assert result.startswith("gothic couture portrait")
547
  assert "Wardrobe controls:" in result
548
  assert "platform boots" in result
549
+ assert "Style direction:" in result
550
 
551
 
552
  def test_prompt_with_controls_returns_prompt_unchanged_when_no_wardrobe() -> None:
 
576
  assert "crimson hardware" in result
577
 
578
 
579
+ def test_generation_dimensions_support_portrait_and_square() -> None:
580
+ assert app._generation_dimensions("Portrait") == (832, 1216)
581
+ assert app._generation_dimensions("Square") == (1024, 1024)
582
+ assert app._generation_dimensions("unknown") == (832, 1216)
583
+
584
+
585
+ def test_resolve_seed_randomizes_negative_and_uses_explicit_seed() -> None:
586
+ assert app._resolve_seed(42) == 42
587
+ assert app._resolve_seed("42") == 42
588
+ assert 0 <= app._resolve_seed(-1) < 1_000_000_000
589
+
590
+
591
+ def test_button_updates_unlock_checkpoint_then_export() -> None:
592
+ state = {
593
+ "provider_state": "generated",
594
+ "checkpoint": "pending_review",
595
+ "generation": {"status": "success", "output_path": "outputs/runtime/test.png"},
596
+ }
597
+ checkpoint, export, stop = app._button_updates(None, state)
598
+ assert checkpoint["interactive"] is True
599
+ assert export["interactive"] is False
600
+ assert stop["interactive"] is False
601
+
602
+ approved_state = {**state, "checkpoint": "approved"}
603
+ checkpoint, export, stop = app._button_updates(None, approved_state)
604
+ assert checkpoint["interactive"] is False
605
+ assert export["interactive"] is True
606
+ assert stop["interactive"] is False
607
+
608
+
609
  def test_prompt_with_controls_does_not_duplicate_prompt() -> None:
610
  controls = app._creator_controls("Strict", "Wan2.2 I2V")
611
  prompt = "gothic couture brief"
tests/test_command_center.py CHANGED
@@ -153,12 +153,11 @@ def test_dashboard_regions_expose_artifacts_and_provider_cards() -> None:
153
  relay_status=relay.dashboard_snapshot(public_demo=True),
154
  )
155
 
156
- assert "Artifact Preview Lane" in regions["artifacts"]
157
  assert "nw-preview-stage" in regions["artifacts"]
158
- assert "nw-preview-ribbon" in regions["artifacts"]
159
  assert "PRIMARY OUTPUT STAGE" in regions["artifacts"]
160
  assert "JUDGE-SAFE DEMO OUTPUT" in regions["artifacts"]
161
- assert "state: dry-run / configured / gated / failed" in regions["artifacts"]
162
  assert "Forge Operations" in regions["operations"]
163
  assert "Optional Provider Lanes" in regions["providers"]
164
  assert "nw-provider-meter" in regions["providers"]
@@ -185,7 +184,7 @@ def test_dashboard_regions_render_with_empty_relay_and_default_scan() -> None:
185
  assert "not-started" in regions["operations"]
186
  assert "snapshot pending" in regions["providers"]
187
  assert "Selected: Forge" in regions["command_rail"]
188
- assert "provider call remains checkpointed" in regions["artifacts"]
189
 
190
 
191
  def test_dashboard_operations_follow_selected_section() -> None:
@@ -265,8 +264,8 @@ def test_render_trust_strip_defaults_to_idle_state() -> None:
265
 
266
  assert "TRUST MODEL" in html
267
  assert "Generation is not export." in html
268
- assert "ST3GG IDLE" in html
269
- assert "EXPORT PENDING" in html
270
  assert "Clean PNG -> pass." in html
271
  assert "FIXTURE EVIDENCE" in html
272
 
 
153
  relay_status=relay.dashboard_snapshot(public_demo=True),
154
  )
155
 
156
+ assert "Output" in regions["artifacts"]
157
  assert "nw-preview-stage" in regions["artifacts"]
 
158
  assert "PRIMARY OUTPUT STAGE" in regions["artifacts"]
159
  assert "JUDGE-SAFE DEMO OUTPUT" in regions["artifacts"]
160
+ assert "Generate an image to unlock checkpoint review." in regions["artifacts"]
161
  assert "Forge Operations" in regions["operations"]
162
  assert "Optional Provider Lanes" in regions["providers"]
163
  assert "nw-provider-meter" in regions["providers"]
 
184
  assert "not-started" in regions["operations"]
185
  assert "snapshot pending" in regions["providers"]
186
  assert "Selected: Forge" in regions["command_rail"]
187
+ assert "Real output and export evidence appear here" in regions["artifacts"]
188
 
189
 
190
  def test_dashboard_operations_follow_selected_section() -> None:
 
264
 
265
  assert "TRUST MODEL" in html
266
  assert "Generation is not export." in html
267
+ assert "ST3GG READY" in html
268
+ assert "Export waits for review" in html
269
  assert "Clean PNG -> pass." in html
270
  assert "FIXTURE EVIDENCE" in html
271