Accept structured bridge decision context

This commit is contained in:
OpenClaw Bot
2026-05-27 19:23:23 +02:00
parent dc75206fcd
commit c26bd4bfb0
3 changed files with 67 additions and 7 deletions
+34
View File
@@ -204,6 +204,40 @@ try {
assert.equal(softGuardrail.buildOrder.doFirst[0], 'decision-strip');
assert.ok(!/dashboard/i.test(softGuardrail.brief.quickGlance.topPick));
const snakeDecisionContextResponse = await fetch(`${base}/api/rank-feedback`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
ranker_bridge: {
schema: 'prioritix-feature-set-v1',
source_name: 'Scattermind',
artifact_id: 'concept_map_snake_context',
snapshot_title: 'Snake context handoff',
original_prompt: 'Clarify a tired-user continuation without dashboard swamp.',
idea: 'Scattermind clarified a continuation plan that must produce one defended next move.',
decision_context: {
target_audience: 'Tired non-AI-native builder',
constraints: ['Manual proof before product surface'],
non_goals: ['Avoid saved workspaces, account dashboards, and billing until proof'],
assumptions: ['A copyable handoff is enough for the first proof'],
},
next_actions: [
{ id: 'account-dashboard', title: 'Saved account dashboard', description: 'Accounts, saved workspaces, billing, and project dashboards.', evidence_needed: 'Would people want accounts later?', ranker_hints: { value: 10, effort: 1, confidence: 9, urgency: 9, risk: 1 } },
{ id: 'copyable-slice', title: 'Copyable active build slice', description: 'Return one defended Do first move with source trace and a proof question.', evidence_needed: 'Can one tired user act from the copied slice?', ranker_hints: { value: 8, effort: 2, confidence: 7, urgency: 7, risk: 2 } },
],
},
}),
});
assert.equal(snakeDecisionContextResponse.status, 200);
const snakeDecisionContext = await snakeDecisionContextResponse.json();
assert.equal(snakeDecisionContext.input.provenance.artifactId, 'concept_map_snake_context');
assert.equal(snakeDecisionContext.input.decisionContext.targetAudience, 'Tired non-AI-native builder');
assert.ok(snakeDecisionContext.input.decisionContext.constraints.includes('Manual proof before product surface'));
assert.ok(snakeDecisionContext.input.decisionContext.nonGoals.some(item => /Avoid saved workspaces/i.test(item)));
assert.equal(snakeDecisionContext.ranked.find(item => item.id === 'account-dashboard').lane.source, 'source-non-goal');
assert.equal(snakeDecisionContext.buildOrder.doFirst[0], 'copyable-slice');
assert.equal(snakeDecisionContext.handoff.readiness.status, 'ready');
const threadGuardrailResponse = await fetch(`${base}/api/rank-feedback`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },