Skip to content

Commit 4937239

Browse files
committed
fix(ai-markmap-agent): delay version cleanup until pipeline completes
- Move version deletion from start to end of pipeline - Old versions are only deleted after successful completion - If pipeline fails, old versions are preserved (safe rollback) - Update documentation to reflect safer behavior
1 parent 1b55513 commit 4937239

File tree

6 files changed

+127
-307
lines changed

6 files changed

+127
-307
lines changed

tools/ai-markmap-agent/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,9 +399,9 @@ output:
399399
| Mode | Behavior |
400400
|------|----------|
401401
| `continue` | Load from latest version (vN), produce vN+1 |
402-
| `reset` | Delete all versions, start fresh from `input.baseline.path`, produce v1 |
402+
| `reset` | Start fresh from `input.baseline.path`, produce v1 |
403403

404-
**Reset mode** prompts for confirmation before deleting existing versions.
404+
**Reset mode** prompts for confirmation. Old versions are deleted only after the pipeline completes successfully (safe: if pipeline fails, old versions are preserved).
405405

406406
---
407407

tools/ai-markmap-agent/README_zh-TW.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,9 +399,9 @@ output:
399399
| 模式 | 行為 |
400400
|------|------|
401401
| `continue` | 從最新版本 (vN) 繼續精進,產生 vN+1 |
402-
| `reset` | 刪除所有版本,從 `input.baseline.path` 重新開始,產生 v1 |
402+
| `reset` | 從 `input.baseline.path` 重新開始,產生 v1 |
403403

404-
**Reset 模式**會在刪除前詢問確認
404+
**Reset 模式**會先詢問確認。舊版本在 pipeline 完成後才刪除(安全機制:如果 pipeline 失敗,舊版本保留)
405405

406406
---
407407

tools/ai-markmap-agent/docs/DESIGN_V4.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -888,12 +888,15 @@ versioning:
888888
現有版本: v1, v2, v3
889889

