Add rank handoff readiness gate
This commit is contained in:
@@ -1141,6 +1141,60 @@ function compactBuildItems(items = []) {
|
||||
}));
|
||||
}
|
||||
|
||||
function handoffReadinessFor({ ranked = [], provenance = {}, warnings = [], expectsSourceTrace = false }) {
|
||||
const uniqueWarnings = [...new Set(warnings)];
|
||||
const activeItems = ranked.filter(item => ['do', 'test'].includes(item.lane?.id));
|
||||
const guardrailWarnings = uniqueWarnings.filter(item => /^active item .* conflicts with source non-goals/i.test(item));
|
||||
const sourceWarnings = uniqueWarnings.filter(item => /^missing (source section|original prompt provenance)/i.test(item));
|
||||
const evidenceWarnings = uniqueWarnings.filter(item => /^missing evidence needed for active item/i.test(item));
|
||||
const duplicateWarnings = uniqueWarnings.filter(item => /^duplicate source id/i.test(item));
|
||||
const missingArtifact = uniqueWarnings.includes('missing source artifact id');
|
||||
const blockers = [
|
||||
...guardrailWarnings,
|
||||
...(expectsSourceTrace ? sourceWarnings : []),
|
||||
...(expectsSourceTrace ? evidenceWarnings : []),
|
||||
];
|
||||
const nextChecks = [];
|
||||
|
||||
if (guardrailWarnings.length) nextChecks.push('Resolve source non-goal conflicts before treating any active item as build-ready.');
|
||||
if (expectsSourceTrace && sourceWarnings.length) nextChecks.push('Attach source section / prompt provenance from the Scattermind artifact.');
|
||||
if (expectsSourceTrace && evidenceWarnings.length) nextChecks.push('Add evidenceNeeded to every Do first / Validate next candidate before handoff.');
|
||||
if (missingArtifact) nextChecks.push(expectsSourceTrace ? 'Attach the Scattermind artifact id so the build order can be traced back.' : 'Attach a source artifact id if this came from Scattermind rather than a plain paste.');
|
||||
if (duplicateWarnings.length) nextChecks.push('Review normalized duplicate IDs before downstream tools store references.');
|
||||
if (!nextChecks.length && activeItems.length) nextChecks.push('Use the Do first item as the only active build slice, then rerank after evidence changes.');
|
||||
|
||||
const status = guardrailWarnings.length
|
||||
? 'blocked'
|
||||
: blockers.length
|
||||
? 'needs-source-context'
|
||||
: uniqueWarnings.length
|
||||
? 'usable-with-warnings'
|
||||
: 'ready';
|
||||
const labels = {
|
||||
ready: 'Ready for Ranker handoff',
|
||||
'usable-with-warnings': 'Usable, but provenance is thin',
|
||||
'needs-source-context': 'Needs source context before handoff',
|
||||
blocked: 'Blocked by source guardrails',
|
||||
};
|
||||
const summaries = {
|
||||
ready: `Active order is traceable and evidence-shaped for ${activeItems.length} active item${activeItems.length === 1 ? '' : 's'}.`,
|
||||
'usable-with-warnings': 'Ranking can be read now, but downstream bridge consumers should review the warnings before storing it as a defended handoff.',
|
||||
'needs-source-context': 'A Scattermind-shaped artifact is present, but active items are missing trace or evidence fields needed to defend the order later.',
|
||||
blocked: 'An active item conflicts with source non-goals; do not continue until the guardrail is resolved or the item moves out of the active lanes.',
|
||||
};
|
||||
|
||||
return {
|
||||
status,
|
||||
label: labels[status],
|
||||
summary: summaries[status],
|
||||
blockers,
|
||||
nextChecks: nextChecks.slice(0, 5),
|
||||
activeItemCount: activeItems.length,
|
||||
warningCount: uniqueWarnings.length,
|
||||
sourceComplete: Boolean(!expectsSourceTrace || (provenance?.originalPrompt && activeItems.every(item => item.provenance?.sourceSection))),
|
||||
};
|
||||
}
|
||||
|
||||
function createHandoffContract({ ranked, provenance, decisionContext }) {
|
||||
const warnings = [];
|
||||
const expectsSourceTrace = Boolean(provenance?.artifactId || provenance?.conceptMapId || provenance?.snapshotTitle);
|
||||
@@ -1169,6 +1223,7 @@ function createHandoffContract({ ranked, provenance, decisionContext }) {
|
||||
nonGoalConflicts: item.metrics?.nonGoalConflicts || [],
|
||||
};
|
||||
});
|
||||
const uniqueWarnings = [...new Set(warnings)];
|
||||
|
||||
return {
|
||||
schema: 'rank-feedback-result-v1',
|
||||
@@ -1189,7 +1244,8 @@ function createHandoffContract({ ranked, provenance, decisionContext }) {
|
||||
assumptions: decisionContext?.assumptions || [],
|
||||
},
|
||||
itemTrace,
|
||||
warnings: [...new Set(warnings)],
|
||||
warnings: uniqueWarnings,
|
||||
readiness: handoffReadinessFor({ ranked, provenance, warnings: uniqueWarnings, expectsSourceTrace }),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user