skill-family-engineering-kit 0.2.0 → 0.2.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.
Files changed (70) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/CHANGELOG.zh-CN.md +21 -0
  3. package/NOTICE +10 -0
  4. package/README.md +157 -55
  5. package/README.zh-CN.md +207 -0
  6. package/candidate/index.mjs +4 -0
  7. package/candidate/profile-bundle.mjs +268 -0
  8. package/candidate/projection-bundle-cli.mjs +22 -0
  9. package/docs/404.html +1434 -408
  10. package/docs/agents/architecture-routing/index.html +1944 -0
  11. package/docs/agents/capability-catalog.en.json +1561 -0
  12. package/docs/agents/capability-catalog.json +934 -0
  13. package/docs/agents/capability-catalog.schema.json +179 -0
  14. package/docs/agents/capability-catalog.zh-CN.json +1561 -0
  15. package/docs/agents/index.html +1914 -0
  16. package/docs/architecture/index.html +1706 -497
  17. package/docs/assets/javascripts/lunr/tinyseg.js +2 -2
  18. package/docs/assets/javascripts/lunr/wordcut.js +37 -37
  19. package/docs/en/agents/architecture-routing/index.html +1944 -0
  20. package/docs/en/agents/index.html +1925 -0
  21. package/docs/en/architecture/index.html +2187 -0
  22. package/docs/en/examples-and-fixtures/index.html +1888 -0
  23. package/docs/en/help/index.html +2035 -0
  24. package/docs/en/index.html +1895 -0
  25. package/docs/en/licensing/index.html +1917 -0
  26. package/docs/en/migration/index.html +2334 -0
  27. package/docs/en/quickstart/index.html +1919 -0
  28. package/docs/en/recipes/adapter-text-closure/index.html +2000 -0
  29. package/docs/en/recipes/adopt-existing-repository/index.html +1986 -0
  30. package/docs/en/recipes/deterministic-human-report/index.html +1998 -0
  31. package/docs/en/recipes/domain-schema-validation/index.html +2007 -0
  32. package/docs/en/recipes/durable-local-state/index.html +2009 -0
  33. package/docs/en/recipes/host-profile-integration/index.html +2001 -0
  34. package/docs/en/recipes/index.html +1876 -0
  35. package/docs/en/recipes/safe-filesystem-and-atomic-write/index.html +1994 -0
  36. package/docs/en/reference/api/index.html +1917 -0
  37. package/docs/en/reference/compatibility/index.html +1990 -0
  38. package/docs/en/reference/failure-and-side-effect-matrix/index.html +2216 -0
  39. package/docs/examples-and-fixtures/index.html +1871 -0
  40. package/docs/git-lifecycle/index.html +1508 -482
  41. package/docs/help/index.html +1655 -554
  42. package/docs/index.html +1479 -450
  43. package/docs/integration/audit/failure-evidence/index.html +1488 -462
  44. package/docs/integration/audit/independence/index.html +1513 -487
  45. package/docs/integration/audit/index.html +1514 -488
  46. package/docs/integration/audit/mutation-taxonomy/index.html +1548 -522
  47. package/docs/integration/audit/version-compatibility/index.html +1489 -463
  48. package/docs/licensing/index.html +1917 -0
  49. package/docs/migration/index.html +1678 -586
  50. package/docs/public/status/index.html +1542 -516
  51. package/docs/quickstart/index.html +1589 -539
  52. package/docs/recipes/adapter-text-closure/index.html +2000 -0
  53. package/docs/recipes/adopt-existing-repository/index.html +1986 -0
  54. package/docs/recipes/deterministic-human-report/index.html +1998 -0
  55. package/docs/recipes/domain-schema-validation/index.html +2007 -0
  56. package/docs/recipes/durable-local-state/index.html +2009 -0
  57. package/docs/recipes/host-profile-integration/index.html +2001 -0
  58. package/docs/recipes/index.html +1876 -0
  59. package/docs/recipes/safe-filesystem-and-atomic-write/index.html +1994 -0
  60. package/docs/reference/api/contracts/index.html +2532 -0
  61. package/docs/reference/api/engineering-kit/index.html +2551 -0
  62. package/docs/reference/api/harness/index.html +2608 -0
  63. package/docs/reference/api/index.html +1857 -0
  64. package/docs/reference/compatibility/index.html +1990 -0
  65. package/docs/reference/failure-and-side-effect-matrix/index.html +2216 -0
  66. package/docs/search/search_index.json +1 -1
  67. package/docs/setup/index.html +1494 -468
  68. package/docs/sitemap.xml +152 -0
  69. package/package.json +14 -4
  70. package/release-notes/0.2.1.yaml +23 -0
