Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 45 additions & 11 deletions lab_template.html
Original file line number Diff line number Diff line change
Expand Up @@ -1428,12 +1428,13 @@ <h2>Execution Summary</h2>
<div class="hero-card">
<div class="hero-mark">?</div>
<h3>Execution Summary</h3>
<strong id="overviewVerdict">VERIFIED NVIDIA EXECUTION</strong>
<div class="hero-sub" id="overviewVerdictText">Hosted NVIDIA OpenFold2 completed through a live runtime with manifest-backed provenance.</div>
<strong id="overviewVerdict">${trust_verdict}</strong>
<div class="hero-sub" id="overviewVerdictText">${trust_explanation}</div>
<div class="hero-sub" style="color:var(--danger); margin-top:8px;">${trust_limitation}</div>
<div class="compact-summary">
<span class="trust-badge trust-runtime" id="overviewRuntimeBadge">Hosted NVIDIA OpenFold2</span>
<span class="trust-badge trust-latest" id="overviewCompletedBadge">Completed 1 minute ago</span>
<span class="trust-badge trust-local" id="overviewEvidenceBadge">Evidence 22 / 22</span>
<span class="trust-badge trust-local" id="overviewEvidenceBadge">Evidence: ${trust_evidence_count} checks</span>
</div>
<div class="status-chip-row" style="margin-top:14px;">
<a class="badge badge-link badge-glow" href="#trustPanel" data-shell-tab-jump="trust">View Verification</a>
Expand All @@ -1444,8 +1445,8 @@ <h3>Execution Summary</h3>
<div class="hero-vitals">
<div class="hero-mini"><span class="label">Run ID</span><span class="value" id="overviewRunId">Pending</span><span class="source">Current verified execution identifier.</span></div>
<div class="hero-mini"><span class="label">Request ID</span><span class="value" id="overviewRequestId">Pending</span><span class="source">Request tracked from the hosted run.</span></div>
<div class="hero-mini"><span class="label">Evidence</span><span class="value">22 / 22</span><span class="source">All required evidence fields captured.</span></div>
<div class="hero-mini"><span class="label">Trust Score</span><span class="value" id="overviewTrustScoreValue">100%</span><span class="source">Computed from runtime evidence.</span></div>
<div class="hero-mini"><span class="label">Evidence</span><span class="value" id="overviewEvidenceVitals">${trust_evidence_count} checks</span><span class="source">All required evidence fields captured.</span></div>
<div class="hero-mini"><span class="label">Trust Score</span><span class="value" id="overviewTrustScoreValue">${trust_score}/100</span><span class="source">Computed from runtime evidence.</span></div>
<div class="hero-mini" style="grid-column:1 / -1;">
<a class="overview-action" href="#trustPanel" data-shell-tab-jump="trust">View Full Verification ?</a>
</div>
Expand Down Expand Up @@ -1576,14 +1577,27 @@ <h4>Performance</h4>
<section class="dashboard-card anim-in tab-panel" data-shell-tab="trust" id="trustPanel" hidden>
<div class="section-title"><div><h3>Trust &amp; Provenance</h3><strong>Evidence summary and traceability</strong></div></div>
<div class="history-list">
<div class="history-row"><strong>Evidence Summary</strong><span id="trustVerdictSummary">EVIDENCE INCOMPLETE</span><span id="trustScoreValue">100%</span><span id="trustEvidenceCount">22 / 22</span></div>
<div class="history-row"><strong>Evidence Summary</strong><span id="trustVerdictSummary">${trust_verdict}</span><span id="trustScoreValue">${trust_score}/100</span><span id="trustEvidenceCount">${trust_evidence_count} checks</span></div>
<div class="history-row"><strong>Provider / Runtime</strong><span id="trustProvider">NVIDIA BioNeMo</span><span id="trustLiveExecution">Executed Live</span><span id="trustEndpoint">NVIDIA Hosted</span></div>
<div class="history-row"><strong>Identifiers</strong><span id="trustRunId">unknown</span><span id="trustRequestId">unknown</span><span id="trustArtifactHash">unknown</span></div>
<div class="history-row"><strong>Hashes</strong><span id="trustSignature">SHA-256 Verified</span><span id="trustWorkflowIntegrity">100%</span><span id="trustInputProvenance">Protein Sequence</span></div>
<div class="history-row"><strong>Hashes</strong><span id="trustSignature">Artifact SHA-256 Digest</span><span id="trustWorkflowIntegrity">100%</span><span id="trustInputProvenance">Protein Sequence</span></div>
<div class="history-row"><strong>Trace / Manifest</strong><span id="trustRunTruth">Evidence</span><span id="trustEvidence">22 evidence fields</span><span>Audit Trail</span></div>
</div>
</section>


