@agfpd/iapeer-memory-core 0.3.0 → 0.3.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/memoryd.ts +23 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agfpd/iapeer-memory-core",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "iapeer-memory core — host-neutral TypeScript memory primitive: vault schema/taxonomy config, search engine, memoryd, context renderer, role contracts. Consumed by the @agfpd/iapeer-memory facade; version kept in lockstep by its release flow (docs/10-distribution.md).",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/memoryd.ts CHANGED
@@ -667,6 +667,19 @@ export type MemorydHandle = {
667
667
  close: () => Promise<void>;
668
668
  };
669
669
 
670
+ /**
671
+ * Whether a note's frontmatter already carries a non-empty `author`. The
672
+ * first-sight guard uses it to tell a SETTLED note (has author — never
673
+ * re-stamp it at startup) from a genuinely NEW one (a human's bare-body canon
674
+ * note with no author yet — fill it on its first event, §9). No frontmatter →
675
+ * bare → not settled.
676
+ */
677
+ function hasAuthorField(content: string): boolean {
678
+ const fm = /^---[^\S\n]*\n([\s\S]*?)\n---[^\S\n]*(?:\n|$)/.exec(content);
679
+ if (!fm) return false;
680
+ return /^author\s*:\s*\S/m.test(fm[1]);
681
+ }
682
+
670
683
  export async function startMemoryd(opts: MemorydOptions): Promise<MemorydHandle> {
671
684
  const { config } = opts;
672
685
  const logger = opts.logger ?? makeLogger("memoryd");
@@ -982,15 +995,16 @@ export async function startMemoryd(opts: MemorydOptions): Promise<MemorydHandle>
982
995
  } catch {
983
996
  continue; // deleted mid-debounce
984
997
  }
985
- // FIRST-SIGHT GUARD (churn-дефект B-приёмки, boris п.3): путь, которого
986
- // нет в hash-базе — это ПЕРВОЕ наблюдение (старт демона над уже
987
- // населённым vault), НЕ обязательно человеческая правка. Запиши
988
- // baseline и не стампь: иначе старт массово штампует все существующие
989
- // ноты как «правки человека». (Размещений Индексом больше нет — инбокс
990
- // устранён; единственный источник never-seen-путей старт/новый файл.)
991
- // ЦЕНА (§9-край, на живой приёмке): свежая bare-body заметка человека
992
- // достраивается со ВТОРОГО fs-события первое лишь пишет baseline.
993
- if (!lastSeenHashes.has(filePath)) {
998
+ // FIRST-SIGHT GUARD (churn-дефект B-приёмки, boris п.3 + §9-фикс 0.3.1):
999
+ // путь, которого нет в hash-базе — это ПЕРВОЕ наблюдение. Если у ноты
1000
+ // УЖЕ есть author она SETTLED (старт демона над населённым vault, или
1001
+ // любая атрибутированная нота): запиши baseline и НЕ стампь (load-bearing
1002
+ // инвариант старт никогда не перештамповывает существующие ноты).
1003
+ // Нота БЕЗ authorгенуинно новая: голое тело человека прямо в канон —
1004
+ // проваливается в fill ниже и достраивается на ЭТОМ первом событии (§9:
1005
+ // голое тело человека достраивается, не откладывается до второго).
1006
+ // (Размещений Индексом больше нет — инбокс устранён.)
1007
+ if (!lastSeenHashes.has(filePath) && hasAuthorField(content)) {
994
1008
  lastSeenHashes.set(filePath, sha256(content));
995
1009
  continue;
996
1010
  }