Carry Scattermind thread guardrails into Ranker

This commit is contained in:
OpenClaw Bot
2026-05-27 18:46:15 +02:00
parent ec27d13330
commit e463f4bc2a
2 changed files with 45 additions and 3 deletions
+13 -3
View File
@@ -817,6 +817,10 @@ function contextGuardrailText(value = '') {
return cleanMultiline(obj.summary || obj.description || obj.notes || obj.brief || obj.text || '', 3000);
}
function guardrailTextItems(value = [], maxItems = 8) {
return cleanFlexibleTextList(value, maxItems, 260).filter(item => /\b(avoid|no|do not|don't|dont|must not|never|non-goal|non goal|not yet|out of scope|defer|hold for later|set aside|probably noise|park|do not let this become|don't let this become|not a dashboard|dashboard swamp)\b/i.test(item));
}
function cleanDecisionContext(input = {}) {
const envelope = bridgeEnvelopeFrom(input);
const featureSet = featureSetFrom(input);
@@ -852,8 +856,14 @@ function cleanDecisionContext(input = {}) {
contextGuardrailText(conceptMap.context || ''),
lensContent(riskLens),
lensContent(constraintsLens),
conceptMap.risk || conceptMap.whatNotToBuildYet || conceptMap.notYet || '',
snapshot.risk || snapshot.whatNotToBuildYet || snapshot.notYet || '',
conceptMap.risk || conceptMap.whatNotToBuildYet || conceptMap.notYet || conceptMap.closing_note || conceptMap.closingNote || '',
snapshot.risk || snapshot.whatNotToBuildYet || snapshot.notYet || snapshot.closing_note || snapshot.closingNote || '',
envelope.closing_note || envelope.closingNote || featureSet.closing_note || featureSet.closingNote || input.closing_note || input.closingNote || '',
...guardrailTextItems(conceptMap.threads_to_hold || conceptMap.threadsToHold || conceptMap.actionThreads || conceptMap.action_threads, 8),
...guardrailTextItems(snapshot.threads_to_hold || snapshot.threadsToHold || snapshot.actionThreads || snapshot.action_threads, 8),
...guardrailTextItems(envelope.threads_to_hold || envelope.threadsToHold || envelope.actionThreads || envelope.action_threads, 8),
...guardrailTextItems(featureSet.threads_to_hold || featureSet.threadsToHold || featureSet.actionThreads || featureSet.action_threads, 8),
...guardrailTextItems(input.threads_to_hold || input.threadsToHold || input.actionThreads || input.action_threads, 8),
].filter(Boolean).join('\n'));
return {
targetAudience: cleanText(input.targetAudience || input.target_audience || envelope.targetAudience || envelope.target_audience || featureSet.targetAudience || featureSet.target_audience || snapshot.targetAudience || snapshot.target_audience || firstContextText(contextSources, ['targetAudience', 'target_audience', 'audience', 'who', 'whoItHelps', 'who_it_helps', 'customer', 'users']) || conceptMap.targetAudience || conceptMap.target_audience || lensContent(audienceLens), 180),
@@ -889,7 +899,7 @@ function cleanContextText(value = '') {
}
function meaningfulTokens(text = '') {
const stop = new Set(['the', 'and', 'with', 'from', 'that', 'this', 'into', 'before', 'after', 'until', 'user', 'users', 'idea', 'ideas', 'build', 'order', 'works', 'first', 'avoid', 'without', 'more', 'full', 'proof', 'manual', 'value', 'layer', 'result', 'sense', 'copyable', 'source', 'traced', 'source-traced', 'evidence']);
const stop = new Set(['the', 'and', 'with', 'from', 'that', 'this', 'into', 'before', 'after', 'until', 'user', 'users', 'idea', 'ideas', 'build', 'order', 'works', 'first', 'avoid', 'without', 'more', 'full', 'proof', 'manual', 'value', 'layer', 'result', 'sense', 'copyable', 'source', 'traced', 'source-traced', 'evidence', 'thread', 'threads']);
return [...new Set(String(text).toLowerCase().match(/[a-z0-9][a-z0-9-]{3,}/g) || [])].filter(token => !stop.has(token)).slice(0, 8);
}