@codyswann/lisa 2.297.4 → 2.297.6

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 (137) hide show
  1. package/all/copy-contents/.gitattributes +9 -0
  2. package/dist/cli/gate-commands.d.ts +22 -3
  3. package/dist/cli/gate-commands.d.ts.map +1 -1
  4. package/dist/cli/gate-commands.js +49 -1
  5. package/dist/cli/gate-commands.js.map +1 -1
  6. package/dist/cli/install-merge-driver-cmd.d.ts +21 -0
  7. package/dist/cli/install-merge-driver-cmd.d.ts.map +1 -0
  8. package/dist/cli/install-merge-driver-cmd.js +37 -0
  9. package/dist/cli/install-merge-driver-cmd.js.map +1 -0
  10. package/dist/cli/merge-learnings-cmd.d.ts +24 -0
  11. package/dist/cli/merge-learnings-cmd.d.ts.map +1 -0
  12. package/dist/cli/merge-learnings-cmd.js +82 -0
  13. package/dist/cli/merge-learnings-cmd.js.map +1 -0
  14. package/dist/core/learnings-budget-check.d.ts.map +1 -1
  15. package/dist/core/learnings-budget-check.js +18 -3
  16. package/dist/core/learnings-budget-check.js.map +1 -1
  17. package/dist/core/learnings-document.d.ts +46 -0
  18. package/dist/core/learnings-document.d.ts.map +1 -1
  19. package/dist/core/learnings-document.js +82 -4
  20. package/dist/core/learnings-document.js.map +1 -1
  21. package/dist/core/learnings-file-safety.d.ts.map +1 -1
  22. package/dist/core/learnings-file-safety.js +22 -0
  23. package/dist/core/learnings-file-safety.js.map +1 -1
  24. package/dist/core/learnings-merge-driver-config.d.ts +7 -0
  25. package/dist/core/learnings-merge-driver-config.d.ts.map +1 -0
  26. package/dist/core/learnings-merge-driver-config.js +58 -0
  27. package/dist/core/learnings-merge-driver-config.js.map +1 -0
  28. package/dist/core/learnings-merge-driver-install.d.ts +45 -0
  29. package/dist/core/learnings-merge-driver-install.d.ts.map +1 -0
  30. package/dist/core/learnings-merge-driver-install.js +161 -0
  31. package/dist/core/learnings-merge-driver-install.js.map +1 -0
  32. package/dist/core/learnings-merge-driver.d.ts +83 -0
  33. package/dist/core/learnings-merge-driver.d.ts.map +1 -0
  34. package/dist/core/learnings-merge-driver.js +100 -0
  35. package/dist/core/learnings-merge-driver.js.map +1 -0
  36. package/dist/core/learnings-merge.d.ts +23 -0
  37. package/dist/core/learnings-merge.d.ts.map +1 -0
  38. package/dist/core/learnings-merge.js +198 -0
  39. package/dist/core/learnings-merge.js.map +1 -0
  40. package/dist/core/learnings-writer.d.ts +6 -0
  41. package/dist/core/learnings-writer.d.ts.map +1 -1
  42. package/dist/core/learnings-writer.js +32 -65
  43. package/dist/core/learnings-writer.js.map +1 -1
  44. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  45. package/dist/core/upstream-evidence-manifest.js +27 -4
  46. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  47. package/dist/health/storage.d.ts.map +1 -1
  48. package/dist/health/storage.js +7 -20
  49. package/dist/health/storage.js.map +1 -1
  50. package/dist/migrations/ensure-learnings-gitattributes.d.ts +43 -0
  51. package/dist/migrations/ensure-learnings-gitattributes.d.ts.map +1 -0
  52. package/dist/migrations/ensure-learnings-gitattributes.js +93 -0
  53. package/dist/migrations/ensure-learnings-gitattributes.js.map +1 -0
  54. package/dist/migrations/ensure-learnings-merge-driver.d.ts +46 -0
  55. package/dist/migrations/ensure-learnings-merge-driver.d.ts.map +1 -0
  56. package/dist/migrations/ensure-learnings-merge-driver.js +70 -0
  57. package/dist/migrations/ensure-learnings-merge-driver.js.map +1 -0
  58. package/dist/migrations/index.d.ts +2 -0
  59. package/dist/migrations/index.d.ts.map +1 -1
  60. package/dist/migrations/index.js +6 -0
  61. package/dist/migrations/index.js.map +1 -1
  62. package/dist/standards/storage.d.ts.map +1 -1
  63. package/dist/standards/storage.js +7 -20
  64. package/dist/standards/storage.js.map +1 -1
  65. package/dist/utils/atomic-file-write.d.ts +30 -0
  66. package/dist/utils/atomic-file-write.d.ts.map +1 -0
  67. package/dist/utils/atomic-file-write.js +61 -0
  68. package/dist/utils/atomic-file-write.js.map +1 -0
  69. package/dist/utils/directory-sync.d.ts.map +1 -0
  70. package/dist/utils/directory-sync.js.map +1 -0
  71. package/package.json +1 -1
  72. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  73. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  74. package/plugins/lisa/.codex-plugin/skills/lisa-drive-pr-to-merge/SKILL.md +12 -0
  75. package/plugins/lisa/.codex-plugin/skills/lisa-persist-learning/SKILL.md +1 -0
  76. package/plugins/lisa/skills/lisa-drive-pr-to-merge/SKILL.md +12 -0
  77. package/plugins/lisa/skills/lisa-persist-learning/SKILL.md +1 -0
  78. package/plugins/lisa-agy/plugin.json +1 -1
  79. package/plugins/lisa-agy/skills/lisa-drive-pr-to-merge/SKILL.md +12 -0
  80. package/plugins/lisa-agy/skills/lisa-persist-learning/SKILL.md +1 -0
  81. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  82. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  83. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  84. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  85. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  86. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  87. package/plugins/lisa-copilot/skills/lisa-drive-pr-to-merge/SKILL.md +12 -0
  88. package/plugins/lisa-copilot/skills/lisa-persist-learning/SKILL.md +1 -0
  89. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  90. package/plugins/lisa-cursor/skills/lisa-drive-pr-to-merge/SKILL.md +12 -0
  91. package/plugins/lisa-cursor/skills/lisa-persist-learning/SKILL.md +1 -0
  92. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  93. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  94. package/plugins/lisa-expo-agy/plugin.json +1 -1
  95. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  96. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  97. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  98. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  99. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  100. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  101. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  102. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  103. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  104. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  105. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  106. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  107. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  108. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  109. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  110. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  111. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  112. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  113. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  114. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  115. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  116. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  117. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  118. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  119. package/plugins/lisa-rails-agy/plugin.json +1 -1
  120. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  121. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  122. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  123. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  124. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  125. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  126. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  127. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  128. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  129. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  130. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  131. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  132. package/plugins/src/base/skills/lisa-drive-pr-to-merge/SKILL.md +12 -0
  133. package/plugins/src/base/skills/lisa-persist-learning/SKILL.md +1 -0
  134. package/dist/health/directory-sync.d.ts.map +0 -1
  135. package/dist/health/directory-sync.js.map +0 -1
  136. /package/dist/{health → utils}/directory-sync.d.ts +0 -0
  137. /package/dist/{health → utils}/directory-sync.js +0 -0
