engineering-memory 1.6.0 → 1.6.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "engineering-memory",
3
- "version": "1.6.0",
3
+ "version": "1.6.1",
4
4
  "description": "Installs the Engineering Memory skill and its local MCP bridge. Sign in after installing; your organization and project are resolved from your account.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -312,13 +312,19 @@ export class BridgeService {
312
312
  resumeIdentityMatches &&
313
313
  conflicts.every(isOfflineDevelopmentWarning) &&
314
314
  isOfflineLeaseUsable(resumedLease, sessionId, pointer?.changeBaseline?.leasePaths ?? [], pointer?.changeBaseline?.diffHash);
315
- const resumedBaseline = pointer?.taskId === backendTask.id &&
316
- pointer.sessionId === sessionId &&
317
- pointer.changeBaseline &&
318
- (resumedLease?.baselineDiffHash === pointer.changeBaseline.diffHash ||
319
- objectValue(backend.verificationRecovery)?.diffHash === repository.git.diffHash)
315
+ const localBaseline = pointer?.taskId === backendTask.id && pointer.sessionId === sessionId
320
316
  ? pointer.changeBaseline
321
317
  : undefined;
318
+ const recordedBaselineDiffHash = typeof backend.changeBaselineDiffHash === 'string'
319
+ ? backend.changeBaselineDiffHash
320
+ : undefined;
321
+ const repairedBaseline = repairChangeBaseline(localBaseline, recordedBaselineDiffHash, repository.git.head);
322
+ const resumedBaseline = repairedBaseline ?? localBaseline;
323
+ if (recordedBaselineDiffHash &&
324
+ resumedBaseline &&
325
+ resumedBaseline.diffHash !== recordedBaselineDiffHash) {
326
+ conflicts.push('task_change_baseline_recaptured');
327
+ }
322
328
  const resumedLastSequence = responseSource === 'stale_cache' && pointer
323
329
  ? Math.max(pointer.lastSequence, numericSequence(backendTask.lastSequence), localJournal.projection?.appliedEventIds.length ?? 0)
324
330
  : numericSequence(backendTask.lastSequence);
@@ -2372,6 +2378,20 @@ function isOfflineLeaseUsable(lease, sessionId, changedPaths, baselineDiffHash)
2372
2378
  return false;
2373
2379
  }
2374
2380
  }
2381
+ function repairChangeBaseline(local, recordedDiffHash, head) {
2382
+ if (!recordedDiffHash || local?.diffHash === recordedDiffHash)
2383
+ return undefined;
2384
+ if (sha256(`${head ?? '<unborn>'}
2385
+ ${stableStringify([])}
2386
+ `) !== recordedDiffHash) {
2387
+ return undefined;
2388
+ }
2389
+ return {
2390
+ diffHash: recordedDiffHash,
2391
+ changedPaths: [],
2392
+ leasePaths: local?.leasePaths ?? [],
2393
+ };
2394
+ }
2375
2395
  function isOfflineDevelopmentWarning(value) {
2376
2396
  return (value === 'backend_resume_is_stale' ||
2377
2397
  value === 'pending_outbox_delivery' ||
@@ -95,6 +95,22 @@ Where the same product has a client and a backend, they are two projects. Adopt
95
95
  then link them with `project.link` once both exist, and ask before linking rather than inferring it
96
96
  from the names.
97
97
 
98
+ ## The Task Baseline
99
+
100
+ A write task's baseline is the tree it started from, and every changed path it reports is the
101
+ difference between that tree and the current one. It is captured once, at the first change
102
+ preparation, and it is never re-captured — a baseline taken again halfway through a task equals the
103
+ finished work, and from then on the task reports the two or three files touched since instead of
104
+ everything it did. Verification then refuses the true path list, and reporting the short one would
105
+ record a task that did something it did not do.
106
+
107
+ `session.resume` therefore carries the baseline through a lease going stale, expiring, or being
108
+ replaced, and repairs one that has already drifted when the backend's record of the original can be
109
+ proved against the current commit. When it cannot prove it, resume reports
110
+ `task_change_baseline_recaptured`. Do not work around that conflict by reporting a shorter path
111
+ list, and do not edit the pointer file: say what happened, and let the user decide between
112
+ reopening the task and abandoning it.
113
+
98
114
  ## Change Preparation
99
115
 
100
116
  Skip change preparation for a read-only task. Do not request an edit lease, send changed paths, record `pre_edit`, or reconcile code resources in that mode. If the user later authorizes a change, call `context.prepare_change` with `transitionToWrite: true`, the bridge-owned current task version, intended paths, and current baseline diff. Continue only after the bridge returns the updated write task and lease.