UNPKG

@medicine-wheel/community-review

Version:

Community-based ceremonial review protocol for Medicine Wheel — implements Wilson's validation through Elder review circles, consensus, and relational accountability

128 lines 4.94 kB
"use strict"; /** * @medicine-wheel/community-review — Consensus & Talking Circle * * Manages the talking circle process and consensus-seeking. * In Wilson's framework, validation comes through community * consensus, not individual expert judgment. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.seekConsensus = seekConsensus; exports.talkingCircle = talkingCircle; exports.recordVoices = recordVoices; exports.resolveDisagreement = resolveDisagreement; /** * Attempt to reach consensus by analyzing all voices in the circle. * Returns whether consensus exists and the emerging outcome type. */ function seekConsensus(circle) { const reviewerIds = new Set(circle.reviewers.map((r) => r.id)); const spokePeople = new Set(circle.talkingCircleLog.map((e) => e.speakerId)); const allSpoken = [...reviewerIds].every((id) => spokePeople.has(id)); // Consensus requires all reviewers to have spoken const consensusReached = allSpoken && circle.reviewers.length > 0; // Determine emerging outcome based on whether voices align let emergingOutcome = null; if (consensusReached && circle.elderValidator) { const elderSpoke = circle.talkingCircleLog.some((e) => e.speakerId === circle.elderValidator && e.role === 'elder'); emergingOutcome = elderSpoke ? 'approved-with-blessings' : 'deepen-required'; } else if (consensusReached) { emergingOutcome = 'deepen-required'; } return { consensusReached, emergingOutcome, voiceCount: circle.talkingCircleLog.length, reviewerCount: circle.reviewers.length, allReviewersSpoken: allSpoken, }; } /** * Add a talking circle entry — one person's voice in the circle. * Validates the speaker is a participant. */ function talkingCircle(circle, entry) { if (circle.status !== 'reviewing' && circle.status !== 'deliberating') { throw new Error(`Cannot add to talking circle — circle is '${circle.status}'`); } return { ...circle, talkingCircleLog: [...circle.talkingCircleLog, entry], }; } /** * Summarize all voices heard in the circle, grouped by direction. */ function recordVoices(circle) { const byDirection = {}; const byRole = {}; for (const entry of circle.talkingCircleLog) { const dir = entry.direction ?? 'unaligned'; if (!byDirection[dir]) byDirection[dir] = []; byDirection[dir].push(entry); if (!byRole[entry.role]) byRole[entry.role] = []; byRole[entry.role].push(entry); } const spoke = new Set(circle.talkingCircleLog.map((e) => e.speakerId)); const unheardReviewers = circle.reviewers .filter((r) => !spoke.has(r.id)) .map((r) => r.id); return { total: circle.talkingCircleLog.length, byDirection, byRole, unheardReviewers, }; } /** * Process for handling disagreement within the circle. * Returns guidance for resolution based on the process type. */ function resolveDisagreement(circle, process) { switch (process) { case 'deeper-listening': return { guidance: 'Return to the talking circle with renewed attention. Each voice deserves to be fully heard.', nextStatus: 'reviewing', suggestedActions: [ 'Invite unheard reviewers to speak', 'Ask clarifying questions without judgment', 'Reflect back what has been heard', ], }; case 'elder-mediation': return { guidance: 'Request Elder guidance to help the circle find its way forward.', nextStatus: 'deliberating', suggestedActions: [ 'Request Elder validation if not already assigned', 'Share the points of tension with the Elder', 'Allow the Elder to guide the process', ], }; case 'return-to-ceremony': return { guidance: 'The disagreement may require ceremonial attention before resolution is possible.', nextStatus: 'reviewing', suggestedActions: [ 'Conduct a smudging ceremony', 'Reground in the Four Directions', 'Check Wilson alignment as a group', ], }; case 'rest-and-return': return { guidance: 'Sometimes wisdom comes through rest. The circle can reconvene when ready.', nextStatus: 'reviewing', suggestedActions: [ 'Set a date to reconvene', 'Invite individual reflection', 'Allow time for the land to speak', ], }; } } //# sourceMappingURL=consensus.js.map