@@ -0,0 +1,198 @@
1
+ /**
2
+ * Three-way union-by-id merge for the canonical project-learnings ledger.
3
+ *
4
+ * ## Why this exists
5
+ *
6
+ * The fs-level write lock (`learnings-lock.ts`) serializes writers that share a
7
+ * filesystem path, but every learner pass runs on its own
8
+ * `learning/<fingerprint>` branch in its own worktree. A path-scoped lock
9
+ * provably cannot serialize two worktrees, so N concurrent passes produce N
10
+ * pull requests that each rewrite the same JSONL block, and the collision
11
+ * surfaces at merge time as literal git conflict markers
12
+ * (CodySwannGT/lisa#1995). Git's default line-based merge is the wrong tool for
13
+ * a document whose real unit is an entry keyed by id.
14
+ *
15
+ * ## Why three-way and not a union of the two sides
16
+ *
17
+ * A two-way union cannot tell "the other branch never had this entry" apart
18
+ * from "the other branch deliberately superseded this entry". The writer's
19
+ * whole consolidation mechanism (`persistConsolidatedLearning`'s `supersede`)
20
+ * works by REMOVING entries, so a two-way union would resurrect every
21
+ * consolidated entry and silently undo the consolidation — the exact
22
+ * "lost consolidation target" symptom reported in the issue. Comparing each
23
+ * side against the merge base is what lets a removal survive the merge.
24
+ *
25
+ * ## Conflict policy
26
+ *
27
+ * Per id, against the base: if only one side changed it, that side wins
28
+ * (including a removal). If both sides made the SAME change, it is not a
29
+ * conflict. If both sides changed it differently, the merge FAILS rather than
30
+ * guessing — with one narrow exception: when the only differing field is
31
+ * `last_confirmed`, the later date wins, because that field is a monotonic
32
+ * "this rule demonstrably applied again" stamp and taking the later one loses
33
+ * no information. A confirmation bump never beats a content edit; that is a
34
+ * genuine conflict, because preferring the later timestamp would silently
35
+ * discard the other branch's rewritten rule.
36
+ *
37
+ * The merged document is re-rendered through the canonical serializer and
38
+ * re-checked against the shared budgets, so the driver can never publish a
39
+ * malformed or over-budget ledger — it fails loudly and lets git leave the
40
+ * conflict for a human or agent to recompact.
41
+ * @module core/learnings-merge
42
+ */
43
+ import { LEARNINGS_CONTRACT, } from "./learnings-contract.js";
44
+ import { assertDocumentBudget, parseLearningsFile, renderLearningsFile, } from "./learnings-document.js";
45
+ /**
46
+ * Merge two divergent ledger versions against their common ancestor.
47
+ * @param base - Merge-base document, or undefined when the file is new on both sides
48
+ * @param ours - Current-branch document
49
+ * @param theirs - Incoming-branch document
50
+ * @returns Canonical merged document, or a conflict with a reason
51
+ */
52
+ export function mergeLearningsDocuments(base, ours, theirs) {
53
+ try {
54
+ const baseEntries = parseSide(base);
55
+ const ourEntries = parseSide(ours);
56
+ const theirEntries = parseSide(theirs);
57
+ const resolved = resolveAllIds(baseEntries, ourEntries, theirEntries);
58
+ if (resolved.kind === "conflict") {
59
+ return resolved;
60
+ }
61
+ return renderWithinBudget(resolved.entries);
62
+ }
63
+ catch (error) {
64
+ return {
65
+ kind: "conflict",
66
+ reason: error instanceof Error ? error.message : String(error),
67
+ };
68
+ }
69
+ }
70
+ /**
71
+ * Parse one side into an id-keyed map, treating an absent side as empty.
72
+ *
73
+ * Parsing (rather than diffing raw lines) is what makes the driver safe: a side
74
+ * carrying conflict markers, a broken fence, or an invalid entry throws here and
75
+ * becomes a conflict instead of being silently half-merged.
76
+ * @param content - Document for one merge side
77
+ * @returns Entries keyed by id
78
+ */
79
+ function parseSide(content) {
80
+ if (content === undefined || content === "") {
81
+ return new Map();
82
+ }
83
+ return new Map(parseLearningsFile(content).map(entry => [entry.id, entry]));
84
+ }
85
+ /**
86
+ * Resolve every id seen on any side into the merged entry set.
87
+ * @param base - Merge-base entries
88
+ * @param ours - Current-branch entries
89
+ * @param theirs - Incoming-branch entries
90
+ * @returns Merged entries, or the first conflicting id
91
+ */
92
+ function resolveAllIds(base, ours, theirs) {
93
+ const ids = [...new Set([...base.keys(), ...ours.keys(), ...theirs.keys()])];
94
+ const resolutions = ids.map(id => resolveOneId(base.get(id), ours.get(id), theirs.get(id)));
95
+ const conflicted = resolutions.find(resolution => resolution === "conflict");
96
+ if (conflicted !== undefined) {
97
+ const conflictingIds = ids.filter((_unused, index) => resolutions[index] === "conflict");
98
+ return {
99
+ kind: "conflict",
100
+ reason: `Both branches changed learning ${conflictingIds.map(id => `'${id}'`).join(", ")} differently; recompact by hand to keep the intended content`,
101
+ };
102
+ }
103
+ return {
104
+ kind: "entries",
105
+ entries: resolutions
106
+ .filter((resolution) => resolution !== "absent" && resolution !== "conflict")
107
+ .sort((left, right) => left.id.localeCompare(right.id)),
108
+ };
109
+ }
110
+ /**
111
+ * Resolve one id with standard three-way semantics.
112
+ * @param base - Ancestor version, if any
113
+ * @param ours - Current-branch version, if any
114
+ * @param theirs - Incoming-branch version, if any
115
+ * @returns The winning entry, `absent` when both sides removed it, or `conflict`
116
+ */
117
+ function resolveOneId(base, ours, theirs) {
118
+ if (sameEntry(ours, theirs)) {
119
+ return ours ?? "absent";
120
+ }
121
+ // Exactly one side diverged from the ancestor: that side's intent wins,
122
+ // whether it was an edit, an addition, or a supersede-driven removal.
123
+ if (sameEntry(base, ours)) {
124
+ return theirs ?? "absent";
125
+ }
126
+ if (sameEntry(base, theirs)) {
127
+ return ours ?? "absent";
128
+ }
129
+ return resolveDivergentEdit(ours, theirs);
130
+ }
131
+ /**
132
+ * Resolve the one divergence that is safe to auto-merge: both branches only
133
+ * re-confirmed the same entry, so the later monotonic stamp wins.
134
+ * @param ours - Current-branch version, if any
135
+ * @param theirs - Incoming-branch version, if any
136
+ * @returns The later-confirmed entry, or `conflict`
137
+ */
138
+ function resolveDivergentEdit(ours, theirs) {
139
+ if (ours === undefined || theirs === undefined) {
140
+ // One side edited the entry while the other superseded it. Dropping the
141
+ // edit or resurrecting the removal are both information loss.
142
+ return "conflict";
143
+ }
144
+ // Neutralize only `last_confirmed`: if the entries match once that field is
145
+ // aligned, it was the sole difference and taking the later stamp loses nothing.
146
+ return sameEntry({ ...ours, last_confirmed: theirs.last_confirmed }, theirs)
147
+ ? pickLaterConfirmation(ours, theirs)
148
+ : "conflict";
149
+ }
150
+ /**
151
+ * Choose the later of two confirmation stamps.
152
+ * @param ours - Current-branch version
153
+ * @param theirs - Incoming-branch version
154
+ * @returns The entry carrying the later `last_confirmed`
155
+ */
156
+ function pickLaterConfirmation(ours, theirs) {
157
+ return theirs.last_confirmed > ours.last_confirmed ? theirs : ours;
158
+ }
159
+ /**
160
+ * Compare two optional entries by value using the canonical serialization.
161
+ *
162
+ * The renderer is the single source of truth for field order, so serializing
163
+ * both sides through `JSON.stringify` compares exactly what would be written.
164
+ * @param left - First entry, if any
165
+ * @param right - Second entry, if any
166
+ * @returns Whether both are absent or byte-identical once serialized
167
+ */
168
+ function sameEntry(left, right) {
169
+ if (left === undefined || right === undefined) {
170
+ return left === undefined && right === undefined;
171
+ }
172
+ return JSON.stringify(left) === JSON.stringify(right);
173
+ }
174
+ /**
175
+ * Render the merged entries and refuse to publish an over-budget ledger.
176
+ *
177
+ * A union can legitimately exceed the budget when both branches added entries
178
+ * to an already-full ledger. Emitting it anyway would push the breach onto the
179
+ * CI gate after the merge has landed; failing here keeps the conflict visible
180
+ * at the point a human or agent can still recompact deliberately.
181
+ * @param entries - Resolved merged entries, sorted by id
182
+ * @returns Canonical merged document, or a budget conflict
183
+ */
184
+ function renderWithinBudget(entries) {
185
+ const content = renderLearningsFile(entries);
186
+ try {
187
+ assertDocumentBudget(content, entries.length, "Merged project learnings");
188
+ return { kind: "merged", content };
189
+ }
190
+ catch (error) {
191
+ const detail = error instanceof Error ? error.message : String(error);
192
+ return {
193
+ kind: "conflict",
194
+ reason: `${detail} — the union of both branches does not fit the ${LEARNINGS_CONTRACT.maxEntries}-entry budget; consolidate before merging`,
195
+ };
196
+ }
197
+ }
198
+ //# sourceMappingURL=learnings-merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"learnings-merge.js","sourceRoot":"","sources":["../../src/core/learnings-merge.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,12 @@
2
2
  export interface ConsolidatedLearningOptions {
3
3
  /** Ids of existing entries the new entry merges or replaces. */
4
4
  readonly supersede?: readonly string[];
5
+ /**
6
+ * Called when a supersede target was already absent at write time — almost
7
+ * always because a concurrent pass consolidated it first. The write still
8
+ * succeeds; this is a diagnostic, not a failure hook.
9
+ */
10
+ readonly onAbsentSupersede?: (ids: readonly string[]) => void;
5
11
  }
