hippo-memory 1.35.0 → 1.37.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,qBAAqB,CAAC;AAEjE,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,OAAO,CAAC;AAEhD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,aAAa,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAwFD,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,UAAU,GAAG,IAAI,CA6BjE;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,WAAW,CAWjE;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAQ9D;AAMD,MAAM,MAAM,OAAO,GACf,UAAU,GACV,QAAQ,GACR,SAAS,GACT,WAAW,GACX,QAAQ,GACR,aAAa,GACb,aAAa,GACb,aAAa,GACb,SAAS,GACT,aAAa,GACb,aAAa,GACb,sBAAsB,GACtB,sBAAsB,GACtB,iBAAiB,GACjB,gBAAgB,GAChB,eAAe,GACf,kBAAkB,GAClB,wBAAwB,GACxB,uCAAuC,GACvC,iCAAiC,GACjC,qCAAqC,GACrC,yCAAyC,GACzC,kCAAkC,GAClC,8BAA8B,GAC9B,iBAAiB,GACjB,oBAAoB,GACpB,gBAAgB,GAChB,eAAe,GACf,kBAAkB,GAClB,gBAAgB,GAChB,gBAAgB,GAChB,mBAAmB,GACnB,eAAe,GACf,eAAe,GACf,kBAAkB,GAClB,cAAc,GACd,cAAc,GACd,iBAAiB,GACjB,aAAa,GACb,sBAAsB,GACtB,yBAAyB,GACzB,qBAAqB,GACrB,sBAAsB,GACtB,yBAAyB,GACzB,qBAAqB,GACrB,WAAW,GACX,cAAc,GACd,gBAAgB,GAChB,gBAAgB,GAChB,kBAAkB,CAAC;AAEvB,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAMlB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAoBD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,eAAe,GAAG,IAAI,CAWlF;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,UAAU,CAAC;CACtB;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,cAAc,GAAG,UAAU,EAAE,CAuCzF"}
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,qBAAqB,CAAC;AAEjE,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,OAAO,CAAC;AAEhD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,aAAa,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AA8GD,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,UAAU,GAAG,IAAI,CA6BjE;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,WAAW,CAWjE;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAQ9D;AAMD,MAAM,MAAM,OAAO,GACf,UAAU,GACV,QAAQ,GACR,SAAS,GACT,WAAW,GACX,QAAQ,GACR,aAAa,GACb,aAAa,GACb,aAAa,GACb,SAAS,GACT,aAAa,GACb,aAAa,GACb,sBAAsB,GACtB,sBAAsB,GACtB,iBAAiB,GACjB,gBAAgB,GAChB,eAAe,GACf,kBAAkB,GAClB,wBAAwB,GACxB,uCAAuC,GACvC,iCAAiC,GACjC,qCAAqC,GACrC,yCAAyC,GACzC,kCAAkC,GAClC,8BAA8B,GAC9B,iBAAiB,GACjB,oBAAoB,GACpB,gBAAgB,GAChB,eAAe,GACf,kBAAkB,GAClB,gBAAgB,GAChB,gBAAgB,GAChB,mBAAmB,GACnB,eAAe,GACf,eAAe,GACf,kBAAkB,GAClB,cAAc,GACd,cAAc,GACd,iBAAiB,GACjB,aAAa,GACb,sBAAsB,GACtB,yBAAyB,GACzB,qBAAqB,GACrB,sBAAsB,GACtB,yBAAyB,GACzB,qBAAqB,GACrB,WAAW,GACX,cAAc,GACd,gBAAgB,GAChB,gBAAgB,GAChB,kBAAkB,CAAC;AAEvB,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAMlB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAoBD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,eAAe,GAAG,IAAI,CAWlF;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,UAAU,CAAC;CACtB;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,cAAc,GAAG,UAAU,EAAE,CAuCzF"}
package/dist/audit.js CHANGED
@@ -80,9 +80,31 @@ function hasNoSpecificity(text) {
80
80
  const words = text.toLowerCase().split(/\s+/);
81
81
  const hasNumber = /\d/.test(text);
82
82
  const hasProperNoun = /[A-Z][a-z]{2,}/.test(text);
83
+ // An ACRONYM is specificity too, and this test could not see one: the
84
+ // proper-noun pattern needs lowercase after the capital, so "PR", "CI",
85
+ // "DB", "API", "S3" - the densest domain tokens in a technical memory -
86
+ // all read as vague. Surfaced by DF2: clause-bounding correctly shortened
87
+ // "The rule is every PR needs two approvals, no exceptions." to "every PR
88
+ // needs two approvals", which then fell under the 40-char vagueness gate
89
+ // and was silently DROPPED - a rule that stored before this branch.
90
+ // ...but an acronym only signals specificity when it stands out AGAINST
91
+ // ordinary prose. Without the lowercase requirement, any shouted phrase
92
+ // qualifies: "FIXED SIGNALS" passed the gate while the identical
93
+ // "fixed signals" was correctly rejected, so capitalization alone bought a
94
+ // bypass - into auditMemory and includeRecent as well, where junk would
95
+ // then occupy recent-context slots. Codex P2, r8.
96
+ // CHAT acronyms are not domain signal. Admitting any all-caps token let
97
+ // "LGTM ship it", "TODO fix this thing", "FYI all done here" through a gate
98
+ // that correctly rejected them before - and this gate is shared, so the
99
+ // effect is retroactive: junk rows already in a user's store were filtered
100
+ // out of recent-context slots and would have started occupying them, and
101
+ // `hippo audit` would have stopped flagging them. Found at the ship gate.
102
+ const CHAT_ACRONYMS = /^(?:TODO|FYI|LGTM|IIRC|IMO|IMHO|FWIW|TBD|BTW|ASAP|AFAIK|WIP|NB|PS)$/;
103
+ const domainAcronyms = (text.match(/\b[A-Z]{2,6}\b/g) ?? []).filter(a => !CHAT_ACRONYMS.test(a));
104
+ const hasAcronym = domainAcronyms.length > 0 && /[a-z]/.test(text);
83
105
  const hasPath = /[/\\.]/.test(text);
84
106
  const hasCode = /[`_{}()\[\]]/.test(text);
85
- if (hasNumber || hasProperNoun || hasPath || hasCode)
107
+ if (hasNumber || hasProperNoun || hasPath || hasCode || hasAcronym)
86
108
  return false;
87
109
  return words.length < 8 && VAGUE_ONLY.test(text);
88
110
  }
package/dist/audit.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,22 @@ export declare function captureError(exitCode: number, stderr: string, command:
13
13
  * Looks for fix:, revert:, bug:, error:, hotfix: commit messages.
14
14
  */
15
15
  export declare function extractLessons(gitLog: string, customPatterns?: string[]): string[];
16
+ /**
17
+ * Split parsed lessons into ones worth storing and low-information ones.
18
+ *
19
+ * `extractLessons` is a published API surface (exported from src/index.ts)
20
+ * and does one job: parse a git log into candidate lesson strings. Adding a
21
+ * quality check inside it would break that contract and silently change
22
+ * what external callers get back. So parsing and admission are separate
23
+ * steps: this function is the write-path gate, called by each caller that
24
+ * actually stores a lesson, not by the parser itself.
25
+ *
26
+ * Order is preserved in both output arrays.
27
+ */
28
+ export declare function partitionLessons(lessons: string[]): {
29
+ kept: string[];
30
+ dropped: string[];
31
+ };
16
32
  /**
17
33
  * Check if a substantially similar memory already exists.
18
34
  * Returns true if overlap > threshold (default 0.7).
@@ -1 +1 @@
1
- {"version":3,"file":"autolearn.d.ts","sourceRoot":"","sources":["../src/autolearn.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,WAAW,EAAuB,MAAM,aAAa,CAAC;AAI/D;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,WAAW,CAoBb;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAsClF;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,kBAAkB,EAAE,MAAM,GAAG,WAAW,EAAE,EAC1C,MAAM,EAAE,MAAM,EACd,SAAS,SAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAWT;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAwBzF;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAY9C;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAS7D"}
1
+ {"version":3,"file":"autolearn.d.ts","sourceRoot":"","sources":["../src/autolearn.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,WAAW,EAAuB,MAAM,aAAa,CAAC;AAK/D;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,WAAW,CAoBb;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAsClF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAWzF;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,kBAAkB,EAAE,MAAM,GAAG,WAAW,EAAE,EAC1C,MAAM,EAAE,MAAM,EACd,SAAS,SAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAWT;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAwBzF;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAY9C;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAS7D"}
package/dist/autolearn.js CHANGED
@@ -6,6 +6,7 @@ import { execSync, execFileSync, spawn } from 'child_process';
6
6
  import { createMemory, Layer } from './memory.js';
7
7
  import { loadAllEntries } from './store.js';
8
8
  import { textOverlap } from './search.js';
9
+ import { isContentWorthStoring } from './audit.js';
9
10
  /**
10
11
  * Create a MemoryEntry capturing a command failure.
11
12
  * Content format: "Command '<cmd>' failed: <truncated stderr>"
@@ -68,6 +69,31 @@ export function extractLessons(gitLog, customPatterns) {
68
69
  // Deduplicate exact matches at extraction time
69
70
  return [...new Set(lessons)];
70
71
  }
72
+ /**
73
+ * Split parsed lessons into ones worth storing and low-information ones.
74
+ *
75
+ * `extractLessons` is a published API surface (exported from src/index.ts)
76
+ * and does one job: parse a git log into candidate lesson strings. Adding a
77
+ * quality check inside it would break that contract and silently change
78
+ * what external callers get back. So parsing and admission are separate
79
+ * steps: this function is the write-path gate, called by each caller that
80
+ * actually stores a lesson, not by the parser itself.
81
+ *
82
+ * Order is preserved in both output arrays.
83
+ */
84
+ export function partitionLessons(lessons) {
85
+ const kept = [];
86
+ const dropped = [];
87
+ for (const lesson of lessons) {
88
+ if (isContentWorthStoring(lesson)) {
89
+ kept.push(lesson);
90
+ }
91
+ else {
92
+ dropped.push(lesson);
93
+ }
94
+ }
95
+ return { kept, dropped };
96
+ }
71
97
  /**
72
98
  * Check if a substantially similar memory already exists.
73
99
  * Returns true if overlap > threshold (default 0.7).
@@ -1 +1 @@
1
- {"version":3,"file":"autolearn.js","sourceRoot":"","sources":["../src/autolearn.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"autolearn.js","sourceRoot":"","sources":["../src/autolearn.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA4BH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AA0HD;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAoC7D;AAuFD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,cAAc,CAAC;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA0BD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAqFzD;AAED;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,MAAM,GAAG,IAAI,CAuCf;AAED,wBAAgB,UAAU,CACxB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,GACtB,IAAI,CAgBN;AAyPD,oFAAoF;AACpF,eAAO,MAAM,sBAAsB,QAAa,CAAC;AAEjD,eAAO,MAAM,oBAAoB,MAAM,CAAC;AACxC,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAC5C,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQ5E;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQzE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,GAAE,MAA+B,GAAG,MAAM,CA4B5G;AA8DD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAG1D;AAqOD,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAQD;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBhG"}
1
+ {"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA4BH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AA6YD;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAoC7D;AAuFD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,cAAc,CAAC;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA0BD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAqFzD;AAED;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,MAAM,GAAG,IAAI,CAuCf;AAED,wBAAgB,UAAU,CACxB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,GACtB,IAAI,CAgBN;AAyPD,oFAAoF;AACpF,eAAO,MAAM,sBAAsB,QAAa,CAAC;AAEjD,eAAO,MAAM,oBAAoB,MAAM,CAAC;AACxC,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAC5C,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQ5E;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQzE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,GAAE,MAA+B,GAAG,MAAM,CA4B5G;AA8DD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAG1D;AAqOD,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAQD;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBhG"}
package/dist/capture.js CHANGED
@@ -22,29 +22,51 @@ import { redactSecrets } from './secret-detect.js';
22
22
  import { RejectedValueError, checkRejectionGuard } from './rejection.js';
23
23
  import { openHippoDb, closeHippoDb } from './db.js';
24
24
  // Sentence-level patterns
25
+ //
26
+ // T1 (DF2): each pattern now carries TWO capture groups — group 1 is the
27
+ // discriminating keyword (plus its trailing separator, verbatim), group 2 is
28
+ // the content that follows it. Previously only the after-keyword content was
29
+ // captured, so a negation like "never" / "must not" was discarded and a
30
+ // prohibition inverted into an instruction ("Never use X" stored as "use X").
31
+ // `extractFromPatterns` reassembles group1 + a clause-bounded group2 (T2, via
32
+ // `boundToClause` below) rather than reading a single fixed-width group —
33
+ // group 2's own reach is widened to {1,500} because the true stopping point
34
+ // is now found by content, not counted characters. Keeping the keyword in
35
+ // its own group (rather than folding it into one bigger capture) matters:
36
+ // `boundToClause` must scan for a clause boundary only in group 2, never in
37
+ // group 1 — several keywords end in their own colon ("error:", "rule:",
38
+ // "decision:") which is not a clause boundary in the prose sense and would
39
+ // wrongly truncate the capture down to just the keyword if scanned.
40
+ // `PREFERENCE_PATTERNS[0]` is the one exception — its two-capture-group
41
+ // shape means something different (two content spans either side of
42
+ // "instead of"/"over"/"not") and is a separate, backlogged defect (see
43
+ // docs/plans/2026-08-23-df2-capture-anchoring.md); left as-is.
25
44
  const DECISION_PATTERNS = [
26
- /(?:we(?:'ve| have)?|i(?:'ve| have)?|let's)\s+decid(?:ed|e)\s+(?:to\s+)?(.{10,200})/i,
27
- /(?:let's|we(?:'ll| will| should)?)\s+(?:go with|do|use|try|build|implement|switch to)\s+(.{5,200})/i,
28
- /(?:going|went)\s+with\s+(.{5,200})/i,
29
- /(?:the plan is|plan:)\s+(.{10,200})/i,
30
- /decision:\s*(.{10,200})/i,
45
+ /(?:we(?:'ve| have)?|i(?:'ve| have)?|let's)\s+(decid(?:ed|e)\s+(?:to\s+)?)(.{1,500})/i,
46
+ /(?:let's|we(?:'ll| will| should)?)\s+((?:go with|do|use|try|build|implement|switch to)\s+)(.{1,500})/i,
47
+ /((?:going|went)\s+with\s+)(.{1,500})/i,
48
+ /((?:the plan is|plan:)\s+)(.{1,500})/i,
49
+ /(decision:\s*)(.{1,500})/i,
31
50
  ];
32
51
  const RULE_PATTERNS = [
33
- /(?:never|always|must(?:\s+not)?|do(?:n't| not)\s+ever)\s+(.{5,200})/i,
34
- /(?:the rule is|rule:)\s*(.{5,200})/i,
35
- /(?:important|critical|remember):\s*(.{10,200})/i,
36
- /(?:make sure|ensure)\s+(?:to\s+)?(.{10,200})/i,
52
+ /((?:never|always|must(?:\s+not)?|do(?:n't| not)\s+ever)\s+)(.{1,500})/i,
53
+ /((?:the rule is|rule:)\s*)(.{1,500})/i,
54
+ /((?:important|critical|remember):\s*)(.{1,500})/i,
55
+ /((?:make sure|ensure)\s+(?:to\s+)?)(.{1,500})/i,
37
56
  ];
38
57
  const ERROR_PATTERNS = [
39
- /(?:error|bug|gotcha|watch out|careful|warning|caveat|trap):\s*(.{10,200})/i,
40
- /(?:this broke|this breaks|this will break|broke because)\s+(.{5,200})/i,
41
- /(?:the (?:issue|problem|fix) (?:is|was))\s+(.{10,200})/i,
42
- /(?:don't forget|easy to miss):\s*(.{5,200})/i,
58
+ /((?:error|bug|gotcha|watch out|careful|warning|caveat|trap):\s*)(.{1,500})/i,
59
+ /((?:this broke|this breaks|this will break|broke because)\s+)(.{1,500})/i,
60
+ /((?:the (?:issue|problem|fix) (?:is|was))\s+)(.{1,500})/i,
61
+ /((?:don't forget|easy to miss):\s*)(.{1,500})/i,
43
62
  ];
63
+ // PREFERENCE_PATTERNS[0] keeps its pre-DF2 two-capture-group shape
64
+ // (match[1]-only, unbounded) — out of scope here, backlogged. See
65
+ // extractFromPatterns' reference check against this exact array element.
44
66
  const PREFERENCE_PATTERNS = [
45
67
  /(?:prefer|use)\s+(.{5,100})\s+(?:instead of|over|not)\s+(.{3,100})/i,
46
- /(?:don't use|avoid|skip)\s+(.{5,200})/i,
47
- /(?:we(?:'re| are)\s+using|the stack is|we use)\s+(.{5,200})/i,
68
+ /((?:don't use|avoid|skip)\s+)(.{1,500})/i,
69
+ /((?:we(?:'re| are)\s+using|the stack is|we use)\s+)(.{1,500})/i,
48
70
  ];
49
71
  // Heading patterns that signal a following list of specs/requirements
50
72
  const SPEC_HEADING_PATTERNS = [
@@ -61,19 +83,280 @@ function splitSentences(text) {
61
83
  .map((s) => s.trim())
62
84
  .filter((s) => s.length > 5);
63
85
  }
86
+ /**
87
+ * T2 (DF2): bound a keyword+content capture to its clause instead of a fixed
88
+ * character count. `full` is `keywordPrefix + content` (already concatenated
89
+ * so the 200-char ceiling below applies to the whole stored string, not just
90
+ * the part after the keyword); `searchFrom` is `keywordPrefix.length`, so the
91
+ * clause/terminator scan only ever looks INSIDE `content` — several keywords
92
+ * end in their own colon ("error:", "rule:", "decision:") which must never
93
+ * be mistaken for a clause boundary in the prose that follows.
94
+ *
95
+ * Stops at the first `,`/`;`/`:` followed by whitespace, or at a sentence
96
+ * terminator `[.!?]` followed by whitespace or end-of-string — whichever
97
+ * comes first — and never past `maxLen` chars total.
98
+ *
99
+ * The whitespace requirement on the terminator is load-bearing: a bare
100
+ * `[.!?]` would split inside a token like `.env` / `capture.ts` / `v1.35.0`,
101
+ * turning a full clause into a fragment that then fails the write gate and
102
+ * is silently dropped (measured in the plan). The `maxLen` ceiling is also
103
+ * load-bearing: without it, a clause-free span can run past the 500-char
104
+ * gate in `extractFromPatterns` and the whole match is dropped, where today
105
+ * it is truncated and stored.
106
+ */
107
+ /**
108
+ * Does a plausible CLOSING single quote appear after `from`? Mirror of the
109
+ * opener rule in `boundToClause`: a closer sits tight against the literal it
110
+ * ends (non-whitespace before) and is followed by whitespace, punctuation, or
111
+ * end-of-string - never by a letter, which is what makes "user's" an
112
+ * apostrophe rather than a partner.
113
+ */
114
+ function isLetterOrDigit(ch) {
115
+ return ch !== undefined && /[\p{L}\p{N}]/u.test(ch);
116
+ }
117
+ function lastCloserIndex(full) {
118
+ // ONE pass, not one per apostrophe. The previous shape rescanned the whole
119
+ // remaining suffix at every boundary apostrophe, so a transcript full of
120
+ // elisions ("keep 'em", "wait 'til", ...) made extraction quadratic and
121
+ // could stall a moderately sized capture. Codex P2, r7.
122
+ //
123
+ // A quote CLOSES THE SIDE IT IS TIGHT AGAINST. The test needs both
124
+ // neighbours, and one round proved that empirically: these two have the
125
+ // same following character and opposite roles -
126
+ // "preserve 'a, b'-style" next '-' -> CLOSER, content on the left
127
+ // "then run '--force," next '-' -> OPENER, content on the right
128
+ // so no forward-only rule can separate them. An earlier revision tried
129
+ // exactly that and broke in both directions at once (codex P1+P2, r10):
130
+ // it missed closers before token-joining punctuation and accepted
131
+ // "'.env" as a closer because a dot happened to be in its class.
132
+ //
133
+ // never a closer next is a letter/digit "user's", "keep 'em"
134
+ // closer prev is non-whitespace "'a, b' to", "'a, b'-style"
135
+ // closer next is whitespace or end "preserve 'a, b ' exactly"
136
+ // closer next is clause punctuation "preserve 'a, b ', then"
137
+ // that itself ends the token
138
+ //
139
+ // The last clause is what separates ", " from ".env": a dot followed by a
140
+ // letter joins a filename, a dot followed by space ends a sentence.
141
+ for (let j = full.length - 1; j >= 0; j--) {
142
+ if (full[j] !== "'")
143
+ continue;
144
+ const prev = full[j - 1];
145
+ const next = full[j + 1];
146
+ if (isLetterOrDigit(next))
147
+ continue;
148
+ // "tight against content" excludes an OPENING delimiter: in
149
+ // "call parse('--force" the paren is non-whitespace but the quote after
150
+ // it is an opener, and treating it as a closer let an earlier elision
151
+ // pair across the clause boundary. Codex P2, r11.
152
+ const tightBefore = prev !== undefined && !/[\s([{]/.test(prev);
153
+ const endsAfter = next === undefined || /\s/.test(next);
154
+ // Punctuation splits in two, and this is the fact the last three
155
+ // revisions kept rediscovering piecemeal:
156
+ // , ; : ! ? ) ] } never join tokens - they end the literal whatever
157
+ // follows, so "'echo a, b ';then" closes at the ;
158
+ // . - _ / @ # DO join tokens - "'.env" and "'--force" continue a
159
+ // filename or flag, so these only close when trailed
160
+ // by whitespace
161
+ const afterNext = full[j + 2];
162
+ const closesRegardless = next !== undefined && /[,;:!?)\]}]/.test(next);
163
+ const joinerThenSpace = next !== undefined && /[.\-_/@#]/.test(next) &&
164
+ (afterNext === undefined || /\s/.test(afterNext));
165
+ if (tightBefore || endsAfter || closesRegardless || joinerThenSpace)
166
+ return j;
167
+ }
168
+ return -1;
169
+ }
170
+ function boundToClause(full, searchFrom, maxLen = 200) {
171
+ // Scan for the first PROSE clause boundary after `searchFrom`.
172
+ //
173
+ // Depth-awareness is not a nicety here: hippo memories are full of code, and
174
+ // a naive scan reintroduces the exact fragment defect this whole change
175
+ // exists to remove. Measured before this guard existed:
176
+ // "Always call build(x, y) before deploy." -> "Always call build(x"
177
+ // "Never pass {a: 1, b: 2} to the writer." -> "Never pass {a"
178
+ // Both then PASS the write gate, because they contain code punctuation and
179
+ // so read as "specific" — a malformed fragment stored with high confidence.
180
+ // Codex review finding (P1) on this branch.
181
+ //
182
+ // So: a separator only ends the clause at bracket depth zero and outside
183
+ // quotes. Unbalanced closers are tolerated (depth floors at 0) because
184
+ // captured text often starts mid-expression.
185
+ const lastCloser = lastCloserIndex(full);
186
+ let depth = 0;
187
+ let quote = null;
188
+ let cutEnd = full.length;
189
+ for (let i = searchFrom; i < full.length; i++) {
190
+ const ch = full[i];
191
+ if (quote) {
192
+ // Closing uses the SAME shape test as opening. This was asymmetric:
193
+ // twelve rounds went into deciding when a quote OPENS a literal, while
194
+ // the close accepted any bare "'" - so the apostrophe in a possessive
195
+ // INSIDE a literal closed it early:
196
+ // "Always pass 'user's a, b list' to the parser."
197
+ // -> "Always pass 'user's a" (master kept the whole literal)
198
+ // a mid-literal fragment that then PASSES the write gate, which is
199
+ // precisely the defect this branch exists to remove. Found by the
200
+ // ship-gate review after every earlier gate missed it.
201
+ if (ch === quote && (quote !== "'" || !isLetterOrDigit(full[i + 1]))) {
202
+ quote = null;
203
+ }
204
+ continue;
205
+ }
206
+ // Quote handling has to tell an APOSTROPHE from a single-quoted
207
+ // LITERAL, because getting either wrong reintroduces the fragment
208
+ // defect this change exists to remove, and both fragments PASS the
209
+ // write gate (code punctuation reads as "specific"):
210
+ // treat every ' as a quote -> "Always ensure it's enabled, then
211
+ // restart..." never leaves quote mode, bounding disabled entirely
212
+ // treat no ' as a quote -> "Always pass 'a, b' to the parser."
213
+ // cuts at the comma and stores "Always pass 'a"
214
+ // Both were codex P1s on this branch, in consecutive rounds.
215
+ //
216
+ // Discriminator: a ' OPENS a literal only at a word boundary - preceded
217
+ // by start/whitespace/open-bracket AND followed by non-whitespace. An
218
+ // in-word apostrophe ("it's", "user's") has letters on both sides and is
219
+ // just a character.
220
+ if (ch === '"' || ch === '`') {
221
+ quote = ch;
222
+ continue;
223
+ }
224
+ if (ch === "'") {
225
+ const prev = i > 0 ? full[i - 1] : undefined;
226
+ const next = full[i + 1];
227
+ const atBoundary = (prev === undefined || /[\s([{]/.test(prev)) &&
228
+ next !== undefined && !/\s/.test(next);
229
+ // Pairing is VERIFIED, not assumed. A word-boundary test alone still
230
+ // opens quote mode on elided forms ("keep 'em", "wait 'til"), which
231
+ // have no closer, so the scanner never leaves quote mode and bounding
232
+ // is disabled for the rest of the capture. Requiring an actual closing
233
+ // quote later in the string replaces a guess with a checkable fact -
234
+ // an elided form simply has no partner. Codex P2, this round.
235
+ // ...and the partner must LOOK like a closer, not merely be another
236
+ // apostrophe. Distance cannot separate the two cases - both put a `'`
237
+ // far downstream:
238
+ // "Always pass '<600-char literal>' to the parser" -> the far ' IS
239
+ // the closer, and pairing must succeed
240
+ // "keep 'em enabled, then <520 chars> check user's config" -> the far
241
+ // ' is in-word, and pairing against it re-opens quote mode on the
242
+ // elision, disabling bounding for the rest of the capture
243
+ // So apply the SAME shape rule already used to open a literal, mirrored:
244
+ // a closer has non-whitespace before it and whitespace/punctuation (not
245
+ // a letter) after. "user's" fails it on both counts. Codex P2, r6.
246
+ if (atBoundary && lastCloser > i) {
247
+ quote = ch;
248
+ }
249
+ continue;
250
+ }
251
+ if (ch === '(' || ch === '[' || ch === '{') {
252
+ depth++;
253
+ continue;
254
+ }
255
+ if (ch === ')' || ch === ']' || ch === '}') {
256
+ if (depth > 0)
257
+ depth--;
258
+ continue;
259
+ }
260
+ if (depth > 0)
261
+ continue;
262
+ const next = full[i + 1];
263
+ // Prose clause separator: , ; : followed by whitespace.
264
+ if ((ch === ',' || ch === ';' || ch === ':') && next !== undefined && /\s/.test(next)) {
265
+ cutEnd = i;
266
+ break;
267
+ }
268
+ // Sentence terminator, but only when followed by whitespace or end — a
269
+ // bare [.!?] splits inside .env, capture.ts, v1.35.0.
270
+ if ((ch === '.' || ch === '!' || ch === '?') && (next === undefined || /\s/.test(next))) {
271
+ cutEnd = i + 1;
272
+ break;
273
+ }
274
+ }
275
+ let bounded = full.slice(0, cutEnd);
276
+ if (bounded.length > maxLen)
277
+ bounded = bounded.slice(0, maxLen);
278
+ return bounded;
279
+ }
64
280
  function cleanExtract(raw) {
65
- return raw
281
+ let content = raw
66
282
  .replace(/^[:\s-]+/, '')
67
283
  .replace(/[.!?,;:\s]+$/, '')
68
284
  .trim();
285
+ // T2 trailing cleanup: clause-bounding can cut inside a parenthetical and
286
+ // leave an unmatched trailing ')' (e.g. "...(two had never got entries),"
287
+ // bounds to "never got entries)"). Strip a trailing ')' ONLY while closes
288
+ // outnumber opens in the string so far — a balanced parenthetical like
289
+ // "always run the suite (twice)" must be left intact.
290
+ while (content.endsWith(')')) {
291
+ const opens = (content.match(/\(/g) ?? []).length;
292
+ const closes = (content.match(/\)/g) ?? []).length;
293
+ if (closes <= opens)
294
+ break;
295
+ content = content
296
+ .slice(0, -1)
297
+ .replace(/[.!?,;:\s]+$/, '')
298
+ .trim();
299
+ }
300
+ return content;
69
301
  }
70
302
  function extractFromPatterns(sentence, patterns, category, tag) {
71
303
  for (const pat of patterns) {
72
- const match = sentence.match(pat);
304
+ // `d` gives per-group offsets; see the contentStart comment below.
305
+ const dpat = pat.flags.includes('d') ? pat : new RegExp(pat.source, pat.flags + 'd');
306
+ const match = dpat.exec(sentence);
73
307
  if (match) {
74
- // Use the captured group if available, otherwise the full match
75
- const raw = match[1] ?? match[0];
76
- const content = cleanExtract(raw);
308
+ let bounded;
309
+ if (pat === PREFERENCE_PATTERNS[0]) {
310
+ // PREFERENCE_PATTERNS[0] is the one pattern left out of T1/T2 (see
311
+ // comment at its definition) — its match[1] keeps its pre-DF2,
312
+ // unbounded shape rather than going through clause-bounding.
313
+ bounded = match[1] ?? match[0];
314
+ }
315
+ else {
316
+ // group1 = keyword + separator (verbatim, never clause-bounded);
317
+ // group2 = the content that follows it (clause-bounded below).
318
+ //
319
+ // T1 preserves the keyword only when it carries SEMANTIC SIGN — a
320
+ // negation or modality ("never", "must not", "do not ever",
321
+ // "always"). Dropping those inverts the meaning, which is the whole
322
+ // point of T1. A LABEL keyword ("decision:", "rule:", "error:",
323
+ // "important:") carries no sign: it only names the category, which
324
+ // is already recorded in `category`/`tags`, so prefixing it onto the
325
+ // content is duplication that also breaks value-keyed matching
326
+ // (AT1's rejected-value digest hashes the bare content).
327
+ // Discriminator: a label ends in its own colon, or is a "the X is"
328
+ // phrase.
329
+ const rawPrefix = match[1] ?? '';
330
+ // ONLY colon-terminated labels are dropped. Dropping "the X is/was"
331
+ // too left the residue starting with "to ", which isFragment then
332
+ // rejected outright - so "The plan is to ship on Friday" and "The fix
333
+ // was to bump the pool timeout" stored NOTHING, where every prior
334
+ // version stored them. Silent loss on two of the highest-traffic
335
+ // patterns, and invisible: an absent memory leaves no trace. The AT1
336
+ // rejected-value evidence only ever involved colon labels
337
+ // ("decision: "), so the narrower rule keeps that guarantee.
338
+ const isLabelPrefix = /:\s*$/.test(rawPrefix);
339
+ const keywordPrefix = isLabelPrefix ? '' : rawPrefix;
340
+ // Scan the UNTRUNCATED remainder, not match[2]. The patterns cap
341
+ // their content group at 500 chars, so a quoted literal whose closer
342
+ // sits past that point had no visible partner and the pairing check
343
+ // read the opener as prose - cutting inside the literal. That was a
344
+ // blindness built into the scanner's INPUT, not a bad predicate, so
345
+ // no further predicate could have fixed it. boundToClause already
346
+ // caps its OUTPUT at maxLen, so widening the input costs nothing and
347
+ // makes pairing decidable on the whole sentence. Codex P2, round 5.
348
+ // Group 2's REAL offset, read from the regex engine. Deriving it as
349
+ // `match.index + rawPrefix.length` assumes group 1 starts the match,
350
+ // but DECISION_PATTERNS carry an uncaptured subject ("we ", "let's ")
351
+ // ahead of it - so the offset landed inside the keyword and the
352
+ // widened slice duplicated text: "We decided to pin..." stored as
353
+ // "decided to to pin...". Real corruption of the commonest decision
354
+ // capture, shipped in the previous commit. Codex P1, r6.
355
+ const contentStart = match.indices?.[2]?.[0] ?? -1;
356
+ const afterKeyword = contentStart >= 0 ? sentence.slice(contentStart) : (match[2] ?? match[0]);
357
+ bounded = boundToClause(keywordPrefix + afterKeyword, keywordPrefix.length);
358
+ }
359
+ const content = cleanExtract(bounded);
77
360
  if (content.length >= 8 && content.length <= 500) {
78
361
  return { content, category, tags: [tag, 'captured'] };
79
362
  }