// ../core/src/pulseDigestPolicy.ts
var PULSE_DIGEST_REASON_LABELS = [
  "Review waiting",
  "Proof blocked",
  "Evidence gap",
  "High blast radius",
  "Stale important work",
  "Ready to continue"
];
function isPulseDigestReasonLabel(value) {
  return typeof value === "string" && PULSE_DIGEST_REASON_LABELS.includes(value);
}
function pulseDigestFocusCategoryForSignals(signals) {
  if (signals.reviewWaiting > 0)
    return "review_waiting";
  if (signals.blockedProof > 0)
    return "proof_blocked";
  if (signals.openEvidenceGaps > 0)
    return "evidence_gap";
  if (signals.blastReach > 0)
    return "high_blast_radius";
  if (signals.staleImportantWork > 0)
    return "stale_important_work";
  return "ready_to_continue";
}
function pulseDigestReasonLabelForCategory(category) {
  switch (category) {
    case "review_waiting":
      return "Review waiting";
    case "proof_blocked":
      return "Proof blocked";
    case "evidence_gap":
      return "Evidence gap";
    case "high_blast_radius":
      return "High blast radius";
    case "stale_important_work":
      return "Stale important work";
    case "ready_to_continue":
    default:
      return "Ready to continue";
  }
}
function pulseDigestCategoryForReasonLabel(label) {
  switch (label) {
    case "Review waiting":
      return "review_waiting";
    case "Proof blocked":
      return "proof_blocked";
    case "Evidence gap":
      return "evidence_gap";
    case "High blast radius":
      return "high_blast_radius";
    case "Stale important work":
      return "stale_important_work";
    case "Ready to continue":
      return "ready_to_continue";
  }
}
function pulseDigestSignalLayersForSignals(signals) {
  const layers = ["pulse"];
  if (signals.contextLensSignal > 0)
    layers.push("context_lens");
  if (signals.connectedWorkSignal > 0)
    layers.push("connected_work");
  if (signals.userPinnedOrRecentlyActive > 0 || signals.staleImportantWork > 0 || pulseDigestFocusCategoryForSignals(signals) === "ready_to_continue") {
    layers.push("focus_meter");
  }
  return [...new Set(layers)];
}
function pulseDigestFocusMeterForSignals(signals, options = {}) {
  const nextScore = typeof options.nextScore === "number" ? options.nextScore : scorePulseDigestNext(signals, options);
  const category = pulseDigestFocusCategoryForSignals(signals);
  const hasPositiveFocusSignal = signals.reviewWaiting > 0 || signals.blockedProof > 0 || signals.openEvidenceGaps > 0 || signals.staleImportantWork > 0 || signals.blastReach > 0 || signals.userPinnedOrRecentlyActive > 0 || signals.contextLensSignal > 0 || signals.connectedWorkSignal > 0;
  const state = !hasPositiveFocusSignal && (signals.repeatedDigestIgnorePenalty > 0 || signals.completedRecentlyPenalty > 0) ? "deprioritized" : category;
  const frictionScore = clampPulseMeterScore(signals.blockedProof * 72 + signals.openEvidenceGaps * 58 + signals.reviewWaiting * 24 + signals.blastReach * 20 + signals.staleImportantWork * 28 + signals.repeatedDigestIgnorePenalty * 24 + signals.completedRecentlyPenalty * 42);
  const readinessScore = clampPulseMeterScore(64 + signals.userPinnedOrRecentlyActive * 18 + signals.contextLensSignal * 6 + signals.connectedWorkSignal * 6 - signals.blockedProof * 70 - signals.openEvidenceGaps * 54 - signals.reviewWaiting * 22 - signals.blastReach * 18 - signals.staleImportantWork * 24 - signals.repeatedDigestIgnorePenalty * 24 - signals.completedRecentlyPenalty * 42);
  return {
    state,
    focusScore: clampPulseMeterScore(nextScore / 2),
    readinessScore,
    frictionScore
  };
}
function scorePulseDigestNext(signals, options = {}) {
  const sectionBonus = pulseDigestSectionBonus(options.section);
  const evidenceBonus = Math.min(18, Math.max(0, Math.round(options.evidenceCount ?? 0)) * 4);
  return Math.max(0, Math.round(signals.reviewWaiting * 90 + signals.blockedProof * 104 + signals.openEvidenceGaps * 78 + signals.blastReach * 62 + signals.staleImportantWork * 54 + signals.userPinnedOrRecentlyActive * 20 + signals.contextLensSignal * 8 + signals.connectedWorkSignal * 8 + sectionBonus + evidenceBonus - signals.repeatedDigestIgnorePenalty * 24 - signals.completedRecentlyPenalty * 42));
}
function pulseDigestSectionBonus(section) {
  switch (section) {
    case "for_review":
      return 22;
    case "waiting_on_you":
      return 18;
    case "changed":
      return 10;
    case "in_motion":
      return 8;
    case "resume":
      return 16;
    default:
      return 0;
  }
}
function clampPulseMeterScore(value) {
  return Math.max(0, Math.min(100, Math.round(value)));
}
// ../core/src/types/nowOverview.ts
var RHEI_NOW_OVERVIEW_SCHEMA_VERSION = 1;
function isRheiNowOverviewV1(value) {
  if (!value || typeof value !== "object")
    return false;
  const record = value;
  return record.kind === "RheiNowOverviewV1" && record.schemaVersion === RHEI_NOW_OVERVIEW_SCHEMA_VERSION && record.advisoryOnly === true && record.noAuthority === true && typeof record.generatedAt === "number" && Boolean(record.goal) && Boolean(record.focus) && Boolean(record.work) && Boolean(record.review) && Boolean(record.trust) && Boolean(record.pulse) && Boolean(record.activity);
}
// ../core/src/nowFocusDecisions.ts
function baseMap(base) {
  const map = new Map;
  for (const item of base) {
    if (item && typeof item.stableKey === "string" && item.stableKey) {
      map.set(item.stableKey, { ...item });
    }
  }
  return map;
}
function ensureState(map, stableKey, source, goalId) {
  const existing = map.get(stableKey);
  if (existing) {
    if (source)
      existing.source = source;
    if (goalId !== undefined)
      existing.goalId = goalId;
    return existing;
  }
  const created = { stableKey, source: source || "status", showCount: 0 };
  if (goalId !== undefined)
    created.goalId = goalId;
  map.set(stableKey, created);
  return created;
}
function applyFocusDecisions(base, decisions) {
  const map = baseMap(base);
  const ordered = [...decisions].sort((a, b) => a.at - b.at);
  for (const record of ordered) {
    if (!record || typeof record.stableKey !== "string" || !record.stableKey)
      continue;
    const state = ensureState(map, record.stableKey, record.source, record.goalId);
    switch (record.decision) {
      case "accept":
        state.snoozedUntil = undefined;
        state.dismissedAt = undefined;
        state.doneAt = undefined;
        break;
      case "snooze":
        if (typeof record.snoozedUntilMs === "number")
          state.snoozedUntil = record.snoozedUntilMs;
        break;
      case "dismiss":
        state.dismissedAt = record.at;
        break;
      case "mark_done":
        state.doneAt = record.at;
        break;
      case "show_next":
        break;
    }
  }
  return [...map.values()];
}
function bumpShowCounts(base, shows, nowMs) {
  const map = baseMap(base);
  for (const show of shows) {
    if (!show || typeof show.stableKey !== "string" || !show.stableKey)
      continue;
    const state = ensureState(map, show.stableKey, show.source, show.goalId);
    state.showCount = (state.showCount ?? 0) + 1;
    state.lastShownAt = nowMs;
  }
  return [...map.values()];
}
// ../core/src/nowActivity.ts
var RHEI_NOW_ACTIVITY_DEFAULT_CAP = 20;
function composeNowActivity(events, options) {
  const cap = options.cap ?? RHEI_NOW_ACTIVITY_DEFAULT_CAP;
  const sorted = [...events].sort((a, b) => b.at - a.at).slice(0, Math.max(0, cap));
  const sinceMs = sorted.length > 0 ? sorted[sorted.length - 1].at : undefined;
  return {
    events: sorted,
    sinceMs,
    receipts: [`now:activity:events_${sorted.length}`],
    advisoryOnly: true,
    noAuthority: true
  };
}
export {
  scorePulseDigestNext,
  pulseDigestSignalLayersForSignals,
  pulseDigestReasonLabelForCategory,
  pulseDigestFocusMeterForSignals,
  pulseDigestFocusCategoryForSignals,
  pulseDigestCategoryForReasonLabel,
  isRheiNowOverviewV1,
  isPulseDigestReasonLabel,
  composeNowActivity,
  bumpShowCounts,
  applyFocusDecisions,
  RHEI_NOW_OVERVIEW_SCHEMA_VERSION,
  RHEI_NOW_ACTIVITY_DEFAULT_CAP,
  PULSE_DIGEST_REASON_LABELS
};