6
12
  /**
7
13
  * Persist one already-selected learning without generating or truncating it.
@@ -1 +1 @@
1
- {"version":3,"file":"learnings-writer.d.ts","sourceRoot":"","sources":["../../src/core/learnings-writer.ts"],"names":[],"mappings":"AAsBA,gFAAgF;AAChF,MAAM,WAAW,2BAA2B;IAC1C,gEAAgE;IAChE,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,OAAO,GACjB,OAAO,CAAC,MAAM,CAAC,CAEjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,2BAA2B,CAC/C,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,OAAO,EAClB,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,MAAM,CAAC,CAWjB;AA+ED,2DAA2D;AAC3D,MAAM,MAAM,qBAAqB,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;AAE5E,uEAAuE;AACvE,MAAM,WAAW,qBAAqB;IACpC,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IACvC,gDAAgD;IAChD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,qBAAqB,CAAC,CAmDhC;AAED,OAAO,EACL,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"learnings-writer.d.ts","sourceRoot":"","sources":["../../src/core/learnings-writer.ts"],"names":[],"mappings":"AAsBA,gFAAgF;AAChF,MAAM,WAAW,2BAA2B;IAC1C,gEAAgE;IAChE,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;CAC/D;AAED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,OAAO,GACjB,OAAO,CAAC,MAAM,CAAC,CAEjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,2BAA2B,CAC/C,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,OAAO,EAClB,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,MAAM,CAAC,CAiBjB;AAkCD,2DAA2D;AAC3D,MAAM,MAAM,qBAAqB,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;AAE5E,uEAAuE;AACvE,MAAM,WAAW,qBAAqB;IACpC,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IACvC,gDAAgD;IAChD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,qBAAqB,CAAC,CA2ChC;AAED,OAAO,EACL,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -1,7 +1,7 @@
1
1
  /** Deterministic persistence for project-local learnings. */
