@vue-skuilder/db 0.2.8 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{contentSource-Cplhv3bJ.d.ts → contentSource-C-0t0y0V.d.ts} +7 -0
- package/dist/{contentSource-kI9_jwTu.d.cts → contentSource-jSkcOt2s.d.cts} +7 -0
- package/dist/core/index.d.cts +29 -4
- package/dist/core/index.d.ts +29 -4
- package/dist/core/index.js +132 -39
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +130 -39
- package/dist/core/index.mjs.map +1 -1
- package/dist/{dataLayerProvider-DrBqOUa3.d.ts → dataLayerProvider-BB0oi9T0.d.ts} +1 -1
- package/dist/{dataLayerProvider-CiA2Rr0v.d.cts → dataLayerProvider-BDClIrFC.d.cts} +1 -1
- package/dist/impl/couch/index.d.cts +2 -2
- package/dist/impl/couch/index.d.ts +2 -2
- package/dist/impl/couch/index.js +128 -39
- package/dist/impl/couch/index.js.map +1 -1
- package/dist/impl/couch/index.mjs +128 -39
- package/dist/impl/couch/index.mjs.map +1 -1
- package/dist/impl/static/index.d.cts +2 -2
- package/dist/impl/static/index.d.ts +2 -2
- package/dist/impl/static/index.js +128 -39
- package/dist/impl/static/index.js.map +1 -1
- package/dist/impl/static/index.mjs +128 -39
- package/dist/impl/static/index.mjs.map +1 -1
- package/dist/index.d.cts +115 -81
- package/dist/index.d.ts +115 -81
- package/dist/index.js +371 -251
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +369 -251
- package/dist/index.mjs.map +1 -1
- package/docs/navigators-architecture.md +29 -13
- package/package.json +3 -3
- package/src/core/interfaces/contentSource.ts +7 -0
- package/src/core/navigators/SrsDebugger.ts +53 -0
- package/src/core/navigators/generators/prescribed.ts +76 -9
- package/src/core/navigators/generators/srs.ts +81 -37
- package/src/core/navigators/index.ts +5 -0
- package/src/study/SessionController.ts +260 -249
- package/src/study/SessionDebugger.ts +15 -25
- package/src/study/SessionOverlay.ts +108 -13
|
@@ -1419,6 +1419,30 @@ Example:
|
|
|
1419
1419
|
}
|
|
1420
1420
|
});
|
|
1421
1421
|
|
|
1422
|
+
// src/core/navigators/SrsDebugger.ts
|
|
1423
|
+
var SrsDebugger_exports = {};
|
|
1424
|
+
__export(SrsDebugger_exports, {
|
|
1425
|
+
captureSrsBacklog: () => captureSrsBacklog,
|
|
1426
|
+
clearSrsBacklogDebug: () => clearSrsBacklogDebug,
|
|
1427
|
+
getSrsBacklogDebug: () => getSrsBacklogDebug
|
|
1428
|
+
});
|
|
1429
|
+
function captureSrsBacklog(snapshot) {
|
|
1430
|
+
snapshots.set(snapshot.courseId, snapshot);
|
|
1431
|
+
}
|
|
1432
|
+
function getSrsBacklogDebug() {
|
|
1433
|
+
return [...snapshots.values()].sort((a, b) => b.timestamp - a.timestamp);
|
|
1434
|
+
}
|
|
1435
|
+
function clearSrsBacklogDebug() {
|
|
1436
|
+
snapshots.clear();
|
|
1437
|
+
}
|
|
1438
|
+
var snapshots;
|
|
1439
|
+
var init_SrsDebugger = __esm({
|
|
1440
|
+
"src/core/navigators/SrsDebugger.ts"() {
|
|
1441
|
+
"use strict";
|
|
1442
|
+
snapshots = /* @__PURE__ */ new Map();
|
|
1443
|
+
}
|
|
1444
|
+
});
|
|
1445
|
+
|
|
1422
1446
|
// src/core/navigators/generators/CompositeGenerator.ts
|
|
1423
1447
|
var CompositeGenerator_exports = {};
|
|
1424
1448
|
__export(CompositeGenerator_exports, {
|
|
@@ -1786,7 +1810,7 @@ function shuffleInPlace(arr) {
|
|
|
1786
1810
|
function pickTopByScore(cards, limit) {
|
|
1787
1811
|
return [...cards].sort((a, b) => b.score - a.score || a.cardId.localeCompare(b.cardId)).slice(0, limit);
|
|
1788
1812
|
}
|
|
1789
|
-
var DEFAULT_FRESHNESS_WINDOW, DEFAULT_MAX_DIRECT_PER_RUN, DEFAULT_MAX_SUPPORT_PER_RUN, DEFAULT_HIERARCHY_DEPTH, DEFAULT_MIN_COUNT, DEFAULT_PRACTICE_MIN_COUNT, DEFAULT_MAX_PRACTICE_PER_RUN, BASE_TARGET_SCORE, BASE_SUPPORT_SCORE, DISCOVERED_SUPPORT_SCORE, BASE_PRACTICE_SCORE, MAX_TARGET_MULTIPLIER, MAX_SUPPORT_MULTIPLIER, PRESCRIBED_DEBUG_VERSION, PrescribedCardsGenerator;
|
|
1813
|
+
var DEFAULT_FRESHNESS_WINDOW, DEFAULT_MAX_DIRECT_PER_RUN, DEFAULT_MAX_SUPPORT_PER_RUN, DEFAULT_HIERARCHY_DEPTH, DEFAULT_MIN_COUNT, DEFAULT_PRACTICE_MIN_COUNT, DEFAULT_MAX_PRACTICE_PER_RUN, BASE_TARGET_SCORE, BASE_SUPPORT_SCORE, DISCOVERED_SUPPORT_SCORE, BASE_PRACTICE_SCORE, PRACTICE_BASE_MULT, MAX_PRACTICE_MULTIPLIER, PRACTICE_STALENESS_BUMP_PER_DAY, MAX_TARGET_MULTIPLIER, MAX_SUPPORT_MULTIPLIER, PRESCRIBED_DEBUG_VERSION, PrescribedCardsGenerator;
|
|
1790
1814
|
var init_prescribed = __esm({
|
|
1791
1815
|
"src/core/navigators/generators/prescribed.ts"() {
|
|
1792
1816
|
"use strict";
|
|
@@ -1803,6 +1827,9 @@ var init_prescribed = __esm({
|
|
|
1803
1827
|
BASE_SUPPORT_SCORE = 0.8;
|
|
1804
1828
|
DISCOVERED_SUPPORT_SCORE = 12;
|
|
1805
1829
|
BASE_PRACTICE_SCORE = 1;
|
|
1830
|
+
PRACTICE_BASE_MULT = 2;
|
|
1831
|
+
MAX_PRACTICE_MULTIPLIER = 4;
|
|
1832
|
+
PRACTICE_STALENESS_BUMP_PER_DAY = 0.5;
|
|
1806
1833
|
MAX_TARGET_MULTIPLIER = 8;
|
|
1807
1834
|
MAX_SUPPORT_MULTIPLIER = 4;
|
|
1808
1835
|
PRESCRIBED_DEBUG_VERSION = "testversion-prescribed-v3";
|
|
@@ -1862,6 +1889,8 @@ var init_prescribed = __esm({
|
|
|
1862
1889
|
const emitted = [];
|
|
1863
1890
|
const emittedIds = /* @__PURE__ */ new Set();
|
|
1864
1891
|
const groupRuntimes = [];
|
|
1892
|
+
const priorPracticeDebt = progress.practiceDebt ?? {};
|
|
1893
|
+
const nextPracticeDebt = {};
|
|
1865
1894
|
for (const group of this.config.groups) {
|
|
1866
1895
|
const runtime = this.buildGroupRuntimeState({
|
|
1867
1896
|
group,
|
|
@@ -1919,10 +1948,13 @@ var init_prescribed = __esm({
|
|
|
1919
1948
|
userTagElo,
|
|
1920
1949
|
userGlobalElo,
|
|
1921
1950
|
activeIds,
|
|
1922
|
-
seenIds
|
|
1951
|
+
seenIds,
|
|
1952
|
+
priorPracticeDebt,
|
|
1953
|
+
nextPracticeDebt
|
|
1923
1954
|
});
|
|
1924
1955
|
emitted.push(...directCards, ...supportCards, ...discoveredSupportCards, ...practiceCards);
|
|
1925
1956
|
}
|
|
1957
|
+
nextState.practiceDebt = nextPracticeDebt;
|
|
1926
1958
|
const hintSummary = this.buildSupportHintSummary(groupRuntimes);
|
|
1927
1959
|
const hints = Object.keys(hintSummary.boostTags).length > 0 ? {
|
|
1928
1960
|
boostTags: hintSummary.boostTags,
|
|
@@ -2256,9 +2288,16 @@ var init_prescribed = __esm({
|
|
|
2256
2288
|
* `practiceMinCount`), this resolves cards carrying that tag and emits them
|
|
2257
2289
|
* into the candidate pool. It exists because global-ELO retrieval
|
|
2258
2290
|
* systematically fails to fetch the (low-ELO) drill cards for a
|
|
2259
|
-
* freshly-introduced skill — putting them in the pool here
|
|
2260
|
-
*
|
|
2261
|
-
*
|
|
2291
|
+
* freshly-introduced skill — putting them in the pool here guarantees presence.
|
|
2292
|
+
*
|
|
2293
|
+
* Emphasis is a **practice-debt pressure** (parallel to SRS backlog pressure):
|
|
2294
|
+
* cards score `base × multiplier`, where the multiplier starts at
|
|
2295
|
+
* PRACTICE_BASE_MULT (so a few reps land promptly post-intro, competing with
|
|
2296
|
+
* pressured reviews) and escalates by how long the debt has stayed open
|
|
2297
|
+
* (per-tag, time-based via `priorPracticeDebt`/`nextPracticeDebt`), clamped at
|
|
2298
|
+
* MAX_PRACTICE_MULTIPLIER. The debt is durable and self-discharges the instant
|
|
2299
|
+
* the skill reaches `practiceMinCount` — so this no longer relies on the
|
|
2300
|
+
* session-scoped intro boost to actually surface.
|
|
2262
2301
|
*
|
|
2263
2302
|
* Fully data-driven: the unlock relation comes from the hierarchy config and
|
|
2264
2303
|
* practice-status from per-tag ELO. No card-id or tag-namespace hard-coding.
|
|
@@ -2273,7 +2312,9 @@ var init_prescribed = __esm({
|
|
|
2273
2312
|
userTagElo,
|
|
2274
2313
|
userGlobalElo,
|
|
2275
2314
|
activeIds,
|
|
2276
|
-
seenIds
|
|
2315
|
+
seenIds,
|
|
2316
|
+
priorPracticeDebt,
|
|
2317
|
+
nextPracticeDebt
|
|
2277
2318
|
} = args;
|
|
2278
2319
|
const patterns = group.practiceTagPatterns ?? [];
|
|
2279
2320
|
if (patterns.length === 0) return [];
|
|
@@ -2283,6 +2324,20 @@ var init_prescribed = __esm({
|
|
|
2283
2324
|
(tag) => patterns.some((p) => matchesTagPattern(tag, p)) && this.isUnlockedGatedSkill(tag, hierarchyConfigs, userTagElo, userGlobalElo) && (userTagElo[tag]?.count ?? 0) < practiceMinCount
|
|
2284
2325
|
);
|
|
2285
2326
|
if (practiceTags.length === 0) return [];
|
|
2327
|
+
const now = Date.now();
|
|
2328
|
+
const DAY_MS = 24 * 60 * 60 * 1e3;
|
|
2329
|
+
const tagMultiplier = /* @__PURE__ */ new Map();
|
|
2330
|
+
for (const tag of practiceTags) {
|
|
2331
|
+
const firstOwedAt = priorPracticeDebt[tag] ?? isoNow();
|
|
2332
|
+
nextPracticeDebt[tag] = firstOwedAt;
|
|
2333
|
+
const staleDays = Math.max(0, (now - new Date(firstOwedAt).getTime()) / DAY_MS);
|
|
2334
|
+
const mult = clamp(
|
|
2335
|
+
PRACTICE_BASE_MULT + staleDays * PRACTICE_STALENESS_BUMP_PER_DAY,
|
|
2336
|
+
PRACTICE_BASE_MULT,
|
|
2337
|
+
MAX_PRACTICE_MULTIPLIER
|
|
2338
|
+
);
|
|
2339
|
+
tagMultiplier.set(tag, mult);
|
|
2340
|
+
}
|
|
2286
2341
|
const practiceCardIds = this.findDiscoveredSupportCards({
|
|
2287
2342
|
supportTags: practiceTags,
|
|
2288
2343
|
cardsByTag,
|
|
@@ -2298,18 +2353,25 @@ var init_prescribed = __esm({
|
|
|
2298
2353
|
const cards = [];
|
|
2299
2354
|
for (const cardId of practiceCardIds) {
|
|
2300
2355
|
emittedIds.add(cardId);
|
|
2356
|
+
let mult = PRACTICE_BASE_MULT;
|
|
2357
|
+
for (const tag of practiceTags) {
|
|
2358
|
+
if (cardsByTag.get(tag)?.includes(cardId) ?? false) {
|
|
2359
|
+
mult = Math.max(mult, tagMultiplier.get(tag) ?? PRACTICE_BASE_MULT);
|
|
2360
|
+
}
|
|
2361
|
+
}
|
|
2362
|
+
const score = BASE_PRACTICE_SCORE * mult;
|
|
2301
2363
|
cards.push({
|
|
2302
2364
|
cardId,
|
|
2303
2365
|
courseId,
|
|
2304
|
-
score
|
|
2366
|
+
score,
|
|
2305
2367
|
provenance: [
|
|
2306
2368
|
{
|
|
2307
2369
|
strategy: "prescribed",
|
|
2308
2370
|
strategyName: this.strategyName || this.name,
|
|
2309
2371
|
strategyId: this.strategyId || "NAVIGATION_STRATEGY-prescribed",
|
|
2310
2372
|
action: "generated",
|
|
2311
|
-
score
|
|
2312
|
-
reason: `mode=practice;group=${group.id};underPracticedSkills=${practiceTags.length};practiceTags=${practiceTags.slice(0, 8).join("|")}${practiceTags.length > 8 ? "|\u2026" : ""};testversion=${PRESCRIBED_DEBUG_VERSION}`
|
|
2373
|
+
score,
|
|
2374
|
+
reason: `mode=practice;group=${group.id};debtMult=\xD7${mult.toFixed(2)};underPracticedSkills=${practiceTags.length};practiceTags=${practiceTags.slice(0, 8).join("|")}${practiceTags.length > 8 ? "|\u2026" : ""};testversion=${PRESCRIBED_DEBUG_VERSION}`
|
|
2313
2375
|
}
|
|
2314
2376
|
]
|
|
2315
2377
|
});
|
|
@@ -2483,14 +2545,15 @@ __export(srs_exports, {
|
|
|
2483
2545
|
default: () => SRSNavigator
|
|
2484
2546
|
});
|
|
2485
2547
|
import moment3 from "moment";
|
|
2486
|
-
var DEFAULT_HEALTHY_BACKLOG,
|
|
2548
|
+
var DEFAULT_HEALTHY_BACKLOG, MAX_BACKLOG_MULTIPLIER, SRSNavigator;
|
|
2487
2549
|
var init_srs = __esm({
|
|
2488
2550
|
"src/core/navigators/generators/srs.ts"() {
|
|
2489
2551
|
"use strict";
|
|
2490
2552
|
init_navigators();
|
|
2553
|
+
init_SrsDebugger();
|
|
2491
2554
|
init_logger();
|
|
2492
2555
|
DEFAULT_HEALTHY_BACKLOG = 20;
|
|
2493
|
-
|
|
2556
|
+
MAX_BACKLOG_MULTIPLIER = 2;
|
|
2494
2557
|
SRSNavigator = class extends ContentNavigator {
|
|
2495
2558
|
/** Human-readable name for CardGenerator interface */
|
|
2496
2559
|
name;
|
|
@@ -2557,9 +2620,18 @@ var init_srs = __esm({
|
|
|
2557
2620
|
}
|
|
2558
2621
|
}
|
|
2559
2622
|
}
|
|
2560
|
-
const
|
|
2623
|
+
const backlogMultiplier = this.computeBacklogMultiplier(dueReviews.length);
|
|
2624
|
+
const notDue = reviews.filter((r) => !now.isAfter(moment3.utc(r.reviewTime)));
|
|
2625
|
+
let nextDueIn = null;
|
|
2626
|
+
if (notDue.length > 0) {
|
|
2627
|
+
const next = notDue.reduce(
|
|
2628
|
+
(a, b) => moment3.utc(a.reviewTime).isBefore(moment3.utc(b.reviewTime)) ? a : b
|
|
2629
|
+
);
|
|
2630
|
+
const until = moment3.duration(moment3.utc(next.reviewTime).diff(now));
|
|
2631
|
+
nextDueIn = until.asHours() < 1 ? `${Math.round(until.asMinutes())}m` : until.asHours() < 24 ? `${Math.round(until.asHours())}h` : `${Math.round(until.asDays())}d`;
|
|
2632
|
+
}
|
|
2561
2633
|
if (dueReviews.length > 0) {
|
|
2562
|
-
const pressureNote =
|
|
2634
|
+
const pressureNote = backlogMultiplier > 1 ? ` [backlog pressure: \xD7${backlogMultiplier.toFixed(2)}]` : ` [healthy backlog]`;
|
|
2563
2635
|
logger.info(
|
|
2564
2636
|
`[SRS] Course ${courseId}: ${dueReviews.length} reviews due now (of ${reviews.length} scheduled)${pressureNote}`
|
|
2565
2637
|
);
|
|
@@ -2578,7 +2650,7 @@ var init_srs = __esm({
|
|
|
2578
2650
|
logger.info(`[SRS] Course ${courseId}: No reviews scheduled`);
|
|
2579
2651
|
}
|
|
2580
2652
|
const scored = dueReviews.map((review) => {
|
|
2581
|
-
const { score, reason } = this.computeUrgencyScore(review, now,
|
|
2653
|
+
const { score, reason } = this.computeUrgencyScore(review, now, backlogMultiplier);
|
|
2582
2654
|
return {
|
|
2583
2655
|
cardId: review.cardId,
|
|
2584
2656
|
courseId: review.courseId,
|
|
@@ -2596,30 +2668,42 @@ var init_srs = __esm({
|
|
|
2596
2668
|
]
|
|
2597
2669
|
};
|
|
2598
2670
|
});
|
|
2599
|
-
|
|
2671
|
+
const sorted = scored.sort((a, b) => b.score - a.score);
|
|
2672
|
+
captureSrsBacklog({
|
|
2673
|
+
courseId,
|
|
2674
|
+
scheduledTotal: reviews.length,
|
|
2675
|
+
dueNow: dueReviews.length,
|
|
2676
|
+
healthyBacklog: this.healthyBacklog,
|
|
2677
|
+
backlogMultiplier,
|
|
2678
|
+
maxBacklogMultiplier: MAX_BACKLOG_MULTIPLIER,
|
|
2679
|
+
topReviewScore: sorted.length > 0 ? sorted[0].score : null,
|
|
2680
|
+
nextDueIn,
|
|
2681
|
+
timestamp: Date.now()
|
|
2682
|
+
});
|
|
2683
|
+
return { cards: sorted.slice(0, limit) };
|
|
2600
2684
|
}
|
|
2601
2685
|
/**
|
|
2602
|
-
* Compute backlog pressure based on number of due reviews.
|
|
2686
|
+
* Compute the multiplicative backlog pressure based on number of due reviews.
|
|
2603
2687
|
*
|
|
2604
|
-
*
|
|
2605
|
-
* and
|
|
2688
|
+
* ×1.0 at or below the healthy threshold (no boost), increasing linearly above
|
|
2689
|
+
* it and maxing out at MAX_BACKLOG_MULTIPLIER at 3× the healthy backlog.
|
|
2606
2690
|
*
|
|
2607
|
-
* Examples (with default healthyBacklog=20):
|
|
2608
|
-
* - 10 due reviews →
|
|
2609
|
-
* - 20 due reviews →
|
|
2610
|
-
* - 40 due reviews →
|
|
2611
|
-
* - 60 due reviews →
|
|
2691
|
+
* Examples (with default healthyBacklog=20, MAX_BACKLOG_MULTIPLIER=2.0):
|
|
2692
|
+
* - 10 due reviews → ×1.00 (healthy)
|
|
2693
|
+
* - 20 due reviews → ×1.00 (at threshold)
|
|
2694
|
+
* - 40 due reviews → ×1.50 (2x threshold)
|
|
2695
|
+
* - 60 due reviews → ×2.00 (3x threshold, maxed)
|
|
2612
2696
|
*
|
|
2613
2697
|
* @param dueCount - Number of reviews currently due
|
|
2614
|
-
* @returns
|
|
2698
|
+
* @returns Multiplier applied to review urgency (1.0 to MAX_BACKLOG_MULTIPLIER)
|
|
2615
2699
|
*/
|
|
2616
|
-
|
|
2700
|
+
computeBacklogMultiplier(dueCount) {
|
|
2617
2701
|
if (dueCount <= this.healthyBacklog) {
|
|
2618
|
-
return
|
|
2702
|
+
return 1;
|
|
2619
2703
|
}
|
|
2620
2704
|
const excess = dueCount - this.healthyBacklog;
|
|
2621
|
-
const
|
|
2622
|
-
return Math.min(
|
|
2705
|
+
const multiplier = 1 + excess / this.healthyBacklog * ((MAX_BACKLOG_MULTIPLIER - 1) / 2);
|
|
2706
|
+
return Math.min(MAX_BACKLOG_MULTIPLIER, multiplier);
|
|
2623
2707
|
}
|
|
2624
2708
|
/**
|
|
2625
2709
|
* Compute urgency score for a review card.
|
|
@@ -2634,19 +2718,20 @@ var init_srs = __esm({
|
|
|
2634
2718
|
* - 30 days (720h) → ~0.56
|
|
2635
2719
|
* - 180 days → ~0.30
|
|
2636
2720
|
*
|
|
2637
|
-
* 3. Backlog pressure = global
|
|
2638
|
-
*
|
|
2639
|
-
* - At 2x healthy: +0.25
|
|
2640
|
-
* - At 3x+ healthy: +0.50 (max)
|
|
2721
|
+
* 3. Backlog pressure = global *multiplier* when review backlog exceeds the
|
|
2722
|
+
* healthy threshold (×1.0 healthy → up to MAX_BACKLOG_MULTIPLIER at 3×).
|
|
2641
2723
|
*
|
|
2642
|
-
* Combined: base 0.5 +
|
|
2643
|
-
*
|
|
2724
|
+
* Combined: (base 0.5 + urgency factors * 0.45) × backlog multiplier.
|
|
2725
|
+
* Per-card range before pressure: ~0.57–0.95. NOT clamped to 1.0 — under a
|
|
2726
|
+
* heavy backlog reviews scale onto the open scale to compete with (and exceed)
|
|
2727
|
+
* new cards; what keeps them from running away is the bounded multiplier, not
|
|
2728
|
+
* a hard ceiling.
|
|
2644
2729
|
*
|
|
2645
2730
|
* @param review - The scheduled card to score
|
|
2646
2731
|
* @param now - Current time
|
|
2647
|
-
* @param
|
|
2732
|
+
* @param backlogMultiplier - Pre-computed backlog multiplier (1.0 to MAX_BACKLOG_MULTIPLIER)
|
|
2648
2733
|
*/
|
|
2649
|
-
computeUrgencyScore(review, now,
|
|
2734
|
+
computeUrgencyScore(review, now, backlogMultiplier) {
|
|
2650
2735
|
const scheduledAt = moment3.utc(review.scheduledAt);
|
|
2651
2736
|
const due = moment3.utc(review.reviewTime);
|
|
2652
2737
|
const intervalHours = Math.max(1, due.diff(scheduledAt, "hours"));
|
|
@@ -2656,15 +2741,15 @@ var init_srs = __esm({
|
|
|
2656
2741
|
const overdueContribution = Math.min(1, Math.max(0, relativeOverdue));
|
|
2657
2742
|
const urgency = overdueContribution * 0.5 + recencyFactor * 0.5;
|
|
2658
2743
|
const baseScore = 0.5 + urgency * 0.45;
|
|
2659
|
-
const score =
|
|
2744
|
+
const score = baseScore * backlogMultiplier;
|
|
2660
2745
|
const reasonParts = [
|
|
2661
2746
|
`${Math.round(hoursOverdue)}h overdue`,
|
|
2662
2747
|
`interval: ${Math.round(intervalHours)}h`,
|
|
2663
2748
|
`relative: ${relativeOverdue.toFixed(2)}`,
|
|
2664
2749
|
`recency: ${recencyFactor.toFixed(2)}`
|
|
2665
2750
|
];
|
|
2666
|
-
if (
|
|
2667
|
-
reasonParts.push(`backlog:
|
|
2751
|
+
if (backlogMultiplier > 1) {
|
|
2752
|
+
reasonParts.push(`backlog: \xD7${backlogMultiplier.toFixed(2)}`);
|
|
2668
2753
|
}
|
|
2669
2754
|
reasonParts.push("review");
|
|
2670
2755
|
const reason = reasonParts.join(", ");
|
|
@@ -4716,6 +4801,7 @@ var init_3 = __esm({
|
|
|
4716
4801
|
"./Pipeline.ts": () => Promise.resolve().then(() => (init_Pipeline(), Pipeline_exports)),
|
|
4717
4802
|
"./PipelineAssembler.ts": () => Promise.resolve().then(() => (init_PipelineAssembler(), PipelineAssembler_exports)),
|
|
4718
4803
|
"./PipelineDebugger.ts": () => Promise.resolve().then(() => (init_PipelineDebugger(), PipelineDebugger_exports)),
|
|
4804
|
+
"./SrsDebugger.ts": () => Promise.resolve().then(() => (init_SrsDebugger(), SrsDebugger_exports)),
|
|
4719
4805
|
"./defaults.ts": () => Promise.resolve().then(() => (init_defaults(), defaults_exports)),
|
|
4720
4806
|
"./diversityRerank.ts": () => Promise.resolve().then(() => (init_diversityRerank(), diversityRerank_exports)),
|
|
4721
4807
|
"./filters/WeightedFilter.ts": () => Promise.resolve().then(() => (init_WeightedFilter(), WeightedFilter_exports)),
|
|
@@ -4748,12 +4834,14 @@ __export(navigators_exports, {
|
|
|
4748
4834
|
NavigatorRole: () => NavigatorRole,
|
|
4749
4835
|
NavigatorRoles: () => NavigatorRoles,
|
|
4750
4836
|
Navigators: () => Navigators,
|
|
4837
|
+
clearSrsBacklogDebug: () => clearSrsBacklogDebug,
|
|
4751
4838
|
diversityRerank: () => diversityRerank,
|
|
4752
4839
|
getActivePipeline: () => getActivePipeline,
|
|
4753
4840
|
getCardOrigin: () => getCardOrigin,
|
|
4754
4841
|
getRegisteredNavigator: () => getRegisteredNavigator,
|
|
4755
4842
|
getRegisteredNavigatorNames: () => getRegisteredNavigatorNames,
|
|
4756
4843
|
getRegisteredNavigatorRole: () => getRegisteredNavigatorRole,
|
|
4844
|
+
getSrsBacklogDebug: () => getSrsBacklogDebug,
|
|
4757
4845
|
hasRegisteredNavigator: () => hasRegisteredNavigator,
|
|
4758
4846
|
initializeNavigatorRegistry: () => initializeNavigatorRegistry,
|
|
4759
4847
|
isFilter: () => isFilter,
|
|
@@ -4835,6 +4923,7 @@ var init_navigators = __esm({
|
|
|
4835
4923
|
"use strict";
|
|
4836
4924
|
init_diversityRerank();
|
|
4837
4925
|
init_PipelineDebugger();
|
|
4926
|
+
init_SrsDebugger();
|
|
4838
4927
|
init_logger();
|
|
4839
4928
|
init_();
|
|
4840
4929
|
init_2();
|