/**
* insight-layer-d.js
*
* Layer D – Insight Review
* ————————
*
* Purpose:
* Review what progress or development occurred during the completed Insight.
*
* Layer D must NOT:
* – continue the live coaching conversation
* – decide next framework steps
* – extract new evidence from a single turn
* – exaggerate progress
* – invent development
*/
(function () {
‘use strict’;
function clean(value) {
return String(value == null ? ” : value).trim();
}
/**
* D1 – Review Eligibility Assessment
*/
async function assessReviewEligibility(ctx) {
const config = ctx.config || {};
if (!config.aiUrl) {
return {
review_required: false,
development_summary: ”,
reason: ‘No AI endpoint available.’
};
}
const payload = {
model: ‘gpt-4o’,
temperature: 0,
messages: [
{
role: ‘system’,
content:
`You are D1 Review Eligibility Assessment.
Your role:
Decide whether the completed Insight conversation contains enough evidence for a meaningful review.
Return ONLY valid JSON:
{
“review_required”: true|false,
“development_summary”: “…”,
“reason”: “…”
}
Rules:
– Base this only on evidence from the completed Insight.
– A review is justified when there is meaningful awareness, clarity, tension, discovery, trait movement, or development.
– Do not invent progress.
– Do not reward length alone.
– If little meaningful development occurred, set review_required to false.
– Do not write the user-facing review.`
},
{
role: ‘user’,
content:
`COMPLETE INSIGHT CONVERSATION:
${JSON.stringify(ctx.thread || [])}
REFLECTIONS GENERATED:
${JSON.stringify(ctx.reflectionHistory || [])}
TRAIT UPDATE RECOMMENDATIONS:
${JSON.stringify(ctx.traitUpdates || [])}
PREVIOUS INSIGHT REVIEWS:
${JSON.stringify(ctx.previousInsightReviews || [])}
RELEVANT TRAIT HISTORY:
${JSON.stringify(ctx.relevantTraitHistory || [])}
INSIGHT SUMMARY:
${clean(ctx.insightSummary)}`
}
]
};
let parsed = {
review_required: false,
development_summary: ”,
reason: ”
};
try {
const aiResult = await window.cpAiService.callJson({
task: ‘layer_d_review_eligibility’,
responseId: ctx.responseId,
config,
payload
});
if (!aiResult.ok) {
throw new Error(
aiResult.error?.message ||
‘Layer D1 AI request failed.’
);
}
parsed = aiResult.data || parsed;
} catch (err) {
console.log(‘LAYER D1 ERROR:’, err);
}
return {
review_required: !!parsed.review_required,
development_summary: clean(parsed.development_summary),
reason: clean(parsed.reason)
};
}
/**
* D2 – Review Evidence Selection
*/
async function selectReviewEvidence(ctx, eligibility) {
const config = ctx.config || {};
if (!eligibility.review_required || !config.aiUrl) {
return { selected_evidence: [] };
}
const payload = {
model: ‘gpt-4o’,
temperature: 0,
messages: [
{
role: ‘system’,
content:
`You are D2 Review Evidence Selection.
Your role:
Select the evidence that should be used in the end-of-Insight review.
Return ONLY valid JSON:
{
“selected_evidence”: [
{
“type”: “awareness|clarity|tension|discovery|theme|trait_development”,
“evidence”: “…”,
“quote”: “…”
}
]
}
Rules:
– Select only evidence from the completed Insight.
– Prefer meaningful evidence over quantity.
– Do not include generic or weak material.
– Do not invent themes.
– Do not write the review.`
},
{
role: ‘user’,
content:
`D1 ELIGIBILITY:
${JSON.stringify(eligibility)}
COMPLETE INSIGHT CONVERSATION:
${JSON.stringify(ctx.thread || [])}
REFLECTION HISTORY:
${JSON.stringify(ctx.reflectionHistory || [])}
TRAIT UPDATE RECOMMENDATIONS:
${JSON.stringify(ctx.traitUpdates || [])}`
}
]
};
let parsed = {
selected_evidence: []
};
try {
const aiResult = await window.cpAiService.callJson({
task: ‘layer_d_review_evidence’,
responseId: ctx.responseId,
config,
payload
});
if (!aiResult.ok) {
throw new Error(
aiResult.error?.message ||
‘Layer D2 AI request failed.’
);
}
parsed = aiResult.data || parsed;
} catch (err) {
console.log(‘LAYER D2 ERROR:’, err);
}
return {
selected_evidence: Array.isArray(parsed.selected_evidence)
? parsed.selected_evidence
: []
};
}
/**
* D3 – Insight Review Writer
*/
async function writeInsightReview(ctx, eligibility, selectedEvidence) {
const config = ctx.config || {};
const fallback = clean(eligibility.development_summary) ||
‘You explored this Insight and shared your perspective on it.’;
if (!config.aiUrl) return fallback;
const payload = {
model: ‘gpt-4o’,
temperature: 0.3,
messages: [
{
role: ‘system’,
content:
`You are D3 Insight Review Writer.
Write the user-facing end-of-Insight review.
Rules:
– Focus primarily on the current Insight.
– Base every observation on selected evidence.
– Do not invent progress.
– Do not exaggerate development.
– Avoid generic encouragement.
– Do not introduce new coaching themes.
– Keep it concise.
– Use UK English.`
},
{
role: ‘user’,
content:
`SELECTED REVIEW EVIDENCE:
${JSON.stringify(selectedEvidence.selected_evidence || [])}
DEVELOPMENT SUMMARY:
${clean(eligibility.development_summary)}
PREVIOUS INSIGHT REVIEWS:
${JSON.stringify(ctx.previousInsightReviews || [])}
RELEVANT TRAIT HISTORY:
${JSON.stringify(ctx.relevantTraitHistory || [])}
INSIGHT SUMMARY:
${clean(ctx.insightSummary)}`
}
]
};
try {
const aiResult = await window.cpAiService.callText({
task: ‘layer_d_review_writer’,
responseId: ctx.responseId,
config,
payload
});
if (!aiResult.ok) {
throw new Error(
aiResult.error?.message ||
‘Layer D3 AI request failed.’
);
}
return clean(aiResult.data) || fallback;
} catch (err) {
console.log(‘LAYER D3 ERROR:’, err);
return fallback;
}
}
/**
* D4 – Minimal Closing Review
*/
async function writeMinimalClosingReview(ctx, eligibility) {
const config = ctx.config || {};
const fallback =
‘You explored this Insight and shared your perspective on it. While no major shift emerged during this conversation, your responses still help build a clearer picture of how you see this area.’;
if (!config.aiUrl) return fallback;
const payload = {
model: ‘gpt-4o’,
temperature: 0.2,
messages: [
{
role: ‘system’,
content:
`You are D4 Minimal Closing Review Writer.
Write a brief factual closing review when there is not enough evidence for a fuller review.
Rules:
– Do not exaggerate progress.
– Do not imply a major shift occurred.
– Remain factual.
– Keep it concise.
– Use UK English.`
},
{
role: ‘user’,
content:
`D1 ELIGIBILITY:
${JSON.stringify(eligibility)}
INSIGHT SUMMARY:
${clean(ctx.insightSummary)}
COMPLETE INSIGHT CONVERSATION:
${JSON.stringify(ctx.thread || [])}`
}
]
};
try {
const aiResult = await window.cpAiService.callText({
task: ‘layer_d_minimal_review’,
responseId: ctx.responseId,
config,
payload
});
if (!aiResult.ok) {
throw new Error(
aiResult.error?.message ||
‘Layer D4 AI request failed.’
);
}
return clean(aiResult.data) || fallback;
} catch (err) {
console.log(‘LAYER D4 ERROR:’, err);
return fallback;
}
}
/**
* runLayerD()
*/
async function runLayerD(ctx) {
const eligibility = await assessReviewEligibility(ctx);
if (!eligibility.review_required) {
const review = await writeMinimalClosingReview(ctx, eligibility);
return {
review_required: false,
eligibility,
selected_evidence: [],
review,
review_type: ‘minimal’,
debug: {
layer: ‘D’,
decision: ‘D1’,
value: ‘minimal_review’,
reason: eligibility.reason
}
};
}
const selectedEvidence = await selectReviewEvidence(ctx, eligibility);
const review = await writeInsightReview(ctx, eligibility, selectedEvidence);
return {
review_required: true,
eligibility,
selected_evidence: selectedEvidence.selected_evidence || [],
review,
review_type: ‘full’,
debug: {
layer: ‘D’,
decision: ‘D3’,
value: ‘full_review’,
reason: eligibility.reason,
details: [
{
decision: ‘D2’,
value: `${(selectedEvidence.selected_evidence || []).length} evidence item(s) selected`
}
]
}
};
}
window.cpInsightLayerD = {
runLayerD,
assessReviewEligibility,
selectReviewEvidence,
writeInsightReview,
writeMinimalClosingReview
};
})();