2
2
  import * as fse from "fs-extra";
3
- import { rename, writeFile } from "node:fs/promises";
4
3
  import * as path from "node:path";
4
+ import { writeFileAtomically } from "../utils/atomic-file-write.js";
5
5
  import { assertDocumentBudget, parseLearningsFile, renderLearningsFile, } from "./learnings-document.js";
6
6
  import { requireIsoDate, validateLearningEntry } from "./learnings-entry.js";
7
7
  import { assertSafeLearningParents, readExistingLearnings, resolveSafeLearningTarget, } from "./learnings-file-safety.js";
@@ -39,25 +39,10 @@ export async function persistConsolidatedLearning(projectRoot, candidate, option
39
39
  const relativeFile = resolveProjectLearningsFile(config);
40
40
  const { root, target } = resolveSafeLearningTarget(projectRoot, relativeFile);
41
41
  // Fast budget fail on the lone entry before any directory is created.
42
- buildNextDocument([], entry, [], new Set());
42
+ buildNextDocument([], entry, []);
43
43
  await assertSafeLearningParents(root, path.dirname(target));
44
44
  await fse.ensureDir(path.dirname(target));
45
- return writeLearningEntriesAfterSafeParent(root, target, entry, supersede);
46
- }
47
- /**
48
- * Snapshot any supersede targets after parent safety is proven, then write.
49
- * @param root - Resolved project root
50
- * @param target - Absolute learnings file path
51
- * @param entry - New validated entry
52
- * @param supersede - Ids of existing entries the new entry replaces
53
- * @returns Absolute path to the persisted learnings file
54
- */
55
- async function writeLearningEntriesAfterSafeParent(root, target, entry, supersede) {
56
- if (supersede.length === 0) {
57
- return writeLearningEntriesWithLock(root, target, entry, supersede, new Set());
58
- }
59
- const preLockSupersedeIds = await readSupersedeIdsPresentBeforeLock(target, supersede);
60
- return writeLearningEntriesWithLock(root, target, entry, supersede, preLockSupersedeIds);
45
+ return writeLearningEntriesWithLock(root, target, entry, supersede, options.onAbsentSupersede);
61
46
  }