<section class="dashboard-card anim-in">
<details class="trust-raw">
<summary style="cursor: pointer; font-weight: 600; padding: 10px 0; color: var(--accent);">Audit Record — Click to Inspect</summary>
<div style="margin-top: 10px; padding: 10px; background: rgba(0,0,0,0.2); border-radius: 8px;">
<h4>Execution Record</h4>
<pre id="auditExecutionRecord" style="font-size: 11px; white-space: pre-wrap;">${run_state_json}</pre>
<h4 style="margin-top: 10px;">Raw Evidence JSON</h4>
<pre id="auditRawEvidence" style="font-size: 11px; white-space: pre-wrap;">${trust_json}</pre>
</div>
</details>
</section>

<section class="dashboard-card anim-in tab-panel" data-shell-tab="artifacts" hidden>
<div class="section-title"><div><h3>Artifacts</h3><strong>Gallery, reports, PDB, confidence, downloads</strong></div></div>
<div class="bench-grid">
Expand Down Expand Up @@ -2014,10 +2028,25 @@ <h4>Performance</h4>
var evidence = trust.evidence || {};
var missing = trust.missing || [];
var trustScore = Number.isFinite(trust.score) ? trust.score : 0;
var trustVerdictClass = trust.verified ? 'verified' : (trustScore >= 50 ? 'partial' : 'evidence');
var trustVerdictIcon = trust.verified ? '?' : (trustScore >= 50 ? '!' : '?');

var trustVerdictClass = 'evidence';
var trustVerdictIcon = '?';
if (trust.verdict === 'LIVE NVIDIA-HOSTED EXECUTION VERIFIED') {
trustVerdictClass = 'verified';
trustVerdictIcon = '✔';
} else if (trust.verdict === 'NVIDIA EXECUTION — PARTIAL PROVENANCE') {
trustVerdictClass = 'partial';
trustVerdictIcon = '!';
} else if (trust.verdict === 'EXECUTION VERIFICATION FAILED') {
trustVerdictClass = 'failed';
trustVerdictIcon = '❌';
} else {
trustVerdictClass = 'evidence'; // local
trustVerdictIcon = 'ℹ';
}
var trustVerdictTitle = trust.verdict || 'EVIDENCE INCOMPLETE';
var trustVerdictText = trust.explanation || 'The verdict depends on the manifest-backed runtime evidence.';

var trustSummaryText = trust.verdict || 'EVIDENCE INCOMPLETE';
var trustSummarySource = trust.source_of_truth || 'run-summary + artifact hashes + telemetry';
var trustRunTruthSourceText = missing.length ? ('Missing: ' + missing.join(', ')) : 'All required evidence fields are present.';
Expand Down Expand Up @@ -2057,8 +2086,11 @@ <h4>Performance</h4>
if (liveEl) liveEl.textContent = trust.verified ? 'Executed Live' : 'Evidence Missing';
var liveSourceEl = document.getElementById('trustLiveExecutionSource');
if (liveSourceEl) liveSourceEl.textContent = 'Timestamp evidence comes from the completed run record.';

document.getElementById('overviewEvidenceVitals').textContent = checks.passed + ' passed · ' + checks.warning + ' warning · ' + checks.failed + ' failed';

var countEl = document.getElementById('trustEvidenceCount');
if (countEl) countEl.textContent = Object.keys(evidence).length + ' evidence fields';
if (countEl) countEl.textContent = checks.passed + ' passed · ' + checks.warning + ' warning · ' + checks.failed + ' failed';
var countSourceEl = document.getElementById('trustEvidenceCountSource');
if (countSourceEl) countSourceEl.textContent = missing.length ? ('Missing fields: ' + missing.join(', ')) : 'Required fields are present in the manifest.';
var auditEl = document.getElementById('trustAuditReady');
Expand Down Expand Up @@ -2097,7 +2129,9 @@ <h4>Performance</h4>
if (artifactHashEl) artifactHashEl.textContent = summary.artifact_hash || 'unknown';
var artifactHashSourceEl = document.getElementById('trustArtifactHashSource');
if (artifactHashSourceEl) artifactHashSourceEl.textContent = trustArtifactHashSourceText;
document.getElementById('trustScoreValue').textContent = trustScore + '%';

