Carry Concept Map thread signals into Ranker
This commit is contained in:
@@ -1663,21 +1663,6 @@ function optionsFromBody(body = {}) {
|
||||
questionSource.sourceSection || 'questionsToSitWith',
|
||||
'Question to sit with'
|
||||
);
|
||||
if (buildOrderOptions.length) {
|
||||
const proofLens = objectFrom(conceptMapLenses.question || conceptMapLenses.proof || conceptMapLenses.validation || conceptMapLenses.evidence);
|
||||
const proofLensText = lensContent(conceptMapLenses.question)
|
||||
|| lensContent(conceptMapLenses.proof)
|
||||
|| lensContent(conceptMapLenses.validation)
|
||||
|| lensContent(conceptMapLenses.evidence)
|
||||
|| '';
|
||||
const proofSourceTitle = cleanText(proofLens.title || 'Proof Steps', 140);
|
||||
const proofOptions = optionsFromProofLensText(proofLensText, 'concept-map.lenses.question', proofSourceTitle);
|
||||
return normalizeCandidateGroup([
|
||||
{ items: buildOrderOptions, sourceSection: 'concept-map.lenses.channel' },
|
||||
...(proofOptions.length ? [{ items: proofOptions, sourceSection: 'concept-map.lenses.question', defaultLane: 'validate-next' }] : []),
|
||||
...(questionOptions.length ? [{ items: questionOptions, sourceSection: questionSource.sourceSection || 'questionsToSitWith', defaultLane: 'validate-next' }] : []),
|
||||
]);
|
||||
}
|
||||
const actionThreadSource = firstArraySource([
|
||||
{ items: conceptMap.threads_to_hold || conceptMap.threadsToHold || conceptMap.actionThreads || conceptMap.action_threads, sourceSection: 'concept-map.threadsToHold' },
|
||||
{ items: snapshot.threads_to_hold || snapshot.threadsToHold || snapshot.actionThreads || snapshot.action_threads, sourceSection: 'snapshot.threadsToHold' },
|
||||
@@ -1690,6 +1675,23 @@ function optionsFromBody(body = {}) {
|
||||
actionThreadSource.sourceSection || 'threadsToHold',
|
||||
'Thread to hold'
|
||||
);
|
||||
if (buildOrderOptions.length) {
|
||||
const proofLens = objectFrom(conceptMapLenses.question || conceptMapLenses.proof || conceptMapLenses.validation || conceptMapLenses.evidence);
|
||||
const proofLensText = lensContent(conceptMapLenses.question)
|
||||
|| lensContent(conceptMapLenses.proof)
|
||||
|| lensContent(conceptMapLenses.validation)
|
||||
|| lensContent(conceptMapLenses.evidence)
|
||||
|| '';
|
||||
const proofSourceTitle = cleanText(proofLens.title || 'Proof Steps', 140);
|
||||
const proofOptions = optionsFromProofLensText(proofLensText, 'concept-map.lenses.question', proofSourceTitle);
|
||||
const supplementalActionThreadOptions = actionThreadOptions.filter(item => item.greenFlag || item.redFlag || ['defer', 'park'].includes(item.suggestedLane));
|
||||
return normalizeCandidateGroup([
|
||||
{ items: buildOrderOptions, sourceSection: 'concept-map.lenses.channel' },
|
||||
...(supplementalActionThreadOptions.length ? [{ items: supplementalActionThreadOptions, sourceSection: actionThreadSource.sourceSection || 'threadsToHold' }] : []),
|
||||
...(proofOptions.length ? [{ items: proofOptions, sourceSection: 'concept-map.lenses.question', defaultLane: 'validate-next' }] : []),
|
||||
...(questionOptions.length ? [{ items: questionOptions, sourceSection: questionSource.sourceSection || 'questionsToSitWith', defaultLane: 'validate-next' }] : []),
|
||||
]);
|
||||
}
|
||||
if (actionThreadOptions.length >= 2) return normalizeCandidateGroup([{ items: actionThreadOptions, sourceSection: actionThreadSource.sourceSection || 'threadsToHold' }]);
|
||||
if (actionThreadOptions.length === 1 && questionOptions.length) {
|
||||
return normalizeCandidateGroup([
|
||||
@@ -1894,6 +1896,18 @@ function killSignalFor(option) {
|
||||
return 'People understand the idea but do not take, request, or value the next step.';
|
||||
}
|
||||
|
||||
function carriedProofSignalFor(active, ranked = [], signalKey = 'successSignal') {
|
||||
if (!active) return '';
|
||||
if (active.factors?.[signalKey]) return active.factors[signalKey];
|
||||
const threadSignal = ranked.find(item => (
|
||||
item.id !== active.id
|
||||
&& /threads(?:ToHold|_to_hold)?/i.test(item.provenance?.sourceSection || '')
|
||||
&& item.factors?.[signalKey]
|
||||
));
|
||||
if (threadSignal?.factors?.[signalKey]) return threadSignal.factors[signalKey];
|
||||
return signalKey === 'killSignal' ? killSignalFor(active) : successSignalFor(active);
|
||||
}
|
||||
|
||||
function scoringNotesFor(option) {
|
||||
const notes = [];
|
||||
const m = option.metrics || {};
|
||||
@@ -1945,6 +1959,8 @@ function createDecisionBrief({ idea, context, mode, ranked, provenance, decision
|
||||
const activeSourceQuote = cleanText(top?.provenance?.sourceQuote || '', 260);
|
||||
const activeSourceTitle = cleanText(top?.provenance?.sourceTitle || '', 140);
|
||||
const activeProofScript = top ? proofScriptFor(top, provenance) : '';
|
||||
const activeSuccessSignal = carriedProofSignalFor(top, ranked, 'successSignal');
|
||||
const activeKillSignal = carriedProofSignalFor(top, ranked, 'killSignal');
|
||||
const firstScreen = top ? {
|
||||
headline: `Build only this first: ${top.title}`,
|
||||
primaryAction: nextStepFor(top),
|
||||
@@ -1954,8 +1970,8 @@ function createDecisionBrief({ idea, context, mode, ranked, provenance, decision
|
||||
sourceAnchor: activeSourceAnchor,
|
||||
sourceTitle: activeSourceTitle,
|
||||
sourceQuote: activeSourceQuote,
|
||||
passSignal: successSignalFor(top),
|
||||
stopSignal: killSignalFor(top),
|
||||
passSignal: activeSuccessSignal,
|
||||
stopSignal: activeKillSignal,
|
||||
proofCadence: 'Run one tiny proof cycle, then rerank before adding surface area.',
|
||||
holdBack: deferred.slice(0, 3).map(item => ({ title: item.title, lane: item.lane?.label || 'Not now', reason: reasonFor(item) })),
|
||||
guardrails: (decisionContext?.nonGoals || []).slice(0, 3),
|
||||
@@ -1967,8 +1983,8 @@ function createDecisionBrief({ idea, context, mode, ranked, provenance, decision
|
||||
firstProofStep: nextStepFor(top),
|
||||
evidenceQuestion: evidenceQuestionFor(top),
|
||||
proofScript: activeProofScript,
|
||||
passSignal: successSignalFor(top),
|
||||
stopSignal: killSignalFor(top),
|
||||
passSignal: activeSuccessSignal,
|
||||
stopSignal: activeKillSignal,
|
||||
proofCadence: 'Run one tiny proof cycle, then rerank before adding surface area.',
|
||||
doNotStartYet: deferred.slice(0, 3).map(item => item.title),
|
||||
sourceAnchor: activeSourceAnchor,
|
||||
@@ -2136,8 +2152,8 @@ function activeSliceFor({ ranked = [], provenance = {}, readiness = {} }) {
|
||||
nextStep: nextStepFor(active),
|
||||
evidenceQuestion: evidenceQuestionFor(active),
|
||||
proofScript: proofScriptFor(active, provenance),
|
||||
successSignal: successSignalFor(active),
|
||||
killSignal: killSignalFor(active),
|
||||
successSignal: carriedProofSignalFor(active, ranked, 'successSignal'),
|
||||
killSignal: carriedProofSignalFor(active, ranked, 'killSignal'),
|
||||
},
|
||||
source: {
|
||||
artifactId: provenance?.artifactId || '',
|
||||
|
||||
Reference in New Issue
Block a user