@@ -0,0 +1,1994 @@
1
+
2
+ <!doctype html>
3
+ <html lang="zh" class="no-js">
4
+ <head>
5
+
6
+ <meta charset="utf-8">
7
+ <meta name="viewport" content="width=device-width,initial-scale=1">
8
+
9
+ <meta name="description" content="Skill Family 生命周期公共工程基础设施父工作区">
10
+
11
+
12
+
13
+ <link rel="canonical" href="https://ifoohoo.github.io/skill-family-engineering-kit/recipes/safe-filesystem-and-atomic-write/">
14
+
15
+
16
+ <link rel="prev" href="../adopt-existing-repository/">
17
+
18
+
19
+ <link rel="next" href="../adapter-text-closure/">
20
+
21
+
22
+
23
+
24
+
25
+ <link rel="icon" href="../../assets/images/favicon.png">
26
+ <meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
27
+
28
+
29
+
30
+ <title>中文 · 安全文件系统与原子写 - Skill Family Foundation</title>
31
+
32
+
33
+
34
+ <link rel="stylesheet" href="../../assets/stylesheets/main.ec1eaa64.min.css">
35
+
36
+
37
+ <link rel="stylesheet" href="../../assets/stylesheets/palette.ab4e12ef.min.css">
38
+
39
+
40
+
41
+
42
+
43
+
44
+
45
+
46
+
47
+
48
+
49
+
50
+ <script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
51
+
52
+
53
+
54
+
55
+
56
+ </head>
57
+
58
+
59
+
60
+
61
+
62
+
63
+
64
+
65
+
66
+ <body dir="ltr" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo">
67
+
68
+
69
+ <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
70
+ <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
71
+ <label class="md-overlay" for="__drawer"></label>
72
+ <div data-md-component="skip">
73
+
74
+
75
+ <a href="#Recipe安全文件访问与原子写" class="md-skip">
76
+ 跳转至
77
+ </a>
78
+
79
+ </div>
80
+ <div data-md-component="announce">
81
+
82
+ </div>
83
+
84
+
85
+
86
+
87
+
88
+
89
+ <header class="md-header md-header--shadow" data-md-component="header">
90
+ <nav class="md-header__inner md-grid" aria-label="页眉">
91
+ <a href="../.." title="Skill Family Foundation" class="md-header__button md-logo" aria-label="Skill Family Foundation" data-md-component="logo">
92
+
93
+
94
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
95
+
96
+ </a>
97
+ <label class="md-header__button md-icon" for="__drawer">
98
+
99
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
100
+ </label>
101
+ <div class="md-header__title" data-md-component="header-title">
102
+ <div class="md-header__ellipsis">
103
+ <div class="md-header__topic">
104
+ <span class="md-ellipsis">
105
+ Skill Family Foundation
106
+ </span>
107
+ </div>
108
+ <div class="md-header__topic" data-md-component="header-topic">
109
+ <span class="md-ellipsis">
110
+
111
+ 中文 · 安全文件系统与原子写
112
+
113
+ </span>
114
+ </div>
115
+ </div>
116
+ </div>
117
+
118
+
119
+ <form class="md-header__option" data-md-component="palette">
120
+
121
+
122
+
123
+
124
+ <input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="切换到深色模式" type="radio" name="__palette" id="__palette_0">
125
+
126
+ <label class="md-header__button md-icon" title="切换到深色模式" for="__palette_1" hidden>
127
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
128
+ </label>
129
+
130
+
131
+
132
+
133
+
134
+ <input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="切换到浅色模式" type="radio" name="__palette" id="__palette_1">
135
+
136
+ <label class="md-header__button md-icon" title="切换到浅色模式" for="__palette_0" hidden>
137
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
138
+ </label>
139
+
140
+
141
+ </form>
142
+
143
+
144
+
145
+ <script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
146
+
147
+
148
+
149
+
150
+
151
+ <label class="md-header__button md-icon" for="__search">
152
+
153
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
154
+ </label>
155
+ <div class="md-search" data-md-component="search" role="dialog">
156
+ <label class="md-search__overlay" for="__search"></label>
157
+ <div class="md-search__inner" role="search">
158
+ <form class="md-search__form" name="search">
159
+ <input type="text" class="md-search__input" name="query" aria-label="搜索" placeholder="搜索" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
160
+ <label class="md-search__icon md-icon" for="__search">
161
+
162
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
163
+
164
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
165
+ </label>
166
+ <nav class="md-search__options" aria-label="查找">
167
+
168
+ <button type="reset" class="md-search__icon md-icon" title="清空当前内容" aria-label="清空当前内容" tabindex="-1">
169
+
170
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
171
+ </button>
172
+ </nav>
173
+
174
+ </form>
175
+ <div class="md-search__output">
176
+ <div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
177
+ <div class="md-search-result" data-md-component="search-result">
178
+ <div class="md-search-result__meta">
179
+ 正在初始化搜索引擎
180
+ </div>
181
+ <ol class="md-search-result__list" role="presentation"></ol>
182
+ </div>
183
+ </div>
184
+ </div>
185
+ </div>
186
+ </div>
187
+
188
+
189
+
190
+ </nav>
191
+
192
+ </header>
193
+
194
+ <div class="md-container" data-md-component="container">
195
+
196
+
197
+
198
+
199
+
200
+
201
+ <main class="md-main" data-md-component="main">
202
+ <div class="md-main__inner md-grid">
203
+
204
+
205
+
206
+ <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
207
+ <div class="md-sidebar__scrollwrap">
208
+ <div class="md-sidebar__inner">
209
+
210
+
211
+
212
+
213
+ <nav class="md-nav md-nav--primary" aria-label="导航栏" data-md-level="0">
214
+ <label class="md-nav__title" for="__drawer">
215
+ <a href="../.." title="Skill Family Foundation" class="md-nav__button md-logo" aria-label="Skill Family Foundation" data-md-component="logo">
216
+
217
+
218
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
219
+
220
+ </a>
221
+ Skill Family Foundation
222
+ </label>
223
+
224
+ <ul class="md-nav__list" data-md-scrollfix>
225
+
226
+
227
+
228
+
229
+
230
+
231
+
232
+ <li class="md-nav__item">
233
+ <a href="../.." class="md-nav__link">
234
+
235
+
236
+
237
+ <span class="md-ellipsis">
238
+
239
+
240
+ 中文 · 首页
241
+
242
+
243
+
244
+ </span>
245
+
246
+
247
+
248
+ </a>
249
+ </li>
250
+
251
+
252
+
253
+
254
+
255
+
256
+
257
+
258
+
259
+ <li class="md-nav__item">
260
+ <a href="../../setup/" class="md-nav__link">
261
+
262
+
263
+
264
+ <span class="md-ellipsis">
265
+
266
+
267
+ 中文 · 安装与环境
268
+
269
+
270
+
271
+ </span>
272
+
273
+
274
+
275
+ </a>
276
+ </li>
277
+
278
+
279
+
280
+
281
+
282
+
283
+
284
+
285
+
286
+ <li class="md-nav__item">
287
+ <a href="../../quickstart/" class="md-nav__link">
288
+
289
+
290
+
291
+ <span class="md-ellipsis">
292
+
293
+
294
+ 中文 · 快速开始
295
+
296
+
297
+
298
+ </span>
299
+
300
+
301
+
302
+ </a>
303
+ </li>
304
+
305
+
306
+
307
+
308
+
309
+
310
+
311
+
312
+
313
+ <li class="md-nav__item">
314
+ <a href="../../git-lifecycle/" class="md-nav__link">
315
+
316
+
317
+
318
+ <span class="md-ellipsis">
319
+
320
+
321
+ 中文 · Git 生命周期指南
322
+
323
+
324
+
325
+ </span>
326
+
327
+
328
+
329
+ </a>
330
+ </li>
331
+
332
+
333
+
334
+
335
+
336
+
337
+
338
+
339
+
340
+ <li class="md-nav__item">
341
+ <a href="../../help/" class="md-nav__link">
342
+
343
+
344
+
345
+ <span class="md-ellipsis">
346
+
347
+
348
+ 中文 · 能力与诊断
349
+
350
+
351
+
352
+ </span>
353
+
354
+
355
+
356
+ </a>
357
+ </li>
358
+
359
+
360
+
361
+
362
+
363
+
364
+
365
+
366
+
367
+ <li class="md-nav__item">
368
+ <a href="../../architecture/" class="md-nav__link">
369
+
370
+
371
+
372
+ <span class="md-ellipsis">
373
+
374
+
375
+ 中文 · 架构边界
376
+
377
+
378
+
379
+ </span>
380
+
381
+
382
+
383
+ </a>
384
+ </li>
385
+
386
+
387
+
388
+
389
+
390
+
391
+
392
+
393
+
394
+ <li class="md-nav__item">
395
+ <a href="../../public/status/" class="md-nav__link">
396
+
397
+
398
+
399
+ <span class="md-ellipsis">
400
+
401
+
402
+ 中文 · 公开状态
403
+
404
+
405
+
406
+ </span>
407
+
408
+
409
+
410
+ </a>
411
+ </li>
412
+
413
+
414
+
415
+
416
+
417
+
418
+
419
+
420
+
421
+ <li class="md-nav__item">
422
+ <a href="../../migration/" class="md-nav__link">
423
+
424
+
425
+
426
+ <span class="md-ellipsis">
427
+
428
+
429
+ 中文 · 存量采用与迁移
430
+
431
+
432
+
433
+ </span>
434
+
435
+
436
+
437
+ </a>
438
+ </li>
439
+
440
+
441
+
442
+
443
+
444
+
445
+
446
+
447
+
448
+ <li class="md-nav__item">
449
+ <a href="../../licensing/" class="md-nav__link">
450
+
451
+
452
+
453
+ <span class="md-ellipsis">
454
+
455
+
456
+ 中文 · 许可与署名
457
+
458
+
459
+
460
+ </span>
461
+
462
+
463
+
464
+ </a>
465
+ </li>
466
+
467
+
468
+
469
+
470
+
471
+
472
+
473
+
474
+
475
+ <li class="md-nav__item">
476
+ <a href="../../agents/" class="md-nav__link">
477
+
478
+
479
+
480
+ <span class="md-ellipsis">
481
+
482
+
483
+ 中文 · 智能体入口
484
+
485
+
486
+
487
+ </span>
488
+
489
+
490
+
491
+ </a>
492
+ </li>
493
+
494
+
495
+
496
+
497
+
498
+
499
+
500
+
501
+
502
+ <li class="md-nav__item">
503
+ <a href="../../agents/architecture-routing/" class="md-nav__link">
504
+
505
+
506
+
507
+ <span class="md-ellipsis">
508
+
509
+
510
+ 中文 · 架构路由
511
+
512
+
513
+
514
+ </span>
515
+
516
+
517
+
518
+ </a>
519
+ </li>
520
+
521
+
522
+
523
+
524
+
525
+
526
+
527
+
528
+
529
+ <li class="md-nav__item">
530
+ <a href="../../reference/compatibility/" class="md-nav__link">
531
+
532
+
533
+
534
+ <span class="md-ellipsis">
535
+
536
+
537
+ 中文 · 兼容性
538
+
539
+
540
+
541
+ </span>
542
+
543
+
544
+
545
+ </a>
546
+ </li>
547
+
548
+
549
+
550
+
551
+
552
+
553
+
554
+
555
+
556
+ <li class="md-nav__item">
557
+ <a href="../../reference/failure-and-side-effect-matrix/" class="md-nav__link">
558
+
559
+
560
+
561
+ <span class="md-ellipsis">
562
+
563
+
564
+ 中文 · 失败与副作用
565
+
566
+
567
+
568
+ </span>
569
+
570
+
571
+
572
+ </a>
573
+ </li>
574
+
575
+
576
+
577
+
578
+
579
+
580
+
581
+
582
+
583
+ <li class="md-nav__item">
584
+ <a href="../../reference/api/" class="md-nav__link">
585
+
586
+
587
+
588
+ <span class="md-ellipsis">
589
+
590
+
591
+ 中文 · API 参考
592
+
593
+
594
+
595
+ </span>
596
+
597
+
598
+
599
+ </a>
600
+ </li>
601
+
602
+
603
+
604
+
605
+
606
+
607
+
608
+
609
+
610
+ <li class="md-nav__item">
611
+ <a href="../../reference/api/contracts/" class="md-nav__link">
612
+
613
+
614
+
615
+ <span class="md-ellipsis">
616
+
617
+
618
+ 中文 · Contracts API
619
+
620
+
621
+
622
+ </span>
623
+
624
+
625
+
626
+ </a>
627
+ </li>
628
+
629
+
630
+
631
+
632
+
633
+
634
+
635
+
636
+
637
+ <li class="md-nav__item">
638
+ <a href="../../reference/api/harness/" class="md-nav__link">
639
+
640
+
641
+
642
+ <span class="md-ellipsis">
643
+
644
+
645
+ 中文 · Harness API
646
+
647
+
648
+
649
+ </span>
650
+
651
+
652
+
653
+ </a>
654
+ </li>
655
+
656
+
657
+
658
+
659
+
660
+
661
+
662
+
663
+
664
+ <li class="md-nav__item">
665
+ <a href="../../reference/api/engineering-kit/" class="md-nav__link">
666
+
667
+
668
+
669
+ <span class="md-ellipsis">
670
+
671
+
672
+ 中文 · Engineering Kit API
673
+
674
+
675
+
676
+ </span>
677
+
678
+
679
+
680
+ </a>
681
+ </li>
682
+
683
+
684
+
685
+
686
+
687
+
688
+
689
+
690
+
691
+ <li class="md-nav__item">
692
+ <a href="../../examples-and-fixtures/" class="md-nav__link">
693
+
694
+
695
+
696
+ <span class="md-ellipsis">
697
+
698
+
699
+ 中文 · 样例与 Fixture
700
+
701
+
702
+
703
+ </span>
704
+
705
+
706
+
707
+ </a>
708
+ </li>
709
+
710
+
711
+
712
+
713
+
714
+
715
+
716
+
717
+
718
+ <li class="md-nav__item">
719
+ <a href="../" class="md-nav__link">
720
+
721
+
722
+
723
+ <span class="md-ellipsis">
724
+
725
+
726
+ 中文 · Recipes
727
+
728
+
729
+
730
+ </span>
731
+
732
+
733
+
734
+ </a>
735
+ </li>
736
+
737
+
738
+
739
+
740
+
741
+
742
+
743
+
744
+
745
+ <li class="md-nav__item">
746
+ <a href="../adopt-existing-repository/" class="md-nav__link">
747
+
748
+
749
+
750
+ <span class="md-ellipsis">
751
+
752
+
753
+ 中文 · 采用存量仓库
754
+
755
+
756
+
757
+ </span>
758
+
759
+
760
+
761
+ </a>
762
+ </li>
763
+
764
+
765
+
766
+
767
+
768
+
769
+
770
+
771
+
772
+
773
+
774
+ <li class="md-nav__item md-nav__item--active">
775
+
776
+ <input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
777
+
778
+
779
+
780
+
781
+
782
+ <label class="md-nav__link md-nav__link--active" for="__toc">
783
+
784
+
785
+
786
+ <span class="md-ellipsis">
787
+
788
+
789
+ 中文 · 安全文件系统与原子写
790
+
791
+
792
+
793
+ </span>
794
+
795
+
796
+
797
+ <span class="md-nav__icon md-icon"></span>
798
+ </label>
799
+
800
+ <a href="./" class="md-nav__link md-nav__link--active">
801
+
802
+
803
+
804
+ <span class="md-ellipsis">
805
+
806
+
807
+ 中文 · 安全文件系统与原子写
808
+
809
+
810
+
811
+ </span>
812
+
813
+
814
+
815
+ </a>
816
+
817
+
818
+
819
+ <nav class="md-nav md-nav--secondary" aria-label="目录">
820
+
821
+
822
+
823
+
824
+
825
+
826
+ <label class="md-nav__title" for="__toc">
827
+ <span class="md-nav__icon md-icon"></span>
828
+ 目录
829
+ </label>
830
+ <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
831
+
832
+ <li class="md-nav__item">
833
+ <a href="#1-场景与非场景" class="md-nav__link">
834
+ <span class="md-ellipsis">
835
+
836
+ 1. 场景与非场景
837
+
838
+ </span>
839
+ </a>
840
+
841
+ </li>
842
+
843
+ <li class="md-nav__item">
844
+ <a href="#2-架构选择及能力-ID" class="md-nav__link">
845
+ <span class="md-ellipsis">
846
+
847
+ 2. 架构选择及能力 ID
848
+
849
+ </span>
850
+ </a>
851
+
852
+ </li>
853
+
854
+ <li class="md-nav__item">
855
+ <a href="#3-前置条件与信任边界" class="md-nav__link">
856
+ <span class="md-ellipsis">
857
+
858
+ 3. 前置条件与信任边界
859
+
860
+ </span>
861
+ </a>
862
+
863
+ </li>
864
+
865
+ <li class="md-nav__item">
866
+ <a href="#4-最小代码" class="md-nav__link">
867
+ <span class="md-ellipsis">
868
+
869
+ 4. 最小代码
870
+
871
+ </span>
872
+ </a>
873
+
874
+ </li>
875
+
876
+ <li class="md-nav__item">
877
+ <a href="#5-预期输出与证据" class="md-nav__link">
878
+ <span class="md-ellipsis">
879
+
880
+ 5. 预期输出与证据
881
+
882
+ </span>
883
+ </a>
884
+
885
+ </li>
886
+
887
+ <li class="md-nav__item">
888
+ <a href="#6-安全失败负例" class="md-nav__link">
889
+ <span class="md-ellipsis">
890
+
891
+ 6. 安全/失败负例
892
+
893
+ </span>
894
+ </a>
895
+
896
+ </li>
897
+
898
+ <li class="md-nav__item">
899
+ <a href="#7-可复制验证命令" class="md-nav__link">
900
+ <span class="md-ellipsis">
901
+
902
+ 7. 可复制验证命令
903
+
904
+ </span>
905
+ </a>
906
+
907
+ </li>
908
+
909
+ <li class="md-nav__item">
910
+ <a href="#8-调用方继续拥有的业务逻辑" class="md-nav__link">
911
+ <span class="md-ellipsis">
912
+
913
+ 8. 调用方继续拥有的业务逻辑
914
+
915
+ </span>
916
+ </a>
917
+
918
+ </li>
919
+
920
+ <li class="md-nav__item">
921
+ <a href="#9-升级与回滚注意事项" class="md-nav__link">
922
+ <span class="md-ellipsis">
923
+
924
+ 9. 升级与回滚注意事项
925
+
926
+ </span>
927
+ </a>
928
+
929
+ </li>
930
+
931
+ </ul>
932
+
933
+ </nav>
934
+
935
+ </li>
936
+
937
+
938
+
939
+
940
+
941
+
942
+
943
+
944
+
945
+ <li class="md-nav__item">
946
+ <a href="../adapter-text-closure/" class="md-nav__link">
947
+
948
+
949
+
950
+ <span class="md-ellipsis">
951
+
952
+
953
+ 中文 · Adapter 文本闭包
954
+
955
+
956
+
957
+ </span>
958
+
959
+
960
+
961
+ </a>
962
+ </li>
963
+
964
+
965
+
966
+
967
+
968
+
969
+
970
+
971
+
972
+ <li class="md-nav__item">
973
+ <a href="../deterministic-human-report/" class="md-nav__link">
974
+
975
+
976
+
977
+ <span class="md-ellipsis">
978
+
979
+
980
+ 中文 · 确定性人类报告
981
+
982
+
983
+
984
+ </span>
985
+
986
+
987
+
988
+ </a>
989
+ </li>
990
+
991
+
992
+
993
+
994
+
995
+
996
+
997
+
998
+
999
+ <li class="md-nav__item">
1000
+ <a href="../durable-local-state/" class="md-nav__link">
1001
+
1002
+
1003
+
1004
+ <span class="md-ellipsis">
1005
+
1006
+
1007
+ 中文 · 持久本地状态
1008
+
1009
+
1010
+
1011
+ </span>
1012
+
1013
+
1014
+
1015
+ </a>
1016
+ </li>
1017
+
1018
+
1019
+
1020
+
1021
+
1022
+
1023
+
1024
+
1025
+
1026
+ <li class="md-nav__item">
1027
+ <a href="../host-profile-integration/" class="md-nav__link">
1028
+
1029
+
1030
+
1031
+ <span class="md-ellipsis">
1032
+
1033
+
1034
+ 中文 · 宿主 Profile 集成
1035
+
1036
+
1037
+
1038
+ </span>
1039
+
1040
+
1041
+
1042
+ </a>
1043
+ </li>
1044
+
1045
+
1046
+
1047
+
1048
+
1049
+
1050
+
1051
+
1052
+
1053
+ <li class="md-nav__item">
1054
+ <a href="../domain-schema-validation/" class="md-nav__link">
1055
+
1056
+
1057
+
1058
+ <span class="md-ellipsis">
1059
+
1060
+
1061
+ 中文 · 领域 Schema 校验
1062
+
1063
+
1064
+
1065
+ </span>
1066
+
1067
+
1068
+
1069
+ </a>
1070
+ </li>
1071
+
1072
+
1073
+
1074
+
1075
+
1076
+
1077
+
1078
+
1079
+
1080
+ <li class="md-nav__item">
1081
+ <a href="../../en/" class="md-nav__link">
1082
+
1083
+
1084
+
1085
+ <span class="md-ellipsis">
1086
+
1087
+
1088
+ English · Home
1089
+
1090
+
1091
+
1092
+ </span>
1093
+
1094
+
1095
+
1096
+ </a>
1097
+ </li>
1098
+
1099
+
1100
+
1101
+
1102
+
1103
+
1104
+
1105
+
1106
+
1107
+ <li class="md-nav__item">
1108
+ <a href="../../en/quickstart/" class="md-nav__link">
1109
+
1110
+
1111
+
1112
+ <span class="md-ellipsis">
1113
+
1114
+
1115
+ English · Quickstart
1116
+
1117
+
1118
+
1119
+ </span>
1120
+
1121
+
1122
+
1123
+ </a>
1124
+ </li>
1125
+
1126
+
1127
+
1128
+
1129
+
1130
+
1131
+
1132
+
1133
+
1134
+ <li class="md-nav__item">
1135
+ <a href="../../en/help/" class="md-nav__link">
1136
+
1137
+
1138
+
1139
+ <span class="md-ellipsis">
1140
+
1141
+
1142
+ English · Capabilities and diagnostics
1143
+
1144
+
1145
+
1146
+ </span>
1147
+
1148
+
1149
+
1150
+ </a>
1151
+ </li>
1152
+
1153
+
1154
+
1155
+
1156
+
1157
+
1158
+
1159
+
1160
+
1161
+ <li class="md-nav__item">
1162
+ <a href="../../en/architecture/" class="md-nav__link">
1163
+
1164
+
1165
+
1166
+ <span class="md-ellipsis">
1167
+
1168
+
1169
+ English · Architecture
1170
+
1171
+
1172
+
1173
+ </span>
1174
+
1175
+
1176
+
1177
+ </a>
1178
+ </li>
1179
+
1180
+
1181
+
1182
+
1183
+
1184
+
1185
+
1186
+
1187
+
1188
+ <li class="md-nav__item">
1189
+ <a href="../../en/migration/" class="md-nav__link">
1190
+
1191
+
1192
+
1193
+ <span class="md-ellipsis">
1194
+
1195
+
1196
+ English · Migration
1197
+
1198
+
1199
+
1200
+ </span>
1201
+
1202
+
1203
+
1204
+ </a>
1205
+ </li>
1206
+
1207
+
1208
+
1209
+
1210
+
1211
+
1212
+
1213
+
1214
+
1215
+ <li class="md-nav__item">
1216
+ <a href="../../en/licensing/" class="md-nav__link">
1217
+
1218
+
1219
+
1220
+ <span class="md-ellipsis">
1221
+
1222
+
1223
+ English · Licensing
1224
+
1225
+
1226
+
1227
+ </span>
1228
+
1229
+
1230
+
1231
+ </a>
1232
+ </li>
1233
+
1234
+
1235
+
1236
+
1237
+
1238
+
1239
+
1240
+
1241
+
1242
+ <li class="md-nav__item">
1243
+ <a href="../../en/agents/" class="md-nav__link">
1244
+
1245
+
1246
+
1247
+ <span class="md-ellipsis">
1248
+
1249
+
1250
+ English · Agent entry
1251
+
1252
+
1253
+
1254
+ </span>
1255
+
1256
+
1257
+
1258
+ </a>
1259
+ </li>
1260
+
1261
+
1262
+
1263
+
1264
+
1265
+
1266
+
1267
+
1268
+
1269
+ <li class="md-nav__item">
1270
+ <a href="../../en/agents/architecture-routing/" class="md-nav__link">
1271
+
1272
+
1273
+
1274
+ <span class="md-ellipsis">
1275
+
1276
+
1277
+ English · Architecture routing
1278
+
1279
+
1280
+
1281
+ </span>
1282
+
1283
+
1284
+
1285
+ </a>
1286
+ </li>
1287
+
1288
+
1289
+
1290
+
1291
+
1292
+
1293
+
1294
+
1295
+
1296
+ <li class="md-nav__item">
1297
+ <a href="../../en/reference/compatibility/" class="md-nav__link">
1298
+
1299
+
1300
+
1301
+ <span class="md-ellipsis">
1302
+
1303
+
1304
+ English · Compatibility
1305
+
1306
+
1307
+
1308
+ </span>
1309
+
1310
+
1311
+
1312
+ </a>
1313
+ </li>
1314
+
1315
+
1316
+
1317
+
1318
+
1319
+
1320
+
1321
+
1322
+
1323
+ <li class="md-nav__item">
1324
+ <a href="../../en/reference/failure-and-side-effect-matrix/" class="md-nav__link">
1325
+
1326
+
1327
+
1328
+ <span class="md-ellipsis">
1329
+
1330
+
1331
+ English · Failures and side effects
1332
+
1333
+
1334
+
1335
+ </span>
1336
+
1337
+
1338
+
1339
+ </a>
1340
+ </li>
1341
+
1342
+
1343
+
1344
+
1345
+
1346
+
1347
+
1348
+
1349
+
1350
+ <li class="md-nav__item">
1351
+ <a href="../../en/reference/api/" class="md-nav__link">
1352
+
1353
+
1354
+
1355
+ <span class="md-ellipsis">
1356
+
1357
+
1358
+ English · API reference
1359
+
1360
+
1361
+
1362
+ </span>
1363
+
1364
+
1365
+
1366
+ </a>
1367
+ </li>
1368
+
1369
+
1370
+
1371
+
1372
+
1373
+
1374
+
1375
+
1376
+
1377
+ <li class="md-nav__item">
1378
+ <a href="../../en/examples-and-fixtures/" class="md-nav__link">
1379
+
1380
+
1381
+
1382
+ <span class="md-ellipsis">
1383
+
1384
+
1385
+ English · Examples and fixtures
1386
+
1387
+
1388
+
1389
+ </span>
1390
+
1391
+
1392
+
1393
+ </a>
1394
+ </li>
1395
+
1396
+
1397
+
1398
+
1399
+
1400
+
1401
+
1402
+
1403
+
1404
+ <li class="md-nav__item">
1405
+ <a href="../../en/recipes/" class="md-nav__link">
1406
+
1407
+
1408
+
1409
+ <span class="md-ellipsis">
1410
+
1411
+
1412
+ English · Recipes
1413
+
1414
+
1415
+
1416
+ </span>
1417
+
1418
+
1419
+
1420
+ </a>
1421
+ </li>
1422
+
1423
+
1424
+
1425
+
1426
+
1427
+
1428
+
1429
+
1430
+
1431
+ <li class="md-nav__item">
1432
+ <a href="../../en/recipes/adopt-existing-repository/" class="md-nav__link">
1433
+
1434
+
1435
+
1436
+ <span class="md-ellipsis">
1437
+
1438
+
1439
+ English · Adopt an existing repository
1440
+
1441
+
1442
+
1443
+ </span>
1444
+
1445
+
1446
+
1447
+ </a>
1448
+ </li>
1449
+
1450
+
1451
+
1452
+
1453
+
1454
+
1455
+
1456
+
1457
+
1458
+ <li class="md-nav__item">
1459
+ <a href="../../en/recipes/safe-filesystem-and-atomic-write/" class="md-nav__link">
1460
+
1461
+
1462
+
1463
+ <span class="md-ellipsis">
1464
+
1465
+
1466
+ English · Safe filesystem and atomic write
1467
+
1468
+
1469
+
1470
+ </span>
1471
+
1472
+
1473
+
1474
+ </a>
1475
+ </li>
1476
+
1477
+
1478
+
1479
+
1480
+
1481
+
1482
+
1483
+
1484
+
1485
+ <li class="md-nav__item">
1486
+ <a href="../../en/recipes/adapter-text-closure/" class="md-nav__link">
1487
+
1488
+
1489
+
1490
+ <span class="md-ellipsis">
1491
+
1492
+
1493
+ English · Adapter text closure
1494
+
1495
+
1496
+
1497
+ </span>
1498
+
1499
+
1500
+
1501
+ </a>
1502
+ </li>
1503
+
1504
+
1505
+
1506
+
1507
+
1508
+
1509
+
1510
+
1511
+
1512
+ <li class="md-nav__item">
1513
+ <a href="../../en/recipes/deterministic-human-report/" class="md-nav__link">
1514
+
1515
+
1516
+
1517
+ <span class="md-ellipsis">
1518
+
1519
+
1520
+ English · Deterministic human report
1521
+
1522
+
1523
+
1524
+ </span>
1525
+
1526
+
1527
+
1528
+ </a>
1529
+ </li>
1530
+
1531
+
1532
+
1533
+
1534
+
1535
+
1536
+
1537
+
1538
+
1539
+ <li class="md-nav__item">
1540
+ <a href="../../en/recipes/durable-local-state/" class="md-nav__link">
1541
+
1542
+
1543
+
1544
+ <span class="md-ellipsis">
1545
+
1546
+
1547
+ English · Durable local state
1548
+
1549
+
1550
+
1551
+ </span>
1552
+
1553
+
1554
+
1555
+ </a>
1556
+ </li>
1557
+
1558
+
1559
+
1560
+
1561
+
1562
+
1563
+
1564
+
1565
+
1566
+ <li class="md-nav__item">
1567
+ <a href="../../en/recipes/host-profile-integration/" class="md-nav__link">
1568
+
1569
+
1570
+
1571
+ <span class="md-ellipsis">
1572
+
1573
+
1574
+ English · Host Profile integration
1575
+
1576
+
1577
+
1578
+ </span>
1579
+
1580
+
1581
+
1582
+ </a>
1583
+ </li>
1584
+
1585
+
1586
+
1587
+
1588
+
1589
+
1590
+
1591
+
1592
+
1593
+ <li class="md-nav__item">
1594
+ <a href="../../en/recipes/domain-schema-validation/" class="md-nav__link">
1595
+
1596
+
1597
+
1598
+ <span class="md-ellipsis">
1599
+
1600
+
1601
+ English · Domain Schema validation
1602
+
1603
+
1604
+
1605
+ </span>
1606
+
1607
+
1608
+
1609
+ </a>
1610
+ </li>
1611
+
1612
+
1613
+
1614
+
1615
+
1616
+
1617
+
1618
+
1619
+
1620
+ <li class="md-nav__item">
1621
+ <a href="../../integration/audit/" class="md-nav__link">
1622
+
1623
+
1624
+
1625
+ <span class="md-ellipsis">
1626
+
1627
+
1628
+ 审计集成 · 入口
1629
+
1630
+
1631
+
1632
+ </span>
1633
+
1634
+
1635
+
1636
+ </a>
1637
+ </li>
1638
+
1639
+
1640
+
1641
+
1642
+
1643
+
1644
+
1645
+
1646
+
1647
+ <li class="md-nav__item">
1648
+ <a href="../../integration/audit/mutation-taxonomy/" class="md-nav__link">
1649
+
1650
+
1651
+
1652
+ <span class="md-ellipsis">
1653
+
1654
+
1655
+ 审计集成 · 变异分类学
1656
+
1657
+
1658
+
1659
+ </span>
1660
+
1661
+
1662
+
1663
+ </a>
1664
+ </li>
1665
+
1666
+
1667
+
1668
+
1669
+
1670
+
1671
+
1672
+
1673
+
1674
+ <li class="md-nav__item">
1675
+ <a href="../../integration/audit/independence/" class="md-nav__link">
1676
+
1677
+
1678
+
1679
+ <span class="md-ellipsis">
1680
+
1681
+
1682
+ 审计集成 · 独立性证明
1683
+
1684
+
1685
+
1686
+ </span>
1687
+
1688
+
1689
+
1690
+ </a>
1691
+ </li>
1692
+
1693
+
1694
+
1695
+
1696
+
1697
+
1698
+
1699
+
1700
+
1701
+ <li class="md-nav__item">
1702
+ <a href="../../integration/audit/version-compatibility/" class="md-nav__link">
1703
+
1704
+
1705
+
1706
+ <span class="md-ellipsis">
1707
+
1708
+
1709
+ 审计集成 · 版本兼容
1710
+
1711
+
1712
+
1713
+ </span>
1714
+
1715
+
1716
+
1717
+ </a>
1718
+ </li>
1719
+
1720
+
1721
+
1722
+
1723
+
1724
+
1725
+
1726
+
1727
+
1728
+ <li class="md-nav__item">
1729
+ <a href="../../integration/audit/failure-evidence/" class="md-nav__link">
1730
+
1731
+
1732
+
1733
+ <span class="md-ellipsis">
1734
+
1735
+
1736
+ 审计集成 · 失败证据与 AUD 码
1737
+
1738
+
1739
+
1740
+ </span>
1741
+
1742
+
1743
+
1744
+ </a>
1745
+ </li>
1746
+
1747
+
1748
+
1749
+ </ul>
1750
+ </nav>
1751
+ </div>
1752
+ </div>
1753
+ </div>
1754
+
1755
+
1756
+
1757
+ <div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
1758
+ <div class="md-sidebar__scrollwrap">
1759
+ <div class="md-sidebar__inner">
1760
+
1761
+
1762
+ <nav class="md-nav md-nav--secondary" aria-label="目录">
1763
+
1764
+
1765
+
1766
+
1767
+
1768
+
1769
+ <label class="md-nav__title" for="__toc">
1770
+ <span class="md-nav__icon md-icon"></span>
1771
+ 目录
1772
+ </label>
1773
+ <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
1774
+
1775
+ <li class="md-nav__item">
1776
+ <a href="#1-场景与非场景" class="md-nav__link">
1777
+ <span class="md-ellipsis">
1778
+
1779
+ 1. 场景与非场景
1780
+
1781
+ </span>
1782
+ </a>
1783
+
1784
+ </li>
1785
+
1786
+ <li class="md-nav__item">
1787
+ <a href="#2-架构选择及能力-ID" class="md-nav__link">
1788
+ <span class="md-ellipsis">
1789
+
1790
+ 2. 架构选择及能力 ID
1791
+
1792
+ </span>
1793
+ </a>
1794
+
1795
+ </li>
1796
+
1797
+ <li class="md-nav__item">
1798
+ <a href="#3-前置条件与信任边界" class="md-nav__link">
1799
+ <span class="md-ellipsis">
1800
+
1801
+ 3. 前置条件与信任边界
1802
+
1803
+ </span>
1804
+ </a>
1805
+
1806
+ </li>
1807
+
1808
+ <li class="md-nav__item">
1809
+ <a href="#4-最小代码" class="md-nav__link">
1810
+ <span class="md-ellipsis">
1811
+
1812
+ 4. 最小代码
1813
+
1814
+ </span>
1815
+ </a>
1816
+
1817
+ </li>
1818
+
1819
+ <li class="md-nav__item">
1820
+ <a href="#5-预期输出与证据" class="md-nav__link">
1821
+ <span class="md-ellipsis">
1822
+
1823
+ 5. 预期输出与证据
1824
+
1825
+ </span>
1826
+ </a>
1827
+
1828
+ </li>
1829
+
1830
+ <li class="md-nav__item">
1831
+ <a href="#6-安全失败负例" class="md-nav__link">
1832
+ <span class="md-ellipsis">
1833
+
1834
+ 6. 安全/失败负例
1835
+
1836
+ </span>
1837
+ </a>
1838
+
1839
+ </li>
1840
+
1841
+ <li class="md-nav__item">
1842
+ <a href="#7-可复制验证命令" class="md-nav__link">
1843
+ <span class="md-ellipsis">
1844
+
1845
+ 7. 可复制验证命令
1846
+
1847
+ </span>
1848
+ </a>
1849
+
1850
+ </li>
1851
+
1852
+ <li class="md-nav__item">
1853
+ <a href="#8-调用方继续拥有的业务逻辑" class="md-nav__link">
1854
+ <span class="md-ellipsis">
1855
+
1856
+ 8. 调用方继续拥有的业务逻辑
1857
+
1858
+ </span>
1859
+ </a>
1860
+
1861
+ </li>
1862
+
1863
+ <li class="md-nav__item">
1864
+ <a href="#9-升级与回滚注意事项" class="md-nav__link">
1865
+ <span class="md-ellipsis">
1866
+
1867
+ 9. 升级与回滚注意事项
1868
+
1869
+ </span>
1870
+ </a>
1871
+
1872
+ </li>
1873
+
1874
+ </ul>
1875
+
1876
+ </nav>
1877
+ </div>
1878
+ </div>
1879
+ </div>
1880
+
1881
+
1882
+
1883
+ <div class="md-content" data-md-component="content">
1884
+
1885
+ <article class="md-content__inner md-typeset">
1886
+
1887
+
1888
+
1889
+
1890
+
1891
+ <blockquote>
1892
+ <p><a href="../../en/recipes/safe-filesystem-and-atomic-write/">English</a></p>
1893
+ </blockquote>
1894
+ <h1 id="Recipe安全文件访问与原子写">Recipe:安全文件访问与原子写<a class="headerlink" href="#Recipe安全文件访问与原子写" title="Permanent link">&para;</a></h1>
1895
+ <h2 id="1-场景与非场景">1. 场景与非场景<a class="headerlink" href="#1-场景与非场景" title="Permanent link">&para;</a></h2>
1896
+ <p>适用:需要在 Node 内把外部提供的路径限制在某个根目录内,并向受收容路径原子写入普通文件,失败时回滚不留残影。</p>
1897
+ <p>不适用:需要把文件选择的业务规则放入 Foundation(业务规则由调用方拥有);需要写入未受收容路径。</p>
1898
+ <h2 id="2-架构选择及能力-ID">2. 架构选择及能力 ID<a class="headerlink" href="#2-架构选择及能力-ID" title="Permanent link">&para;</a></h2>
1899
+ <p>首选能力:<code>foundation.harness.path-containment</code>(路径分类与受收容解析)与 <code>foundation.harness.atomic-write</code>(受收容路径内原子写)。两者都只实现机制,不拥有语义。</p>
1900
+ <h2 id="3-前置条件与信任边界">3. 前置条件与信任边界<a class="headerlink" href="#3-前置条件与信任边界" title="Permanent link">&para;</a></h2>
1901
+ <ul>
1902
+ <li>调用方提供明确的根目录(收容边界)。</li>
1903
+ <li>信任边界:所有解析结果必须落在根目录内;越界、符号链接逃逸、真实路径逃逸均被拒绝。</li>
1904
+ </ul>
1905
+ <h2 id="4-最小代码">4. 最小代码<a class="headerlink" href="#4-最小代码" title="Permanent link">&para;</a></h2>
1906
+ <pre><code class="language-js">import { mkdtempSync } from &quot;node:fs&quot;;
1907
+ import { tmpdir } from &quot;node:os&quot;;
1908
+ import { join } from &quot;node:path&quot;;
1909
+ import { resolveContained, writeFileAtomic } from &quot;skill-family-harness-node&quot;;
1910
+
1911
+ const root = mkdtempSync(join(tmpdir(), &quot;sf-safe-&quot;));
1912
+ const target = resolveContained(root, &quot;nested/config.json&quot;); // 受收容绝对路径
1913
+ await writeFileAtomic(target, JSON.stringify({ ok: true }));
1914
+ </code></pre>
1915
+ <p>以上代码展示了先收容路径、再原子写入的基本顺序;<code>writeFileAtomic</code> 用临时文件 + fsync + rename,失败回滚。</p>
1916
+ <h2 id="5-预期输出与证据">5. 预期输出与证据<a class="headerlink" href="#5-预期输出与证据" title="Permanent link">&para;</a></h2>
1917
+ <p><code>resolveContained</code> 返回落在根内的绝对路径;<code>writeFileAtomic</code> 写入完成的文件,字节与输入一致。证据:<code>packages/skill-family-harness-node/test/containment.test.mjs</code> 与 <code>test/atomic.test.mjs</code>。</p>
1918
+ <h2 id="6-安全失败负例">6. 安全/失败负例<a class="headerlink" href="#6-安全失败负例" title="Permanent link">&para;</a></h2>
1919
+ <pre><code class="language-js">// 负例:试图越出根目录 -&gt; SFC2004 (path-traversal)
1920
+ import { resolveContained } from &quot;skill-family-harness-node&quot;;
1921
+ resolveContained(root, &quot;../escape.json&quot;); // 抛 HarnessError,details.kind = &quot;path-traversal&quot;
1922
+ </code></pre>
1923
+ <p>越界、symlink-escape、realpath-escape 均归 <code>SFC2004</code> 加稳定 <code>details.kind</code>;原子写对越界路径或非法数据类型抛错并回滚临时文件。</p>
1924
+ <h2 id="7-可复制验证命令">7. 可复制验证命令<a class="headerlink" href="#7-可复制验证命令" title="Permanent link">&para;</a></h2>
1925
+ <pre><code class="language-sh">node --test packages/skill-family-harness-node/test/containment.test.mjs \
1926
+ packages/skill-family-harness-node/test/atomic.test.mjs
1927
+ </code></pre>
1928
+ <h2 id="8-调用方继续拥有的业务逻辑">8. 调用方继续拥有的业务逻辑<a class="headerlink" href="#8-调用方继续拥有的业务逻辑" title="Permanent link">&para;</a></h2>
1929
+ <ul>
1930
+ <li>哪些路径是业务允许的选择规则(不在 Foundation 内)。</li>
1931
+ <li>写入内容的业务正确性。</li>
1932
+ </ul>
1933
+ <h2 id="9-升级与回滚注意事项">9. 升级与回滚注意事项<a class="headerlink" href="#9-升级与回滚注意事项" title="Permanent link">&para;</a></h2>
1934
+ <ul>
1935
+ <li>路径收容与原子写均为受收容机制,失败回滚不留半成品,无外部回滚需求。</li>
1936
+ <li>升级跟随 <code>skill-family-harness-node</code> 版本;<code>HARNESS_EXCLUSIONS</code> 不引入远端或 git 写。</li>
1937
+ </ul>
1938
+
1939
+
1940
+
1941
+
1942
+
1943
+
1944
+
1945
+
1946
+
1947
+
1948
+
1949
+
1950
+
1951
+ </article>
1952
+ </div>
1953
+
1954
+
1955
+ <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
1956
+ </div>
1957
+
1958
+ </main>
1959
+
1960
+ <footer class="md-footer">
1961
+
1962
+ <div class="md-footer-meta md-typeset">
1963
+ <div class="md-footer-meta__inner md-grid">
1964
+ <div class="md-copyright">
1965
+
1966
+
1967
+ Made with
1968
+ <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
1969
+ Material for MkDocs
1970
+ </a>
1971
+
1972
+ </div>
1973
+
1974
+ </div>
1975
+ </div>
1976
+ </footer>
1977
+
1978
+ </div>
1979
+ <div class="md-dialog" data-md-component="dialog">
1980
+ <div class="md-dialog__inner md-typeset"></div>
1981
+ </div>
1982
+
1983
+
1984
+
1985
+
1986
+
1987
+ <script id="__config" type="application/json">{"annotate": null, "base": "../..", "features": [], "search": "../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "\u5df2\u590d\u5236", "clipboard.copy": "\u590d\u5236", "search.result.more.one": "\u5728\u8be5\u9875\u4e0a\u8fd8\u6709 1 \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.more.other": "\u5728\u8be5\u9875\u4e0a\u8fd8\u6709 # \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.none": "\u6ca1\u6709\u627e\u5230\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.one": "\u627e\u5230 1 \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.other": "# \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.placeholder": "\u952e\u5165\u4ee5\u5f00\u59cb\u641c\u7d22", "search.result.term.missing": "\u7f3a\u5c11", "select.version": "\u9009\u62e9\u5f53\u524d\u7248\u672c"}, "version": null}</script>
1988
+
1989
+
1990
+ <script src="../../assets/javascripts/bundle.d7400e89.min.js"></script>
1991
+
1992
+
1993
+ </body>
1994
+ </html>