Accept soft Scattermind bridge lane labels

This commit is contained in:
OpenClaw Bot
2026-05-27 01:32:17 +02:00
parent bf29b7ab95
commit b5e791ae33
3 changed files with 78 additions and 16 deletions
+22 -16
View File
@@ -682,7 +682,7 @@ function cleanContextText(value = '') {
}
function meaningfulTokens(text = '') {
const stop = new Set(['the', 'and', 'with', 'from', 'that', 'this', 'into', 'before', 'after', 'user', 'users', 'idea', 'ideas', 'build', 'first', 'avoid', 'without', 'more', 'full', 'proof', 'manual', 'value', 'layer']);
const stop = new Set(['the', 'and', 'with', 'from', 'that', 'this', 'into', 'before', 'after', 'until', 'user', 'users', 'idea', 'ideas', 'build', 'first', 'avoid', 'without', 'more', 'full', 'proof', 'manual', 'value', 'layer', 'result', 'sense', 'copyable']);
return [...new Set(String(text).toLowerCase().match(/[a-z0-9][a-z0-9-]{3,}/g) || [])].filter(token => !stop.has(token)).slice(0, 8);
}
@@ -769,10 +769,10 @@ function compactCandidateGroup(group = []) {
function buildOrderSectionGroup(buildOrder = {}, baseSection = 'buildOrder') {
const source = objectFrom(buildOrder);
return compactCandidateGroup([
{ items: source.doFirst || source.do_first || source.buildFirst || source.buildNow || source.now, sourceSection: `${baseSection}.doFirst`, defaultLane: 'do-first' },
{ items: source.validateNext || source.validate_next || source.testNext || source.testManually || source.validation, sourceSection: `${baseSection}.validateNext`, defaultLane: 'validate-next' },
{ items: source.defer || source.deferred || source.later || source.afterProof, sourceSection: `${baseSection}.defer`, defaultLane: 'defer' },
{ items: source.park || source.parkingLot || source.parking_lot || source.parked || source.probablyNoise || source.probably_noise || source.noise, sourceSection: `${baseSection}.park`, defaultLane: 'park' },
{ items: source.doFirst || source.do_first || source.buildFirst || source.buildNow || source.now || source.continueFirst || source.continue_first || source.makeTangible || source.make_tangible || source.startHere || source.start_here, sourceSection: `${baseSection}.doFirst`, defaultLane: 'do-first' },
{ items: source.validateNext || source.validate_next || source.testNext || source.testManually || source.validation || source.evidenceNext || source.evidence_next || source.tryNext || source.try_next || source.learnNext || source.learn_next, sourceSection: `${baseSection}.validateNext`, defaultLane: 'validate-next' },
{ items: source.defer || source.deferred || source.later || source.afterProof || source.holdForLater || source.hold_for_later || source.notYet || source.not_yet, sourceSection: `${baseSection}.defer`, defaultLane: 'defer' },
{ items: source.park || source.parkingLot || source.parking_lot || source.parked || source.probablyNoise || source.probably_noise || source.noise || source.setAside || source.set_aside || source.outOfScope || source.out_of_scope, sourceSection: `${baseSection}.park`, defaultLane: 'park' },
]);
}
@@ -786,23 +786,23 @@ function normalizeCandidateGroup(group = []) {
function sentenceFragments(text = '') {
return cleanMultiline(text, 4000)
.replace(/\s+(build first|start here|ship first|test manually|validate next|defer|probably noise|park|do not build yet|don't build yet)\s*:/gi, '\n$1:')
.replace(/\s+(build first|start here|ship first|continue first|make tangible first|make tangible|try next|evidence next|learn next|test manually|validate next|hold for later|not yet|defer|set aside|out of scope|probably noise|park|do not build yet|don't build yet)\s*:/gi, '\n$1:')
.split(/\n|;|\s+[•-]\s+/)
.map(part => part.trim())
.filter(Boolean);
}
function titleFromBuildOrderFragment(value = '') {
const cleaned = cleanText(value.replace(/^(build first|start here|ship first|test manually|validate next|defer|probably noise|park|do not build yet|don't build yet)\s*:\s*/i, ''), 220);
const cleaned = cleanText(value.replace(/^(build first|start here|ship first|continue first|make tangible first|make tangible|try next|evidence next|learn next|test manually|validate next|hold for later|not yet|defer|set aside|out of scope|probably noise|park|do not build yet|don't build yet)\s*:\s*/i, ''), 220);
const first = cleaned.split(/\s[-–—:]\s|\.\s/)[0] || cleaned;
return cleanText(first, 120);
}
function laneFromBuildOrderLabel(fragment = '') {
if (/^(build first|start here|ship first)\s*:/i.test(fragment)) return 'do-first';
if (/^(test manually|validate next)\s*:/i.test(fragment)) return 'validate-next';
if (/^(defer|do not build yet|don't build yet)\s*:/i.test(fragment)) return 'defer';
if (/^(probably noise|park)\s*:/i.test(fragment)) return 'park';
if (/^(build first|start here|ship first|continue first|make tangible first|make tangible)\s*:/i.test(fragment)) return 'do-first';
if (/^(try next|evidence next|learn next|test manually|validate next)\s*:/i.test(fragment)) return 'validate-next';
if (/^(hold for later|not yet|defer|do not build yet|don't build yet)\s*:/i.test(fragment)) return 'defer';
if (/^(set aside|out of scope|probably noise|park)\s*:/i.test(fragment)) return 'park';
return '';
}
@@ -815,7 +815,13 @@ function optionsFromBuildOrderText(text = '', sourceSection = 'concept-map.lense
id: `build-order-${index + 1}`,
action: titleFromBuildOrderFragment(fragment),
why: fragment.replace(/^\s*[^:]{1,40}:\s*/, '').trim(),
evidence: /test|validate|proof|prove|signal|ask|show/i.test(fragment) ? fragment : (lane === 'do-first' ? 'Prove this first move manually before adding product machinery.' : ''),
evidence: /test|validate|proof|prove|signal|ask|show/i.test(fragment)
? fragment
: lane === 'do-first'
? 'Prove this first move manually before adding product machinery.'
: lane === 'validate-next'
? 'Collect the smallest real signal before promoting this into the build lane.'
: '',
suggestedLane: lane,
rankerHints: lane === 'do-first'
? { value: 8, effort: 2, confidence: 7, urgency: 7, risk: 2 }
@@ -965,10 +971,10 @@ function scoreOption(option, mode, context = '', decisionContext = {}) {
function normalizeLaneHint(value = '') {
const hint = cleanText(value, 40).toLowerCase().replace(/_/g, '-');
if (/^(do|do-first|first|build|build-now|now)$/.test(hint)) return 'do';
if (/^(validate|validate-next|test|test-next|proof|evidence)$/.test(hint)) return 'test';
if (/^(defer|later|sequence-later|after-proof)$/.test(hint)) return 'defer';
if (/^(park|cut|drop|icebox|not-now)$/.test(hint)) return 'park';
if (/^(do|do-first|first|build|build-now|now|continue-first|make-tangible|start-here)$/.test(hint)) return 'do';
if (/^(validate|validate-next|test|test-next|proof|evidence|evidence-next|try-next|learn-next)$/.test(hint)) return 'test';
if (/^(defer|later|sequence-later|after-proof|hold-for-later|not-yet)$/.test(hint)) return 'defer';
if (/^(park|cut|drop|icebox|not-now|set-aside|out-of-scope)$/.test(hint)) return 'park';
return '';
}