memhtml 0.5.0 → 0.5.1

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.
@@ -9021,17 +9021,42 @@ const keyMembers = (items, textOf, options) => {
9021
9021
  };
9022
9022
  };
9023
9023
  /**
9024
+ * The offered key a model's answer denotes, or `undefined` when it denotes none.
9025
+ *
9026
+ * A model shown `<member_m3>` answers `member_m3` at least as readily as `m3`: the wrapper tag is
9027
+ * the only place most batch prompts DISPLAY a key, so the label-prefixed form is the one the prompt
9028
+ * itself teaches (measured live 2026-08-23: `gpt-5.6-sol` answers the prefixed form on every call,
9029
+ * Claude Sonnet 5 on most). So a key that does not match directly is retried once with everything
9030
+ * up to its last `_` stripped, and only a suffix the batch actually offered resolves — `member_m9`
9031
+ * in a batch of three still denotes nothing, and a path or an invented name still drops. The
9032
+ * canonical form is returned so two spellings of one member collapse to one key everywhere a phase
9033
+ * keeps per-key state.
9034
+ */
9035
+ const offeredKeyFor = (batch, key) => {
9036
+ if (batch.itemForKey.has(key)) return key;
9037
+ const at = key.lastIndexOf("_");
9038
+ if (at === -1) return void 0;
9039
+ const suffix = key.slice(at + 1);
9040
+ return batch.itemForKey.has(suffix) ? suffix : void 0;
9041
+ };
9042
+ /**
9024
9043
  * Resolve the keys a model named back to items: unknown keys are dropped, repeats collapse.
9025
9044
  *
9026
9045
  * A key the batch never offered is a member the model invented, and every phase on this kernel turns
9027
9046
  * a named member into a write, so an unresolvable key must not reach that write. Dropping it leaves
9028
9047
  * the corresponding file untouched, which is the safe outcome for every one of the five phases.
9048
+ * Resolution goes through {@link offeredKeyFor}, so the label-prefixed spelling of an offered key
9049
+ * (`member_m3` for `m3`) resolves rather than reading as an invention.
9029
9050
  *
9030
9051
  * The result keeps the order the model named the keys in, and a key named twice appears once.
9031
- * De-duplication is on the KEY rather than on the resolved item, so the count a phase gates on
9032
- * ("at least two members absorbed") counts distinct offered members.
9033
- */
9034
- const resolveKeys = (batch, keys) => [...new Set(keys)].flatMap((key) => {
9052
+ * De-duplication is on the CANONICAL key rather than on the spelling or the resolved item, so `m1`
9053
+ * and `member_m1` in one answer count as one member, and the count a phase gates on ("at least two
9054
+ * members absorbed") counts distinct offered members.
9055
+ */
9056
+ const resolveKeys = (batch, keys) => [...new Set(keys.flatMap((key) => {
9057
+ const canonical = offeredKeyFor(batch, key);
9058
+ return canonical === void 0 ? [] : [canonical];
9059
+ }))].flatMap((key) => {
9035
9060
  const item = batch.itemForKey.get(key);
9036
9061
  return item === void 0 ? [] : [item];
9037
9062
  });
@@ -11038,7 +11063,9 @@ const compress = (env) => Effect.gen(function* () {
11038
11063
  batches: batches.length,
11039
11064
  canonicals: 0,
11040
11065
  archived: 0,
11041
- skipped: 0
11066
+ skipped: 0,
11067
+ failed: 0,
11068
+ refused: 0
11042
11069
  };
11043
11070
  if (batches.length === 0) return emptyOutcome(counts);
11044
11071
  if (env.dryRun) return emptyOutcome(counts);
@@ -11046,7 +11073,16 @@ const compress = (env) => Effect.gen(function* () {
11046
11073
  let llmCalls = 0;
11047
11074
  let canonicals = 0;
11048
11075
  let archived = 0;
11076
+ /**
11077
+ * `skipped` stays the total, and `failed` + `refused` partition it. The two are different
11078
+ * diagnoses with different fixes — a failed call is the model or the wire (already logged by
11079
+ * `isolate`), a refusal is an answer the phase declined to act on (logged below) — and a night
11080
+ * reporting only their sum cannot say which one it had. 47 of 47 batches once skipped as
11081
+ * refusals with nothing on stderr, and the sum read as flaky calls.
11082
+ */
11049
11083
  let skipped = 0;
11084
+ let failed = 0;
11085
+ let refused = 0;
11050
11086
  let lastCommit = null;
11051
11087
  for (const batch of batches) {
11052
11088
  /** Opaque keys again, so `absorbedKeys` cannot name a path. */
@@ -11062,12 +11098,15 @@ const compress = (env) => Effect.gen(function* () {
11062
11098
  });
11063
11099
  if (synthesis === void 0) {
11064
11100
  skipped += 1;
11101
+ failed += 1;
11065
11102
  continue;
11066
11103
  }
11067
11104
  /** A key the batch never offered resolves to nothing, so a fold reaches only offered files. */
11068
11105
  const absorbed = resolveKeys(keyed, synthesis.absorbedKeys).map((entry) => entry.row.path);
11069
11106
  if (absorbed.length < 2 || synthesis.title.trim() === "" || synthesis.claim.trim() === "") {
11070
11107
  skipped += 1;
11108
+ refused += 1;
11109
+ yield* Effect.logWarning(`sleep.llm compress batch of ${batch.length} refused: the model absorbed ${absorbed.length} of ${synthesis.absorbedKeys.length} named keys` + (synthesis.absorbedKeys.length > 0 && absorbed.length === 0 ? ` (none of the named keys resolved: ${synthesis.absorbedKeys.slice(0, 3).join(", ")}${synthesis.absorbedKeys.length > 3 ? ", …" : ""})` : ""));
11071
11110
  continue;
11072
11111
  }
11073
11112
  /**
@@ -11080,6 +11119,8 @@ const compress = (env) => Effect.gen(function* () {
11080
11119
  const members = excludeSelfSupersede(canonicalPath, absorbed);
11081
11120
  if (members.length === 0) {
11082
11121
  skipped += 1;
11122
+ refused += 1;
11123
+ yield* Effect.logWarning(`sleep.llm compress batch of ${batch.length} refused: every absorbed member was the canonical itself`);
11083
11124
  continue;
11084
11125
  }
11085
11126
  /**
@@ -11094,6 +11135,8 @@ const compress = (env) => Effect.gen(function* () {
11094
11135
  }
11095
11136
  if (archivedPaths.length === 0) {
11096
11137
  skipped += 1;
11138
+ refused += 1;
11139
+ yield* Effect.logWarning(`sleep.llm compress batch of ${batch.length} refused: every member was already gone from the tree`);
11097
11140
  continue;
11098
11141
  }
11099
11142
  yield* writeFileBytes(env, canonicalPath, renderTemplate({
@@ -11112,7 +11155,9 @@ const compress = (env) => Effect.gen(function* () {
11112
11155
  ...counts,
11113
11156
  canonicals,
11114
11157
  archived,
11115
- skipped
11158
+ skipped,
11159
+ failed,
11160
+ refused
11116
11161
  });
11117
11162
  if (commitSha !== null) lastCommit = commitSha;
11118
11163
  }
@@ -11121,7 +11166,9 @@ const compress = (env) => Effect.gen(function* () {
11121
11166
  ...counts,
11122
11167
  canonicals,
11123
11168
  archived,
11124
- skipped
11169
+ skipped,
11170
+ failed,
11171
+ refused
11125
11172
  },
11126
11173
  commitSha: lastCommit,
11127
11174
  llmCalls
@@ -12032,7 +12079,9 @@ const dedupMerge = (env) => Effect.gen(function* () {
12032
12079
  candidates: oriented.length,
12033
12080
  components: 0,
12034
12081
  llmGroups: 0,
12035
- vetoed: oriented.length - decisions.length
12082
+ vetoed: oriented.length - decisions.length,
12083
+ skipped: 0,
12084
+ unresolved: 0
12036
12085
  },
12037
12086
  /**
12038
12087
  * Every mined pair on this arm cleared 0.92, so a vetoed one here is a near-certain duplicate
@@ -12103,6 +12152,12 @@ const dedupMerge = (env) => Effect.gen(function* () {
12103
12152
  let llmCalls = 0;
12104
12153
  let llmGroups = 0;
12105
12154
  let skipped = 0;
12155
+ /**
12156
+ * Model-named member keys that resolved to no offered member, dropped unacted. The drop is the
12157
+ * safe outcome and stays; the count makes a systematic naming pattern visible instead of reading
12158
+ * as a night in which the model proposed no merges (issue #58).
12159
+ */
12160
+ let unresolved = 0;
12106
12161
  /** Group-implied pairs, in batch then component then group order. */
12107
12162
  const groupPairs = [];
12108
12163
  /** Every path a surviving group claimed, so the mined arm cannot re-propose one. */
@@ -12142,11 +12197,17 @@ const dedupMerge = (env) => Effect.gen(function* () {
12142
12197
  skipped += 1;
12143
12198
  continue;
12144
12199
  }
12200
+ /** This batch's unresolvable keys, so the warning below can name the spellings that failed. */
12201
+ const unresolvedKeys = [];
12145
12202
  for (const group of partition.groups) {
12203
+ const dropped = group.memberKeys.filter((key) => offeredKeyFor(keyed, key) === void 0);
12204
+ unresolved += dropped.length;
12205
+ unresolvedKeys.push(...dropped);
12146
12206
  const members = resolveKeys(keyed, group.memberKeys);
12147
12207
  if (members.length < 2) continue;
12148
12208
  if (new Set(group.memberKeys.flatMap((key) => {
12149
- const id = componentOfKey.get(key);
12209
+ const canonical = offeredKeyFor(keyed, key);
12210
+ const id = canonical === void 0 ? void 0 : componentOfKey.get(canonical);
12150
12211
  return id === void 0 ? [] : [id];
12151
12212
  })).size !== 1) continue;
12152
12213
  /** The keeper is the OLDEST member: the lowest corpus offset, the same rule a pair uses. */
@@ -12172,6 +12233,7 @@ const dedupMerge = (env) => Effect.gen(function* () {
12172
12233
  }
12173
12234
  grouped.add(keeper.path);
12174
12235
  }
12236
+ if (unresolvedKeys.length > 0) yield* Effect.logWarning(`sleep.llm dedup batch of ${batch.length} components dropped ${unresolvedKeys.length} member keys naming no offered member (${unresolvedKeys.slice(0, 3).join(", ")}${unresolvedKeys.length > 3 ? ", …" : ""})`);
12175
12237
  }
12176
12238
  /**
12177
12239
  * Groups first, then the mined pairs above the DETERMINISTIC floor that no group claimed. The
@@ -12191,7 +12253,8 @@ const dedupMerge = (env) => Effect.gen(function* () {
12191
12253
  components: components.length,
12192
12254
  llmGroups,
12193
12255
  vetoed: proposed.length - decisions.length,
12194
- skipped
12256
+ skipped,
12257
+ unresolved
12195
12258
  },
12196
12259
  /**
12197
12260
  * On this arm a vetoed pair is one the MODEL grouped as the same memory, or one that cleared
@@ -12202,11 +12265,13 @@ const dedupMerge = (env) => Effect.gen(function* () {
12202
12265
  *
12203
12266
  * `judged` is false when a batch's call failed, because those components were never partitioned:
12204
12267
  * their pairs reach the veto only through the mined arm, so a night that lost a call cannot say
12205
- * whether a pair it did not see is still a candidate.
12268
+ * whether a pair it did not see is still a candidate. An unresolved member key is the same
12269
+ * hazard from the answer side — a group the phase could not fully map was not fully judged —
12270
+ * so it holds the sweep back the same way.
12206
12271
  */
12207
12272
  {
12208
12273
  vetoed: vetoedPairs(proposed),
12209
- judged: skipped === 0
12274
+ judged: skipped === 0 && unresolved === 0
12210
12275
  }
12211
12276
  ),
12212
12277
  llmCalls
@@ -12631,6 +12696,7 @@ const edgeTyping = (env) => Effect.gen(function* () {
12631
12696
  contradictions: 0,
12632
12697
  promoted: 0,
12633
12698
  skipped: 0,
12699
+ unresolved: 0,
12634
12700
  capped: 0,
12635
12701
  duplicates: 0,
12636
12702
  tasksMinted: 0,
@@ -12697,6 +12763,13 @@ const edgeTyping = (env) => Effect.gen(function* () {
12697
12763
  let capped = 0;
12698
12764
  /** Second-and-later verdicts naming a key their batch had already answered for. */
12699
12765
  let duplicates = 0;
12766
+ /**
12767
+ * Verdicts whose key resolved to no offered pair, so they were dropped unacted. Dropping is the
12768
+ * safe outcome and stays; the count is what makes a SYSTEMATIC pattern visible — a model naming
12769
+ * keys in a spelling the resolver refuses drops every verdict of every batch, and a night that
12770
+ * judged nothing looked identical to a night whose model answered nothing (issue #58).
12771
+ */
12772
+ let unresolved = 0;
12700
12773
  let llmCalls = 0;
12701
12774
  /**
12702
12775
  * Contradictions this night detected for the FIRST time, so below the promotion gate.
@@ -12737,18 +12810,27 @@ const edgeTyping = (env) => Effect.gen(function* () {
12737
12810
  * rather than silently swallowed, so a model doing this is visible in a night's report.
12738
12811
  */
12739
12812
  const answered = /* @__PURE__ */ new Set();
12813
+ /** This batch's dropped verdicts, so the warning below can name the spellings that failed. */
12814
+ const unresolvedKeys = [];
12740
12815
  for (const verdict of answer.verdicts) {
12741
12816
  /**
12742
12817
  * The key is resolved through the kernel, so an invented key yields no candidate and no
12743
- * write.
12818
+ * write. The CANONICAL key feeds the repeat guard, so `m1` and its label-prefixed spelling
12819
+ * `pair_m1` in one answer are one pair answered twice, not two pairs.
12744
12820
  */
12745
- const [candidate] = resolveKeys(keyed, [verdict.pairKey]);
12821
+ const pairKey = offeredKeyFor(keyed, verdict.pairKey);
12822
+ if (pairKey === void 0) {
12823
+ unresolved += 1;
12824
+ unresolvedKeys.push(verdict.pairKey);
12825
+ continue;
12826
+ }
12827
+ const [candidate] = resolveKeys(keyed, [pairKey]);
12746
12828
  if (candidate === void 0) continue;
12747
- if (answered.has(verdict.pairKey)) {
12829
+ if (answered.has(pairKey)) {
12748
12830
  duplicates += 1;
12749
12831
  continue;
12750
12832
  }
12751
- answered.add(verdict.pairKey);
12833
+ answered.add(pairKey);
12752
12834
  judged += 1;
12753
12835
  if (!assertsEdge(verdict)) continue;
12754
12836
  if (assertsContradiction(verdict)) {
@@ -12851,14 +12933,18 @@ const edgeTyping = (env) => Effect.gen(function* () {
12851
12933
  const [subject, object] = verdict.direction === "src_to_dst" ? [candidate.pair.src, candidate.pair.dst] : [candidate.pair.dst, candidate.pair.src];
12852
12934
  if (yield* stampFile(env, subject, [link(verdict.rel, hrefFor(object)), meta("memhtml-updated", env.at)])) typed += 1;
12853
12935
  }
12936
+ if (unresolvedKeys.length > 0) yield* Effect.logWarning(`sleep.llm edge-typing batch of ${batch.length} dropped ${unresolvedKeys.length} verdicts naming no offered pair (${unresolvedKeys.slice(0, 3).join(", ")}${unresolvedKeys.length > 3 ? ", …" : ""})`);
12854
12937
  }
12855
12938
  /**
12856
12939
  * The single-detection contradictions become tasks in the SAME commit as the promotions. The
12857
12940
  * sweep is gated on a night that judged its whole candidate set: `skipped` counts pairs whose
12858
12941
  * batch's call failed as well as pairs whose endpoint the tree no longer holds, and a pair the
12859
12942
  * model was never asked about must not read as a pair the model stopped contradicting.
12943
+ * `unresolved` is the same hazard from the answer side — a verdict the phase could not map to a
12944
+ * pair is a pair that was never judged, so its held-back contradiction must not close as "no
12945
+ * longer detected" over a misspelled key.
12860
12946
  */
12861
- const tasks = yield* mintContradictionTasks(env, deferred, skipped === 0);
12947
+ const tasks = yield* mintContradictionTasks(env, deferred, skipped === 0 && unresolved === 0);
12862
12948
  const counts = {
12863
12949
  candidates: candidates.length,
12864
12950
  judged,
@@ -12866,6 +12952,7 @@ const edgeTyping = (env) => Effect.gen(function* () {
12866
12952
  contradictions,
12867
12953
  promoted,
12868
12954
  skipped,
12955
+ unresolved,
12869
12956
  capped,
12870
12957
  duplicates,
12871
12958
  tasksMinted: tasks.minted,
@@ -13382,6 +13469,12 @@ const entityResolution = (env) => Effect.gen(function* () {
13382
13469
  /** Model calls that came back malformed. The sweep's precondition reads this; see below. */
13383
13470
  let callsFailed = 0;
13384
13471
  /**
13472
+ * Cluster member keys (or canonical keys) resolving to no offered member, dropped unacted. The
13473
+ * drop is the safe outcome and stays; the count makes a systematic naming pattern visible
13474
+ * instead of reading as a night in which the model proposed no merges (issue #58).
13475
+ */
13476
+ let unresolved = 0;
13477
+ /**
13385
13478
  * Every pair this night deferred to a human, as a value rather than only a count.
13386
13479
  *
13387
13480
  * This is issue #44's motivating case in one variable. The phase used to report
@@ -13493,6 +13586,8 @@ const entityResolution = (env) => Effect.gen(function* () {
13493
13586
  callsFailed += 1;
13494
13587
  continue;
13495
13588
  }
13589
+ /** This shard's unresolvable keys, so the warning below names the spellings that failed. */
13590
+ const unresolvedKeys = [];
13496
13591
  for (const cluster of clustering.clusters) {
13497
13592
  /**
13498
13593
  * A key the batch never offered resolves to nothing, so an invented member cannot become a
@@ -13500,6 +13595,9 @@ const entityResolution = (env) => Effect.gen(function* () {
13500
13595
  * canonical is outside it contradicts itself, and guessing which half was meant would be
13501
13596
  * the caller inventing a merge.
13502
13597
  */
13598
+ const droppedKeys = [...cluster.memberKeys, cluster.canonicalKey].filter((key) => offeredKeyFor(keyed, key) === void 0);
13599
+ unresolved += droppedKeys.length;
13600
+ unresolvedKeys.push(...droppedKeys);
13503
13601
  const memberNames = resolveKeys(keyed, cluster.memberKeys).map((centroid) => centroid.name);
13504
13602
  const [canonicalMember] = resolveKeys(keyed, [cluster.canonicalKey]);
13505
13603
  if (canonicalMember === void 0 || !memberNames.includes(canonicalMember.name)) continue;
@@ -13558,6 +13656,7 @@ const entityResolution = (env) => Effect.gen(function* () {
13558
13656
  });
13559
13657
  }
13560
13658
  }
13659
+ if (unresolvedKeys.length > 0) yield* Effect.logWarning(`sleep.llm entity-resolution ${entityType} batch of ${shard.length} dropped ${unresolvedKeys.length} cluster keys naming no offered member (${unresolvedKeys.slice(0, 3).join(", ")}${unresolvedKeys.length > 3 ? ", …" : ""})`);
13561
13660
  }
13562
13661
  }
13563
13662
  /**
@@ -13595,6 +13694,8 @@ const entityResolution = (env) => Effect.gen(function* () {
13595
13694
  aliasMerges,
13596
13695
  pendingCorroboration,
13597
13696
  reviewCandidates,
13697
+ callsFailed,
13698
+ unresolved,
13598
13699
  tasksMinted: 0,
13599
13700
  tasksFramed: 0,
13600
13701
  tasksDismissed: 0,
@@ -13620,7 +13721,12 @@ const entityResolution = (env) => Effect.gen(function* () {
13620
13721
  * 1. The old early return on `rewrites.size === 0` would have skipped exactly the night this
13621
13722
  * feature exists for: a night whose only outcome was deferrals is a night with no rewrites.
13622
13723
  */
13623
- const tasks = yield* mintReviewTasks(env, deferred, model !== void 0 && callsFailed === 0);
13724
+ /**
13725
+ * `unresolved === 0` joins the sweep gate for the reason `callsFailed === 0` is already in it: a
13726
+ * cluster key the phase could not map to a member is a name that was never judged, and sweeping
13727
+ * against a night that lost part of an answer closes reviews over a misspelling.
13728
+ */
13729
+ const tasks = yield* mintReviewTasks(env, deferred, model !== void 0 && callsFailed === 0 && unresolved === 0);
13624
13730
  let rewritten = 0;
13625
13731
  for (const [path, pairs] of [...rewrites.entries()].sort(([left], [right]) => left < right ? -1 : 1)) {
13626
13732
  const html = yield* readFileBytes(env, path);
@@ -14617,6 +14723,12 @@ const taskDetection = (env) => Effect.gen(function* () {
14617
14723
  let dismissed = 0;
14618
14724
  let skipped = 0;
14619
14725
  /**
14726
+ * Findings whose key resolved to no offered member, dropped unacted. The drop is the safe
14727
+ * outcome and stays; the count makes a systematic pattern visible, because a night whose every
14728
+ * finding named an unresolvable key otherwise reads as a night with no open work (issue #58).
14729
+ */
14730
+ let unresolved = 0;
14731
+ /**
14620
14732
  * Every key this night's scan SAW, whether or not it minted and whether or not it cleared the floor.
14621
14733
  * The sweep's input; see the `liveKeys.add` below for why the floor is not a filter here.
14622
14734
  */
@@ -14644,11 +14756,20 @@ const taskDetection = (env) => Effect.gen(function* () {
14644
14756
  * because it is called one key at a time here — a finding names one member.
14645
14757
  */
14646
14758
  const answered = /* @__PURE__ */ new Set();
14759
+ /** This batch's dropped findings, so the warning below can name the spellings that failed. */
14760
+ const unresolvedKeys = [];
14647
14761
  for (const finding of answer.findings) {
14648
- const [row] = resolveKeys(keyed, [finding.memberKey]);
14762
+ /** The CANONICAL key feeds the repeat guard, same as edge-typing's, and for the same reason. */
14763
+ const memberKey = offeredKeyFor(keyed, finding.memberKey);
14764
+ if (memberKey === void 0) {
14765
+ unresolved += 1;
14766
+ unresolvedKeys.push(finding.memberKey);
14767
+ continue;
14768
+ }
14769
+ const [row] = resolveKeys(keyed, [memberKey]);
14649
14770
  if (row === void 0) continue;
14650
- if (answered.has(finding.memberKey)) continue;
14651
- answered.add(finding.memberKey);
14771
+ if (answered.has(memberKey)) continue;
14772
+ answered.add(memberKey);
14652
14773
  findings += 1;
14653
14774
  /**
14654
14775
  * The key is the SOURCE PATH plus the normalized sentence, so the same commitment found again
@@ -14694,13 +14815,17 @@ const taskDetection = (env) => Effect.gen(function* () {
14694
14815
  else if (outcome === "framed") framed += 1;
14695
14816
  else if (outcome === "dismissed") dismissed += 1;
14696
14817
  }
14818
+ if (unresolvedKeys.length > 0) yield* Effect.logWarning(`sleep.llm task-detection batch of ${batch.length} dropped ${unresolvedKeys.length} findings naming no offered member (${unresolvedKeys.slice(0, 3).join(", ")}${unresolvedKeys.length > 3 ? ", …" : ""})`);
14697
14819
  }
14698
14820
  /**
14699
14821
  * The sweep, only from a full-strength scan. `skipped > 0` means at least one batch's memories
14700
14822
  * went unread, so a finding of theirs is missing from `liveKeys` because the phase could not look
14701
- * rather than because it is gone.
14823
+ * rather than because it is gone. `unresolved > 0` is the same hazard from the answer side: the
14824
+ * model reported a finding the phase could not map to a member, so its detection key was never
14825
+ * constructed, and sweeping against that would close a live task because the model misspelled a
14826
+ * key rather than because the finding vanished.
14702
14827
  */
14703
- const closed = skipped === 0 ? yield* closeVanishedDetections(env, TASK_DETECT_DETECTOR, liveKeys) : 0;
14828
+ const closed = skipped === 0 && unresolved === 0 ? yield* closeVanishedDetections(env, TASK_DETECT_DETECTOR, liveKeys) : 0;
14704
14829
  const counts = {
14705
14830
  candidates: candidates.length,
14706
14831
  batches: batches.length,
@@ -14712,7 +14837,8 @@ const taskDetection = (env) => Effect.gen(function* () {
14712
14837
  dismissed,
14713
14838
  closed,
14714
14839
  capped: budget.overflow,
14715
- skipped
14840
+ skipped,
14841
+ unresolved
14716
14842
  };
14717
14843
  /**
14718
14844
  * A refresh writes a `memhtml-updated` stamp, which is a staged file, so it commits — the queue's
@@ -14748,7 +14874,8 @@ const ZERO = {
14748
14874
  dismissed: 0,
14749
14875
  closed: 0,
14750
14876
  capped: 0,
14751
- skipped: 0
14877
+ skipped: 0,
14878
+ unresolved: 0
14752
14879
  };
14753
14880
 
14754
14881
  //#endregion
@@ -16861,4 +16988,4 @@ const latest = (left, right) => left === null ? right : right === null ? left :
16861
16988
 
16862
16989
  //#endregion
16863
16990
  export { STATE_DB_PATH as $, IndexRecorder as A, IndexGit as B, ModelClient as C, EmbeddingsLive as D, Embeddings as E, makeRetrieval as F, MIGRATIONS_DIR as G, sanitizeFtsQuery as H, reinforce as I, Store as J, STATE_MIGRATIONS_DIR as K, Indexer as L, persistScanned as M, readWatermark as N, EMBED_DIM as O, Retrieval as P, SLEEP_REPORTS_DIR as Q, makeIndexer as R, runDiscrimination as S, wrapAsData as T, DatabaseService as U, makeGitPort as V, makeDatabase as W, makeStore as X, expandRoot as Y, INDEX_DB_PATH as Z, meta as _, parseSidecar as a, makeGit as at, isSleepPhase as b, generateArtifacts as c, setMeta as ct, allPaths as d, fenceOpeningOf as dt, STATE_SIDECAR_PATH as et, danglingEdges as f, REINFORCE_SIGNALS as ft, link as g, hrefFor as h, makeSleep as i, Git as it, makeIndexRecorder as j, EMBED_WATERMARK as k, DETECTION_PREFIX as l, isValidDatetime as lt, applyHeadEdits as m, scanTraceRoot as n, initRepo as nt, renderSidecar as o, commitSubject as ot, publishRows as p, frameKeyOf as pt, STATE_SCHEMA as q, Sleep as r, readFileOrNull as rt, archivedFormOf as s, checkMemory as st, mergeTailExtract as t, attemptIo as tt, accessRows as u, closesFence as ut, unlink as v, ModelClientLive as w, discriminationGate as x, SLEEP_PHASES as y, readIndexState as z };
16864
- //# sourceMappingURL=dist-D5DlgqH2.mjs.map
16991
+ //# sourceMappingURL=dist-DgKlozi6.mjs.map