hook-policy.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import type { HookPayoffTiming } from "../models/runtime-state.js";
  2. export type HookPhase = "opening" | "middle" | "late";
  3. export type HookAgendaLoad = "light" | "medium" | "heavy";
  4. export interface HookLifecycleProfile {
  5. readonly earliestResolveAge: number;
  6. readonly staleDormancy: number;
  7. readonly overdueAge: number;
  8. readonly minimumPhase: HookPhase;
  9. readonly resolveBias: number;
  10. }
  11. export const HOOK_TIMING_PROFILES: Record<HookPayoffTiming, HookLifecycleProfile> = {
  12. immediate: {
  13. earliestResolveAge: 1,
  14. staleDormancy: 1,
  15. overdueAge: 3,
  16. minimumPhase: "opening",
  17. resolveBias: 5,
  18. },
  19. "near-term": {
  20. earliestResolveAge: 1,
  21. staleDormancy: 2,
  22. overdueAge: 5,
  23. minimumPhase: "opening",
  24. resolveBias: 4,
  25. },
  26. "mid-arc": {
  27. earliestResolveAge: 2,
  28. staleDormancy: 4,
  29. overdueAge: 8,
  30. minimumPhase: "opening",
  31. resolveBias: 3,
  32. },
  33. "slow-burn": {
  34. earliestResolveAge: 4,
  35. staleDormancy: 5,
  36. overdueAge: 12,
  37. minimumPhase: "middle",
  38. resolveBias: 2,
  39. },
  40. endgame: {
  41. earliestResolveAge: 6,
  42. staleDormancy: 6,
  43. overdueAge: 16,
  44. minimumPhase: "late",
  45. resolveBias: 1,
  46. },
  47. };
  48. export const HOOK_PHASE_WEIGHT: Record<HookPhase, number> = {
  49. opening: 0,
  50. middle: 1,
  51. late: 2,
  52. };
  53. export const HOOK_PHASE_THRESHOLDS = {
  54. middleProgress: 0.33,
  55. lateProgress: 0.72,
  56. middleChapter: 8,
  57. lateChapter: 24,
  58. } as const;
  59. export const HOOK_PRESSURE_WEIGHTS = {
  60. staleAdvanceBonus: 8,
  61. overdueAdvanceBonus: 6,
  62. resolveBiasMultiplier: 10,
  63. progressingResolveBonus: 5,
  64. dormancyResolveMultiplier: 2,
  65. maxDormancyResolveBonus: 12,
  66. overdueResolveBonus: 10,
  67. mustAdvancePressureFloor: 8,
  68. criticalResolvePressure: 40,
  69. } as const;
  70. export const HOOK_ACTIVITY_THRESHOLDS = {
  71. recentlyTouchedDormancy: 1,
  72. longArcQuietHoldMaxAge: 2,
  73. longArcQuietHoldMaxDormancy: 1,
  74. refreshDormancy: 2,
  75. freshPromiseAge: 1,
  76. } as const;
  77. export const HOOK_AGENDA_LIMITS: Record<HookAgendaLoad, {
  78. readonly staleDebt: number;
  79. readonly mustAdvance: number;
  80. readonly eligibleResolve: number;
  81. readonly avoidFamilies: number;
  82. }> = {
  83. light: {
  84. staleDebt: 1,
  85. mustAdvance: 2,
  86. eligibleResolve: 1,
  87. avoidFamilies: 2,
  88. },
  89. medium: {
  90. staleDebt: 2,
  91. mustAdvance: 2,
  92. eligibleResolve: 1,
  93. avoidFamilies: 3,
  94. },
  95. heavy: {
  96. staleDebt: 3,
  97. mustAdvance: 3,
  98. eligibleResolve: 2,
  99. avoidFamilies: 4,
  100. },
  101. };
  102. export const HOOK_AGENDA_LOAD_THRESHOLDS = {
  103. heavyReadyCount: 3,
  104. heavyStaleCount: 4,
  105. heavyCriticalCount: 3,
  106. heavyPressuredCount: 6,
  107. mediumReadyCount: 2,
  108. mediumStaleCount: 2,
  109. mediumCriticalCount: 1,
  110. mediumPressuredFamilies: 3,
  111. } as const;
  112. export const HOOK_VISIBILITY_WINDOWS: Record<HookPayoffTiming, number> = {
  113. immediate: 5,
  114. "near-term": 5,
  115. "mid-arc": 6,
  116. "slow-burn": 8,
  117. endgame: 10,
  118. };
  119. export const HOOK_RELEVANT_SELECTION_DEFAULTS = {
  120. primary: {
  121. baseLimit: 3,
  122. pressuredExpansionLimit: 4,
  123. pressuredThreshold: 4,
  124. },
  125. stale: {
  126. defaultLimit: 1,
  127. expandedLimit: 2,
  128. overdueThreshold: 2,
  129. familySpreadThreshold: 2,
  130. },
  131. } as const;
  132. export const HOOK_HEALTH_DEFAULTS = {
  133. maxActiveHooks: 12,
  134. staleAfterChapters: 10,
  135. noAdvanceWindow: 5,
  136. newHookBurstThreshold: 2,
  137. } as const;
  138. export function resolveHookVisibilityWindow(timing: HookPayoffTiming): number {
  139. return HOOK_VISIBILITY_WINDOWS[timing];
  140. }