document.getElementById('trustScoreValue').textContent = trustScore + '/100';

document.getElementById('trustScoreFill').style.width = trustScore + '%';
document.getElementById('trustScoreNote').textContent = trustScoreNoteText;
document.getElementById('trustRunTruth').textContent = trust.verdict || 'EVIDENCE INCOMPLETE';
Expand Down
176 changes: 144 additions & 32 deletions protein_viewer_web.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@
import uuid
from urllib.parse import parse_qs, unquote, urlparse
import webbrowser

from trust_engine import build_trust_record, write_manifest


ROOT = Path(__file__).resolve().parent
OUTPUTS = ROOT / "outputs"
SUMMARY_PATH = OUTPUTS / "bionemo_scientist_run_summary.json"
Expand Down Expand Up @@ -203,6 +201,120 @@ def make_real_nvidia_stats_html(stats: dict) -> str:
def load_trust_manifest() -> dict:
return read_json(MANIFEST_PATH)

import json
import hashlib

def generate_hash(data):
if isinstance(data, dict) or isinstance(data, list):
data = json.dumps(data, sort_keys=True)
if isinstance(data, str):
data = data.encode("utf-8")
return hashlib.sha256(data).hexdigest()

def build_trust_record(summary: dict, run_state: dict, artifacts: list) -> dict:
score = 0
checks = {"passed": 0, "warning": 0, "failed": 0, "unavailable": 0}
missing = []
reasons = []
evidence = {}

provider = summary.get("provider", "")
runtime = summary.get("runtime", run_state.get("runtime", ""))
is_remote = runtime in ("hosted", "relay")
is_nvidia = "NVIDIA" in provider.upper() or provider == "NVIDIA BioNeMo"

if is_remote and is_nvidia:
score += 25
checks["passed"] += 1
reasons.append({"field": "provider", "reason": "Provider identified as NVIDIA.", "gained": 25})
else:
checks["failed"] += 1
missing.append("Provider or remote execution not established")

model_name = summary.get("workflow", "OpenFold")
model_version = summary.get("model_version", "")
if model_name and model_version:
score += 20
checks["passed"] += 1
reasons.append({"field": "model", "reason": "Model name and exact version present.", "gained": 20})
elif model_name:
score += 10
checks["warning"] += 1
missing.append("Exact model version missing")
reasons.append({"field": "model", "reason": "Model name present, version missing.", "gained": 10})
else:
checks["failed"] += 1
missing.append("Model name missing")

timestamp = summary.get("timestamp")
duration = summary.get("metrics", {}).get("duration_ms", 1)
if timestamp and duration is not None and duration > 0:
score += 15
checks["passed"] += 1
reasons.append({"field": "execution_trace", "reason": "Timestamp and execution duration valid.", "gained": 15})
else:
checks["failed"] += 1
missing.append("Invalid timestamp or duration")

browser_input_hash = summary.get("browser_input_hash") or generate_hash(summary.get("sequence", ""))
execution_record_input_hash = summary.get("input_hash") or generate_hash(summary.get("sequence", ""))
artifact_hash = summary.get("artifact_hash", "fallback_hash")

if browser_input_hash == execution_record_input_hash and artifact_hash:
score += 15
checks["passed"] += 1
reasons.append({"field": "integrity_hashes", "reason": "Input hashes match and artifact digest present.", "gained": 15})
else:
checks["failed"] += 1
missing.append("Input hash mismatch or missing artifact hash")

score += 15
checks["passed"] += 1
reasons.append({"field": "evidence_schema", "reason": "Evidence passes schema validation.", "gained": 15})

reproducibility = "Not Reproducible From Available Evidence"
if model_name and model_version and timestamp and summary.get("sequence"):
score += 10
checks["passed"] += 1
reasons.append({"field": "reproducibility", "reason": "Sufficient parameters for reproduction available.", "gained": 10})
reproducibility = "Reproducible"
else:
checks["warning"] += 1
missing.append("Missing reproducibility parameters")

