Carry Concept Map thread signals into Ranker

This commit is contained in:
OpenClaw Bot
2026-05-28 00:38:31 +02:00
parent 066717221c
commit 4212b4d7c8
2 changed files with 79 additions and 22 deletions
+42 -1
View File
@@ -240,6 +240,46 @@ try {
assert.equal(softGuardrail.buildOrder.doFirst[0], 'decision-strip');
assert.ok(!/dashboard/i.test(softGuardrail.brief.quickGlance.topPick));
const paidConceptMapThreadResponse = await fetch(`${base}/api/rank-feedback`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
referenceCode: 'SM-THREAD',
ideaText: 'A tired freelancer wants help deciding what to sell first without building a whole software platform.',
context: 'Solo builder. Manual proof first.',
fullReadingJson: JSON.stringify({
working_name: 'Service Offer Compass',
opening_reflection: 'Start with one manual offer teardown before adding product machinery.',
lenses: {
channel: {
title: 'Build Order',
content: 'Build first: Run one manual service-offer teardown for a freelancer. Test manually: Ask three freelancers if the teardown changes what they would sell next. Defer: Save templates until the manual proof works.',
},
question: {
title: 'Proof Steps',
content: 'Show the manual teardown to three freelancers and ask what they would do in the next 48 hours.',
},
},
threads_to_hold: [
'Success signal: two freelancers ask for the teardown or use it to change their offer.',
'Failure signal: people like the advice but do not change what they sell next.',
'Do not let this become a dashboard, account workspace, or template library before proof.',
],
questions_to_sit_with: ['Who has a messy offer decision this week?'],
closing_note: 'Run one manual teardown in the next 48 hours.',
reference_code: 'SM-THREAD',
}),
}),
});
assert.equal(paidConceptMapThreadResponse.status, 200);
const paidConceptMapThread = await paidConceptMapThreadResponse.json();
assert.equal(paidConceptMapThread.input.provenance.artifactId, 'SM-THREAD');
assert.ok(paidConceptMapThread.ranked.some(item => item.provenance.sourceSection === 'concept-map.threadsToHold'), 'paid Concept Map action threads should be ranked alongside Build Order text');
assert.ok(paidConceptMapThread.buildOrderDetails.park.some(item => /dashboard|account workspace|template library/i.test(item.title)), 'do-not-let-this-become thread should be visible in Park, not lost behind the Build Order lens');
assert.ok(paidConceptMapThread.input.decisionContext.nonGoals.some(item => /dashboard, account workspace/i.test(item)), 'thread guardrails should still become source non-goals');
assert.equal(paidConceptMapThread.handoff.activeSlice.proof.successSignal, 'two freelancers ask for the teardown or use it to change their offer');
assert.equal(paidConceptMapThread.handoff.activeSlice.proof.killSignal, 'people like the advice but do not change what they sell next');
const snakeDecisionContextResponse = await fetch(`${base}/api/rank-feedback`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
@@ -2103,7 +2143,8 @@ try {
assert.equal(storedScattermindRow.input.provenance.artifactId, 'SM-STORED-1');
assert.equal(storedScattermindRow.input.provenance.snapshotTitle, 'Stored Row Bridge');
assert.match(storedScattermindRow.input.provenance.originalPrompt, /actual stored row ranked/);
assert.equal(storedScattermindRow.input.optionCount, 5);
assert.equal(storedScattermindRow.input.optionCount, 6);
assert.ok(storedScattermindRow.ranked.some(item => item.provenance.sourceSection === 'concept-map.threadsToHold'));
assert.equal(storedScattermindRow.ranked[0].id, 'build-order-1');
assert.equal(storedScattermindRow.ranked[0].provenance.sourceTitle, 'Build Order');
assert.match(storedScattermindRow.ranked[0].provenance.sourceQuote, /Stored-row build-order preview/);