@nxuss/lemma 1.15.0 → 1.16.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.
package/README.md CHANGED
@@ -41,7 +41,10 @@ lemma start # gateway + dashboard on http://localhost:8081
41
41
  one. Memories can depend on other memories (`derivedFrom`) and inherit their staleness
42
42
  transitively; `verify_memory` batch-revalidates a set of ids by hash-compare alone, no search
43
43
  round trip; `semanticDiff` tells a comment/formatting-only edit apart from a real one so
44
- reformatting a file doesn't falsely invalidate what was learned about it. Ranking factors in
44
+ reformatting a file doesn't falsely invalidate what was learned about it. Write tools
45
+ (`surgical_ast_insert`, `apply_workspace_patch`, `write_workspace_file`) warn proactively when
46
+ the code they're about to touch has dependent memories — including a documented failed
47
+ attempt — instead of only finding out on the next search. Ranking factors in
45
48
  real usage (`hits`), explicit negative feedback (`downvote_memory`), and `cognitive_map` domain
46
49
  tags; a passing `test_oracle` run over an uncommitted diff auto-captures itself; two memories
47
50
  about the same symbol that disagree on outcome are flagged, not silently both suggested.
@@ -2102,7 +2102,8 @@ async function handleWriteWorkspaceFile(args) {
2102
2102
  fs_1.default.mkdirSync(dir, { recursive: true });
2103
2103
  }
2104
2104
  fs_1.default.writeFileSync(resolved, content, "utf8");
2105
- return { content: [{ type: "text", text: `Success: Written file to ${filePath}` }] };
2105
+ const blastRadius = formatBlastRadiusNote((0, TheBrainV2_1.getBrain)().findBlastRadius(filePath));
2106
+ return { content: [{ type: "text", text: `Success: Written file to ${filePath}${blastRadius}` }] };
2106
2107
  }
2107
2108
  catch (err) {
2108
2109
  (0, utils_1.logError)("write_workspace_file", err);
@@ -2153,6 +2154,24 @@ function stripLineNumberGutter(text) {
2153
2154
  }
2154
2155
  // Splices one resolved match into the file and writes it. Shared by the normal
2155
2156
  // single-match path and the ambiguous-match-resolved-via-elicitation path below.
2157
+ /**
2158
+ * Fase E — blast radius. Purely advisory text appended to a write tool's success response:
2159
+ * which Brain memories (direct or derived via Fase B's derivedFrom) depend on the
2160
+ * file/symbol just written, and which of those document a documented FAILED attempt. Never
2161
+ * blocks the write and never mutates anything — the next search_memory/verify_memory call
2162
+ * already re-checks freshness lazily; this only surfaces the same signal earlier, at the
2163
+ * moment it's cheapest to act on.
2164
+ */
2165
+ function formatBlastRadiusNote(result) {
2166
+ if (result.hits.length === 0)
2167
+ return "";
2168
+ const ids = result.hits.map((h) => h.id).join(", ");
2169
+ const base = `\n📎 ${result.hits.length} memor${result.hits.length === 1 ? "y" : "ies"} in the Brain depend on this and will go stale: ${ids}. They'll re-verify next time they're searched.`;
2170
+ if (result.failedHits.length === 0)
2171
+ return base;
2172
+ const failedIds = result.failedHits.map((h) => h.id).join(", ");
2173
+ return `${base}\n⚠️ ${result.failedHits.length} of those document a PRIOR ATTEMPT THAT FAILED on related code: ${failedIds}. Review before continuing down this path.`;
2174
+ }
2156
2175
  async function applyMatch(match, filePath, resolved, originalContent, searchContent, replaceContent) {
2157
2176
  let updatedContent;
2158
2177
  if (match.strategy === "exact" && match.charStart !== undefined && match.charEnd !== undefined) {
@@ -2173,7 +2192,8 @@ async function applyMatch(match, filePath, resolved, originalContent, searchCont
2173
2192
  }
2174
2193
  fs_1.default.writeFileSync(resolved, updatedContent, "utf8");
2175
2194
  const note = match.strategy === "exact" ? "" : ` (matched via ${match.strategy}, score ${match.score.toFixed(2)})`;
2176
- return { content: [{ type: "text", text: `Success: Patch successfully applied to ${filePath}${note}` }] };
2195
+ const blastRadius = formatBlastRadiusNote((0, TheBrainV2_1.getBrain)().findBlastRadius(filePath));
2196
+ return { content: [{ type: "text", text: `Success: Patch successfully applied to ${filePath}${note}${blastRadius}` }] };
2177
2197
  }
2178
2198
  async function handleApplyWorkspacePatch(args) {
2179
2199
  const filePath = args?.filePath;
@@ -5157,10 +5177,11 @@ async function handleSurgicalAstInsert(args) {
5157
5177
  toolName: "surgical_ast_insert",
5158
5178
  filePath
5159
5179
  });
5180
+ const blastRadius = formatBlastRadiusNote((0, TheBrainV2_1.getBrain)().findBlastRadius(filePath, symbolName || anchorSymbol));
5160
5181
  return {
5161
5182
  content: [{
5162
5183
  type: "text",
5163
- text: `Success: Surgically inserted code into ${filePath} using AST compiler.`
5184
+ text: `Success: Surgically inserted code into ${filePath} using AST compiler.${blastRadius}`
5164
5185
  }]
5165
5186
  };
5166
5187
  }