@smthrs/kernel 0.0.0-stage → 1.0.0-rc.3

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 (267) hide show
  1. package/CHANGELOG.md +206 -0
  2. package/LICENSE +21 -0
  3. package/README.md +154 -2
  4. package/dist/cjs/CapabilitySet.d.ts +6 -0
  5. package/dist/cjs/CapabilitySet.d.ts.map +1 -0
  6. package/dist/cjs/CapabilitySet.js +19 -0
  7. package/dist/cjs/CapabilitySet.js.map +7 -0
  8. package/dist/cjs/ChildProcessEnvironment.d.ts +60 -0
  9. package/dist/cjs/ChildProcessEnvironment.d.ts.map +1 -0
  10. package/dist/cjs/ChildProcessEnvironment.js +61 -0
  11. package/dist/cjs/ChildProcessEnvironment.js.map +7 -0
  12. package/dist/cjs/ChildProcessSpawner.d.ts +100 -0
  13. package/dist/cjs/ChildProcessSpawner.d.ts.map +1 -0
  14. package/dist/cjs/ChildProcessSpawner.js +291 -0
  15. package/dist/cjs/ChildProcessSpawner.js.map +7 -0
  16. package/dist/cjs/CommandLine.d.ts +173 -0
  17. package/dist/cjs/CommandLine.d.ts.map +1 -0
  18. package/dist/cjs/CommandLine.js +54 -0
  19. package/dist/cjs/CommandLine.js.map +7 -0
  20. package/dist/cjs/ContainedSpawner.d.ts +135 -0
  21. package/dist/cjs/ContainedSpawner.d.ts.map +1 -0
  22. package/dist/cjs/ContainedSpawner.js +141 -0
  23. package/dist/cjs/ContainedSpawner.js.map +7 -0
  24. package/dist/cjs/FileSystem.d.ts +452 -0
  25. package/dist/cjs/FileSystem.d.ts.map +1 -0
  26. package/dist/cjs/FileSystem.js +890 -0
  27. package/dist/cjs/FileSystem.js.map +7 -0
  28. package/dist/cjs/FileSystemBatch.d.ts +94 -0
  29. package/dist/cjs/FileSystemBatch.d.ts.map +1 -0
  30. package/dist/cjs/FileSystemBatch.js +31 -0
  31. package/dist/cjs/FileSystemBatch.js.map +7 -0
  32. package/dist/cjs/GrantEvent.d.ts +240 -0
  33. package/dist/cjs/GrantEvent.d.ts.map +1 -0
  34. package/dist/cjs/GrantEvent.js +115 -0
  35. package/dist/cjs/GrantEvent.js.map +7 -0
  36. package/dist/cjs/GrantStore.d.ts +270 -0
  37. package/dist/cjs/GrantStore.d.ts.map +1 -0
  38. package/dist/cjs/GrantStore.js +857 -0
  39. package/dist/cjs/GrantStore.js.map +7 -0
  40. package/dist/cjs/HostError.d.ts +36 -0
  41. package/dist/cjs/HostError.d.ts.map +1 -0
  42. package/dist/cjs/HostError.js +17 -0
  43. package/dist/cjs/HostError.js.map +7 -0
  44. package/dist/cjs/HostServices.d.ts +101 -0
  45. package/dist/cjs/HostServices.d.ts.map +1 -0
  46. package/dist/cjs/HostServices.js +66 -0
  47. package/dist/cjs/HostServices.js.map +7 -0
  48. package/dist/cjs/HttpClient.d.ts +177 -0
  49. package/dist/cjs/HttpClient.d.ts.map +1 -0
  50. package/dist/cjs/HttpClient.js +217 -0
  51. package/dist/cjs/HttpClient.js.map +7 -0
  52. package/dist/cjs/Jj.d.ts +67 -0
  53. package/dist/cjs/Jj.d.ts.map +1 -0
  54. package/dist/cjs/Jj.js +118 -0
  55. package/dist/cjs/Jj.js.map +7 -0
  56. package/dist/cjs/JournalGrantStore.d.ts +65 -0
  57. package/dist/cjs/JournalGrantStore.d.ts.map +1 -0
  58. package/dist/cjs/JournalGrantStore.js +354 -0
  59. package/dist/cjs/JournalGrantStore.js.map +7 -0
  60. package/dist/cjs/Path.d.ts +37 -0
  61. package/dist/cjs/Path.d.ts.map +1 -0
  62. package/dist/cjs/Path.js +46 -0
  63. package/dist/cjs/Path.js.map +7 -0
  64. package/dist/cjs/ProcessConfinement.d.ts +55 -0
  65. package/dist/cjs/ProcessConfinement.d.ts.map +1 -0
  66. package/dist/cjs/ProcessConfinement.js +94 -0
  67. package/dist/cjs/ProcessConfinement.js.map +7 -0
  68. package/dist/cjs/ProcessLedger.d.ts +260 -0
  69. package/dist/cjs/ProcessLedger.d.ts.map +1 -0
  70. package/dist/cjs/ProcessLedger.js +190 -0
  71. package/dist/cjs/ProcessLedger.js.map +7 -0
  72. package/dist/cjs/Rooted.d.ts +53 -0
  73. package/dist/cjs/Rooted.d.ts.map +1 -0
  74. package/dist/cjs/Rooted.js +101 -0
  75. package/dist/cjs/Rooted.js.map +7 -0
  76. package/dist/cjs/Unreachable.d.ts +27 -0
  77. package/dist/cjs/Unreachable.d.ts.map +1 -0
  78. package/dist/cjs/Unreachable.js +43 -0
  79. package/dist/cjs/Unreachable.js.map +7 -0
  80. package/dist/cjs/Workspace.d.ts +62 -0
  81. package/dist/cjs/Workspace.d.ts.map +1 -0
  82. package/dist/cjs/Workspace.js +35 -0
  83. package/dist/cjs/Workspace.js.map +7 -0
  84. package/dist/cjs/index.d.ts +161 -0
  85. package/dist/cjs/index.d.ts.map +1 -0
  86. package/dist/cjs/index.js +73 -0
  87. package/dist/cjs/index.js.map +7 -0
  88. package/dist/cjs/internal/Containment.d.ts +24 -0
  89. package/dist/cjs/internal/Containment.d.ts.map +1 -0
  90. package/dist/cjs/internal/Containment.js +30 -0
  91. package/dist/cjs/internal/Containment.js.map +7 -0
  92. package/dist/cjs/internal/Pipeline.d.ts +18 -0
  93. package/dist/cjs/internal/Pipeline.d.ts.map +1 -0
  94. package/dist/cjs/internal/Pipeline.js +90 -0
  95. package/dist/cjs/internal/Pipeline.js.map +7 -0
  96. package/dist/cjs/internal/makeCapability.d.ts +16 -0
  97. package/dist/cjs/internal/makeCapability.d.ts.map +1 -0
  98. package/dist/cjs/internal/makeCapability.js +44 -0
  99. package/dist/cjs/internal/makeCapability.js.map +7 -0
  100. package/dist/cjs/package.json +1 -0
  101. package/dist/cjs/test/FileSystemBatchContract.d.ts +15 -0
  102. package/dist/cjs/test/FileSystemBatchContract.d.ts.map +1 -0
  103. package/dist/cjs/test/FileSystemBatchContract.js +76 -0
  104. package/dist/cjs/test/FileSystemBatchContract.js.map +7 -0
  105. package/dist/cjs/test/HostContract.d.ts +225 -0
  106. package/dist/cjs/test/HostContract.d.ts.map +1 -0
  107. package/dist/cjs/test/HostContract.js +489 -0
  108. package/dist/cjs/test/HostContract.js.map +7 -0
  109. package/dist/cjs/test/TestGrantStore.d.ts +31 -0
  110. package/dist/cjs/test/TestGrantStore.d.ts.map +1 -0
  111. package/dist/cjs/test/TestGrantStore.js +65 -0
  112. package/dist/cjs/test/TestGrantStore.js.map +7 -0
  113. package/dist/esm/CapabilitySet.d.ts +6 -0
  114. package/dist/esm/CapabilitySet.d.ts.map +1 -0
  115. package/dist/esm/CapabilitySet.js +6 -0
  116. package/dist/esm/CapabilitySet.js.map +1 -0
  117. package/dist/esm/ChildProcessEnvironment.d.ts +60 -0
  118. package/dist/esm/ChildProcessEnvironment.d.ts.map +1 -0
  119. package/dist/esm/ChildProcessEnvironment.js +91 -0
  120. package/dist/esm/ChildProcessEnvironment.js.map +1 -0
  121. package/dist/esm/ChildProcessSpawner.d.ts +100 -0
  122. package/dist/esm/ChildProcessSpawner.d.ts.map +1 -0
  123. package/dist/esm/ChildProcessSpawner.js +342 -0
  124. package/dist/esm/ChildProcessSpawner.js.map +1 -0
  125. package/dist/esm/CommandLine.d.ts +173 -0
  126. package/dist/esm/CommandLine.d.ts.map +1 -0
  127. package/dist/esm/CommandLine.js +195 -0
  128. package/dist/esm/CommandLine.js.map +1 -0
  129. package/dist/esm/ContainedSpawner.d.ts +135 -0
  130. package/dist/esm/ContainedSpawner.d.ts.map +1 -0
  131. package/dist/esm/ContainedSpawner.js +180 -0
  132. package/dist/esm/ContainedSpawner.js.map +1 -0
  133. package/dist/esm/FileSystem.d.ts +452 -0
  134. package/dist/esm/FileSystem.d.ts.map +1 -0
  135. package/dist/esm/FileSystem.js +989 -0
  136. package/dist/esm/FileSystem.js.map +1 -0
  137. package/dist/esm/FileSystemBatch.d.ts +94 -0
  138. package/dist/esm/FileSystemBatch.d.ts.map +1 -0
  139. package/dist/esm/FileSystemBatch.js +26 -0
  140. package/dist/esm/FileSystemBatch.js.map +1 -0
  141. package/dist/esm/GrantEvent.d.ts +240 -0
  142. package/dist/esm/GrantEvent.d.ts.map +1 -0
  143. package/dist/esm/GrantEvent.js +155 -0
  144. package/dist/esm/GrantEvent.js.map +1 -0
  145. package/dist/esm/GrantStore.d.ts +270 -0
  146. package/dist/esm/GrantStore.d.ts.map +1 -0
  147. package/dist/esm/GrantStore.js +951 -0
  148. package/dist/esm/GrantStore.js.map +1 -0
  149. package/dist/esm/HostError.d.ts +36 -0
  150. package/dist/esm/HostError.d.ts.map +1 -0
  151. package/dist/esm/HostError.js +20 -0
  152. package/dist/esm/HostError.js.map +1 -0
  153. package/dist/esm/HostServices.d.ts +101 -0
  154. package/dist/esm/HostServices.d.ts.map +1 -0
  155. package/dist/esm/HostServices.js +76 -0
  156. package/dist/esm/HostServices.js.map +1 -0
  157. package/dist/esm/HttpClient.d.ts +177 -0
  158. package/dist/esm/HttpClient.d.ts.map +1 -0
  159. package/dist/esm/HttpClient.js +299 -0
  160. package/dist/esm/HttpClient.js.map +1 -0
  161. package/dist/esm/Jj.d.ts +67 -0
  162. package/dist/esm/Jj.d.ts.map +1 -0
  163. package/dist/esm/Jj.js +111 -0
  164. package/dist/esm/Jj.js.map +1 -0
  165. package/dist/esm/JournalGrantStore.d.ts +65 -0
  166. package/dist/esm/JournalGrantStore.d.ts.map +1 -0
  167. package/dist/esm/JournalGrantStore.js +350 -0
  168. package/dist/esm/JournalGrantStore.js.map +1 -0
  169. package/dist/esm/Path.d.ts +37 -0
  170. package/dist/esm/Path.d.ts.map +1 -0
  171. package/dist/esm/Path.js +34 -0
  172. package/dist/esm/Path.js.map +1 -0
  173. package/dist/esm/ProcessConfinement.d.ts +55 -0
  174. package/dist/esm/ProcessConfinement.d.ts.map +1 -0
  175. package/dist/esm/ProcessConfinement.js +106 -0
  176. package/dist/esm/ProcessConfinement.js.map +1 -0
  177. package/dist/esm/ProcessLedger.d.ts +260 -0
  178. package/dist/esm/ProcessLedger.d.ts.map +1 -0
  179. package/dist/esm/ProcessLedger.js +283 -0
  180. package/dist/esm/ProcessLedger.js.map +1 -0
  181. package/dist/esm/Rooted.d.ts +53 -0
  182. package/dist/esm/Rooted.d.ts.map +1 -0
  183. package/dist/esm/Rooted.js +104 -0
  184. package/dist/esm/Rooted.js.map +1 -0
  185. package/dist/esm/Unreachable.d.ts +27 -0
  186. package/dist/esm/Unreachable.d.ts.map +1 -0
  187. package/dist/esm/Unreachable.js +26 -0
  188. package/dist/esm/Unreachable.js.map +1 -0
  189. package/dist/esm/Workspace.d.ts +62 -0
  190. package/dist/esm/Workspace.d.ts.map +1 -0
  191. package/dist/esm/Workspace.js +51 -0
  192. package/dist/esm/Workspace.js.map +1 -0
  193. package/dist/esm/index.d.ts +161 -0
  194. package/dist/esm/index.d.ts.map +1 -0
  195. package/dist/esm/index.js +151 -0
  196. package/dist/esm/index.js.map +1 -0
  197. package/dist/esm/internal/Containment.d.ts +24 -0
  198. package/dist/esm/internal/Containment.d.ts.map +1 -0
  199. package/dist/esm/internal/Containment.js +27 -0
  200. package/dist/esm/internal/Containment.js.map +1 -0
  201. package/dist/esm/internal/Pipeline.d.ts +18 -0
  202. package/dist/esm/internal/Pipeline.d.ts.map +1 -0
  203. package/dist/esm/internal/Pipeline.js +68 -0
  204. package/dist/esm/internal/Pipeline.js.map +1 -0
  205. package/dist/esm/internal/makeCapability.d.ts +16 -0
  206. package/dist/esm/internal/makeCapability.d.ts.map +1 -0
  207. package/dist/esm/internal/makeCapability.js +22 -0
  208. package/dist/esm/internal/makeCapability.js.map +1 -0
  209. package/dist/esm/test/FileSystemBatchContract.d.ts +15 -0
  210. package/dist/esm/test/FileSystemBatchContract.d.ts.map +1 -0
  211. package/dist/esm/test/FileSystemBatchContract.js +57 -0
  212. package/dist/esm/test/FileSystemBatchContract.js.map +1 -0
  213. package/dist/esm/test/HostContract.d.ts +225 -0
  214. package/dist/esm/test/HostContract.d.ts.map +1 -0
  215. package/dist/esm/test/HostContract.js +460 -0
  216. package/dist/esm/test/HostContract.js.map +1 -0
  217. package/dist/esm/test/TestGrantStore.d.ts +31 -0
  218. package/dist/esm/test/TestGrantStore.d.ts.map +1 -0
  219. package/dist/esm/test/TestGrantStore.js +57 -0
  220. package/dist/esm/test/TestGrantStore.js.map +1 -0
  221. package/docs/README.md +162 -0
  222. package/docs/api.md +1532 -0
  223. package/docs/concepts/decoration-in-place.md +117 -0
  224. package/docs/concepts/filesystem-batches.md +58 -0
  225. package/docs/concepts/filesystem-confinement.md +168 -0
  226. package/docs/concepts/grant-decisions.md +181 -0
  227. package/docs/concepts/process-containment.md +155 -0
  228. package/docs/contract.md +14 -0
  229. package/docs/guides/adapt-a-new-host-platform.md +148 -0
  230. package/docs/guides/answer-permission-requests.md +151 -0
  231. package/docs/guides/authorize-network-and-model-calls.md +118 -0
  232. package/docs/guides/contain-spawned-processes.md +118 -0
  233. package/docs/guides/guard-a-host-bundle.md +109 -0
  234. package/docs/guides/persist-grants-across-restarts.md +135 -0
  235. package/docs/guides/write-a-capability-policy.md +159 -0
  236. package/docs/installation.md +115 -0
  237. package/docs/quickstart.md +182 -0
  238. package/docs/testing.md +108 -0
  239. package/docs/troubleshooting.md +281 -0
  240. package/package.json +344 -3
  241. package/src/CapabilitySet.ts +6 -0
  242. package/src/ChildProcessEnvironment.ts +98 -0
  243. package/src/ChildProcessSpawner.ts +414 -0
  244. package/src/CommandLine.ts +250 -0
  245. package/src/ContainedSpawner.ts +284 -0
  246. package/src/FileSystem.ts +1655 -0
  247. package/src/FileSystemBatch.ts +90 -0
  248. package/src/GrantEvent.ts +174 -0
  249. package/src/GrantStore.ts +1345 -0
  250. package/src/HostError.ts +37 -0
  251. package/src/HostServices.ts +133 -0
  252. package/src/HttpClient.ts +406 -0
  253. package/src/Jj.ts +159 -0
  254. package/src/JournalGrantStore.ts +461 -0
  255. package/src/Path.ts +47 -0
  256. package/src/ProcessConfinement.ts +156 -0
  257. package/src/ProcessLedger.ts +423 -0
  258. package/src/Rooted.ts +128 -0
  259. package/src/Unreachable.ts +30 -0
  260. package/src/Workspace.ts +65 -0
  261. package/src/index.ts +181 -0
  262. package/src/internal/Containment.ts +37 -0
  263. package/src/internal/Pipeline.ts +85 -0
  264. package/src/internal/makeCapability.ts +26 -0
  265. package/src/test/FileSystemBatchContract.ts +59 -0
  266. package/src/test/HostContract.ts +785 -0
  267. package/src/test/TestGrantStore.ts +73 -0
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Deterministic grant-store layers for tests.
3
+ *
4
+ * @since 1.0.0-rc.0
5
+ */
6
+ import { GrantStoreError, permissionDenied } from "@smthrs/capability/Permission";
7
+ import { Effect, Layer } from "effect";
8
+ import { emptyPolicy as closedPolicy } from "../GrantStore.js";
9
+ import { GrantStore, layerNoop } from "../GrantStore.js";
10
+ /**
11
+ * An allow-all grant store.
12
+ *
13
+ * @category layers
14
+ * @since 1.0.0-rc.0
15
+ */
16
+ export const layerAllow = layerNoop;
17
+ /**
18
+ * Provides a grant store that denies every capability.
19
+ *
20
+ * @category layers
21
+ * @since 1.0.0-rc.0
22
+ */
23
+ export const layerDeny = (reason = "denied by test") => {
24
+ const service = GrantStore.of({
25
+ policy: closedPolicy,
26
+ check: Effect.fn("GrantStore.check")((capability) => Effect.fail(permissionDenied(capability, reason))),
27
+ reply: Effect.fn("GrantStore.reply")(() => Effect.fail(new GrantStoreError({ code: "request_not_found" }))),
28
+ list: Effect.fn("GrantStore.list")(() => Effect.succeed([]))(),
29
+ grantEnvelope: Effect.fn("GrantStore.grantEnvelope")(() => Effect.void)
30
+ });
31
+ return Layer.succeed(GrantStore)(service);
32
+ };
33
+ /**
34
+ * Provides a grant store whose checks consume a deterministic sequence of
35
+ * attended-style replies. `once`, `run`, and `remembered` allow the check;
36
+ * `deny` rejects it. Exhausting the script rejects further checks.
37
+ *
38
+ * @category layers
39
+ * @since 1.0.0-rc.0
40
+ */
41
+ export const layerScripted = (replies) => Layer.effect(GrantStore, Effect.sync(() => {
42
+ let index = 0;
43
+ const service = GrantStore.of({
44
+ policy: closedPolicy,
45
+ check: Effect.fn("GrantStore.check")((capability) => Effect.suspend(() => {
46
+ const reply = replies[index++];
47
+ return reply !== undefined && reply !== "deny"
48
+ ? Effect.void
49
+ : Effect.fail(permissionDenied(capability, reply === undefined ? "permission reply script exhausted" : "permission request denied"));
50
+ })),
51
+ reply: Effect.fn("GrantStore.reply")(() => Effect.fail(new GrantStoreError({ code: "request_not_found" }))),
52
+ list: Effect.fn("GrantStore.list")(() => Effect.succeed([]))(),
53
+ grantEnvelope: Effect.fn("GrantStore.grantEnvelope")(() => Effect.void)
54
+ });
55
+ return service;
56
+ }));
57
+ //# sourceMappingURL=TestGrantStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TestGrantStore.js","sourceRoot":"","sources":["../../../src/test/TestGrantStore.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Deterministic grant-store layers for tests.\n *\n * @since 1.0.0-rc.0\n */\n\nimport { GrantStoreError, permissionDenied } from \"@smthrs/capability/Permission\"\nimport { Effect, Layer } from \"effect\"\nimport { emptyPolicy as closedPolicy } from \"../GrantStore.ts\"\nimport { GrantStore, layerNoop, type Resolution, type Service } from \"../GrantStore.ts\"\n\n/**\n * An allow-all grant store.\n *\n * @category layers\n * @since 1.0.0-rc.0\n */\nexport const layerAllow: Layer.Layer<GrantStore> = layerNoop\n\n/**\n * Provides a grant store that denies every capability.\n *\n * @category layers\n * @since 1.0.0-rc.0\n */\nexport const layerDeny = (reason = \"denied by test\"): Layer.Layer<GrantStore> => {\n const service = GrantStore.of({\n policy: closedPolicy,\n check: Effect.fn(\"GrantStore.check\")((capability) => Effect.fail(permissionDenied(capability, reason))),\n reply: Effect.fn(\"GrantStore.reply\")(() => Effect.fail(new GrantStoreError({ code: \"request_not_found\" }))),\n list: Effect.fn(\"GrantStore.list\")(() => Effect.succeed([]))(),\n grantEnvelope: Effect.fn(\"GrantStore.grantEnvelope\")(() => Effect.void)\n })\n return Layer.succeed(GrantStore)(service)\n}\n\n/**\n * Provides a grant store whose checks consume a deterministic sequence of\n * attended-style replies. `once`, `run`, and `remembered` allow the check;\n * `deny` rejects it. Exhausting the script rejects further checks.\n *\n * @category layers\n * @since 1.0.0-rc.0\n */\nexport const layerScripted = (\n replies: ReadonlyArray<Resolution>\n): Layer.Layer<GrantStore> =>\n Layer.effect(\n GrantStore,\n Effect.sync(() => {\n let index = 0\n const service: Service = GrantStore.of({\n policy: closedPolicy,\n check: Effect.fn(\"GrantStore.check\")((capability) =>\n Effect.suspend(() => {\n const reply = replies[index++]\n return reply !== undefined && reply !== \"deny\"\n ? Effect.void\n : Effect.fail(\n permissionDenied(\n capability,\n reply === undefined ? \"permission reply script exhausted\" : \"permission request denied\"\n )\n )\n })\n ),\n reply: Effect.fn(\"GrantStore.reply\")(() => Effect.fail(new GrantStoreError({ code: \"request_not_found\" }))),\n list: Effect.fn(\"GrantStore.list\")(() => Effect.succeed([]))(),\n grantEnvelope: Effect.fn(\"GrantStore.grantEnvelope\")(() => Effect.void)\n })\n return service\n })\n )\n"]}
package/docs/README.md ADDED
@@ -0,0 +1,162 @@
1
+ ---
2
+ title: "@smthrs/kernel"
3
+ description: "A capability kernel for Effect hosts: it decorates the filesystem, process, network, path, and Jujutsu service tags in place, so every side effect is checked against a grant store before it runs and refused with a typed error when nobody authorized it."
4
+ ---
5
+
6
+ `@smthrs/kernel` puts a permission check in front of every side effect an
7
+ [Effect](https://effect.website) program can reach. It wraps the five service
8
+ tags a host provides, `FileSystem`, `Path`, `ChildProcessSpawner`, `HttpClient`,
9
+ and `Jj`, with middleware that names the operation as a capability, asks a grant
10
+ store whether it may proceed, and refuses it with a typed error when no rule
11
+ allows it and nobody is there to ask. Four of those tags are Effect's own; `Jj`
12
+ is the [Jujutsu](https://jj-vcs.github.io) repository port from
13
+ [`@smthrs/jj`](/api/jj).
14
+
15
+ ## What it solves
16
+
17
+ Running code you did not write, an agent's plan, a plugin, a generated build
18
+ script, means every file write and every spawned process needs an answer to one
19
+ question: did anyone authorize this. The usual way to enforce that answer is a
20
+ second, protected service, and to tell every caller to use it. That breaks on
21
+ the first dependency that never heard of your kernel and reaches for the
22
+ ordinary `FileSystem` tag instead.
23
+
24
+ This package decorates the ordinary tag in place. Once the layer is composed,
25
+ the guarded implementation _is_ what the tag resolves to, so there is no
26
+ unguarded one left to reach for. Code that calls `fs.readFileString` is checked
27
+ without ever mentioning permission.
28
+
29
+ A yes or no answer is not enough on its own, so the kernel also closes the gaps
30
+ around it:
31
+
32
+ - **Confinement.** A path is authorized as a canonical resource and the
33
+ operation runs through a pinned directory descriptor, so a symlink or a
34
+ rename between the decision and the call cannot redirect it.
35
+ - **Containment.** A cancelled run signals its children, escalates to
36
+ `SIGKILL` on a deadline, and records each child in a durable ledger, so a
37
+ host that dies leaves orphan records its successor can reap.
38
+ - **A ceiling that only narrows.** `CapabilitySet.attenuate` bounds what a
39
+ fiber may ask for, and no public operation widens it again.
40
+ - **Grants that outlive the process.** A decision is written to a journal
41
+ before it takes effect, so a permission a person chose to remember is still
42
+ in force after a restart.
43
+
44
+ ## Install
45
+
46
+ `@smthrs/kernel` is not on npm at 1.0.0-rc.0. Its source lives in the
47
+ [smithers repository](https://github.com/smithersai/smithers), and
48
+ [Installation](./installation.md) covers how to depend on it from a checkout,
49
+ the import forms, and the three test subpaths.
50
+
51
+ The package needs Node.js 26.4.0 or later. It carries no platform
52
+ implementations of its own, so a composition that reaches a real machine also
53
+ adds a bundle such as [`@smthrs/platform-node`](/api/platform-node).
54
+
55
+ ## Refuse an operation nobody authorized
56
+
57
+ This program composes the kernel over `@smthrs/testing/TestHost`. Add
58
+ `"@smthrs/testing": "workspace:*"` to the consuming package's devDependencies
59
+ before running it. The policy allows reads under the workspace and says
60
+ nothing about writes:
61
+
62
+ ```ts
63
+ import { Capability, GrantStore, HostServices, Permission, Workspace } from "@smthrs/kernel"
64
+ import * as TestHost from "@smthrs/testing/TestHost"
65
+ import { Effect, FileSystem, Layer } from "effect"
66
+
67
+ const rules = [
68
+ new Permission.Rule({
69
+ effect: "allow",
70
+ pattern: new Capability.CapabilityPattern({ action: "fs:read", resource: "/workspace/**" })
71
+ })
72
+ ]
73
+
74
+ const guarded = HostServices.layer.pipe(
75
+ Layer.provide(Layer.orDie(GrantStore.layer({ attended: false, rules }))),
76
+ Layer.provideMerge(TestHost.layer({ files: { "/workspace/README.md": "# hello" } })),
77
+ Layer.provide(Workspace.layer("/workspace"))
78
+ )
79
+
80
+ /** Ordinary Effect code. Nothing here knows a kernel exists. */
81
+ const program = Effect.gen(function*() {
82
+ const fs = yield* FileSystem.FileSystem
83
+ const readme = yield* fs.readFileString("/workspace/README.md")
84
+ yield* fs.writeFileString("/workspace/out.txt", readme)
85
+ })
86
+
87
+ Effect.runPromise(program.pipe(Effect.provide(guarded), Effect.scoped))
88
+ ```
89
+
90
+ The read returns `"# hello"`. The write never reaches the filesystem. Effect
91
+ fixes that method's error channel to `PlatformError`, so the kernel projects
92
+ its refusal into one and keeps the structured original on the cause;
93
+ `Permission.fromPlatformError` reads it back:
94
+
95
+ ```text
96
+ {
97
+ _tag: '@smthrs/capability/PermissionRequired',
98
+ code: 'permission_required',
99
+ requestId: 'permission-1',
100
+ capability: { action: 'fs:write', resource: '/workspace/out.txt' },
101
+ tier: 'compensable',
102
+ meta: {}
103
+ }
104
+ ```
105
+
106
+ The `tier` says what re-running the refused operation would cost: a write
107
+ inside the workspace is `compensable`, because the run can undo it from its own
108
+ snapshot. See [effect tiers](/pkg/capability/concepts/effect-tiers) for the
109
+ other two.
110
+
111
+ `permission_required`, not `permission_denied`: no rule matched, silence is not
112
+ consent, and this store has nobody to ask. Build the store with
113
+ `attended: true` instead and the same write parks on a request an operator can
114
+ answer, then resumes the operation it was authorized for. The
115
+ [Quickstart](./quickstart.md) runs both halves.
116
+
117
+ ## How this fits with @smthrs/flows
118
+
119
+ `@smthrs/kernel` is one package of the Smithers durable flow engine, which
120
+ ships whole as [`@smthrs/flows`](/api/flows). Inside that engine the kernel is
121
+ the layer between a flow's body and the machine:
122
+ [`@smthrs/capability`](/api/capability) supplies the vocabulary it decides with,
123
+ the [`@smthrs/platform-node`](/api/platform-node) family implements the ports it
124
+ decorates, and [`@smthrs/engine`](/api/engine) runs steps over the guarded
125
+ surface it composes. `@smthrs/flows` re-exports all of it as the `Kernel`
126
+ namespace, and the durable Node runtime it builds is this composition at full
127
+ size, so a program that already depends on the barrel does not install this
128
+ package separately.
129
+
130
+ Depend on `@smthrs/kernel` on its own when you are guarding a host of your own
131
+ rather than running Smithers flows. Its only Smithers dependencies are the
132
+ capability vocabulary, the journal, and the Jujutsu port, and its root entry
133
+ point imports no Node built-ins, so the kernel runs wherever its host does.
134
+
135
+ Further up, [`@smthrs/cli`](/api/cli) is the `smthrs` command line that
136
+ everything here sits under. It finds the flows in a project, plans them, takes
137
+ an approval, and runs them, and it builds its host through this kernel with a
138
+ policy scoped to the project root, which is how a step that reaches outside
139
+ that root gets stopped.
140
+
141
+ ## Where to go next
142
+
143
+ - [Installation](./installation.md): runtime requirements, the import forms,
144
+ the three test subpaths, and the platform bundle you choose yourself.
145
+ - [Quickstart](./quickstart.md): refuse a read on an unattended store, then
146
+ answer the same read on an attended one.
147
+ - [Guard a host bundle](./guides/guard-a-host-bundle.md): the composition over
148
+ a real platform, in the right order, and the two mistakes that defeat it.
149
+ - [Write a capability policy](./guides/write-a-capability-policy.md): the four
150
+ rulesets, the hard veto, and the resource each action names.
151
+ - [Answer permission requests](./guides/answer-permission-requests.md): the
152
+ code on the other side of a parked request.
153
+ - [Decoration in place](./concepts/decoration-in-place.md): why the kernel
154
+ guards the platform's own tags instead of publishing protected copies.
155
+ - [How a grant decision is made](./concepts/grant-decisions.md): the ceiling,
156
+ the four rulesets, and the order they are consulted in.
157
+ - [API reference](./api.md): every public export, its signature, and its
158
+ bounds.
159
+ - [The kernel contract](./contract.md): what this package guarantees at a host
160
+ boundary, in one paragraph.
161
+ - [Troubleshooting](./troubleshooting.md): each refusal this package raises,
162
+ what it means, and what to change.