A newer version of the Gradio SDK is available: 6.20.0
HearthNet β Master Task & Improvement List
Updated June 15, 2026 Β· Priority order: highest impact first
β DONE β Hackathon Critical
| # | Task | Commit |
|---|---|---|
| C1 | Demo video recorded and linked in README | ee40c33 |
| C2 | Social post on X @zX14_7 | ee40c33 |
| C3 | NVIDIA_API_KEY set in HF Space secrets | β |
| C4 | Deploy app_nemotron.py as second HF Space (HearthNet-Nemotron) |
feat/nemotron-space |
| C5 | MiniCPM3-4B as default model in main Space (OpenBMB + Tiny Titan) | ee40c33 |
| C6 | Modal deploy fix β scaledown_window replacing deprecated param |
ee40c33 |
| C7 | GitHub Codex commits pushed | ee40c33 |
| C8 | NVIDIA API key removed from Gradio frontend (SEC-1 critical fix) | 1c211eb |
| C9 | /data permission graceful fallback β Space no longer crashes |
c9bf597 |
β DONE β Services Wired Up
Previously implemented in code but never connected or visible:
| # | Task | What was broken | Commit |
|---|---|---|---|
| W1 | Nemotron tab added to main Gradio UI | nemotron.py existed, never imported |
c021486 |
| W2 | Voice tab (STT + TTS) β new voice.py |
STT/TTS services registered but no UI | c021486 |
| W3 | FederationService (M14) registered in install_services() |
Never registered anywhere | c021486 |
| W4 | ImageGenerateService gets Florence2Backend at init | Was instantiated with empty backends=[] |
c021486 |
| W5 | edge-tts, faster-whisper, pytesseract added to requirements |
Not in requirements, so backends silently failed | c021486 |
| W6 | HearthNet theme applied to main app (purple/dark) | hearthnet_theme defined but never passed to gr.Blocks |
latest |
| W7 | Custom CSS header, badges, animated status dot, button hover | Main app had zero custom styling | latest |
| W8 | Voice tab asyncio pattern fixed for Gradio async context | get_event_loop() fails inside Gradio's running loop |
latest |
π΄ P0 β Must fix before next demo
P0-1 β Image tab: upload β Florence2 describe
Impact: Shows off Florence2 + vision capability β judge can upload a photo and see AI describe it
Effort: 1 hour
File to create: hearthnet/ui/tabs/image.py
Capability: img.describe@1.0
Add to ui/app.py: from hearthnet.ui.tabs.image import build_image_tab + with gr.Tab("πΌ Image"): build_image_tab(bus)
# Minimal implementation:
def build_image_tab(bus):
img_input = gr.Image(type="filepath", label="Upload image")
describe_btn = gr.Button("π Describe with Florence2", variant="primary")
description_out = gr.Textbox(label="Description", lines=4)
def _describe(path):
import base64
with open(path, "rb") as f:
b64 = base64.b64encode(f.read()).decode()
result = _run(bus.call("img.describe", (1,0), {"input": {"image_b64": b64}}))
return result.get("output", {}).get("caption", result.get("caption", str(result)))
describe_btn.click(_describe, inputs=[img_input], outputs=[description_out])
P0-2 β OCR tab: upload scan/PDF β text
Impact: Tesseract/TrOCR β a common real-world need
Effort: 45 min
File to create: hearthnet/ui/tabs/ocr.py
Capability: ocr.image@1.0, ocr.pdf@1.0
def build_ocr_tab(bus):
ocr_input = gr.File(label="Upload image or PDF", file_types=[".png",".jpg",".pdf"])
ocr_btn = gr.Button("π Extract Text", variant="primary")
ocr_out = gr.Textbox(label="Extracted text", lines=10)
def _ocr(file_path):
cap = "ocr.pdf" if file_path.endswith(".pdf") else "ocr.image"
import base64
with open(file_path, "rb") as f:
b64 = base64.b64encode(f.read()).decode()
result = _run(bus.call(cap, (1,0), {"input": {"file_b64": b64}}))
return result.get("output", {}).get("text", str(result))
ocr_btn.click(_ocr, inputs=[ocr_input], outputs=[ocr_out])
P0-3 β Translation tab: text + language β translated text
Impact: NLLB-200 covers 200 languages β real differentiator
Effort: 30 min
File to create: hearthnet/ui/tabs/translation.py
Capability: trans.text@1.0
def build_translation_tab(bus):
src_text = gr.Textbox(label="Text to translate", lines=5)
src_lang = gr.Textbox(label="Source language", value="en")
tgt_lang = gr.Textbox(label="Target language", value="de")
translate_btn = gr.Button("π Translate", variant="primary")
out_text = gr.Textbox(label="Translation", lines=5)
def _translate(text, src, tgt):
result = _run(bus.call("trans.text", (1,0),
{"params": {"source_lang": src, "target_lang": tgt},
"input": {"text": text}}))
return result.get("output", {}).get("text", str(result))
translate_btn.click(_translate, inputs=[src_text, src_lang, tgt_lang], outputs=[out_text])
π P1 β High value, medium effort
P1-1 β Apply styled HTML headers to ALL tabs
Current state: Only voice.py and nemotron.py have styled section headers. Ask, Chat, Mesh, etc. have plain Markdown.
Fix: Add a gr.HTML(...) styled section header at the top of each build_*_tab() function, matching the gradient style in voice.py.
P1-2 β Rate limiting on /bus/v1/call and /relay/v1/*
File: app.py β _mount_bus_endpoints()
Fix: Wire RateLimiter from hearthnet/bus/backpressure.py
from hearthnet.bus.backpressure import RateLimiter
_limiter = RateLimiter(max_calls=60, window_seconds=60)
@app.middleware("http")
async def _rate_limit(request, call_next):
ip = request.client.host if request.client else "unknown"
if request.url.path.startswith(("/bus/v1", "/relay/v1")):
if not _limiter.allow(ip):
return JSONResponse({"error": "rate_limited"}, status_code=429)
return await call_next(request)
P1-3 β Capability token expiry enforcement
File: hearthnet/bus/router.py
Fix: Check token.exp < time.time() before routing β exp is stored in the token but never validated.
P1-4 β E2E encryption as default in chat (M23)
File: hearthnet/services/chat/service.py
Status: X3DH + Double Ratchet implemented in hearthnet/crypto/ but ChatService.send() sends plaintext
Fix: Thread ratchet state through ChatService._sessions dict, encrypt payload before bus dispatch.
P1-5 β Wire node.start() properly in app.py
File: app.py
Currently: node.install_services() called manually β skips mDNS, transport start, gossip sync
Fix:
# Replace:
_node.install_services(corpus="community")
# With (in a thread or via asyncio.get_event_loop):
loop.run_until_complete(_node.start(corpus="community"))
P1-6 β Gossip sync between nodes (X02)
File: hearthnet/node.py β add to node.start() after step 9
Fix:
from hearthnet.events.sync import SyncServer
self._sync_server = SyncServer(self._event_log, self.peers)
asyncio.create_task(self._sync_server.run())
Enables marketplace posts and RAG documents to auto-replicate across mesh nodes.
π‘ P2 β Medium value
P2-1 β Evidence UI tab (M30)
Capabilities: evidence.claim.add, evidence.claim.attest, evidence.claim.dispute
Service: EvidenceService β registered in research mode (install_extended_services(research=True))
File to create: hearthnet/ui/tabs/evidence.py
Add to ui/app.py once implemented.
P2-2 β Civil Defense UI tab (M31)
Capabilities: civdef.alert.issue, civdef.cert.*, civdef.audit.chain
Service: CivilDefenseService β registered in research mode
File to create: hearthnet/ui/tabs/civdef.py
P2-3 β Routing trace as flow chart (U2)
Current state: Routing trace shown as plain text in Ask tab Fix: Render as HTML/Mermaid flow diagram showing scored candidates and winner.
P2-4 β Peer capability matrix in Mesh tab (U5)
File: hearthnet/ui/tabs/mesh.py
Add: Table showing each discovered peer and their capabilities.
P2-5 β Dark mode toggle
File: hearthnet/ui/app.py
Note: hearthnet/ui/theme.py already has emergency_theme as a dark variant. Add a toggle.
P2-6 β Model selection UI in Settings tab
Current state: Model is fixed at startup via MODEL_ID env var
Fix: Add a dropdown in Settings showing available registered backends + restart hint.
P2-7 β Relay hub rate limiting
File: hearthnet/transport/relay_hub.py
Fix: Max 5 join attempts per IP per minute to prevent roster flooding.
π’ P3 β Future / research
P3-1 β ShardServer.forward() for distributed inference (M26)
File: hearthnet/distributed_inference/shard.py:75 β NotImplementedError
Requires: torch model slicing, attention head partitioning across nodes
P3-2 β FedLearnCoordinator.aggregate() (M28)
File: hearthnet/fedlearn/coordinator.py:95 β NotImplementedError
Requires: peft, LoRA delta accumulation, secure aggregation protocol
P3-3 β LoRa hardware serial port (M29)
File: hearthnet/lora/service.py:96 β silent stub without pyserial
Fix: serial.Serial("/dev/ttyUSB0", 9600) + add pyserial>=3.5 to requirements
P3-4 β Browser β Python mesh bridge
Files: webagent/src/mesh/browsermesh.js (PeerJS/WebRTC)
Status: Browser mesh and Python relay run as separate isolated meshes
Fix: Bidirectional WebRTCβmailbox translation, ICE/TURN server
P3-5 β RelayDiscovery.start() (Phase 2 peer discovery)
File: hearthnet/discovery/relay.py:8 β NotImplementedError
Fix: Poll /relay/v1/roster on a timer, add discovered peers to PeerRegistry
P3-6 β Publish to PyPI
Command: python -m build && twine upload dist/*
Note: pyproject.toml is ready
P3-7 β Docker image publish
File: Dockerfile.slim exists
Command: docker build -t hearthnet:latest . && docker push ghcr.io/ckal/hearthnet:latest
π All Tasks β Status at a Glance
| Priority | Task | Status |
|---|---|---|
| C1βC9 | Hackathon critical items | β All done |
| W1βW8 | Service/UI wiring | β All done |
| P0-1 | πΌ Image describe tab | β Done |
| P0-2 | π OCR tab | β Done |
| P0-3 | π Translation tab | β Done |
| P1-1 | Styled headers on all tabs | β Done |
| P1-2 | Rate limiting on bus/relay | β³ Open |
| P1-3 | Token expiry enforcement | β³ Open |
| P1-4 | E2E encryption default | β³ Open |
| P1-5 | node.start() wiring | β³ Open |
| P1-6 | Gossip sync | β³ Open |
| P2-1 | Evidence UI tab | β³ Open |
| P2-2 | CivilDefense UI tab | β³ Open |
| P2-3 | Routing trace flow chart | β³ Open |
| P2-4 | Peer capability matrix | β³ Open |
| P2-5 | Dark mode toggle | β³ Open |
| P2-6 | Model selection UI | β³ Open |
| P2-7 | Relay hub rate limiting | β³ Open |
| P3-1 | M26 distributed inference | β³ Future |
| P3-2 | M28 federated learning | β³ Future |
| P3-3 | M29 LoRa hardware | β³ Future |
| P3-4 | BrowserβPython mesh bridge | β³ Future |
| P3-5 | RelayDiscovery.start() | β³ Future |
| P3-6 | PyPI publish | β³ Future |
| P3-7 | Docker image publish | β³ Future |
See Also
docs/ENV.mdβ all environment variables, secrets, and model referencedocs/SECURITY_FINDINGS.mdβ SEC-1 through SEC-8 with fixeshackathon_final_step.mdβ project status and prize tracking