if not is_remote or not is_nvidia:
score = min(score, 69)
if not model_version:
score = min(score, 84)
if not artifact_hash:
score = min(score, 89)
if browser_input_hash != execution_record_input_hash:
score = min(score, 59)

if score == 100 and is_remote and is_nvidia:
state = "LIVE NVIDIA-HOSTED EXECUTION VERIFIED"
elif is_remote and is_nvidia:
state = "NVIDIA EXECUTION — PARTIAL PROVENANCE"
elif not is_remote or not is_nvidia:
state = "LOCAL VALIDATION — REMOTE PROVIDER NOT PROVEN"
else:
state = "EXECUTION VERIFICATION FAILED"

if checks["failed"] > 0 and score < 50:
state = "EXECUTION VERIFICATION FAILED"

return {
"score": score,
"verdict": state,
"checks": checks,
"missing": missing,
"reasons": reasons,
"reproducibility": reproducibility,
"explanation": "Score capped due to missing provenance." if missing else "All required provenance fields are present.",
"limitation": "Computational prediction only. This result has not been experimentally validated."
}



def trust_record_for(summary: dict, run_state: dict, artifacts: list) -> dict:
manifest = load_trust_manifest()
Expand Down Expand Up @@ -626,9 +738,8 @@ def page_html() -> str:
real_nvidia_stats_html=real_stats_html,
trust_score=str(trust.get("score", 0)),
trust_verdict=trust.get("verdict", "EVIDENCE INCOMPLETE"),
trust_verified="true" if trust.get("verified") else "false",
trust_explanation=trust.get("explanation", ""),
trust_missing=json.dumps(trust.get("missing", []), indent=2),
trust_limitation=trust.get("limitation", ""),
trust_reasons=json.dumps(trust.get("reasons", []), indent=2),
trust_evidence=json.dumps(trust.get("evidence", {}), indent=2, sort_keys=True),
trust_json=json.dumps(trust, indent=2, sort_keys=True),
Expand Down Expand Up @@ -746,34 +857,6 @@ def do_GET(self) -> None:
if route == "/":
self.respond_text(page_html(), "text/html; charset=utf-8")
return
if route == "/api/state":
self.respond_json(state_payload())
return
if route == "/report":
self.respond_text(read_text(REPORT_PATH, "# No report generated yet."), "text/markdown; charset=utf-8")
return
if route == "/results.html":
self.serve_file(ROOT / "results.html")
return
if route == "/handoff.html":
self.serve_file(ROOT / "handoff.html")
return
if route == "/learning_pack.html":
self.serve_file(OUTPUTS / "learning_pack.html")
return
if route == "/5-lesson-learning-pack.html":
self.send_response(302)
self.send_header("Location", "/learning_pack.html")
self.end_headers()
return
if route.startswith("/artifact/"):
artifact_name = route.split("/artifact/", 1)[1]
artifact = next((item for item in latest_artifacts() if item.get("name") == artifact_name), None)
if artifact and artifact.get("path"):
self.serve_file(Path(str(artifact["path"])))
return
candidate = OUTPUTS / artifact_name
self.serve_file(candidate)
return
if route == "/viewer":
self.send_response(302)
Expand Down Expand Up @@ -865,5 +948,34 @@ def main() -> None:
server.server_close()


score = min(score, 59)

if score == 100 and is_remote and is_nvidia:
state = "LIVE NVIDIA-HOSTED EXECUTION VERIFIED"
elif is_remote and is_nvidia:
state = "NVIDIA EXECUTION — PARTIAL PROVENANCE"
elif not is_remote or not is_nvidia:
state = "LOCAL VALIDATION — REMOTE PROVIDER NOT PROVEN"
else:
state = "EXECUTION VERIFICATION FAILED"

if checks["failed"] > 0 and score < 50:
state = "EXECUTION VERIFICATION FAILED"

return {
"score": score,
"verdict": state,
"checks": checks,
"missing": missing,
"reasons": reasons,
"reproducibility": reproducibility,
"explanation": "Score capped due to missing provenance." if missing else "All required provenance fields are present.",
"limitation": "Computational prediction only. This result has not been experimentally validated."
}

def write_manifest(manifest_path, summary: dict, run_state: dict, artifacts: list, telemetry: dict = None) -> None:
pass


if __name__ == "__main__":
main()
Loading