diff --git a/research_ui/app.js b/research_ui/app.js
index cb95c17..2ae34d7 100644
--- a/research_ui/app.js
+++ b/research_ui/app.js
@@ -767,6 +767,50 @@ function buildPretradePanel(pretrade) {
const reasons = Array.isArray(pretrade.reasons) && pretrade.reasons.length
? pretrade.reasons.map((reason) => `${escapeHtml(reason)}`).join("")
: `No rejection reasons.`;
+ const artifactEntries = [
+ {
+ label: "Validation artifact",
+ path: pretrade.latest_validation_path,
+ href: pretrade.latest_validation_href,
+ fallback: "Latest validation artifact not available yet.",
+ },
+ {
+ label: "Source artifact",
+ path: pretrade.source_artifact_path,
+ href: pretrade.source_artifact_href,
+ fallback: "Source artifact not available yet.",
+ },
+ ].filter((artifact) => artifact.path || artifact.href);
+
+ const artifactLinks = artifactEntries.length
+ ? `
+
+ ${artifactEntries.map((artifact) => {
+ const label = escapeHtml(artifact.label);
+ const path = escapeHtml(artifact.path || artifact.fallback);
+ if (artifact.href) {
+ return `
+
+ ${label}
+ ${path}
+
+ `;
+ }
+ return `
+
+ ${label}
+ ${path}
+
+ `;
+ }).join("")}
+
+ `
+ : `
+
+ No artifact paths yet
+ QuantLab will show the validation and source artifact paths here once the first bounded handoff is ingested.
+
+ `;
return `
@@ -777,6 +821,7 @@ function buildPretradePanel(pretrade) {
${keyValue("Side", titleCase(pretrade.side || "-"))}
${keyValue("Draft ready", pretrade.ready_for_draft_execution_intent ? "Yes" : "No")}
+ ${artifactLinks}
${reasons}
`;
}
diff --git a/test/test_research_ui_server.py b/test/test_research_ui_server.py
index 7584b6a..b7c8e6e 100644
--- a/test/test_research_ui_server.py
+++ b/test/test_research_ui_server.py
@@ -511,6 +511,8 @@ def test_build_pretrade_handoff_payload_selects_latest_validation_artifact(tmp_p
assert payload["handoff_id"] == "handoff-newer"
assert payload["latest_validation_path"] == str(newer)
assert payload["latest_validation_href"] == "/outputs/pretrade_handoff/newer/pretrade_handoff_validation.json"
+ assert payload["source_artifact_path"] == "C:\\Users\\marce\\Documents\\meta_trade\\tests\\fixtures\\expected_quantlab_handoff.json"
+ assert payload["source_artifact_href"] is None
def test_normalize_launch_request_accepts_run_payload():