Accept rank-ready candidate action aliases
This commit is contained in:
@@ -68,6 +68,8 @@ function parsePastedJsonPayload(value) {
|
||||
|| parsed.reference_code || parsed.referenceCode || parsed.artifactId || parsed.sourceArtifactId || parsed.source_artifact_id
|
||||
|| parsed.ideaText || parsed.idea_text || parsed.originalPrompt || parsed.original_prompt || parsed.sourceSummary || parsed.source_summary || parsed.opening_reflection || parsed.restated_idea
|
||||
|| Array.isArray(parsed.features) || Array.isArray(parsed.actions) || Array.isArray(parsed.candidates)
|
||||
|| Array.isArray(parsed.candidateActions) || Array.isArray(parsed.candidate_actions) || Array.isArray(parsed.candidateMoves) || Array.isArray(parsed.candidate_moves)
|
||||
|| Array.isArray(parsed.rankReadyActions) || Array.isArray(parsed.rank_ready_actions)
|
||||
|| Array.isArray(parsed.recommendedActions) || Array.isArray(parsed.recommended_actions) || Array.isArray(parsed.suggestedActions) || Array.isArray(parsed.suggested_actions)
|
||||
|| Array.isArray(parsed.nextActions) || Array.isArray(parsed.next_actions) || Array.isArray(parsed.nextMoves) || Array.isArray(parsed.next_moves)
|
||||
|| Array.isArray(parsed.doFirst) || Array.isArray(parsed.do_first) || Array.isArray(parsed.continueFirst) || Array.isArray(parsed.continue_first) || Array.isArray(parsed.makeTangible) || Array.isArray(parsed.make_tangible)
|
||||
|
||||
@@ -1414,7 +1414,75 @@ try {
|
||||
assert.equal(storedScattermindRow.handoff.readiness.status, 'ready');
|
||||
assert.deepEqual(storedScattermindRow.handoff.warnings, []);
|
||||
|
||||
console.log(JSON.stringify({ ok: true, top: data.ranked[0].id, hintedTop: hinted.ranked[0].id, actionTop: actions.ranked[0].id, nestedConceptTop: nestedConcept.ranked[0].id, nonGoalTop: nonGoal.ranked[0].id, structuredContextTop: structuredContext.ranked[0].id, lensOnlyTop: lensOnly.ranked[0].id, scattermindPaidShapeTop: scattermindPaidShape.ranked[0].id, mergedContextTop: mergedContext.ranked[0].id, embeddedJsonTop: embeddedJson.ranked[0].id, fencedJsonTop: fencedJson.ranked[0].id, embeddedSnapshotTop: embeddedSnapshot.ranked[0].id, sourceExcerptTop: sourceExcerpt.ranked[0].id, snakeCaseBridgeTop: snakeCaseBridge.ranked[0].id, nextStepsAliasTop: nextStepsAlias.ranked[0].id, summaryGuardrailTop: summaryGuardrail.ranked[0].id, bridgeEnvelopeTop: bridgeEnvelope.ranked[0].id, directEnvelopeSectionsTop: directEnvelopeSections.ranked[0].id, softDirectLaneAliasesTop: softDirectLaneAliases.ranked[0].id, threadsFallbackTop: threadsFallback.ranked[0].id, questionsFallbackTop: questionsFallback.ranked[0].id, freeSnapshotTop: freeSnapshot.ranked[0].id, storedScattermindRowTop: storedScattermindRow.ranked[0].id, duplicateIds: duplicateIds.ranked.map(item => item.id), readiness: data.handoff.readiness.status, provenance: data.input.provenance, buildOrder: data.buildOrder }, null, 2));
|
||||
const candidateActionsAliasResponse = await fetch(`${base}/api/rank-feedback`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
sourceName: 'Scattermind',
|
||||
artifactId: 'concept_map_candidate_actions_aliases',
|
||||
originalPrompt: 'Scattermind exported candidate_actions as the rank-ready action set after a Concept Map.',
|
||||
idea: 'Ranker should accept candidate action set naming without making Scattermind rename it into features.',
|
||||
context: {
|
||||
targetAudience: 'Tired non-AI-native solo builder',
|
||||
nonGoals: ['Avoid saved workspace dashboards before the first defended action works'],
|
||||
},
|
||||
mode: 'mvp',
|
||||
conceptMap: {
|
||||
candidate_actions: [
|
||||
{ id: 'candidate-manual-preview', action: 'Candidate manual preview', why: 'Turn the Concept Map into one defended active build-order slice.', evidence_needed: 'Can one tired user explain why this candidate should be first?', suggested_lane: 'do-first', source_item_id: 'candidate-action-1', source_title: 'Rank-ready candidate actions', ranker_hints: { value: 9, effort: 2, confidence: 8, urgency: 8, risk: 2 } },
|
||||
{ id: 'candidate-copyable-handoff', action: 'Candidate copyable handoff', why: 'Make the defended order portable after the active slice is clear.', evidence_needed: 'Does the copied handoff preserve the first action and source?', suggested_lane: 'validate-next', source_item_id: 'candidate-action-2', source_title: 'Rank-ready candidate actions' },
|
||||
{ id: 'candidate-workspace-dashboard', action: 'Candidate saved workspace dashboard', why: 'Accounts, saved projects, collaboration, and dashboard history before proof.', evidence_needed: 'No bridge proof yet.', suggested_lane: 'park', source_item_id: 'candidate-action-3', source_title: 'Rank-ready candidate actions' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
});
|
||||
assert.equal(candidateActionsAliasResponse.status, 200);
|
||||
const candidateActionsAlias = await candidateActionsAliasResponse.json();
|
||||
assert.equal(candidateActionsAlias.input.optionCount, 3);
|
||||
assert.equal(candidateActionsAlias.ranked[0].id, 'candidate-manual-preview');
|
||||
assert.equal(candidateActionsAlias.ranked[0].provenance.sourceSection, 'concept-map.candidateActions');
|
||||
assert.equal(candidateActionsAlias.ranked[0].provenance.sourceId, 'candidate-action-1');
|
||||
assert.equal(candidateActionsAlias.ranked[0].provenance.sourceTitle, 'Rank-ready candidate actions');
|
||||
assert.ok(['test', 'defer'].includes(candidateActionsAlias.ranked.find(item => item.id === 'candidate-copyable-handoff').lane.id));
|
||||
assert.equal(candidateActionsAlias.ranked.find(item => item.id === 'candidate-workspace-dashboard').lane.id, 'park');
|
||||
assert.equal(candidateActionsAlias.handoff.readiness.status, 'ready');
|
||||
assert.deepEqual(candidateActionsAlias.handoff.warnings, []);
|
||||
|
||||
const rankReadyActionsEnvelopeResponse = await fetch(`${base}/api/rank-feedback`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
schema: 'scattermind-ranker-bridge-v1',
|
||||
rank_ready: {
|
||||
sourceName: 'Scattermind',
|
||||
reference_code: 'SM-RANK-READY-ACTIONS-1',
|
||||
working_name: 'Rank-ready action envelope',
|
||||
ideaText: 'Scattermind wrapped a candidate action set under rank_ready with rank_ready_actions.',
|
||||
context: {
|
||||
targetAudience: 'Overwhelmed solo maker',
|
||||
avoid: ['Avoid auth dashboards before action proof'],
|
||||
},
|
||||
rank_ready_actions: [
|
||||
{ id: 'rank-ready-action-proof', action: 'Rank-ready action proof', why: 'Accept the bridge naming directly and defend the first action.', evidence_needed: 'Can the action envelope produce a source-traced Do first?', suggested_lane: 'do-first', source_item_id: 'rank-ready-action-1', source_section: 'rank_ready.rank_ready_actions', ranker_hints: { value: 9, effort: 2, confidence: 8, urgency: 8, risk: 2 } },
|
||||
{ id: 'rank-ready-action-copy', action: 'Rank-ready action copy brief', why: 'Preserve the defended order outside the app.', evidence_needed: 'Does copyable text keep the active action clear?', suggested_lane: 'validate-next', source_item_id: 'rank-ready-action-2', source_section: 'rank_ready.rank_ready_actions' },
|
||||
{ id: 'rank-ready-action-dashboard', action: 'Rank-ready action dashboard', why: 'Auth dashboard and saved workspaces for every idea.', evidence_needed: 'No proof yet.', suggested_lane: 'park', source_item_id: 'rank-ready-action-3', source_section: 'rank_ready.rank_ready_actions' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
});
|
||||
assert.equal(rankReadyActionsEnvelopeResponse.status, 200);
|
||||
const rankReadyActionsEnvelope = await rankReadyActionsEnvelopeResponse.json();
|
||||
assert.equal(rankReadyActionsEnvelope.input.provenance.artifactId, 'SM-RANK-READY-ACTIONS-1');
|
||||
assert.equal(rankReadyActionsEnvelope.input.provenance.snapshotTitle, 'Rank-ready action envelope');
|
||||
assert.equal(rankReadyActionsEnvelope.input.optionCount, 3);
|
||||
assert.equal(rankReadyActionsEnvelope.ranked[0].id, 'rank-ready-action-proof');
|
||||
assert.equal(rankReadyActionsEnvelope.ranked[0].provenance.sourceSection, 'rank_ready.rank_ready_actions');
|
||||
assert.ok(['test', 'defer'].includes(rankReadyActionsEnvelope.ranked.find(item => item.id === 'rank-ready-action-copy').lane.id));
|
||||
assert.equal(rankReadyActionsEnvelope.ranked.find(item => item.id === 'rank-ready-action-dashboard').lane.id, 'park');
|
||||
assert.equal(rankReadyActionsEnvelope.handoff.readiness.status, 'ready');
|
||||
assert.deepEqual(rankReadyActionsEnvelope.handoff.warnings, []);
|
||||
|
||||
console.log(JSON.stringify({ ok: true, top: data.ranked[0].id, hintedTop: hinted.ranked[0].id, actionTop: actions.ranked[0].id, nestedConceptTop: nestedConcept.ranked[0].id, nonGoalTop: nonGoal.ranked[0].id, structuredContextTop: structuredContext.ranked[0].id, lensOnlyTop: lensOnly.ranked[0].id, scattermindPaidShapeTop: scattermindPaidShape.ranked[0].id, mergedContextTop: mergedContext.ranked[0].id, embeddedJsonTop: embeddedJson.ranked[0].id, fencedJsonTop: fencedJson.ranked[0].id, embeddedSnapshotTop: embeddedSnapshot.ranked[0].id, sourceExcerptTop: sourceExcerpt.ranked[0].id, snakeCaseBridgeTop: snakeCaseBridge.ranked[0].id, nextStepsAliasTop: nextStepsAlias.ranked[0].id, summaryGuardrailTop: summaryGuardrail.ranked[0].id, bridgeEnvelopeTop: bridgeEnvelope.ranked[0].id, directEnvelopeSectionsTop: directEnvelopeSections.ranked[0].id, softDirectLaneAliasesTop: softDirectLaneAliases.ranked[0].id, threadsFallbackTop: threadsFallback.ranked[0].id, questionsFallbackTop: questionsFallback.ranked[0].id, freeSnapshotTop: freeSnapshot.ranked[0].id, storedScattermindRowTop: storedScattermindRow.ranked[0].id, candidateActionsAliasTop: candidateActionsAlias.ranked[0].id, rankReadyActionsEnvelopeTop: rankReadyActionsEnvelope.ranked[0].id, duplicateIds: duplicateIds.ranked.map(item => item.id), readiness: data.handoff.readiness.status, provenance: data.input.provenance, buildOrder: data.buildOrder }, null, 2));
|
||||
} finally {
|
||||
server.kill('SIGTERM');
|
||||
}
|
||||
|
||||
@@ -580,6 +580,12 @@ function looksLikeRankPayload(value = {}) {
|
||||
|| Array.isArray(value.nextMoves)
|
||||
|| Array.isArray(value.next_moves)
|
||||
|| Array.isArray(value.candidates)
|
||||
|| Array.isArray(value.candidateActions)
|
||||
|| Array.isArray(value.candidate_actions)
|
||||
|| Array.isArray(value.candidateMoves)
|
||||
|| Array.isArray(value.candidate_moves)
|
||||
|| Array.isArray(value.rankReadyActions)
|
||||
|| Array.isArray(value.rank_ready_actions)
|
||||
|| Array.isArray(value.doFirst)
|
||||
|| Array.isArray(value.do_first)
|
||||
|| Array.isArray(value.continueFirst)
|
||||
@@ -1134,6 +1140,9 @@ function optionsFromBody(body = {}) {
|
||||
{ items: body.candidates, sourceSection: 'candidates' },
|
||||
{ items: envelope.candidates, sourceSection: 'ranker-input.candidates' },
|
||||
{ items: featureSet.candidates, sourceSection: 'feature-set.candidates' },
|
||||
{ items: body.candidateActions || body.candidate_actions || body.candidateMoves || body.candidate_moves || body.rankReadyActions || body.rank_ready_actions, sourceSection: 'candidateActions' },
|
||||
{ items: envelope.candidateActions || envelope.candidate_actions || envelope.candidateMoves || envelope.candidate_moves || envelope.rankReadyActions || envelope.rank_ready_actions, sourceSection: 'ranker-input.candidateActions' },
|
||||
{ items: featureSet.candidateActions || featureSet.candidate_actions || featureSet.candidateMoves || featureSet.candidate_moves || featureSet.rankReadyActions || featureSet.rank_ready_actions, sourceSection: 'feature-set.candidateActions' },
|
||||
{ items: body.doFirst || body.do_first || body.buildFirst || body.build_first || body.buildNow || body.build_now || body.continueFirst || body.continue_first || body.makeTangible || body.make_tangible || body.startHere || body.start_here, sourceSection: 'doFirst', defaultLane: 'do-first' },
|
||||
{ items: envelope.doFirst || envelope.do_first || envelope.buildFirst || envelope.build_first || envelope.buildNow || envelope.build_now || envelope.continueFirst || envelope.continue_first || envelope.makeTangible || envelope.make_tangible || envelope.startHere || envelope.start_here, sourceSection: 'ranker-input.doFirst', defaultLane: 'do-first' },
|
||||
{ items: featureSet.doFirst || featureSet.do_first || featureSet.buildFirst || featureSet.build_first || featureSet.buildNow || featureSet.build_now || featureSet.continueFirst || featureSet.continue_first || featureSet.makeTangible || featureSet.make_tangible || featureSet.startHere || featureSet.start_here, sourceSection: 'feature-set.doFirst', defaultLane: 'do-first' },
|
||||
@@ -1161,6 +1170,7 @@ function optionsFromBody(body = {}) {
|
||||
{ items: conceptMap.nextMoves || conceptMap.next_moves, sourceSection: 'concept-map.nextMoves' },
|
||||
{ items: conceptMap.features, sourceSection: 'concept-map.features' },
|
||||
{ items: conceptMap.candidates, sourceSection: 'concept-map.candidates' },
|
||||
{ items: conceptMap.candidateActions || conceptMap.candidate_actions || conceptMap.candidateMoves || conceptMap.candidate_moves || conceptMap.rankReadyActions || conceptMap.rank_ready_actions, sourceSection: 'concept-map.candidateActions' },
|
||||
{ items: conceptMap.doFirst || conceptMap.do_first || conceptMap.buildFirst || conceptMap.build_first || conceptMap.buildNow || conceptMap.build_now || conceptMap.continueFirst || conceptMap.continue_first || conceptMap.makeTangible || conceptMap.make_tangible || conceptMap.startHere || conceptMap.start_here, sourceSection: 'concept-map.doFirst', defaultLane: 'do-first' },
|
||||
{ items: conceptMap.validateNext || conceptMap.validate_next || conceptMap.validate || conceptMap.validation || conceptMap.evidenceNext || conceptMap.evidence_next || conceptMap.tryNext || conceptMap.try_next || conceptMap.learnNext || conceptMap.learn_next || conceptMap.testManually || conceptMap.test_manually, sourceSection: 'concept-map.validateNext', defaultLane: 'validate-next' },
|
||||
{ items: conceptMap.experiments, sourceSection: 'concept-map.experiments', defaultLane: 'validate-next' },
|
||||
@@ -1175,6 +1185,7 @@ function optionsFromBody(body = {}) {
|
||||
{ items: snapshot.actions, sourceSection: 'snapshot.actions' },
|
||||
{ items: snapshot.features, sourceSection: 'snapshot.features' },
|
||||
{ items: snapshot.candidates, sourceSection: 'snapshot.candidates' },
|
||||
{ items: snapshot.candidateActions || snapshot.candidate_actions || snapshot.candidateMoves || snapshot.candidate_moves || snapshot.rankReadyActions || snapshot.rank_ready_actions, sourceSection: 'snapshot.candidateActions' },
|
||||
{ items: snapshot.doFirst || snapshot.do_first || snapshot.buildFirst || snapshot.build_first || snapshot.buildNow || snapshot.build_now || snapshot.continueFirst || snapshot.continue_first || snapshot.makeTangible || snapshot.make_tangible || snapshot.startHere || snapshot.start_here, sourceSection: 'snapshot.doFirst', defaultLane: 'do-first' },
|
||||
{ items: snapshot.validateNext || snapshot.validate_next || snapshot.validate || snapshot.validation || snapshot.evidenceNext || snapshot.evidence_next || snapshot.tryNext || snapshot.try_next || snapshot.learnNext || snapshot.learn_next || snapshot.testManually || snapshot.test_manually, sourceSection: 'snapshot.validateNext', defaultLane: 'validate-next' },
|
||||
{ items: snapshot.experiments, sourceSection: 'snapshot.experiments', defaultLane: 'validate-next' },
|
||||
|
||||
Reference in New Issue
Block a user