62
47
  /**
63
48
  * Perform the locked read-validate-write transaction for a learnings update.
@@ -65,24 +50,21 @@ async function writeLearningEntriesAfterSafeParent(root, target, entry, supersed
65
50
  * @param target - Absolute learnings file path
66
51
  * @param entry - New validated entry
67
52
  * @param supersede - Ids of existing entries the new entry replaces
68
- * @param preLockSupersedeIds - Supersede ids observed before lock acquisition
53
+ * @param onAbsentSupersede - Diagnostic sink for already-consolidated targets
69
54
  * @returns Absolute path to the persisted learnings file
70
55
  */
71
- function writeLearningEntriesWithLock(root, target, entry, supersede, preLockSupersedeIds) {
56
+ function writeLearningEntriesWithLock(root, target, entry, supersede, onAbsentSupersede) {
72
57
  return withLearningTargetLock(target, async () => {
73
58
  await assertSafeLearningParents(root, path.dirname(target));
74
59
  const existing = await readExistingLearnings(target);
75
60
  const entries = existing === undefined ? [] : parseLearningsFile(existing);
76
- const rendered = buildNextDocument(entries, entry, supersede, preLockSupersedeIds);
77
- const temporary = path.join(path.dirname(target), `.${path.basename(target)}.${process.pid}.${crypto.randomUUID()}.tmp`);
78
- try {
79
- await writeFile(temporary, rendered, { encoding: "utf8", flag: "wx" });
80
- await assertSafeLearningParents(root, path.dirname(target));
81
- await rename(temporary, target);
82
- }
83
- finally {
84
- await fse.remove(temporary);
85
- }
61
+ const absent = supersede.filter(id => !entries.some(current => current.id === id));
62
+ if (absent.length > 0)
63
+ onAbsentSupersede?.(absent);
64
+ const rendered = buildNextDocument(entries, entry, supersede);
65
+ await writeFileAtomically(target, rendered, {
66
+ beforeRename: () => assertSafeLearningParents(root, path.dirname(target)),
67
+ });
86
68
  return target;
87
69
  });
88
70
  }
@@ -132,15 +114,9 @@ export async function confirmLearningEntry(projectRoot, id, date) {
132
114
  });
133
115
  const nextEntries = entries.map(entry => entry.id === id ? confirmed : entry);
134
116
  const rendered = renderConfirmedDocument(nextEntries);
