failproofai 0.0.15 → 1.0.0-beta.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 (136) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +3 -3
  3. package/.next/standalone/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  6. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  7. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  10. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  11. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  12. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  13. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  14. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  15. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  16. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.rsc +14 -14
  20. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
  21. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  22. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +9 -9
  23. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  24. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  25. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  26. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/audit/run/route.js +1 -1
  28. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/api/auth/reminder/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  36. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  38. package/.next/standalone/.next/server/app/index.html +1 -1
  39. package/.next/standalone/.next/server/app/index.rsc +14 -14
  40. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  41. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +14 -14
  42. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  43. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +9 -9
  44. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  45. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  46. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  47. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  48. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +9 -9
  49. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  50. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  51. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  52. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  53. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  54. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  55. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  56. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  59. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  60. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  61. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0id_xf7._.js +3 -0
  62. package/.next/standalone/.next/server/chunks/[root-of-the-server]__19120tr._.js +1 -1
  63. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1fwl2mz._.js +1 -1
  64. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1myjm-d._.js +1 -1
  65. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_17k9e3w.js +4 -4
  66. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  67. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0114ewg._.js +2 -2
  68. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__06b4trb._.js → [root-of-the-server]__0259h38._.js} +2 -2
  69. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02r5bgf._.js +2 -2
  70. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e8sjqm._.js +2 -2
  71. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0lkzqax._.js +2 -2
  72. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qucxyj._.js +2 -2
  73. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u02miy._.js +2 -2
  74. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__170799-._.js +1 -1
  75. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ath6v_._.js +2 -2
  76. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1zj-87g._.js +3 -0
  77. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1zqz4v8._.js +2 -2
  78. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
  79. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  80. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
  81. package/.next/standalone/.next/server/chunks/ssr/{node_modules_html-to-image_es_index_0hs_5mh.js → node_modules_html-to-image_es_index_1-upb14.js} +1 -1
  82. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1ezd2jf._.js +1 -1
  83. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1tnuifj._.js +1 -1
  84. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  85. package/.next/standalone/.next/server/pages/404.html +1 -1
  86. package/.next/standalone/.next/server/pages/500.html +1 -1
  87. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  88. package/.next/standalone/.next/server/server-reference-manifest.json +11 -11
  89. package/.next/standalone/.next/static/chunks/{1_v8b8mxhk25s.js → 0ip1n8xmgxarv.js} +1 -1
  90. package/.next/standalone/.next/static/chunks/{33rm-y-i4uzvv.js → 0u9hc6oxx-gpj.js} +1 -1
  91. package/.next/standalone/.next/static/chunks/{11qhtpk2cvoxv.js → 1d6ncspjagm53.js} +1 -1
  92. package/.next/standalone/.next/static/chunks/{2f4mxqkkoa_7d.js → 1grd7y94-igz9.js} +1 -1
  93. package/.next/standalone/.next/static/chunks/{3m8wmvlhsy1mx.js → 1s-_swlc80y43.js} +1 -1
  94. package/.next/standalone/.next/static/chunks/{0kf9j0pf_j9-0.js → 29k6ef49zppxj.js} +1 -1
  95. package/.next/standalone/.next/static/chunks/{2h7vw-ojgr9fz.js → 29ydr-8q0zis6.js} +1 -1
  96. package/.next/standalone/.next/static/chunks/{1-ng45379-ztb.js → 2vr7aazw6k2-n.js} +1 -1
  97. package/.next/standalone/.next/static/chunks/{2geh8s7d3ead-.js → 3wrgbih-516uj.js} +1 -1
  98. package/.next/standalone/Cargo.lock +428 -0
  99. package/.next/standalone/Cargo.toml +9 -0
  100. package/.next/standalone/crates/PROTOCOL.md +122 -0
  101. package/.next/standalone/crates/failproofaid/Cargo.toml +18 -0
  102. package/.next/standalone/crates/failproofaid/src/lock.rs +81 -0
  103. package/.next/standalone/crates/failproofaid/src/main.rs +83 -0
  104. package/.next/standalone/crates/failproofaid/src/paths.rs +172 -0
  105. package/.next/standalone/crates/failproofaid/src/server.rs +502 -0
  106. package/.next/standalone/crates/failproofaid/src/worker.rs +400 -0
  107. package/.next/standalone/crates/failproofaid/tests/daemon_e2e.rs +241 -0
  108. package/.next/standalone/crates/fpai-ipc/Cargo.toml +16 -0
  109. package/.next/standalone/crates/fpai-ipc/src/envelope.rs +175 -0
  110. package/.next/standalone/crates/fpai-ipc/src/framing.rs +177 -0
  111. package/.next/standalone/crates/fpai-ipc/src/lib.rs +10 -0
  112. package/.next/standalone/crates/fpai-ipc/src/peer.rs +80 -0
  113. package/.next/standalone/package.json +5 -3
  114. package/.next/standalone/rust-toolchain.toml +4 -0
  115. package/.next/standalone/server.js +1 -1
  116. package/bin/failproofai-worker.mjs +51 -0
  117. package/bin/failproofai.mjs +68 -1
  118. package/bin/failproofaid-shim.mjs +67 -0
  119. package/dist/cli.mjs +1202 -624
  120. package/dist/worker.mjs +8441 -0
  121. package/package.json +5 -3
  122. package/src/hooks/builtin-policies.ts +37 -13
  123. package/src/hooks/configure-wizard.ts +73 -1
  124. package/src/hooks/daemon-client.ts +199 -0
  125. package/src/hooks/daemon-download.ts +152 -0
  126. package/src/hooks/daemon-service.ts +449 -0
  127. package/src/hooks/handler.ts +231 -195
  128. package/src/hooks/normalize-cli-payload.ts +61 -0
  129. package/src/hooks/policy-types.ts +15 -0
  130. package/src/hooks/read-stdin.ts +48 -0
  131. package/src/hooks/worker-server.ts +154 -0
  132. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1is3glr._.js +0 -3
  133. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0fopait._.js +0 -3
  134. /package/.next/standalone/.next/static/{ePKMmXXfXxThNsxwv1EiF → 7Lxtd352rSaHB-pmm6G8M}/_buildManifest.js +0 -0
  135. /package/.next/standalone/.next/static/{ePKMmXXfXxThNsxwv1EiF → 7Lxtd352rSaHB-pmm6G8M}/_clientMiddlewareManifest.js +0 -0
  136. /package/.next/standalone/.next/static/{ePKMmXXfXxThNsxwv1EiF → 7Lxtd352rSaHB-pmm6G8M}/_ssgManifest.js +0 -0
