Add copyable Ranker handoff text
This commit is contained in:
@@ -1276,6 +1276,54 @@ function handoffReadinessFor({ ranked = [], provenance = {}, warnings = [], expe
|
||||
};
|
||||
}
|
||||
|
||||
function copyableHandoffText({ ranked = [], provenance = {}, decisionContext = {}, readiness = {} }) {
|
||||
const lanes = [
|
||||
['do', 'Do first'],
|
||||
['test', 'Validate next'],
|
||||
['defer', 'Defer'],
|
||||
['park', 'Park / cut'],
|
||||
];
|
||||
const sourceLine = [
|
||||
provenance?.source || 'Scattermind',
|
||||
provenance?.snapshotTitle,
|
||||
provenance?.artifactId,
|
||||
].filter(Boolean).join(' · ');
|
||||
const contextLines = [
|
||||
decisionContext?.targetAudience ? `Audience: ${decisionContext.targetAudience}` : '',
|
||||
...(decisionContext?.constraints || []).slice(0, 3).map(item => `Constraint: ${item}`),
|
||||
...(decisionContext?.nonGoals || []).slice(0, 3).map(item => `Non-goal: ${item}`),
|
||||
].filter(Boolean);
|
||||
const itemLines = lanes.flatMap(([laneId, label]) => {
|
||||
const laneItems = ranked.filter(item => item.lane?.id === laneId).slice(0, laneId === 'do' ? 1 : 3);
|
||||
return [
|
||||
`## ${label}`,
|
||||
...(laneItems.length
|
||||
? laneItems.map(item => {
|
||||
const sourceTrace = [item.provenance?.sourceSection, item.provenance?.sourceId].filter(Boolean).join(' · ');
|
||||
return [
|
||||
`- ${item.title}`,
|
||||
` Why: ${reasonFor(item)}.`,
|
||||
` Next: ${nextStepFor(item)}`,
|
||||
` Evidence: ${evidenceQuestionFor(item)}`,
|
||||
sourceTrace ? ` Source: ${sourceTrace}` : '',
|
||||
item.provenance?.sourceQuote ? ` Quote: ${cleanText(item.provenance.sourceQuote, 180)}` : '',
|
||||
].filter(Boolean).join('\n');
|
||||
})
|
||||
: ['- None']),
|
||||
'',
|
||||
];
|
||||
});
|
||||
return [
|
||||
'# Ranker build-order handoff',
|
||||
sourceLine ? `Source: ${sourceLine}` : '',
|
||||
provenance?.originalPrompt ? `Original prompt: ${cleanText(provenance.originalPrompt, 240)}` : '',
|
||||
readiness?.status ? `Readiness: ${readiness.status} — ${readiness.summary || ''}` : '',
|
||||
contextLines.length ? ['## Carried context', ...contextLines.map(item => `- ${item}`)].join('\n') : '',
|
||||
...itemLines,
|
||||
'Rule: only the Do first item is active. Re-rank after evidence changes; do not quietly turn this into a workspace/dashboard backlog.',
|
||||
].filter(Boolean).join('\n\n');
|
||||
}
|
||||
|
||||
function createHandoffContract({ ranked, provenance, decisionContext }) {
|
||||
const warnings = [];
|
||||
const expectsSourceTrace = Boolean(provenance?.artifactId || provenance?.conceptMapId || provenance?.snapshotTitle);
|
||||
@@ -1305,6 +1353,7 @@ function createHandoffContract({ ranked, provenance, decisionContext }) {
|
||||
};
|
||||
});
|
||||
const uniqueWarnings = [...new Set(warnings)];
|
||||
const readiness = handoffReadinessFor({ ranked, provenance, warnings: uniqueWarnings, expectsSourceTrace });
|
||||
|
||||
return {
|
||||
schema: 'rank-feedback-result-v1',
|
||||
@@ -1326,7 +1375,8 @@ function createHandoffContract({ ranked, provenance, decisionContext }) {
|
||||
},
|
||||
itemTrace,
|
||||
warnings: uniqueWarnings,
|
||||
readiness: handoffReadinessFor({ ranked, provenance, warnings: uniqueWarnings, expectsSourceTrace }),
|
||||
readiness,
|
||||
copyableText: copyableHandoffText({ ranked, provenance, decisionContext, readiness }),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user