@latysh-development/monolith 0.0.0-stage → 0.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (291) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +132 -2
  3. package/dist/brief/cli.d.ts +30 -0
  4. package/dist/brief/cli.d.ts.map +1 -0
  5. package/dist/brief/cli.js +85 -0
  6. package/dist/brief/collect.d.ts +17 -0
  7. package/dist/brief/collect.d.ts.map +1 -0
  8. package/dist/brief/collect.js +302 -0
  9. package/dist/brief/config.d.ts +40 -0
  10. package/dist/brief/config.d.ts.map +1 -0
  11. package/dist/brief/config.js +85 -0
  12. package/dist/brief/constants.d.ts +10 -0
  13. package/dist/brief/constants.d.ts.map +1 -0
  14. package/dist/brief/constants.js +9 -0
  15. package/dist/brief/docs.d.ts +53 -0
  16. package/dist/brief/docs.d.ts.map +1 -0
  17. package/dist/brief/docs.js +229 -0
  18. package/dist/brief/freshness.d.ts +104 -0
  19. package/dist/brief/freshness.d.ts.map +1 -0
  20. package/dist/brief/freshness.js +263 -0
  21. package/dist/brief/git-signals.d.ts +17 -0
  22. package/dist/brief/git-signals.d.ts.map +1 -0
  23. package/dist/brief/git-signals.js +101 -0
  24. package/dist/brief/index.d.ts +11 -0
  25. package/dist/brief/index.d.ts.map +1 -0
  26. package/dist/brief/index.js +5 -0
  27. package/dist/brief/reconcile.d.ts +75 -0
  28. package/dist/brief/reconcile.d.ts.map +1 -0
  29. package/dist/brief/reconcile.js +259 -0
  30. package/dist/brief/render.d.ts +60 -0
  31. package/dist/brief/render.d.ts.map +1 -0
  32. package/dist/brief/render.js +407 -0
  33. package/dist/brief/sanitize.d.ts +38 -0
  34. package/dist/brief/sanitize.d.ts.map +1 -0
  35. package/dist/brief/sanitize.js +48 -0
  36. package/dist/brief/selectors.d.ts +36 -0
  37. package/dist/brief/selectors.d.ts.map +1 -0
  38. package/dist/brief/selectors.js +75 -0
  39. package/dist/brief/story.d.ts +18 -0
  40. package/dist/brief/story.d.ts.map +1 -0
  41. package/dist/brief/story.js +59 -0
  42. package/dist/brief/types.d.ts +110 -0
  43. package/dist/brief/types.d.ts.map +1 -0
  44. package/dist/brief/types.js +11 -0
  45. package/dist/cli/index.d.ts +3 -0
  46. package/dist/cli/index.d.ts.map +1 -0
  47. package/dist/cli/index.js +166 -0
  48. package/dist/cli/init-args.d.ts +16 -0
  49. package/dist/cli/init-args.d.ts.map +1 -0
  50. package/dist/cli/init-args.js +24 -0
  51. package/dist/cli/ui-args.d.ts +23 -0
  52. package/dist/cli/ui-args.d.ts.map +1 -0
  53. package/dist/cli/ui-args.js +66 -0
  54. package/dist/cli/ui.d.ts +40 -0
  55. package/dist/cli/ui.d.ts.map +1 -0
  56. package/dist/cli/ui.js +180 -0
  57. package/dist/coordinatorium/checkpoint.d.ts +44 -0
  58. package/dist/coordinatorium/checkpoint.d.ts.map +1 -0
  59. package/dist/coordinatorium/checkpoint.js +124 -0
  60. package/dist/coordinatorium/cli.d.ts +39 -0
  61. package/dist/coordinatorium/cli.d.ts.map +1 -0
  62. package/dist/coordinatorium/cli.js +203 -0
  63. package/dist/coordinatorium/errors.d.ts +112 -0
  64. package/dist/coordinatorium/errors.d.ts.map +1 -0
  65. package/dist/coordinatorium/errors.js +145 -0
  66. package/dist/coordinatorium/index.d.ts +11 -0
  67. package/dist/coordinatorium/index.d.ts.map +1 -0
  68. package/dist/coordinatorium/index.js +5 -0
  69. package/dist/coordinatorium/lock.d.ts +187 -0
  70. package/dist/coordinatorium/lock.d.ts.map +1 -0
  71. package/dist/coordinatorium/lock.js +659 -0
  72. package/dist/coordinatorium/mission.d.ts +32 -0
  73. package/dist/coordinatorium/mission.d.ts.map +1 -0
  74. package/dist/coordinatorium/mission.js +87 -0
  75. package/dist/coordinatorium/state-keeper.d.ts +115 -0
  76. package/dist/coordinatorium/state-keeper.d.ts.map +1 -0
  77. package/dist/coordinatorium/state-keeper.js +396 -0
  78. package/dist/coordinatorium/types.d.ts +69 -0
  79. package/dist/coordinatorium/types.d.ts.map +1 -0
  80. package/dist/coordinatorium/types.js +27 -0
  81. package/dist/durable/assess.d.ts +105 -0
  82. package/dist/durable/assess.d.ts.map +1 -0
  83. package/dist/durable/assess.js +239 -0
  84. package/dist/durable/canonical.d.ts +25 -0
  85. package/dist/durable/canonical.d.ts.map +1 -0
  86. package/dist/durable/canonical.js +78 -0
  87. package/dist/durable/cli.d.ts +37 -0
  88. package/dist/durable/cli.d.ts.map +1 -0
  89. package/dist/durable/cli.js +141 -0
  90. package/dist/durable/errors.d.ts +188 -0
  91. package/dist/durable/errors.d.ts.map +1 -0
  92. package/dist/durable/errors.js +317 -0
  93. package/dist/durable/fs-store.d.ts +233 -0
  94. package/dist/durable/fs-store.d.ts.map +1 -0
  95. package/dist/durable/fs-store.js +1393 -0
  96. package/dist/durable/index.d.ts +20 -0
  97. package/dist/durable/index.d.ts.map +1 -0
  98. package/dist/durable/index.js +13 -0
  99. package/dist/durable/log.d.ts +33 -0
  100. package/dist/durable/log.d.ts.map +1 -0
  101. package/dist/durable/log.js +157 -0
  102. package/dist/durable/memory-store.d.ts +51 -0
  103. package/dist/durable/memory-store.d.ts.map +1 -0
  104. package/dist/durable/memory-store.js +302 -0
  105. package/dist/durable/projection.d.ts +35 -0
  106. package/dist/durable/projection.d.ts.map +1 -0
  107. package/dist/durable/projection.js +328 -0
  108. package/dist/durable/prune-check.d.ts +17 -0
  109. package/dist/durable/prune-check.d.ts.map +1 -0
  110. package/dist/durable/prune-check.js +45 -0
  111. package/dist/durable/register.d.ts +100 -0
  112. package/dist/durable/register.d.ts.map +1 -0
  113. package/dist/durable/register.js +532 -0
  114. package/dist/durable/retention.d.ts +49 -0
  115. package/dist/durable/retention.d.ts.map +1 -0
  116. package/dist/durable/retention.js +59 -0
  117. package/dist/durable/runtime.d.ts +497 -0
  118. package/dist/durable/runtime.d.ts.map +1 -0
  119. package/dist/durable/runtime.js +1271 -0
  120. package/dist/durable/seams.d.ts +40 -0
  121. package/dist/durable/seams.d.ts.map +1 -0
  122. package/dist/durable/seams.js +21 -0
  123. package/dist/durable/testing.d.ts +11 -0
  124. package/dist/durable/testing.d.ts.map +1 -0
  125. package/dist/durable/testing.js +25 -0
  126. package/dist/durable/types.d.ts +442 -0
  127. package/dist/durable/types.d.ts.map +1 -0
  128. package/dist/durable/types.js +75 -0
  129. package/dist/graph/builder.d.ts +11 -0
  130. package/dist/graph/builder.d.ts.map +1 -0
  131. package/dist/graph/builder.js +153 -0
  132. package/dist/graph/identity.d.ts +37 -0
  133. package/dist/graph/identity.d.ts.map +1 -0
  134. package/dist/graph/identity.js +46 -0
  135. package/dist/graph/index.d.ts +7 -0
  136. package/dist/graph/index.d.ts.map +1 -0
  137. package/dist/graph/index.js +3 -0
  138. package/dist/graph/resolver.d.ts +41 -0
  139. package/dist/graph/resolver.d.ts.map +1 -0
  140. package/dist/graph/resolver.js +36 -0
  141. package/dist/graph/types.d.ts +42 -0
  142. package/dist/graph/types.d.ts.map +1 -0
  143. package/dist/graph/types.js +1 -0
  144. package/dist/http/index.d.ts +5 -0
  145. package/dist/http/index.d.ts.map +1 -0
  146. package/dist/http/index.js +2 -0
  147. package/dist/http/server.d.ts +76 -0
  148. package/dist/http/server.d.ts.map +1 -0
  149. package/dist/http/server.js +195 -0
  150. package/dist/http/ui-assets.d.ts +22 -0
  151. package/dist/http/ui-assets.d.ts.map +1 -0
  152. package/dist/http/ui-assets.js +100 -0
  153. package/dist/index.d.ts +31 -0
  154. package/dist/index.d.ts.map +1 -0
  155. package/dist/index.js +26 -0
  156. package/dist/init/index.d.ts +12 -0
  157. package/dist/init/index.d.ts.map +1 -0
  158. package/dist/init/index.js +90 -0
  159. package/dist/init/prompts.d.ts +3 -0
  160. package/dist/init/prompts.d.ts.map +1 -0
  161. package/dist/init/prompts.js +47 -0
  162. package/dist/init/scaffold.d.ts +25 -0
  163. package/dist/init/scaffold.d.ts.map +1 -0
  164. package/dist/init/scaffold.js +204 -0
  165. package/dist/init/types.d.ts +14 -0
  166. package/dist/init/types.d.ts.map +1 -0
  167. package/dist/init/types.js +1 -0
  168. package/dist/readmodel/dashboard.d.ts +40 -0
  169. package/dist/readmodel/dashboard.d.ts.map +1 -0
  170. package/dist/readmodel/dashboard.js +236 -0
  171. package/dist/readmodel/index.d.ts +3 -0
  172. package/dist/readmodel/index.d.ts.map +1 -0
  173. package/dist/readmodel/index.js +1 -0
  174. package/dist/readmodel/types.d.ts +104 -0
  175. package/dist/readmodel/types.d.ts.map +1 -0
  176. package/dist/readmodel/types.js +15 -0
  177. package/dist/root/index.d.ts +179 -0
  178. package/dist/root/index.d.ts.map +1 -0
  179. package/dist/root/index.js +418 -0
  180. package/dist/root/safe-write.d.ts +268 -0
  181. package/dist/root/safe-write.d.ts.map +1 -0
  182. package/dist/root/safe-write.js +966 -0
  183. package/dist/root/write-artifacts.d.ts +20 -0
  184. package/dist/root/write-artifacts.d.ts.map +1 -0
  185. package/dist/root/write-artifacts.js +42 -0
  186. package/dist/scriptorium/compile.d.ts +4 -0
  187. package/dist/scriptorium/compile.d.ts.map +1 -0
  188. package/dist/scriptorium/compile.js +185 -0
  189. package/dist/scriptorium/frontmatter.d.ts +13 -0
  190. package/dist/scriptorium/frontmatter.d.ts.map +1 -0
  191. package/dist/scriptorium/frontmatter.js +90 -0
  192. package/dist/scriptorium/index.d.ts +3 -0
  193. package/dist/scriptorium/index.d.ts.map +1 -0
  194. package/dist/scriptorium/index.js +1 -0
  195. package/dist/scriptorium/markdown.d.ts +31 -0
  196. package/dist/scriptorium/markdown.d.ts.map +1 -0
  197. package/dist/scriptorium/markdown.js +88 -0
  198. package/dist/scriptorium/types.d.ts +78 -0
  199. package/dist/scriptorium/types.d.ts.map +1 -0
  200. package/dist/scriptorium/types.js +1 -0
  201. package/dist/types/enforcement.d.ts +11 -0
  202. package/dist/types/enforcement.d.ts.map +1 -0
  203. package/dist/types/enforcement.js +1 -0
  204. package/dist/types/integrity.d.ts +33 -0
  205. package/dist/types/integrity.d.ts.map +1 -0
  206. package/dist/types/integrity.js +1 -0
  207. package/dist/types/project-definition.d.ts +30 -0
  208. package/dist/types/project-definition.d.ts.map +1 -0
  209. package/dist/types/project-definition.js +1 -0
  210. package/dist/ui/assets/cosmic-glass-bg-Dwx47zPu.webp +0 -0
  211. package/dist/ui/assets/index-C4NhMaq7.js +28 -0
  212. package/dist/ui/assets/index-DMZ7ZvZY.css +1 -0
  213. package/dist/ui/index.html +13 -0
  214. package/dist/validate/index.d.ts +6 -0
  215. package/dist/validate/index.d.ts.map +1 -0
  216. package/dist/validate/index.js +214 -0
  217. package/dist/version.d.ts +2 -0
  218. package/dist/version.d.ts.map +1 -0
  219. package/dist/version.js +1 -0
  220. package/package.json +67 -4
  221. package/templates/.gitkeep +0 -0
  222. package/templates/default-instance/instruction/.cursorrules +53 -0
  223. package/templates/default-instance/instruction/.windsurfrules +53 -0
  224. package/templates/default-instance/instruction/CLAUDE.md +53 -0
  225. package/templates/default-instance/monolith/context/boot/HANDOFF.md +49 -0
  226. package/templates/default-instance/monolith/context/boot/WORK_SESSION.md +30 -0
  227. package/templates/default-instance/monolith/context/execution/current-state.md +30 -0
  228. package/templates/default-instance/monolith/context/maps/dependency-map.md +38 -0
  229. package/templates/default-instance/monolith/context/maps/project-map.md +85 -0
  230. package/templates/default-instance/monolith/context/maps/roadmap-index.md +41 -0
  231. package/templates/default-instance/monolith/context/maps/routing-map.md +147 -0
  232. package/templates/default-instance/monolith/context/maps/semantic-map.md +73 -0
  233. package/templates/default-instance/monolith/context/models/model-registry.md +37 -0
  234. package/templates/default-instance/monolith/context/models/privacy-classification.md +35 -0
  235. package/templates/default-instance/monolith/context/templates/plan-template.md +56 -0
  236. package/templates/default-instance/monolith/governance/README.md +29 -0
  237. package/templates/default-instance/monolith/governance/RULE_SCHEMA.md +58 -0
  238. package/templates/default-instance/monolith/learning/INDEX.md +48 -0
  239. package/templates/default-instance/monolith/learning/injection-map.md +49 -0
  240. package/templates/default-instance/monolith/learning/taxonomy.md +30 -0
  241. package/templates/default-instance/monolith/memory/errors/README.md +26 -0
  242. package/templates/default-instance/monolith/memory/errors/SCHEMA.md +47 -0
  243. package/templates/default-instance/monolith/memory/errors/TAXONOMY.md +27 -0
  244. package/templates/default-instance/monolith/memory/long-term/architecture-principles.md +31 -0
  245. package/templates/default-instance/monolith/memory/long-term/decisions.md +36 -0
  246. package/templates/default-instance/monolith/memory/long-term/execution-history.md +20 -0
  247. package/templates/default-instance/monolith/memory/long-term/tech-debt.md +25 -0
  248. package/templates/default-instance/monolith/memory/working/active.md +41 -0
  249. package/templates/default-instance/monolith/memory/working/governance-result.md +0 -0
  250. package/templates/default-instance/monolith/memory/working/integrity-result.md +0 -0
  251. package/templates/default-instance/monolith/memory/working/story-index.md +28 -0
  252. package/templates/default-instance/monolith/protocols/boot/boot-sequence.md +59 -0
  253. package/templates/default-instance/monolith/protocols/cognition/cognitive-modes.md +90 -0
  254. package/templates/default-instance/monolith/protocols/cognition/dry-run.md +56 -0
  255. package/templates/default-instance/monolith/protocols/cognition/execution-trace-format.md +52 -0
  256. package/templates/default-instance/monolith/protocols/cognition/semantic-planning.md +51 -0
  257. package/templates/default-instance/monolith/protocols/execution/hybrid-execution.md +37 -0
  258. package/templates/default-instance/monolith/protocols/execution/local-llm-governance.md +42 -0
  259. package/templates/default-instance/monolith/protocols/governance/command-policy.md +51 -0
  260. package/templates/default-instance/monolith/protocols/governance/core-invariants.md +40 -0
  261. package/templates/default-instance/monolith/protocols/governance/memory-governance.md +54 -0
  262. package/templates/default-instance/monolith/protocols/governance/metadata-schema.md +62 -0
  263. package/templates/default-instance/monolith/protocols/governance/skills.md +53 -0
  264. package/templates/default-instance/monolith/protocols/governance/work-session.md +46 -0
  265. package/templates/default-instance/monolith/skills/INDEX.md +28 -0
  266. package/templates/default-instance/monolith/skills/current-status/SKILL.md +47 -0
  267. package/templates/default-instance/monolith/skills/finalize-story/SKILL.md +86 -0
  268. package/templates/default-instance/monolith/skills/global-status/SKILL.md +56 -0
  269. package/templates/default-instance/monolith/skills/self-improvement/SKILL.md +77 -0
  270. package/templates/default-instance/monolith/state.json +11 -0
  271. package/templates/default-instance/monolith/tests/INDEX.md +57 -0
  272. package/templates/default-instance/monolith/tests/scenarios/architecture-review.md +32 -0
  273. package/templates/default-instance/monolith/tests/scenarios/debug-failure.md +32 -0
  274. package/templates/default-instance/monolith/tests/scenarios/dry-run-activation.md +33 -0
  275. package/templates/default-instance/monolith/tests/scenarios/execution-trace-verification.md +31 -0
  276. package/templates/default-instance/monolith/tests/scenarios/finalize-story.md +35 -0
  277. package/templates/default-instance/monolith/tests/scenarios/implement-feature.md +36 -0
  278. package/templates/default-instance/monolith/tests/scenarios/local-llm-delegation.md +31 -0
  279. package/templates/default-instance/monolith/tests/scenarios/planning-request.md +32 -0
  280. package/templates/default-instance/monolith/tests/scenarios/sensitive-context-task.md +30 -0
  281. package/templates/default-instance/monolith/tests/scenarios/validator-verification.md +33 -0
  282. package/templates/default-instance/monolith/tests/validation/expected-behavior.md +70 -0
  283. package/templates/default-instance/monolith/tests/validators/INDEX.md +17 -0
  284. package/templates/default-instance/monolith/tests/validators/delegation-semantics.md +22 -0
  285. package/templates/default-instance/monolith/tests/validators/mode-consistency.md +25 -0
  286. package/templates/default-instance/monolith/tests/validators/privacy-routing.md +23 -0
  287. package/templates/default-instance/monolith/tests/validators/protocol-references.md +27 -0
  288. package/templates/default-instance/monolith/tests/validators/routing-integrity.md +30 -0
  289. package/templates/default-instance/projectroot/AGENTS.md +107 -0
  290. package/templates/default-instance/projectroot/monolith.config.json +32 -0
  291. package/templates/default-instance/projectroot/project.definition.mjs.template +41 -0