890890
執行流程:
891-
1. 程式詢問:「確定要刪除 v1, v2, v3 嗎?[Y/N]」
892-
2. Y → 刪除所有版本,從 input.baseline.path 重新開始
891+
1. 程式詢問:「確定要 reset 嗎?[Y/N]」
892+
2. Y → 從 input.baseline.path 開始執行 pipeline
893893
3. N → 程式結束,不做任何事
894-
4. 產生新的 v1
894+
4. Pipeline 完成後,刪除舊版本 (v1, v2, v3),儲存新的 v1
895+
5. 如果 pipeline 失敗,舊版本保留不受影響
895896
```
896897

898+
**安全機制**:舊版本在 pipeline 完成後才刪除,確保失敗時不會遺失資料。
899+
897900
### 使用場景
898901

899902
| 場景 | 使用模式 |

tools/ai-markmap-agent/outputs/versions/v1/neetcode_ontology_agent_evolved_en.html

Lines changed: 47 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -76,31 +76,18 @@
7676
7777
---
7878
79-
## 🧭 Quick Access Index
80-
- [SubstringSlidingWindow](#substring-sliding-window)
81-
- [TwoPointersTraversal](#two-pointers-traversal)
82-
- [TwoPointerPartition](#two-pointer-partition)
83-
- [FastSlowPointers](#fast-slow-pointers)
84-
- [MergeSortedSequences](#merge-sorted-sequences)
85-
- [KWayMerge](#k-way-merge)
86-
- [HeapTopK](#heap-top-k)
87-
- [LinkedListInPlaceReversal](#linked-list-in-place-reversal)
88-
- [BacktrackingExploration](#backtracking-exploration)
89-
- [GridBFSMultiSource](#grid-bfs-multi-source)
90-
91-
---
92-
9379
## 🧠 API Kernels (the “engines”)
9480
### SubstringSlidingWindow — *1D window state machine*
9581
- ==Core invariant==: window \`[L,R]\` stays valid by **expand right** + **contract left**
96-
- Complexity: typically $O(n)$ time, $O(n)$ space in worst case due to frequency map size
82+
- Complexity: typically $O(n)$ time, $O(\\Sigma)$ space (alphabet / distinct keys)
9783
84+
<!-- markmap: fold -->
9885
#### Pattern cheat sheet (from docs)
9986
| Problem | Invariant | State | Window Size | Goal |
10087
|---------|-----------|-------|-------------|------|
10188
| [LeetCode 3 - Longest Substring Without Repeating Characters](https://github.com/lufftw/neetcode/blob/main/solutions/0003_longest_substring_without_repeating_characters.py) | All unique | last index map | Variable | Max |
10289
| [LeetCode 340 - Longest Substring with At Most K Distinct Characters](https://github.com/lufftw/neetcode/blob/main/solutions/0340_longest_substring_with_at_most_k_distinct.py) | ≤K distinct | freq map | Variable | Max |
103-
| [LeetCode 76 - Minimum Window Substring](https://github.com/lufftw/neetcode/blob/main/solutions/0076_minimum_window_substring.py) | window contains all characters of \`t\` with at least the required frequency | need/have | Variable | Min |
90+
| [LeetCode 76 - Minimum Window Substring](https://github.com/lufftw/neetcode/blob/main/solutions/0076_minimum_window_substring.py) | covers \`t\` | need/have | Variable | Min |
10491
| [LeetCode 567 - Permutation in String](https://github.com/lufftw/neetcode/blob/main/solutions/0567_permutation_in_string.py) | exact freq match | freq + matches | Fixed | Exists |
10592
| [LeetCode 438 - Find All Anagrams in a String](https://github.com/lufftw/neetcode/blob/main/solutions/0438_find_all_anagrams_in_a_string.py) | exact freq match | freq + matches | Fixed | All |
10693
| [LeetCode 209 - Minimum Size Subarray Sum](https://github.com/lufftw/neetcode/blob/main/solutions/0209_minimum_size_subarray_sum.py) | sum ≥ target | integer sum | Variable | Min |
@@ -124,17 +111,6 @@
124111
- [ ] [LeetCode 209 - Minimum Size Subarray Sum](https://github.com/lufftw/neetcode/blob/main/solutions/0209_minimum_size_subarray_sum.py)
125112
- Typical requirement: positives → monotone contraction works
126113
127-
#### Real-world Application
128-
- **Example**: Network packet analysis where you need to find the longest sequence of packets without repetition.
129-
130-
#### Problem-Solving Strategy
131-
1. Identify the invariant condition for the window.
132-
2. Use a frequency map to manage state.
133-
3. Expand and contract the window to maintain the invariant.
134-
135-
#### See Also
136-
- TwoPointersTraversal for similar problems involving sequence traversal.
137-
138114
---
139115
140116
### TwoPointersTraversal — *pointer choreography on sequences*
@@ -144,7 +120,7 @@
144120
#### Pattern comparison (from docs)
145121
| Pattern | Pointer Init | Movement | Termination | Time | Space | Key Use Case |
146122
|---------|--------------|----------|-------------|------|-------|--------------|
147-
| Opposite | \`0, n-1\` | toward center | \`L>=R\` | $O(n)$ | $O(1)$ | sorted pairs / palindrome / optimize |
123+
| Opposite | \`0, n-1\` | toward center | \`L>=R\` | $O(n)$ | $O(1)$ | sorted pairs / palindrome / maximize |
148124
| Same-direction | \`write, read\` | forward | \`read==n\` | $O(n)$ | $O(1)$ | in-place modify |
149125
| Fast–Slow | \`slow, fast\` | 1× / 2× | meet or null | $O(n)$ | $O(1)$ | cycle / midpoint |
150126
| Dedup enum | \`i\` + \`L,R\` | nested | done | $O(n^2)$ | $O(1)$ | 3Sum/4Sum |
@@ -174,43 +150,6 @@
174150
- 🎯 Problems
175151
- [ ] [LeetCode 283 - Move Zeroes](https://github.com/lufftw/neetcode/blob/main/solutions/0283_move_zeroes.py)
176152
177-
#### When to Use Opposite vs. Same-Direction
178-
- **Opposite Pointers**: Best for problems where elements are compared or combined from both ends (e.g., finding pairs).
179-
- **Same-Direction Pointers**: Suitable for in-place modifications or when a single pass is needed.
180-
181-
#### Complexity Note
182-
- Understand the difference between average-case and worst-case complexities, especially for inputs that may lead to different performance characteristics.
183-
184-
#### See Also
185-
- Sliding Window techniques for problems involving dynamic window management.
186-
187-
---
188-
189-
### TwoPointerPartition — *in-place partitioning “mini quicksort”*
190-
- ==Core invariant==: elements are rearranged such that all elements satisfying the partition property precede those that do not
191-
192-
#### Patterns
193-
- **dutch_flag_partition**
194-
- 🎯 Problems
195-
- [ ] [LeetCode 75 - Sort Colors](https://github.com/lufftw/neetcode/blob/main/solutions/0075_sort_colors.py)
196-
- **two_way_partition**
197-
- 🎯 Problems
198-
- [ ] [LeetCode 905 - Sort Array By Parity](https://github.com/lufftw/neetcode/blob/main/solutions/0905_sort_array_by_parity.py)
199-
- [ ] [LeetCode 922 - Sort Array By Parity II](https://github.com/lufftw/neetcode/blob/main/solutions/0922_sort_array_by_parity_ii.py)
200-
- **quickselect_partition** *(selection via partition)*
201-
- 🎯 Problems
202-
- [ ] [LeetCode 215 - Kth Largest Element in an Array](https://github.com/lufftw/neetcode/blob/main/solutions/0215_kth_largest_element_in_an_array.py)
203-
204-
#### Real-world Application
205-
- **Example**: Efficiently organizing data such as segregating even and odd numbers in a dataset.
206-
207-
#### Problem-Solving Strategy
208-
1. Choose a pivot or condition for partitioning.
209-
2. Rearrange elements around the pivot to satisfy the partition property.
210-
211-
#### See Also
212-
- FastSlowPointers for more advanced pointer manipulations.
213-
214153
---
215154
216155
### FastSlowPointers — *Floyd + midpoints + implicit sequences*
@@ -225,20 +164,23 @@
225164
- **fast_slow_implicit_cycle**
226165
- [ ] [LeetCode 202 - Happy Number](https://github.com/lufftw/neetcode/blob/main/solutions/0202_happy_number.py)
227166
228-
#### Real-world Application
229-
- **Example**: Detecting cycles in network routing or data processing pipelines.
230-
231-
#### Problem-Solving Strategy
232-
1. Use two pointers with different speeds.
233-
2. Detect cycle presence and locate cycle start if needed.
167+
---
234168
235-
#### See Also
236-
- TwoPointerPartition for simpler partitioning tasks.
169+
### TwoPointerPartition — *in-place partitioning “mini quicksort”*
170+
- ==Core invariant==: regions are partitioned by property
171+
- Patterns
172+
- **dutch_flag_partition**
173+
- [ ] [LeetCode 75 - Sort Colors](https://github.com/lufftw/neetcode/blob/main/solutions/0075_sort_colors.py)
174+
- **two_way_partition**
175+
- [ ] [LeetCode 905 - Sort Array By Parity](https://github.com/lufftw/neetcode/blob/main/solutions/0905_sort_array_by_parity.py)
176+
- [ ] [LeetCode 922 - Sort Array By Parity II](https://github.com/lufftw/neetcode/blob/main/solutions/0922_sort_array_by_parity_ii.py)
177+
- **quickselect_partition** *(selection via partition)*
178+
- [ ] [LeetCode 215 - Kth Largest Element in an Array](https://github.com/lufftw/neetcode/blob/main/solutions/0215_kth_largest_element_in_an_array.py)
237179
238180
---
239181
240182
### MergeSortedSequences — *merge two sorted sequences*
241-
- ==Core invariant==: at each step, the smallest unmerged element is added to the output, maintaining sorted order
183+
- ==Core invariant==: output prefix is fully sorted
242184
- Patterns
243185
- **merge_two_sorted_lists**
244186
- [ ] [LeetCode 21 - Merge Two Sorted Lists](https://github.com/lufftw/neetcode/blob/main/solutions/0021_merge_two_sorted_lists.py)
@@ -247,16 +189,6 @@
247189
- **merge_sorted_from_ends**
248190
- [ ] [LeetCode 977 - Squares of a Sorted Array](https://github.com/lufftw/neetcode/blob/main/solutions/0977_squares_of_a_sorted_array.py)
249191
250-
#### Real-world Application
251-
- **Example**: Merging sorted data streams or logs in real-time analytics systems.
252-
253-
#### Problem-Solving Strategy
254-
1. Compare elements from the start of each sequence.
255-
2. Append the smallest to the result and advance the pointer.
256-
257-
#### See Also
258-
- KWayMerge for merging multiple sequences.
259-
260192
---
261193
262194
### KWayMerge — *merge K sorted sequences*
@@ -267,33 +199,13 @@
267199
- [ ] [LeetCode 23 - Merge k Sorted Lists](https://github.com/lufftw/neetcode/blob/main/solutions/0023_merge_k_sorted_lists.py)
268200
- Related “hybrid thinking”: [LeetCode 4 - Median of Two Sorted Arrays](https://github.com/lufftw/neetcode/blob/main/solutions/0004_median_of_two_sorted_arrays.py)
269201
270-
#### Real-world Application
271-
- **Example**: Combining multiple sorted data feeds into a single sorted output.
272-
273-
#### Problem-Solving Strategy
274-
1. Use a min-heap to efficiently track the smallest elements.
275-
2. Continuously extract and insert elements to maintain order.
276-
277-
#### See Also
278-
- MergeSortedSequences for simpler two-sequence merging.
279-
280202
---
281203
282204
### HeapTopK — *keep best K under streaming updates*
283205
- Patterns
284206
- **heap_kth_element**
285207
- [ ] [LeetCode 215 - Kth Largest Element in an Array](https://github.com/lufftw/neetcode/blob/main/solutions/0215_kth_largest_element_in_an_array.py)
286208
287-
#### Real-world Application
288-
- **Example**: Real-time leaderboard updates where only the top scores are maintained.
289-
290-
#### Problem-Solving Strategy
291-
1. Use a min-heap to track the top K elements.
292-
2. Insert new elements and remove the smallest when exceeding K.
293-
294-
#### See Also
295-
- KWayMerge for merging top elements from multiple lists.
296-
297209
---
298210
299211
### LinkedListInPlaceReversal — *pointer surgery*
@@ -303,39 +215,13 @@
303215
- Also core linked list arithmetic
304216
- [ ] [LeetCode 2 - Add Two Numbers](https://github.com/lufftw/neetcode/blob/main/solutions/0002_add_two_numbers.py)
305217
306-
#### Edge Cases
307-
- Handle empty lists or lists with fewer nodes than the reversal group size.
308-
309-
#### Real-world Application
310-
- **Example**: Reversing segments of data in network packets for reordering.
311-
312-
#### Problem-Solving Strategy
313-
1. Identify groups of nodes to reverse.
314-
2. Use pointers to reverse nodes in place.
315-
316-
#### See Also
317-
- FastSlowPointers for cycle detection in linked lists.
318-
319218
---
320219
321220
### BacktrackingExploration — *search tree with pruning*
322221
- Pattern
323222
- **backtracking_n_queens**
324223
- [ ] [LeetCode 51 - N-Queens](https://github.com/lufftw/neetcode/blob/main/solutions/0051_n_queens.py)
325224
326-
#### Pruning Efficiency
327-
- Pruning reduces the search space and improves efficiency by eliminating impossible paths early.
328-
329-
#### Real-world Application
330-
- **Example**: Solving constraint satisfaction problems like Sudoku or N-Queens.
331-
332-
#### Problem-Solving Strategy
333-
1. Explore all potential configurations.
334-
2. Use pruning to eliminate invalid paths early.
335-
336-
#### See Also
337-
- GridBFSMultiSource for exploring grid-based problems.
338-
339225
---
340226
341227
### GridBFSMultiSource — *wavefront propagation on grids*
@@ -344,15 +230,32 @@
344230
- [ ] [LeetCode 994 - Rotting Oranges](https://github.com/lufftw/neetcode/blob/main/solutions/0994_rotting_oranges.py)
345231
- Implementation invariant: queue holds frontier of current “minute/level”
346232
347-
#### Real-world Application
348-
- **Example**: Simulating the spread of information or disease in a network.
349-
350-
#### Problem-Solving Strategy
351-
1. Initialize the queue with all sources.
352-
2. Propagate the wavefront level by level.
233+
---
353234
354-
#### See Also
355-
- BacktrackingExploration for exhaustive search techniques.
235+
## 🧭 Roadmap slices (what to do next)
236+
### Sliding Window Mastery 📚
237+
- [ ] [LeetCode 3 - Longest Substring Without Repeating Characters](https://github.com/lufftw/neetcode/blob/main/solutions/0003_longest_substring_without_repeating_characters.py)
238+
- [ ] [LeetCode 340 - Longest Substring with At Most K Distinct Characters](https://github.com/lufftw/neetcode/blob/main/solutions/0340_longest_substring_with_at_most_k_distinct.py)
239+
- [ ] [LeetCode 209 - Minimum Size Subarray Sum](https://github.com/lufftw/neetcode/blob/main/solutions/0209_minimum_size_subarray_sum.py)
240+
- [ ] [LeetCode 567 - Permutation in String](https://github.com/lufftw/neetcode/blob/main/solutions/0567_permutation_in_string.py)
241+
- [ ] [LeetCode 438 - Find All Anagrams in a String](https://github.com/lufftw/neetcode/blob/main/solutions/0438_find_all_anagrams_in_a_string.py)
242+
- [ ] [LeetCode 76 - Minimum Window Substring](https://github.com/lufftw/neetcode/blob/main/solutions/0076_minimum_window_substring.py) 🔥
243+
244+
### Two Pointers Mastery ⚡
245+
- Opposite pointers
246+
- [ ] [LeetCode 11 - Container With Most Water](https://github.com/lufftw/neetcode/blob/main/solutions/0011_container_with_most_water.py)
247+
- [ ] [LeetCode 125 - Valid Palindrome](https://github.com/lufftw/neetcode/blob/main/solutions/0125_valid_palindrome.py)
248+
- [ ] [LeetCode 680 - Valid Palindrome II](https://github.com/lufftw/neetcode/blob/main/solutions/0680_valid_palindrome_ii.py)
249+
- Writer pointers (in-place)
250+
- [ ] [LeetCode 26 - Remove Duplicates from Sorted Array](https://github.com/lufftw/neetcode/blob/main/solutions/0026_remove_duplicates_from_sorted_array.py)
251+
- [ ] [LeetCode 27 - Remove Element](https://github.com/lufftw/neetcode/blob/main/solutions/0027_remove_element.py)
252+
- [ ] [LeetCode 283 - Move Zeroes](https://github.com/lufftw/neetcode/blob/main/solutions/0283_move_zeroes.py)
253+
- [ ] [LeetCode 80 - Remove Duplicates from Sorted Array II](https://github.com/lufftw/neetcode/blob/main/solutions/0080_remove_duplicates_from_sorted_array_ii.py)
254+
- Fast–slow
255+
- [ ] [LeetCode 141 - Linked List Cycle](https://github.com/lufftw/neetcode/blob/main/solutions/0141_linked_list_cycle.py)
256+
- [ ] [LeetCode 142 - Linked List Cycle II](https://github.com/lufftw/neetcode/blob/main/solutions/0142_linked_list_cycle_ii.py)
257+
- [ ] [LeetCode 876 - Middle of the Linked List](https://github.com/lufftw/neetcode/blob/main/solutions/0876_middle_of_the_linked_list.py)
258+
- [ ] [LeetCode 202 - Happy Number](https://github.com/lufftw/neetcode/blob/main/solutions/0202_happy_number.py)
356259
357260
---
358261
@@ -375,21 +278,20 @@
375278
L = 0
376279
ans = 0
377280
for R, x in enumerate(seq):
378-
add(state, x) # Add current element to the state
379-
while invalid(state): # While the state is invalid
380-
remove(state, seq[L]) # Remove the leftmost element from the state
381-
L += 1 # Move the left pointer right
382-
ans = max(ans, R - L + 1) # Update the answer with the maximum window size
281+
add(state, x)
282+
while invalid(state):
283+
remove(state, seq[L]); L += 1
284+
ans = max(ans, R - L + 1)
383285
return ans
384286
385287
# Two pointers (opposite)
386288
def opposite(arr):
387289
L, R = 0, len(arr) - 1
388290
while L < R:
389-
if should_move_left(arr, L, R): # Determine if left pointer should move
291+
if should_move_left(arr, L, R):
390292
L += 1
391293
else:
392-
R -= 1 # Otherwise, move the right pointer
294+
R -= 1
393295
\`\`\`
394296
395297
---`;

0 commit comments

Comments
 (0)