@@ -0,0 +1,428 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "autocfg"
7
+ version = "1.5.1"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
10
+
11
+ [[package]]
12
+ name = "bit-set"
13
+ version = "0.8.0"
14
+ source = "registry+https://github.com/rust-lang/crates.io-index"
15
+ checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3"
16
+ dependencies = [
17
+ "bit-vec",
18
+ ]
19
+
20
+ [[package]]
21
+ name = "bit-vec"
22
+ version = "0.8.0"
23
+ source = "registry+https://github.com/rust-lang/crates.io-index"
24
+ checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
25
+
26
+ [[package]]
27
+ name = "bitflags"
28
+ version = "2.13.1"
29
+ source = "registry+https://github.com/rust-lang/crates.io-index"
30
+ checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
31
+
32
+ [[package]]
33
+ name = "cfg-if"
34
+ version = "1.0.4"
35
+ source = "registry+https://github.com/rust-lang/crates.io-index"
36
+ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
37
+
38
+ [[package]]
39
+ name = "errno"
40
+ version = "0.3.14"
41
+ source = "registry+https://github.com/rust-lang/crates.io-index"
42
+ checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
43
+ dependencies = [
44
+ "libc",
45
+ "windows-sys",
46
+ ]
47
+
48
+ [[package]]
49
+ name = "failproofaid"
50
+ version = "1.0.0-beta.0"
51
+ dependencies = [
52
+ "fpai-ipc",
53
+ "libc",
54
+ "serde",
55
+ "serde_json",
56
+ ]
57
+
58
+ [[package]]
59
+ name = "fastrand"
60
+ version = "2.5.0"
61
+ source = "registry+https://github.com/rust-lang/crates.io-index"
62
+ checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223"
63
+
64
+ [[package]]
65
+ name = "fnv"
66
+ version = "1.0.7"
67
+ source = "registry+https://github.com/rust-lang/crates.io-index"
68
+ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
69
+
70
+ [[package]]
71
+ name = "fpai-ipc"
72
+ version = "1.0.0-beta.0"
73
+ dependencies = [
74
+ "libc",
75
+ "proptest",
76
+ "serde",
77
+ "serde_json",
78
+ ]
79
+
80
+ [[package]]
81
+ name = "getrandom"
82
+ version = "0.3.4"
83
+ source = "registry+https://github.com/rust-lang/crates.io-index"
84
+ checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
85
+ dependencies = [
86
+ "cfg-if",
87
+ "libc",
88
+ "r-efi 5.3.0",
89
+ "wasip2",
90
+ ]
91
+
92
+ [[package]]
93
+ name = "getrandom"
94
+ version = "0.4.3"
95
+ source = "registry+https://github.com/rust-lang/crates.io-index"
96
+ checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
97
+ dependencies = [
98
+ "cfg-if",
99
+ "libc",
100
+ "r-efi 6.0.0",
101
+ ]
102
+
103
+ [[package]]
104
+ name = "itoa"
105
+ version = "1.0.18"
106
+ source = "registry+https://github.com/rust-lang/crates.io-index"
107
+ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
108
+
109
+ [[package]]
110
+ name = "libc"
111
+ version = "0.2.189"
112
+ source = "registry+https://github.com/rust-lang/crates.io-index"
113
+ checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
114
+
115
+ [[package]]
116
+ name = "linux-raw-sys"
117
+ version = "0.12.1"
118
+ source = "registry+https://github.com/rust-lang/crates.io-index"
119
+ checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
120
+
121
+ [[package]]
122
+ name = "memchr"
123
+ version = "2.8.3"
124
+ source = "registry+https://github.com/rust-lang/crates.io-index"
125
+ checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
126
+
127
+ [[package]]
128
+ name = "num-traits"
129
+ version = "0.2.19"
130
+ source = "registry+https://github.com/rust-lang/crates.io-index"
131
+ checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
132
+ dependencies = [
133
+ "autocfg",
134
+ ]
135
+
136
+ [[package]]
137
+ name = "once_cell"
138
+ version = "1.21.4"
139
+ source = "registry+https://github.com/rust-lang/crates.io-index"
140
+ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
141
+
142
+ [[package]]
143
+ name = "ppv-lite86"
144
+ version = "0.2.21"
145
+ source = "registry+https://github.com/rust-lang/crates.io-index"
146
+ checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
147
+ dependencies = [
148
+ "zerocopy",
149
+ ]
150
+
151
+ [[package]]
152
+ name = "proc-macro2"
153
+ version = "1.0.107"
154
+ source = "registry+https://github.com/rust-lang/crates.io-index"
155
+ checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
156
+ dependencies = [
157
+ "unicode-ident",
158
+ ]
159
+
160
+ [[package]]
161
+ name = "proptest"
162
+ version = "1.11.0"
163
+ source = "registry+https://github.com/rust-lang/crates.io-index"
164
+ checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744"
165
+ dependencies = [
166
+ "bit-set",
167
+ "bit-vec",
168
+ "bitflags",
169
+ "num-traits",
170
+ "rand",
171
+ "rand_chacha",
172
+ "rand_xorshift",
173
+ "regex-syntax",
174
+ "rusty-fork",
175
+ "tempfile",
176
+ "unarray",
177
+ ]
178
+
179
+ [[package]]
180
+ name = "quick-error"
181
+ version = "1.2.3"
182
+ source = "registry+https://github.com/rust-lang/crates.io-index"
183
+ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
184
+
185
+ [[package]]
186
+ name = "quote"
187
+ version = "1.0.47"
188
+ source = "registry+https://github.com/rust-lang/crates.io-index"
189
+ checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
190
+ dependencies = [
191
+ "proc-macro2",
192
+ ]
193
+
194
+ [[package]]
195
+ name = "r-efi"
196
+ version = "5.3.0"
197
+ source = "registry+https://github.com/rust-lang/crates.io-index"
198
+ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
199
+
200
+ [[package]]
201
+ name = "r-efi"
202
+ version = "6.0.0"
203
+ source = "registry+https://github.com/rust-lang/crates.io-index"
204
+ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
205
+
206
+ [[package]]
207
+ name = "rand"
208
+ version = "0.9.5"
209
+ source = "registry+https://github.com/rust-lang/crates.io-index"
210
+ checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41"
211
+ dependencies = [
212
+ "rand_chacha",
213
+ "rand_core",
214
+ ]
215
+
216
+ [[package]]
217
+ name = "rand_chacha"
218
+ version = "0.9.0"
219
+ source = "registry+https://github.com/rust-lang/crates.io-index"
220
+ checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
221
+ dependencies = [
222
+ "ppv-lite86",
223
+ "rand_core",
224
+ ]
225
+
226
+ [[package]]
227
+ name = "rand_core"
228
+ version = "0.9.5"
229
+ source = "registry+https://github.com/rust-lang/crates.io-index"
230
+ checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
231
+ dependencies = [
232
+ "getrandom 0.3.4",
233
+ ]
234
+
235
+ [[package]]
236
+ name = "rand_xorshift"
237
+ version = "0.4.0"
238
+ source = "registry+https://github.com/rust-lang/crates.io-index"
239
+ checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a"
240
+ dependencies = [
241
+ "rand_core",
242
+ ]
243
+
244
+ [[package]]
245
+ name = "regex-syntax"
246
+ version = "0.8.11"
247
+ source = "registry+https://github.com/rust-lang/crates.io-index"
248
+ checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
249
+
250
+ [[package]]
251
+ name = "rustix"
252
+ version = "1.1.4"
253
+ source = "registry+https://github.com/rust-lang/crates.io-index"
254
+ checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
255
+ dependencies = [
256
+ "bitflags",
257
+ "errno",
258
+ "libc",
259
+ "linux-raw-sys",
260
+ "windows-sys",
261
+ ]
262
+
263
+ [[package]]
264
+ name = "rusty-fork"
265
+ version = "0.3.1"
266
+ source = "registry+https://github.com/rust-lang/crates.io-index"
267
+ checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2"
268
+ dependencies = [
269
+ "fnv",
270
+ "quick-error",
271
+ "tempfile",
272
+ "wait-timeout",
273
+ ]
274
+
275
+ [[package]]
276
+ name = "serde"
277
+ version = "1.0.229"
278
+ source = "registry+https://github.com/rust-lang/crates.io-index"
279
+ checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
280
+ dependencies = [
281
+ "serde_core",
282
+ "serde_derive",
283
+ ]
284
+
285
+ [[package]]
286
+ name = "serde_core"
287
+ version = "1.0.229"
288
+ source = "registry+https://github.com/rust-lang/crates.io-index"
289
+ checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
290
+ dependencies = [
291
+ "serde_derive",
292
+ ]
293
+
294
+ [[package]]
295
+ name = "serde_derive"
296
+ version = "1.0.229"
297
+ source = "registry+https://github.com/rust-lang/crates.io-index"
298
+ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
299
+ dependencies = [
300
+ "proc-macro2",
301
+ "quote",
302
+ "syn 3.0.3",
303
+ ]
304
+
305
+ [[package]]
306
+ name = "serde_json"
307
+ version = "1.0.151"
308
+ source = "registry+https://github.com/rust-lang/crates.io-index"
309
+ checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
310
+ dependencies = [
311
+ "itoa",
312
+ "memchr",
313
+ "serde",
314
+ "serde_core",
315
+ "zmij",
316
+ ]
317
+
318
+ [[package]]
319
+ name = "syn"
320
+ version = "2.0.119"
321
+ source = "registry+https://github.com/rust-lang/crates.io-index"
322
+ checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
323
+ dependencies = [
324
+ "proc-macro2",
325
+ "quote",
326
+ "unicode-ident",
327
+ ]
328
+
329
+ [[package]]
330
+ name = "syn"
331
+ version = "3.0.3"
332
+ source = "registry+https://github.com/rust-lang/crates.io-index"
333
+ checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
334
+ dependencies = [
335
+ "proc-macro2",
336
+ "quote",
337
+ "unicode-ident",
338
+ ]
339
+
340
+ [[package]]
341
+ name = "tempfile"
342
+ version = "3.27.0"
343
+ source = "registry+https://github.com/rust-lang/crates.io-index"
344
+ checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
345
+ dependencies = [
346
+ "fastrand",
347
+ "getrandom 0.4.3",
348
+ "once_cell",
349
+ "rustix",
350
+ "windows-sys",
351
+ ]
352
+
353
+ [[package]]
354
+ name = "unarray"
355
+ version = "0.1.4"
356
+ source = "registry+https://github.com/rust-lang/crates.io-index"
357
+ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
358
+
359
+ [[package]]
360
+ name = "unicode-ident"
361
+ version = "1.0.24"
362
+ source = "registry+https://github.com/rust-lang/crates.io-index"
363
+ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
364
+
365
+ [[package]]
366
+ name = "wait-timeout"
367
+ version = "0.2.1"
368
+ source = "registry+https://github.com/rust-lang/crates.io-index"
369
+ checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11"
370
+ dependencies = [
371
+ "libc",
372
+ ]
373
+
374
+ [[package]]
375
+ name = "wasip2"
376
+ version = "1.0.4+wasi-0.2.12"
377
+ source = "registry+https://github.com/rust-lang/crates.io-index"
378
+ checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487"
379
+ dependencies = [
380
+ "wit-bindgen",
381
+ ]
382
+
383
+ [[package]]
384
+ name = "windows-link"
385
+ version = "0.2.1"
386
+ source = "registry+https://github.com/rust-lang/crates.io-index"
387
+ checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
388
+
389
+ [[package]]
390
+ name = "windows-sys"
391
+ version = "0.61.2"
392
+ source = "registry+https://github.com/rust-lang/crates.io-index"
393
+ checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
394
+ dependencies = [
395
+ "windows-link",
396
+ ]
397
+
398
+ [[package]]
399
+ name = "wit-bindgen"
400
+ version = "0.57.1"
401
+ source = "registry+https://github.com/rust-lang/crates.io-index"
402
+ checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
403
+
404
+ [[package]]
405
+ name = "zerocopy"
406
+ version = "0.8.55"
407
+ source = "registry+https://github.com/rust-lang/crates.io-index"
408
+ checksum = "b5a105cd7b140f6eeec8acff2ea38135d3cab283ada58540f629fe51e46696eb"
409
+ dependencies = [
410
+ "zerocopy-derive",
411
+ ]
412
+
413
+ [[package]]
414
+ name = "zerocopy-derive"
415
+ version = "0.8.55"
416
+ source = "registry+https://github.com/rust-lang/crates.io-index"
417
+ checksum = "0fe976fb70c78cd64cccfe3a6fc142244e8a77b70959b30faf9d0ac37ee228eb"
418
+ dependencies = [
419
+ "proc-macro2",
420
+ "quote",
421
+ "syn 2.0.119",
422
+ ]
423
+
424
+ [[package]]
425
+ name = "zmij"
426
+ version = "1.0.23"
427
+ source = "registry+https://github.com/rust-lang/crates.io-index"
428
+ checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
@@ -0,0 +1,9 @@
1
+ [workspace]
2
+ resolver = "3"
3
+ members = ["crates/*"]
4
+
5
+ [workspace.package]
6
+ version = "1.0.0-beta.0"
7
+ edition = "2024"
8
+ license-file = "LICENSE"
9
+ repository = "https://github.com/FailproofAI/failproofai"
@@ -0,0 +1,122 @@
1
+ # failproofaid wire protocol
2
+
3
+ The contract between the `failproofai` CLI (thin client) and the `failproofaid`
4
+ daemon over a Unix domain socket. This is the same contract every hook
5
+ invocation already has today — see `src/hooks/handler.ts`'s
6
+ `handleHookEvent`: `(argv --hook <Event> --cli <cli>, stdin JSON payload) ->
7
+ (stdout, stderr, exitCode)`. The daemon adds nothing to that contract; it only
8
+ relays it over a socket instead of a fresh process's argv/stdin/stdout.
9
+
10
+ Implemented in `crates/fpai-ipc` (framing + envelope + peer verification) and
11
+ `crates/failproofaid` (the socket server itself). As of Stage 2, the daemon
12
+ answers `ping` and rejects `hook` with a stub "not implemented" error — Stage 3
13
+ wires `hook` up to a real warm Node/Bun worker.
14
+
15
+ ## Transport
16
+
17
+ One Unix domain socket, one connection per request. The daemon reads exactly
18
+ one frame, dispatches it, writes exactly one frame back, and lets the
19
+ connection close — there is no request-ID multiplexing because there is never
20
+ more than one logical request in flight per connection.
21
+
22
+ Default path: `~/.failproofai/run/failproofaid.sock`. Overridable via the
23
+ `FAILPROOFAI_DAEMON_SOCKET` env var (used by local dev and tests — never point
24
+ this at a directory failproofaid doesn't own itself; see
25
+ `crates/failproofaid/src/paths.rs`'s `ensure_run_dir`, which refuses to modify
26
+ permissions on a pre-existing directory it didn't create).
27
+
28
+ Permissions: the run directory is `0700` and the socket file `0600` — this is
29
+ the actual access-control boundary (user-scope only, no elevation, same OS
30
+ user only). `crates/fpai-ipc/src/peer.rs`'s `SO_PEERCRED` (Linux) /
31
+ `getpeereid` (macOS) check is defense-in-depth on top of that, not a stronger
32
+ boundary — same-user access can always reach this daemon regardless.
33
+
34
+ ## Framing
35
+
36
+ Every message, in both directions, is:
37
+
38
+ ```
39
+ +----------------------------+------------------------------+
40
+ | length (4 bytes, big-endian u32) | UTF-8 JSON body (length bytes) |
41
+ +----------------------------+------------------------------+
42
+ ```
43
+
44
+ A declared length over `MAX_FRAME_LEN` (16 MiB) is rejected without
45
+ allocating a body buffer for it — a hook payload is at most 1 MiB (see
46
+ `handler.ts`'s own stdin cap), so 16 MiB is headroom, not an expected size.
47
+
48
+ ## Envelope
49
+
50
+ Tagged JSON, `"type"` as the discriminant, camelCase field names.
51
+
52
+ ### Client → daemon (`ClientMessage`)
53
+
54
+ ```jsonc
55
+ // Liveness/handshake check.
56
+ { "type": "ping", "protocolVersion": 1 }
57
+
58
+ // One hook evaluation request — one per `failproofai --hook <Event> --cli <cli>` invocation.
59
+ {
60
+ "type": "hook",
61
+ "protocolVersion": 1,
62
+ "hookEvent": "PreToolUse",
63
+ "cli": "claude",
64
+ "stdin": "<raw stdin payload the calling agent CLI wrote to the one-shot failproofai process, forwarded verbatim>",
65
+ "cwd": "/path/to/session/cwd" // optional; see the note below
66
+ }
67
+ ```
68
+
69
+ `cwd` must be the *originating* CLI process's cwd, captured by the thin
70
+ client before dispatch — never the daemon's own cwd. The daemon is a single
71
+ long-lived process; its own `cwd` does not vary per request and must never be
72
+ used to resolve project config or custom policies (this is the "process.cwd()
73
+ hazard" the TS-side plan calls out explicitly).
74
+
75
+ ### Daemon → client (`ServerMessage`)
76
+
77
+ ```jsonc
78
+ { "type": "pong", "protocolVersion": 1 }
79
+
80
+ {
81
+ "type": "hookResult",
82
+ "protocolVersion": 1,
83
+ "exitCode": 0,
84
+ "stdout": "...",
85
+ "stderr": "..."
86
+ }
87
+
88
+ // The daemon accepted the connection and parsed the request, but could not
89
+ // produce a verdict (worker down/hung, or — in Stage 2 — hook evaluation
90
+ // simply isn't wired up yet). Distinct from hookResult so the client can
91
+ // tell "ran and decided" apart from "daemon couldn't evaluate at all" — the
92
+ // latter is what drives the client's fail-closed path.
93
+ { "type": "error", "protocolVersion": 1, "message": "..." }
94
+ ```
95
+
96
+ ## Protocol versioning
97
+
98
+ `protocolVersion` is carried on every message in both directions. A mismatch
99
+ gets an explicit `error` response from the daemon — the client treats *any*
100
+ failure mode (missing socket, refused connection, timeout, malformed
101
+ response, or an explicit version mismatch) identically: fall through to
102
+ whatever the client's fail-closed/in-process policy dictates. There is no
103
+ negotiation, only agree-or-fall-back.
104
+
105
+ ## Peer verification
106
+
107
+ Every connection is checked with `SO_PEERCRED`/`getpeereid` before a single
108
+ byte of the request is read. A peer running as a different OS user gets the
109
+ connection dropped with **no response at all** — not even an `error` frame —
110
+ so a connection from the wrong user can't even confirm a daemon is listening
111
+ there.
112
+
113
+ ## Malformed input handling
114
+
115
+ - A frame whose declared length exceeds `MAX_FRAME_LEN`: connection closed,
116
+ no response, no allocation attempted for the declared size.
117
+ - A syntactically invalid or truncated frame: connection closed, no response.
118
+ - A well-formed frame with an unrecognized `"type"`: fails to deserialize,
119
+ same as above.
120
+
121
+ None of these crash the daemon or the connection-handling thread — a bad
122
+ frame from one connection has no effect on any other connection.
@@ -0,0 +1,18 @@
1
+ [package]
2
+ name = "failproofaid"
3
+ version.workspace = true
4
+ edition.workspace = true
5
+ license-file.workspace = true
6
+ repository.workspace = true
7
+ description = "Thin Rust supervisor: owns the failproofai IPC socket, service lifecycle, and warm worker process supervision. Carries no policy logic."
8
+ publish = false
9
+
10
+ [[bin]]
11
+ name = "failproofaid"
12
+ path = "src/main.rs"
13
+
14
+ [dependencies]
15
+ fpai-ipc = { path = "../fpai-ipc" }
16
+ serde = { version = "1", features = ["derive"] }
17
+ serde_json = "1"
18
+ libc = "0.2"
@@ -0,0 +1,81 @@
1
+ //! Single-instance guard: at most one `failproofaid` per OS user.
2
+ //!
3
+ //! Uses an advisory `flock()` on a dedicated lock file rather than a
4
+ //! PID file — a PID file has to be checked-then-trusted (the PID could
5
+ //! have been reused by an unrelated process since), whereas `flock` is
6
+ //! released automatically by the kernel when the holding process exits or
7
+ //! is killed, for any reason, with no stale-file cleanup required.
8
+
9
+ use std::fs::{File, OpenOptions};
10
+ use std::io;
11
+ use std::os::unix::io::AsRawFd;
12
+ use std::path::Path;
13
+
14
+ pub struct SingletonLock {
15
+ // Held for the guard's lifetime; the flock is released when this File
16
+ // (and its underlying fd) is dropped.
17
+ _file: File,
18
+ }
19
+
20
+ #[derive(Debug)]
21
+ pub enum LockError {
22
+ Io(io::Error),
23
+ AlreadyRunning,
24
+ }
25
+
26
+ impl std::fmt::Display for LockError {
27
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28
+ match self {
29
+ LockError::Io(e) => write!(f, "io error acquiring daemon lock: {e}"),
30
+ LockError::AlreadyRunning => {
31
+ write!(f, "another failproofaid is already running for this user")
32
+ }
33
+ }
34
+ }
35
+ }
36
+
37
+ impl std::error::Error for LockError {}
38
+
39
+ /// Tries to acquire the singleton lock at `path`, creating the file if
40
+ /// needed. Returns [`LockError::AlreadyRunning`] immediately (non-blocking)
41
+ /// if another live process already holds it.
42
+ pub fn acquire(path: &Path) -> Result<SingletonLock, LockError> {
43
+ let file = OpenOptions::new()
44
+ .create(true)
45
+ .truncate(false)
46
+ .write(true)
47
+ .open(path)
48
+ .map_err(LockError::Io)?;
49
+
50
+ let ret = unsafe { libc::flock(file.as_raw_fd(), libc::LOCK_EX | libc::LOCK_NB) };
51
+ if ret != 0 {
52
+ let err = io::Error::last_os_error();
53
+ return match err.raw_os_error() {
54
+ Some(libc::EWOULDBLOCK) => Err(LockError::AlreadyRunning),
55
+ _ => Err(LockError::Io(err)),
56
+ };
57
+ }
58
+ Ok(SingletonLock { _file: file })
59
+ }
60
+
61
+ #[cfg(test)]
62
+ mod tests {
63
+ use super::*;
64
+
65
+ #[test]
66
+ fn a_second_acquire_in_the_same_process_fails_while_the_first_is_held() {
67
+ let tmp = std::env::temp_dir().join(format!(
68
+ "failproofaid-lock-test-{}-{}",
69
+ std::process::id(),
70
+ line!()
71
+ ));
72
+ let first = acquire(&tmp).expect("first acquire should succeed");
73
+ let second = acquire(&tmp);
74
+ assert!(matches!(second, Err(LockError::AlreadyRunning)));
75
+ drop(first);
76
+ // Once released, a fresh acquire succeeds again.
77
+ let third = acquire(&tmp);
78
+ assert!(third.is_ok());
79
+ std::fs::remove_file(&tmp).ok();
80
+ }
81
+ }