@@ -0,0 +1,268 @@
1
+ /**
2
+ * Safe write primitive (SEC-001B.2, ADR-012).
3
+ *
4
+ * The one code path that PUBLISHES project files (creates a new one or replaces
5
+ * an existing one). It adds, for every write:
6
+ *
7
+ * - an explicit WRITE BOUNDARY (`projectBoundary` / `trustedDirectoryBoundary`);
8
+ * there is no boundary-less write;
9
+ * - refusal of symlinks anywhere below the boundary, including symlinks that
10
+ * stay inside the project (W-SYM), of non-regular destinations (FIFO,
11
+ * device, directory) and of hardlinked destinations (`nlink > 1`);
12
+ * - a temp file opened `O_CREAT|O_EXCL|O_NOFOLLOW` (where the platform has
13
+ * `O_NOFOLLOW`) and published atomically: `rename()` over a regular file
14
+ * (`replaceFile`) or `link()` to a name that must not exist (`createFile`);
15
+ * - explicit PUBLICATION STATES. A failed write is NOT_PUBLISHED or UNKNOWN; a
16
+ * write that reached the final name is PUBLISHED and never throws. The state
17
+ * is decided from the identity (`dev/ino`) of the destination and of the
18
+ * temp name, never from an error code. UNKNOWN is never retried and never
19
+ * silently downgraded;
20
+ * - identity-checked cleanup: only a temp file THIS call created, and only if
21
+ * the name still shows the `dev/ino` recorded from the descriptor.
22
+ *
23
+ * Not routed through here: lock release and stale-lock recovery (`lock.ts`)
24
+ * unlink the lock path directly, and `trusted-directory` scope creates its
25
+ * directory with `mkdirSync`; see ADR-012 "Single primitive".
26
+ *
27
+ * What this module does NOT do — and must not be described as doing: it does
28
+ * not defend against a local actor who swaps directories or symlinks
29
+ * concurrently with an operation (SEC-001B.3). `ParentRef` is a path plus a
30
+ * `dev/ino` snapshot; re-checking it before an operation is a diagnostic
31
+ * tripwire, not protection, because the operation resolves the path again.
32
+ * Likewise the final `unlink` of an owned temp file cannot be made conditional
33
+ * without `unlinkat`/dirfd: a name swapped between the identity check and the
34
+ * unlink is a residual race.
35
+ *
36
+ * Platform: guarantees are stated for POSIX. Where `O_NOFOLLOW` or directory
37
+ * fsync is missing (Windows) the checks that can still be done with
38
+ * `lstat`/`fstat` are done, and a PLATFORM_BEST_EFFORT warning is returned.
39
+ */
40
+ import * as fs from 'fs';
41
+ export type PublicationState = 'NOT_PUBLISHED' | 'PUBLISHED' | 'UNKNOWN';
42
+ export type WriteErrorCode = 'WRITE_SCOPE_REQUIRED' | 'WRITE_BOUNDARY_INVALID' | 'WRITE_OUTSIDE_BOUNDARY' | 'WRITE_PARENT_SYMLINK' | 'WRITE_PARENT_NOT_DIRECTORY' | 'WRITE_PARENT_MISSING' | 'WRITE_PARENT_CHANGED' | 'WRITE_TARGET_SYMLINK' | 'WRITE_TARGET_NOT_REGULAR' | 'WRITE_TARGET_EXISTS' | 'WRITE_TARGET_HARDLINKED' | 'WRITE_TMP_COLLISION' | 'WRITE_TOO_LARGE' | 'WRITE_READONLY' | 'WRITE_PERMISSION' | 'WRITE_NO_SPACE' | 'WRITE_FSYNC_FAILED' | 'WRITE_VERIFY_FAILED' | 'WRITE_LINK_UNSUPPORTED' | 'WRITE_PUBLICATION_UNKNOWN' | 'WRITE_FAILED';
43
+ export type WriteWarningCode = 'DIR_FSYNC_UNSUPPORTED' | 'DIR_FSYNC_FAILED' | 'STAGING_RESIDUE' | 'PUBLICATION_VERIFIED_AFTER_ERROR' | 'PLATFORM_BEST_EFFORT';
44
+ export interface WriteWarning {
45
+ code: WriteWarningCode;
46
+ message: string;
47
+ path?: string;
48
+ }
49
+ /** What the caller asked to be fsynced. */
50
+ export type DurabilityRequest = 'full' | 'file' | 'none';
51
+ /** What was actually achieved. `unknown`: a directory fsync failed with an I/O error. */
52
+ export type DurabilityReached = 'full' | 'file' | 'none' | 'unknown';
53
+ export interface TempFileInfo {
54
+ name: string;
55
+ /** Ownership (successful `O_EXCL` create + recorded identity) is established. */
56
+ owned: boolean;
57
+ /** `true` removed/absent, `false` left in place, `null` not attempted. */
58
+ removed: boolean | null;
59
+ }
60
+ export interface SafeWriteErrorInit {
61
+ code: WriteErrorCode;
62
+ phase: string;
63
+ publication: 'NOT_PUBLISHED' | 'UNKNOWN';
64
+ path: string;
65
+ tmp?: TempFileInfo;
66
+ cause?: unknown;
67
+ }
68
+ export declare class SafeWriteError extends Error {
69
+ readonly code: WriteErrorCode;
70
+ readonly phase: string;
71
+ readonly publication: 'NOT_PUBLISHED' | 'UNKNOWN';
72
+ readonly path: string;
73
+ readonly tmp?: TempFileInfo;
74
+ readonly cause?: unknown;
75
+ constructor(message: string, init: SafeWriteErrorInit);
76
+ }
77
+ export interface WriteOutcome {
78
+ publication: 'PUBLISHED';
79
+ durability: DurabilityReached;
80
+ warnings: WriteWarning[];
81
+ }
82
+ export interface PlatformCaps {
83
+ /** `O_NOFOLLOW` exists. */
84
+ noFollow: boolean;
85
+ /** A directory can be opened and fsynced. */
86
+ dirFsync: boolean;
87
+ /** `process.geteuid` exists, so file ownership can be checked. */
88
+ ownerCheck: boolean;
89
+ /** Security guarantees of ADR-012 are stated for this platform. */
90
+ posix: boolean;
91
+ }
92
+ export declare function detectPlatformCaps(): PlatformCaps;
93
+ /** The filesystem calls the primitive makes. Overridable ONLY by tests, for fault injection. */
94
+ export interface FsOps {
95
+ openSync: typeof fs.openSync;
96
+ writeSync: typeof fs.writeSync;
97
+ fchmodSync: typeof fs.fchmodSync;
98
+ fstatSync: typeof fs.fstatSync;
99
+ fsyncSync: typeof fs.fsyncSync;
100
+ closeSync: typeof fs.closeSync;
101
+ renameSync: typeof fs.renameSync;
102
+ linkSync: typeof fs.linkSync;
103
+ unlinkSync: typeof fs.unlinkSync;
104
+ lstatSync: typeof fs.lstatSync;
105
+ mkdirSync: typeof fs.mkdirSync;
106
+ }
107
+ export declare const realFsOps: FsOps;
108
+ /** Test-only knobs; production callers never pass them. */
109
+ export interface InternalOptions {
110
+ ops?: Partial<FsOps>;
111
+ caps?: Partial<PlatformCaps>;
112
+ }
113
+ export type WriteScopeMode = 'project' | 'trusted-directory';
114
+ /**
115
+ * Trust boundary of a write. Created only by `projectBoundary` /
116
+ * `trustedDirectoryBoundary`. In both modes the ANCESTORS of the boundary are
117
+ * trusted (in `project` mode: the root the user pointed at; in
118
+ * `trusted-directory` mode: because the caller asserts it); every component
119
+ * below the boundary is checked.
120
+ */
121
+ export declare class WriteBoundary {
122
+ private constructor();
123
+ get mode(): WriteScopeMode;
124
+ /** @internal */
125
+ static create(mode: WriteScopeMode, dir: string): WriteBoundary;
126
+ }
127
+ /** Project scope: `projectRoot` is the boundary; target directories must lie inside it. */
128
+ export declare function projectBoundary(projectRoot: string): WriteBoundary;
129
+ /** Trusted-directory scope: the caller asserts `dir` and ALL its ancestors are trusted. */
130
+ export declare function trustedDirectoryBoundary(dir: string): WriteBoundary;
131
+ interface ParentData {
132
+ path: string;
133
+ dev: bigint;
134
+ ino: bigint;
135
+ boundary: WriteBoundary;
136
+ }
137
+ /**
138
+ * A verified directory below a boundary. Opaque on purpose: code outside this
139
+ * module must not read its path. Today it is a path with a `dev/ino` snapshot;
140
+ * SEC-001B.3 may replace it with a directory descriptor. It is NOT a security
141
+ * handle (see the module comment).
142
+ */
143
+ export declare class ParentRef {
144
+ private constructor();
145
+ /** @internal */
146
+ static create(data: ParentData): ParentRef;
147
+ }
148
+ /**
149
+ * Absolute path of the boundary a verified parent lies below, for the READ side
150
+ * of the same trust decision (SEC-001B.1-R): a lock file is read under the
151
+ * boundary its staging files are written under. Not a handle; a path.
152
+ */
153
+ export declare function boundaryPathOf(p: ParentRef): string;
154
+ export interface OpenParentOptions extends InternalOptions {
155
+ /** Create missing directories (one `mkdir` per component, never `recursive`). */
156
+ create?: boolean;
157
+ }
158
+ /**
159
+ * Walk `dirAbs` below the boundary, `lstat`-ing every component: it must be a
160
+ * real directory, never a symlink (W-SYM) — including a symlink that stays
161
+ * inside the project. Missing components are created only with `create`.
162
+ */
163
+ export declare function openParent(boundary: WriteBoundary, dirAbs: string, opts?: OpenParentOptions): ParentRef;
164
+ export type TargetProbe = {
165
+ state: 'free';
166
+ path: string;
167
+ } | {
168
+ state: 'exists';
169
+ path: string;
170
+ } | {
171
+ state: 'symlink';
172
+ path: string;
173
+ } | {
174
+ state: 'special';
175
+ path: string;
176
+ } | {
177
+ state: 'parent-symlink';
178
+ path: string;
179
+ } | {
180
+ state: 'parent-not-directory';
181
+ path: string;
182
+ } | {
183
+ state: 'outside';
184
+ path: string;
185
+ } | {
186
+ state: 'unreadable';
187
+ path: string;
188
+ detail: string;
189
+ };
190
+ /**
191
+ * Read-only: classify what is at `fileAbs` without writing. Missing parent
192
+ * directories make the target `free` (they would be created). A dangling
193
+ * symlink is a `symlink`, never `free`.
194
+ */
195
+ export declare function probeTarget(boundary: WriteBoundary, fileAbs: string, opts?: InternalOptions): TargetProbe;
196
+ /** Proof that THIS call created the file: the identity recorded from the descriptor. */
197
+ export interface OwnedToken {
198
+ readonly name: string;
199
+ readonly dev: bigint;
200
+ readonly ino: bigint;
201
+ }
202
+ export interface OwnedFile {
203
+ fd: number;
204
+ token: OwnedToken;
205
+ }
206
+ export type DisposeResult = 'removed' | 'absent' | 'not-owned' | 'failed';
207
+ /**
208
+ * Create a brand-new file `name` in `parent`: `O_CREAT|O_EXCL|O_NOFOLLOW` at
209
+ * `mode`. Success proves this call created it; its identity is recorded
210
+ * immediately. If the identity cannot be recorded, ownership is NOT claimed:
211
+ * the descriptor is closed, the file is left alone and the error says so.
212
+ */
213
+ export declare function createExclusive(parent: ParentRef, name: string, mode: number, opts?: InternalOptions): OwnedFile;
214
+ /**
215
+ * Remove `token`'s file iff the name still shows the recorded identity. Never
216
+ * removes anything else. The unlink itself is not conditional (no `unlinkat`):
217
+ * a name swapped between the check and the unlink is a residual race.
218
+ */
219
+ export declare function disposeOwned(parent: ParentRef, token: OwnedToken, opts?: InternalOptions): DisposeResult;
220
+ export interface WriteOptions extends InternalOptions {
221
+ /** Mode for a NEW file (`0o600` for state). With `exactMode: false` it is only the creation mode (umask applies). */
222
+ mode: number;
223
+ /** `fchmod` the file to exactly `mode` (default). Set `false` for documents that follow the umask. */
224
+ exactMode?: boolean;
225
+ /** `replaceFile` only: keep the mode (`& 0o777`) of an existing destination. Default `true`. */
226
+ preserveMode?: boolean;
227
+ /** `'full'` (default): fsync file and directory. `'file'`: file only. `'none'`. */
228
+ durability?: DurabilityRequest;
229
+ /** Refuse data larger than this. */
230
+ maxBytes?: number;
231
+ }
232
+ export interface LinkPublishResult {
233
+ outcome: 'published' | 'lost-race';
234
+ warnings: WriteWarning[];
235
+ }
236
+ /**
237
+ * Publish an owned, completely written and closed temp file under `finalName`
238
+ * with `link()`, which fails if the name exists (symlink, FIFO or file alike).
239
+ * `lost-race`: somebody else owns the name — nothing of ours was published
240
+ * (the temp file is NOT removed here; the caller disposes it). Errors follow
241
+ * the publication-state rules in the module comment.
242
+ */
243
+ export declare function publishLink(parent: ParentRef, token: OwnedToken, finalName: string, opts?: InternalOptions): LinkPublishResult;
244
+ /**
245
+ * Atomically replace `name` in `parent` (or create it if absent): temp file ->
246
+ * fsync -> `rename`. The destination must be absent or a regular file with a
247
+ * single link; its mode is kept unless `preserveMode: false`. Throws
248
+ * `SafeWriteError` (NOT_PUBLISHED / UNKNOWN); once published it never throws.
249
+ */
250
+ export declare function replaceFile(parent: ParentRef, name: string, data: string | Buffer, opts: WriteOptions): WriteOutcome;
251
+ /**
252
+ * Create `name` in `parent` without ever overwriting: temp file -> fsync ->
253
+ * `link()`, then the temp name is removed. The final name never shows a
254
+ * partially written file. A destination that exists in any form (file,
255
+ * symlink, FIFO, ...) is refused. Failures after the link succeeded are
256
+ * warnings (`STAGING_RESIDUE`, directory fsync), never errors.
257
+ */
258
+ export declare function createFile(parent: ParentRef, name: string, data: string | Buffer, opts: WriteOptions): WriteOutcome;
259
+ /**
260
+ * Print a post-publication finding as one `warning` line (stderr by default).
261
+ * The platform note is printed once per process, however many files are written.
262
+ * Never throws: the write it reports on is already published.
263
+ */
264
+ export declare function reportWriteWarning(warning: WriteWarning, print?: (line: string) => void): void;
265
+ /** Test-only: forget that the platform note was printed. */
266
+ export declare function resetWriteWarningState(): void;
267
+ export {};
268
+ //# sourceMappingURL=safe-write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-write.d.ts","sourceRoot":"","sources":["../../src/root/safe-write.ts"],"names":[],"mappings":"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"}