Expose Ranker source traces in result cards
This commit is contained in:
+31
-3
@@ -61,8 +61,13 @@ function parsePastedJsonPayload(value) {
|
|||||||
try {
|
try {
|
||||||
const parsed = JSON.parse(jsonText);
|
const parsed = JSON.parse(jsonText);
|
||||||
const looksLikeBridgePayload = parsed && typeof parsed === 'object' && !Array.isArray(parsed) && (
|
const looksLikeBridgePayload = parsed && typeof parsed === 'object' && !Array.isArray(parsed) && (
|
||||||
parsed.schema || parsed.featureSet || parsed.snapshot || parsed.conceptMap || parsed.buildOrder || parsed.lenses || parsed.reference_code || parsed.referenceCode || parsed.artifactId || parsed.ideaText
|
parsed.schema || parsed.featureSet || parsed.feature_set || parsed.snapshot || parsed.conceptMap || parsed.concept_map || parsed.buildOrder || parsed.build_order || parsed.lenses
|
||||||
|| Array.isArray(parsed.nextActions) || Array.isArray(parsed.nextMoves) || Array.isArray(parsed.validateNext) || Array.isArray(parsed.deferred) || Array.isArray(parsed.parkingLot)
|
|| parsed.payload || parsed.rankPayload || parsed.scattermindPayload || parsed.conceptMapJson
|
||||||
|
|| parsed.reference_code || parsed.referenceCode || parsed.artifactId || parsed.sourceArtifactId || parsed.source_artifact_id
|
||||||
|
|| parsed.ideaText || parsed.idea_text || parsed.originalPrompt || parsed.original_prompt || parsed.sourceSummary || parsed.source_summary || parsed.opening_reflection || parsed.restated_idea
|
||||||
|
|| Array.isArray(parsed.features) || Array.isArray(parsed.actions) || Array.isArray(parsed.candidates)
|
||||||
|
|| Array.isArray(parsed.nextActions) || Array.isArray(parsed.next_actions) || Array.isArray(parsed.nextMoves) || Array.isArray(parsed.next_moves)
|
||||||
|
|| Array.isArray(parsed.validateNext) || Array.isArray(parsed.validate_next) || Array.isArray(parsed.deferred) || Array.isArray(parsed.parkingLot) || Array.isArray(parsed.parking_lot)
|
||||||
);
|
);
|
||||||
return looksLikeBridgePayload ? parsed : null;
|
return looksLikeBridgePayload ? parsed : null;
|
||||||
} catch {
|
} catch {
|
||||||
@@ -105,7 +110,8 @@ function payloadFromForm(formPayload) {
|
|||||||
const optionsJson = parsePastedJsonPayload(formPayload.optionsText);
|
const optionsJson = parsePastedJsonPayload(formPayload.optionsText);
|
||||||
const embedded = ideaJson || optionsJson;
|
const embedded = ideaJson || optionsJson;
|
||||||
if (!embedded) return formPayload;
|
if (!embedded) return formPayload;
|
||||||
const merged = { ...embedded };
|
const unwrapped = embedded.payload || embedded.rankPayload || embedded.scattermindPayload || embedded.conceptMapJson || embedded;
|
||||||
|
const merged = { ...unwrapped };
|
||||||
if (!merged.mode && formPayload.mode) merged.mode = formPayload.mode;
|
if (!merged.mode && formPayload.mode) merged.mode = formPayload.mode;
|
||||||
if (String(formPayload.context || '').trim() && !merged.context) merged.context = formPayload.context;
|
if (String(formPayload.context || '').trim() && !merged.context) merged.context = formPayload.context;
|
||||||
return merged;
|
return merged;
|
||||||
@@ -142,6 +148,26 @@ function renderSourceTrace(sourceTrace = {}) {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderItemSourceTrace(item = {}) {
|
||||||
|
const provenance = item.provenance || {};
|
||||||
|
const trace = {
|
||||||
|
sourceSection: provenance.sourceSection || '',
|
||||||
|
sourceId: provenance.sourceId || '',
|
||||||
|
sourceTitle: provenance.sourceTitle || '',
|
||||||
|
sourceQuote: provenance.sourceQuote || '',
|
||||||
|
};
|
||||||
|
const hasTrace = trace.sourceSection || trace.sourceId || trace.sourceQuote;
|
||||||
|
if (!hasTrace) return '';
|
||||||
|
const label = [trace.sourceTitle, trace.sourceId || trace.sourceSection].filter(Boolean).join(' · ');
|
||||||
|
return `
|
||||||
|
<details class="item-source-trace">
|
||||||
|
<summary>Source trace${label ? ` · ${escapeHtml(label)}` : ''}</summary>
|
||||||
|
${trace.sourceQuote ? `<p>${escapeHtml(trace.sourceQuote)}</p>` : ''}
|
||||||
|
${trace.sourceSection ? `<small>Section: ${escapeHtml(trace.sourceSection)}</small>` : ''}
|
||||||
|
</details>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
function renderHandoffStatus(handoff = {}) {
|
function renderHandoffStatus(handoff = {}) {
|
||||||
const readiness = handoff.readiness || {};
|
const readiness = handoff.readiness || {};
|
||||||
if (!readiness.status) return '';
|
if (!readiness.status) return '';
|
||||||
@@ -174,6 +200,7 @@ function renderRankCard(item) {
|
|||||||
<div><span>Evidence question</span><p>${escapeHtml(item.evidenceQuestion || 'What proof would change this ranking?')}</p></div>
|
<div><span>Evidence question</span><p>${escapeHtml(item.evidenceQuestion || 'What proof would change this ranking?')}</p></div>
|
||||||
<div><span>Success / kill signal</span><p>${escapeHtml(item.successSignal || '')} ${escapeHtml(item.killSignal ? `Kill if: ${item.killSignal}` : '')}</p></div>
|
<div><span>Success / kill signal</span><p>${escapeHtml(item.successSignal || '')} ${escapeHtml(item.killSignal ? `Kill if: ${item.killSignal}` : '')}</p></div>
|
||||||
</div>
|
</div>
|
||||||
|
${renderItemSourceTrace(item)}
|
||||||
${renderMetrics(item.metrics)}
|
${renderMetrics(item.metrics)}
|
||||||
${renderPills(item.scoringNotes || [])}
|
${renderPills(item.scoringNotes || [])}
|
||||||
</article>
|
</article>
|
||||||
@@ -210,6 +237,7 @@ function sourceCitation(data) {
|
|||||||
trace.sourceTitle ? `Source title: ${trace.sourceTitle}` : '',
|
trace.sourceTitle ? `Source title: ${trace.sourceTitle}` : '',
|
||||||
trace.sourceQuote ? `Source quote: ${trace.sourceQuote}` : '',
|
trace.sourceQuote ? `Source quote: ${trace.sourceQuote}` : '',
|
||||||
source.originalPromptExcerpt ? `Original prompt: ${source.originalPromptExcerpt}` : '',
|
source.originalPromptExcerpt ? `Original prompt: ${source.originalPromptExcerpt}` : '',
|
||||||
|
source.sourceSummaryExcerpt ? `Source summary: ${source.sourceSummaryExcerpt}` : '',
|
||||||
].filter(Boolean);
|
].filter(Boolean);
|
||||||
return parts.length ? parts.join('\n') : 'No source citation was carried into this result.';
|
return parts.length ? parts.join('\n') : 'No source citation was carried into this result.';
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -4,9 +4,9 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta name="theme-color" content="#f3eee4" />
|
<meta name="theme-color" content="#f3eee4" />
|
||||||
<meta name="rank-version" content="2.2.0-feedback-front-door" />
|
<meta name="rank-version" content="2.2.1-source-trace-paste" />
|
||||||
<title>Ranker — feedback front door for messy decisions</title>
|
<title>Ranker — feedback front door for messy decisions</title>
|
||||||
<link rel="stylesheet" href="/styles.css?v=2.2.0-feedback-front-door" />
|
<link rel="stylesheet" href="/styles.css?v=2.2.1-source-trace-paste" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main class="page-shell">
|
<main class="page-shell">
|
||||||
@@ -127,6 +127,6 @@ Or paste a Scattermind Concept Map JSON object here; Ranker will preserve source
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div class="toast" id="toast" hidden></div>
|
<div class="toast" id="toast" hidden></div>
|
||||||
<script src="/app.js?v=2.2.0-feedback-front-door" type="module"></script>
|
<script src="/app.js?v=2.2.1-source-trace-paste" type="module"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+1
-1
@@ -39,4 +39,4 @@ button,input,textarea{font:inherit} button{cursor:pointer} a{color:inherit;text-
|
|||||||
.lane-column .rank-card{box-shadow:none;margin:0;border-width:1.5px}.lane-column .rank-card h3{font-size:clamp(20px,2vw,28px)}.lane-column .metrics{grid-template-columns:1fr}.signal-pills{margin:10px 0}.signal-pills span{background:#f0e8d9;font-size:10px;padding:5px 8px}.action-strip{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:14px 0}.action-strip>div{border:1.5px solid var(--hair);background:#fff6e6;padding:10px}.action-strip span{color:var(--blue2);font-size:10px}.action-strip p{margin:0;font-size:13px;line-height:1.35}.reflection-room{margin-top:24px}.expert-card{position:relative}.expert-card::before{content:"“";position:absolute;right:14px;top:0;font-size:72px;line-height:1;color:rgba(36,92,255,.16);font-weight:1000}
|
.lane-column .rank-card{box-shadow:none;margin:0;border-width:1.5px}.lane-column .rank-card h3{font-size:clamp(20px,2vw,28px)}.lane-column .metrics{grid-template-columns:1fr}.signal-pills{margin:10px 0}.signal-pills span{background:#f0e8d9;font-size:10px;padding:5px 8px}.action-strip{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:14px 0}.action-strip>div{border:1.5px solid var(--hair);background:#fff6e6;padding:10px}.action-strip span{color:var(--blue2);font-size:10px}.action-strip p{margin:0;font-size:13px;line-height:1.35}.reflection-room{margin-top:24px}.expert-card{position:relative}.expert-card::before{content:"“";position:absolute;right:14px;top:0;font-size:72px;line-height:1;color:rgba(36,92,255,.16);font-weight:1000}
|
||||||
@media (max-width:1100px){.lane-board{grid-template-columns:repeat(2,minmax(0,1fr))}.quick-glance{grid-template-columns:repeat(2,minmax(0,1fr))}.action-strip{grid-template-columns:1fr}}
|
@media (max-width:1100px){.lane-board{grid-template-columns:repeat(2,minmax(0,1fr))}.quick-glance{grid-template-columns:repeat(2,minmax(0,1fr))}.action-strip{grid-template-columns:1fr}}
|
||||||
@media (max-width:700px){.lane-board,.quick-glance{grid-template-columns:1fr}.memo-head::after{position:static;display:inline-block;margin-top:14px;transform:none}.result-actions .button{width:100%;justify-content:center}.quick-glance{box-shadow:6px 6px 0 var(--ink)}.quick-glance>div{min-height:auto}}
|
@media (max-width:700px){.lane-board,.quick-glance{grid-template-columns:1fr}.memo-head::after{position:static;display:inline-block;margin-top:14px;transform:none}.result-actions .button{width:100%;justify-content:center}.quick-glance{box-shadow:6px 6px 0 var(--ink)}.quick-glance>div{min-height:auto}}
|
||||||
.source-trace{margin:-4px 0 22px;padding:14px 16px;border:2px dashed var(--ink);background:#fff6e5;color:var(--ink2);box-shadow:5px 5px 0 rgba(21,19,15,.16)}.source-trace span,.handoff-card>span{display:block;margin-bottom:8px;color:var(--blue2);text-transform:uppercase;letter-spacing:.12em;font-size:11px;font-weight:1000}.source-trace b{display:block;margin-bottom:6px;font-size:14px}.source-trace p{margin:0;color:var(--muted);line-height:1.45}.handoff-card{border-left:8px solid var(--green)}.handoff-card.status-usable-with-warnings{border-left-color:var(--amber)}.handoff-card.status-needs-source-context,.handoff-card.status-blocked{border-left-color:var(--red)}.handoff-warnings{display:grid;gap:6px;margin-top:12px}.handoff-warnings code{display:block;white-space:normal;border:1px solid var(--hair);background:#f3eee4;padding:7px 9px;font-size:12px;color:var(--ink2)}
|
.source-trace{margin:-4px 0 22px;padding:14px 16px;border:2px dashed var(--ink);background:#fff6e5;color:var(--ink2);box-shadow:5px 5px 0 rgba(21,19,15,.16)}.source-trace span,.handoff-card>span{display:block;margin-bottom:8px;color:var(--blue2);text-transform:uppercase;letter-spacing:.12em;font-size:11px;font-weight:1000}.source-trace b{display:block;margin-bottom:6px;font-size:14px}.source-trace p{margin:0;color:var(--muted);line-height:1.45}.item-source-trace{margin:12px 0;padding:9px 10px;border:1.5px dashed var(--hair);background:#fffaf1;color:var(--ink2)}.item-source-trace summary{cursor:pointer;color:var(--blue2);font-size:11px;font-weight:1000;letter-spacing:.08em;text-transform:uppercase}.item-source-trace p{margin:8px 0 6px;color:var(--muted);font-size:13px;line-height:1.4}.item-source-trace small{display:block;color:var(--muted);font-size:11px;font-weight:800}.handoff-card{border-left:8px solid var(--green)}.handoff-card.status-usable-with-warnings{border-left-color:var(--amber)}.handoff-card.status-needs-source-context,.handoff-card.status-blocked{border-left-color:var(--red)}.handoff-warnings{display:grid;gap:6px;margin-top:12px}.handoff-warnings code{display:block;white-space:normal;border:1px solid var(--hair);background:#f3eee4;padding:7px 9px;font-size:12px;color:var(--ink2)}
|
||||||
|
|||||||
Reference in New Issue
Block a user