135
- const temporary = path.join(path.dirname(target), `.${path.basename(target)}.${process.pid}.${crypto.randomUUID()}.tmp`);
136
- try {
137
- await writeFile(temporary, rendered, { encoding: "utf8", flag: "wx" });
138
- await assertSafeLearningParents(root, path.dirname(target));
139
- await rename(temporary, target);
140
- }
141
- finally {
142
- await fse.remove(temporary);
143
- }
117
+ await writeFileAtomically(target, rendered, {
118
+ beforeRename: () => assertSafeLearningParents(root, path.dirname(target)),
119
+ });
144
120
  return {
145
121
  status: "confirmed",
146
122
  id,
@@ -166,18 +142,28 @@ function renderConfirmedDocument(entries) {
166
142
  * Build and budget-check the next canonical document, dropping superseded
167
143
  * entries before the new entry is added so consolidation and the budget
168
144
  * re-assertion happen in one deterministic step.
145
+ *
146
+ * A supersede target that is already absent is NOT an error. "Replace X with Y"
147
+ * is already satisfied when X is gone, and at write time a concurrently
148
+ * consolidated id is indistinguishable from a bogus one — so an error here
149
+ * cannot mean what it claims. The costs are wildly asymmetric: throwing
150
+ * discards the writer's ENTIRE learning (the CodySwannGT/lisa#1995 data-loss
151
+ * symptom, just pointed the other way), while proceeding leaves at worst two
152
+ * entries where one consolidation was intended — visible, bounded, and exactly
153
+ * what the gardener and the entry budget already handle. Callers that care are
154
+ * told through `onAbsentSupersede`.
155
+ *
156
+ * This replaces PR #2008's pre-lock snapshot, which tried to tell those two
157
+ * cases apart by reading the file before acquiring the lock. That read is
158
+ * itself a TOCTOU: it only rescues writers whose snapshot predates the removal,
159
+ * so it narrowed the window rather than closing it and failed intermittently in
160
+ * CI under precisely the contention it was written for.
169
161
  * @param entries - Existing validated entries
170
162
  * @param entry - New validated entry
171
163
  * @param supersede - Ids of existing entries the new entry replaces
172
- * @param preLockSupersedeIds - Supersede ids observed before lock acquisition
173
164
  * @returns Next canonical document
174
165
  */
175
- function buildNextDocument(entries, entry, supersede, preLockSupersedeIds) {
176
- const missing = supersede.filter(id => !entries.some(current => current.id === id));
177
- const unknown = missing.filter(id => !preLockSupersedeIds.has(id));
178
- if (unknown.length > 0) {
179
- throw new Error(`Cannot supersede unknown learning id(s): ${unknown.join(", ")}`);
180
- }
166
+ function buildNextDocument(entries, entry, supersede) {
181
167
  const supersededIds = new Set(supersede);
182
168
  const retained = entries.filter(current => !supersededIds.has(current.id));
183
169
  if (retained.some(current => current.id === entry.id)) {
@@ -188,25 +174,6 @@ function buildNextDocument(entries, entry, supersede, preLockSupersedeIds) {
188
174
  assertDocumentBudget(rendered, nextEntries.length, "Learnings file");
189
175
  return rendered;
190
176
  }
191
- /**
192
- * Snapshot supersede ids that existed before waiting on the writer lock. When a
193
- * concurrent writer removes one of those ids first, the later writer should
194
- * still preserve its candidate instead of dropping the learning as stale.
195
- * @param target - Resolved learnings file path
196
- * @param supersede - Validated supersede ids requested by the caller
197
- * @returns Supersede ids observed in the file before lock acquisition
198
- */
199
- async function readSupersedeIdsPresentBeforeLock(target, supersede) {
200
- if (supersede.length === 0) {
201
- return new Set();
202
- }
203
- const existing = await readExistingLearnings(target);
204
- if (existing === undefined) {
205
- return new Set();
206
- }
207
- const existingIds = new Set(parseLearningsFile(existing).map(({ id }) => id));
208
- return new Set(supersede.filter(id => existingIds.has(id)));
209
- }
210
177
  /**
211
178
  * Reject malformed supersede directives before any filesystem work.
212
179
  * @param supersede - Caller-supplied (possibly untrusted) supersede ids
@@ -1 +1 @@
1
- {"version":3,"file":"learnings-writer.js","sourceRoot":"","sources":["../../src/core/learnings-writer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"learnings-writer.js","sourceRoot":"","sources":["../../src/core/learnings-writer.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"upstream-evidence-manifest.d.ts","sourceRoot":"","sources":["../../src/core/upstream-evidence-manifest.ts"],"names":[],"mappings":"AACA,iFAAiF;AACjF,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgiEpE,CAAC;AAEL,4EAA4E;AAC5E,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CA0wMjE,CAAC;AAEL,sFAAsF;AACtF,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAk6I/D,CAAC"}
1
+ {"version":3,"file":"upstream-evidence-manifest.d.ts","sourceRoot":"","sources":["../../src/core/upstream-evidence-manifest.ts"],"names":[],"mappings":"AACA,iFAAiF;AACjF,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAkiEpE,CAAC;AAEL,4EAA4E;AAC5E,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAgyMjE,CAAC;AAEL,sFAAsF;AACtF,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAk6I/D,CAAC"}
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable max-lines -- generated exact public-evidence allowlist */
2
2
  /** Generated by scripts/generate-upstream-evidence-manifest.mjs. Do not edit. */
3
3
  export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
4
+ "all/copy-contents/.gitattributes": "f5b6d4b75afe753f17dc9a2027eb8eca4dcee326921cc59a36bd0616bfb0636a",
4
5
  "all/copy-contents/gitignore": "06b56376465d5421db55d0b04958bbc79fdbf33b42f0559fe5ef6875ced1160f",
5
6
  "all/copy-overwrite/scripts/lisa-work-item.mjs": "5eb31c284e820a51312d4484f0669128007326af55ee515923fec33700d003a1",
6
7
  "all/create-only/.claude/rules/PROJECT_RULES.md": "6e1c7923ad2a15356babc60c97e7f97be728d790af285b6a7cd7d1b4d39cd97f",
@@ -403,7 +404,7 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
403
404
  "plugins/src/base/skills/lisa-debrief-apply/SKILL.md": "90c5f01994bb0f8e71947e8a2f765ccf9a6aa3da47b8d7b8e2022150ef89c2b2",
404
405
  "plugins/src/base/skills/lisa-debrief/SKILL.md": "47e4cda36b07994ff47ab15fb04a17dd6b0c310ad804f9cae9d69637edaaa72a",
405
406
  "plugins/src/base/skills/lisa-doctor/SKILL.md": "1702485809533a2e546a590b9d2f67cbb420c8f0cb0eac8609b0287b05122ad3",
406
- "plugins/src/base/skills/lisa-drive-pr-to-merge/SKILL.md": "cd692a3343f2306a3d5b96a1cb9662e3abdc557df24d733138b23fde2aa8bad9",
407
+ "plugins/src/base/skills/lisa-drive-pr-to-merge/SKILL.md": "c78ae2ba32c830d0b2cd7d24de91adf99e2b3cef4c7cab1c417580d86f41351f",
407
408
  "plugins/src/base/skills/lisa-epic-triage/SKILL.md": "d02760411249bddbd396f283191fe3e82bb7b95bf9393a19a7025dc5a57c3ab7",
408
409
  "plugins/src/base/skills/lisa-exploratory-qa/SKILL.md": "bc34dfc6418bff6eb5bc03f0c5cd98c7b6164ca3f4f80774d981f681321119b0",
409
410
  "plugins/src/base/skills/lisa-fix-linter-error/SKILL.md": "3a8f01f014ac7f7ac37024c67df1ba07202331542d269d27da3356a7fa0a5599",
@@ -486,7 +487,7 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
486
487
  "plugins/src/base/skills/lisa-parity-sentry-seer/SKILL.md": "f44216fa7c8f0c3c3371c65ff73bbeadd1717579502a5603f16b3b33291cab7a",
487
488
  "plugins/src/base/skills/lisa-parity-skill-creator/SKILL.md": "616e0493f75fe92c18137548d7c86a91a9b04d9844ca76fa3f14156e3e7814e5",
488
489
  "plugins/src/base/skills/lisa-performance-review/SKILL.md": "351542c256e54940e6d672a70606b8414425c6435ae6f026841bcc02f9fce9c4",
489
- "plugins/src/base/skills/lisa-persist-learning/SKILL.md": "d682b944ae099cdad8c91762b6665b8ef613b58bb8b041335841c116c94dd891",
490
+ "plugins/src/base/skills/lisa-persist-learning/SKILL.md": "d1dc476137dbec1e9de31eb467d69424e48f3ac0271ae36eb66b2e7b110db603",
490
491
  "plugins/src/base/skills/lisa-plan/SKILL.md": "9c372e106afd53ff988046119cf36b0f6519c4426775dd8ad3c9d9baeee5d3e2",
491
492
  "plugins/src/base/skills/lisa-plugin-sync-explain/SKILL.md": "b41619f3d0d342af2438afd54cb97db7d2445e54e3fc7bb012292079acbc6a4f",
492
493
  "plugins/src/base/skills/lisa-posthog-access/SKILL.md": "977aef803160b04312c0408136882ac106d8357caf5063a523e72f265bf20cb1",
@@ -1116,6 +1117,7 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
1116
1117
  ".codex/config.toml": true,
1117
1118
  ".entire/.gitignore": true,
1118
1119
  ".entire/settings.json": true,
1120
+ ".gitattributes": true,
1119
1121
  ".github/GITHUB_ACTIONS.md": true,
1120
1122
  ".github/dependabot.yml": true,
1121
1123
  ".github/workflows/auto-update-pr-branches-dispatch.yml": true,
@@ -1182,6 +1184,7 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
1182
1184
  LICENSE: true,
1183
1185
  "PLAN.md": true,
1184
1186
  "README.md": true,
1187
+ "all/copy-contents/.gitattributes": true,
1185
1188
  "all/copy-contents/gitignore": true,
1186
1189
  "all/copy-overwrite/scripts/lisa-work-item.mjs": true,
1187
1190
  "all/create-only/.claude/rules/PROJECT_RULES.md": true,
@@ -6353,7 +6356,9 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
6353
6356
  "src/cli/gate-commands.ts": true,
6354
6357
  "src/cli/health-cmd.ts": true,
6355
6358
  "src/cli/index.ts": true,
6359
+ "src/cli/install-merge-driver-cmd.ts": true,
6356
6360
  "src/cli/kane-cmd.ts": true,
6361
+ "src/cli/merge-learnings-cmd.ts": true,
6357
6362
  "src/cli/print-update-warning.ts": true,
6358
6363
  "src/cli/prompts.ts": true,
6359
6364
  "src/cli/remote-environment-catalog.ts": true,
@@ -6466,6 +6471,10 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
6466
6471
  "src/core/learnings-entry.ts": true,
6467
6472
  "src/core/learnings-file-safety.ts": true,
6468
6473
  "src/core/learnings-lock.ts": true,
6474
+ "src/core/learnings-merge-driver-config.ts": true,
6475
+ "src/core/learnings-merge-driver-install.ts": true,
6476
+ "src/core/learnings-merge-driver.ts": true,
6477
+ "src/core/learnings-merge.ts": true,
6469
6478
  "src/core/learnings-projection.ts": true,
6470
6479
  "src/core/learnings-writer.ts": true,
6471
6480
  "src/core/learnings.ts": true,
@@ -6495,7 +6504,6 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
6495
6504
  "src/health/contract.ts": true,
6496
6505
  "src/health/deadline.ts": true,
6497
6506
  "src/health/deterministic.ts": true,
6498
- "src/health/directory-sync.ts": true,
6499
6507
  "src/health/evaluation-protocol.ts": true,
6500
6508
  "src/health/finding-utils.ts": true,
6501
6509
  "src/health/governance-probes.ts": true,
@@ -6516,6 +6524,8 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
6516
6524
  "src/logging/silent-logger.ts": true,
6517
6525
  "src/migrations/ensure-audit-ignore-local-exclusions.ts": true,
6518
6526
  "src/migrations/ensure-jest-rn-mock-accessibility-manager.ts": true,
6527
+ "src/migrations/ensure-learnings-gitattributes.ts": true,
6528
+ "src/migrations/ensure-learnings-merge-driver.ts": true,
6519
6529
  "src/migrations/ensure-lisa-postinstall.ts": true,
6520
6530
  "src/migrations/ensure-sonar-excludes-lisa-harness.ts": true,
6521
6531
  "src/migrations/ensure-tsconfig-local-files-fallback.ts": true,
@@ -6572,7 +6582,9 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
6572
6582
  "src/transaction/index.ts": true,
6573
6583
  "src/transaction/transaction.ts": true,
6574
6584
  "src/types/minimatch.d.ts": true,
6585
+ "src/utils/atomic-file-write.ts": true,
6575
6586
  "src/utils/decimal-sum.ts": true,
6587
+ "src/utils/directory-sync.ts": true,
6576
6588
  "src/utils/fibonacci.ts": true,
6577
6589
  "src/utils/file-operations.ts": true,
6578
6590
  "src/utils/ignore-patterns.ts": true,
@@ -6727,6 +6739,7 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
6727
6739
  "tests/unit/cli/index.test.ts": true,
6728
6740
  "tests/unit/cli/kane-cmd.test.ts": true,
6729
6741
  "tests/unit/cli/kane-index.test.ts": true,
6742
+ "tests/unit/cli/merge-learnings-cmd.test.ts": true,
6730
6743
  "tests/unit/cli/prompts.test.ts": true,
6731
6744
  "tests/unit/cli/setup-project.test.ts": true,
6732
6745
  "tests/unit/cli/setup-wiki.test.ts": true,
@@ -6828,10 +6841,17 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
6828
6841
  "tests/unit/core/learnings-budget-check.test.ts": true,
6829
6842
  "tests/unit/core/learnings-concurrency.test.ts": true,
6830
6843
  "tests/unit/core/learnings-confirm.test.ts": true,
6844
+ "tests/unit/core/learnings-conflict-markers.test.ts": true,
6831
6845
  "tests/unit/core/learnings-consolidation.test.ts": true,
6832
6846
  "tests/unit/core/learnings-contract.test.ts": true,
6847
+ "tests/unit/core/learnings-gitattributes.test.ts": true,
6833
6848
  "tests/unit/core/learnings-lock-reclaim.test.ts": true,
6849
+ "tests/unit/core/learnings-merge-driver-install.test.ts": true,
6850
+ "tests/unit/core/learnings-merge-driver.test.ts": true,
6851
+ "tests/unit/core/learnings-merge.test.ts": true,
6834
6852
  "tests/unit/core/learnings-projection.test.ts": true,
6853
+ "tests/unit/core/learnings-supersede-race.test.ts": true,
6854
+ "tests/unit/core/learnings-unlocked-read.test.ts": true,
6835
6855
  "tests/unit/core/learnings-writer.test.ts": true,
6836
6856
  "tests/unit/core/lisa-plugin-selection.test.ts": true,
6837
6857
  "tests/unit/core/lisa-skill-sources.test.ts": true,
@@ -6853,7 +6873,6 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
6853
6873
  "tests/unit/health/contract.test.ts": true,
6854
6874
  "tests/unit/health/deterministic-regressions.test.ts": true,
6855
6875
  "tests/unit/health/deterministic.test.ts": true,
6856
- "tests/unit/health/directory-sync.test.ts": true,
6857
6876
  "tests/unit/health/gitignore.test.ts": true,
6858
6877
  "tests/unit/health/package-surfaces.test.ts": true,
6859
6878
  "tests/unit/health/storage.test.ts": true,
@@ -6885,6 +6904,8 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
6885
6904
  "tests/unit/migrations/ensure-audit-ignore-local-exclusions-esbuild.test.ts": true,
6886
6905
  "tests/unit/migrations/ensure-audit-ignore-local-exclusions.test.ts": true,
6887
6906
  "tests/unit/migrations/ensure-jest-rn-mock-accessibility-manager.test.ts": true,
6907
+ "tests/unit/migrations/ensure-learnings-gitattributes.test.ts": true,
6908
+ "tests/unit/migrations/ensure-learnings-merge-driver.test.ts": true,
6888
6909
  "tests/unit/migrations/ensure-lisa-postinstall.test.ts": true,
6889
6910
  "tests/unit/migrations/ensure-sonar-excludes-lisa-harness.test.ts": true,
6890
6911
  "tests/unit/migrations/ensure-tsconfig-local-files-fallback.test.ts": true,
@@ -7120,6 +7141,8 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
7120
7141
  "tests/unit/templates/project-learnings-template.test.ts": true,
7121
7142
  "tests/unit/templates/stack-tsconfig-shadowing.test.ts": true,
7122
7143
  "tests/unit/transaction/backup.test.ts": true,
7144
+ "tests/unit/utils/atomic-file-write.test.ts": true,
7145
+ "tests/unit/utils/directory-sync.test.ts": true,
7123
7146
  "tests/unit/utils/fibonacci.test.ts": true,
7124
7147
  "tests/unit/utils/file-operations.test.ts": true,
7125
7148
  "tests/unit/utils/ignore-patterns.test.ts": true,