@passioncode-ai/fabric-agent-adapter 0.40.0 → 0.41.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 (89) hide show
  1. package/CHANGELOG.md +124 -0
  2. package/README.md +9 -3
  3. package/SECURITY.md +27 -6
  4. package/bin/fabric-agent-adapter.js +71 -6
  5. package/package.json +2 -2
  6. package/plugins/fabric-agent-adapter/.claude-plugin/plugin.json +1 -1
  7. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/SKILL.md +42 -66
  8. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/references/dashboard-links.md +4 -2
  9. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/references/operator-channel-and-repository.md +55 -0
  10. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/references/provider-entry.md +9 -3
  11. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/references/verification.md +15 -0
  12. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/scripts/adapt_project.py +181 -26
  13. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/scripts/check_dashboard_link.py +66 -5
  14. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/scripts/fabric_provider.py +81 -23
  15. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/scripts/fabric_secrets.py +1 -1
  16. package/plugins/fabric-agent-adapter/skills/building-fabric-services/SKILL.md +28 -30
  17. package/plugins/fabric-agent-adapter/skills/building-fabric-services/assets/dashboard-kit/fabric-button.js +21 -9
  18. package/plugins/fabric-agent-adapter/skills/building-fabric-services/assets/dashboard-kit/fabric-dashboard.css +1 -1
  19. package/plugins/fabric-agent-adapter/skills/building-fabric-services/assets/dashboard-kit/fabric-dashboard.js +2 -2
  20. package/plugins/fabric-agent-adapter/skills/building-fabric-services/assets/dashboard-kit/kit.json +9 -4
  21. package/plugins/fabric-agent-adapter/skills/building-fabric-services/recipes/support-agent/README.md +47 -7
  22. package/plugins/fabric-agent-adapter/skills/building-fabric-services/recipes/support-agent/support_agent.py +230 -29
  23. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/board.md +21 -5
  24. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/dashboard-kit.md +2 -1
  25. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/dashboard-links.md +4 -2
  26. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/delegation.md +3 -2
  27. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/estate-record.md +2 -2
  28. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/interop.md +5 -0
  29. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/kit-modules.md +3 -2
  30. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/lifecycle.md +3 -1
  31. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/package.md +5 -1
  32. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/check_dashboard_layout.mjs +48 -19
  33. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/check_dashboard_link.py +66 -5
  34. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/check_service.py +1 -1
  35. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/check_service_rules.py +1 -1
  36. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/dashboard_kit.py +53 -19
  37. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-auth.mjs +4 -2
  38. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-board-link.mjs +145 -0
  39. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-board-session.mjs +196 -188
  40. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-board-shapes.mjs +5 -5
  41. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-board.mjs +2 -2
  42. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-ceremonies.mjs +6 -2
  43. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-delegation.mjs +2 -1
  44. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-descriptor.mjs +1 -1
  45. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-estate.mjs +3 -1
  46. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-interop.mjs +48 -14
  47. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-lock.mjs +34 -1
  48. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-package.mjs +144 -20
  49. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-supervisors.mjs +7 -3
  50. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_auth.py +12 -6
  51. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_backups.py +6 -6
  52. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_base.py +17 -4
  53. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_board.py +3 -3
  54. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_board_link.py +162 -0
  55. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_board_session.py +207 -227
  56. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_board_shapes.py +4 -4
  57. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_ceremonies.py +0 -1
  58. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_crypto.py +52 -5
  59. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_delegation.py +101 -45
  60. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_descriptor.py +12 -12
  61. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_estate.py +5 -5
  62. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_events.py +13 -10
  63. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_http.py +1 -1
  64. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_hub.py +6 -2
  65. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_interop.py +118 -71
  66. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_package.py +272 -74
  67. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_profiles.py +1 -1
  68. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_secrets.py +1 -1
  69. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_supervisors.py +36 -11
  70. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_usage.py +3 -3
  71. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/kit.json +130 -35
  72. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/sample_service.py +25 -7
  73. package/plugins/fabric-agent-adapter/skills/creating-fabric-agents/SKILL.md +29 -60
  74. package/plugins/fabric-agent-adapter/skills/creating-fabric-agents/references/dashboard-links.md +4 -2
  75. package/plugins/fabric-agent-adapter/skills/creating-fabric-agents/references/operator-channel-and-repository.md +55 -0
  76. package/plugins/fabric-agent-adapter/skills/creating-fabric-agents/scripts/check_dashboard_link.py +66 -5
  77. package/plugins/fabric-agent-adapter/skills/working-with-fabric/SKILL.md +3 -3
  78. package/plugins/fabric-agent-adapter/skills/working-with-fabric/references/native-host-hooks.md +2 -1
  79. package/plugins/fabric-agent-adapter/skills/working-with-fabric/references/session-hooks.md +26 -13
  80. package/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/fabric_session.py +6 -0
  81. package/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/fabric_session_cli.py +30 -22
  82. package/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/fabric_session_env.py +37 -6
  83. package/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/fabric_session_hosts.py +72 -13
  84. package/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/fabric_session_mail.py +25 -7
  85. package/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/fabric_session_mcp.py +199 -43
  86. package/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/host_hooks.py +10 -1
  87. package/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/hosts/context.mjs +25 -2
  88. package/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/hosts/openclaw/index.mjs +4 -2
  89. package/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/hosts/opencode/fabric.mjs +2 -1
@@ -49,7 +49,7 @@ USAGE_DAYS = 31
49
49
  COST_BASES = ("provider", "price-list", "unknown")
50
50
 
51
51
 
52
- _PROVIDER = re.compile(r"^[a-z][a-z0-9._-]{0,63}$")
52
+ _PROVIDER = re.compile(r"^[a-z][a-z0-9._-]{0,63}\Z")
53
53
 
54
54
 
55
55
  def make_usage_receipt(provider: str, model: str, *, input_tokens: int, output_tokens: int,
@@ -517,10 +517,10 @@ LIMIT_SCOPES = ("machine", "project", "pool", "job")
517
517
  PER_ORDER_KINDS = ("per_job", "approval")
518
518
 
519
519
 
520
- _LIMIT_ID = re.compile(r"^[a-z0-9][a-z0-9._:-]{0,63}$")
520
+ _LIMIT_ID = re.compile(r"^[a-z0-9][a-z0-9._:-]{0,63}\Z")
521
521
 
522
522
 
523
- _LIMIT_KIND = re.compile(r"^[a-z][a-z0-9_]{0,31}$")
523
+ _LIMIT_KIND = re.compile(r"^[a-z][a-z0-9_]{0,31}\Z")
524
524
 
525
525
 
526
526
  _LIMIT_FIELDS = ("id", "scope", "subject", "kind", "period", "windowSeconds", "since", "limitUsd", "spentUsd", "enforced", "tripped")
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fabric-service-kit",
3
- "version": "0.40.0",
3
+ "version": "0.41.0",
4
4
  "about": "The service kit's modules in dependency order: a module imports only modules listed before it. Written by fabric_kit.py build; edit the order and layers by hand, never the digests.",
5
5
  "python": [
6
6
  {
@@ -31,14 +31,14 @@
31
31
  "file": "fabric_secrets.py",
32
32
  "layer": "L0",
33
33
  "imports": [],
34
- "sha256": "452cb2955be438568fc241e263908813b5d4f52d65150f3685199c12d3e5071d"
34
+ "sha256": "68a0b5e9e90c468ec9ac67b2f0fd1848e08813d6ec1ec14a2a47337eb1a98911"
35
35
  },
36
36
  {
37
37
  "module": "fabric_crypto",
38
38
  "file": "fabric_crypto.py",
39
39
  "layer": "L1",
40
40
  "imports": [],
41
- "sha256": "87e3cc70f6c877d214717f0c4478cd1777a7f93ed7141647b6f023a71d0e7803"
41
+ "sha256": "9c34aee20dbe4d6742e4fdbaab68ceb934bbe7dbd3a904c0010824ace16cdeaa"
42
42
  },
43
43
  {
44
44
  "module": "fabric_estate",
@@ -51,7 +51,7 @@
51
51
  "fabric_secrets",
52
52
  "fabric_time"
53
53
  ],
54
- "sha256": "fe20cf6157cdb52d2c314d7f543334263a7ea2a6478a353ce6991b9cb5e32533"
54
+ "sha256": "50cc12166a00b680ba5b2e458200912d7bcfbef70bd73ec4edf57c7fcfa9b687"
55
55
  },
56
56
  {
57
57
  "module": "fabric_delegation",
@@ -62,7 +62,7 @@
62
62
  "fabric_estate",
63
63
  "fabric_jsvalue"
64
64
  ],
65
- "sha256": "395ccd01a1430bbcb3e01ec32229ecdd4f7c97574af3dce60b56dbbf24ee4c89"
65
+ "sha256": "92ff745fb76ebb5856f9bb55f7c46936035f1ae836056c71065b7bb6276b35e7"
66
66
  },
67
67
  {
68
68
  "module": "fabric_share",
@@ -85,12 +85,11 @@
85
85
  "layer": "L2",
86
86
  "imports": [
87
87
  "fabric_crypto",
88
- "fabric_delegation",
89
88
  "fabric_estate",
90
89
  "fabric_jsvalue",
91
90
  "fabric_time"
92
91
  ],
93
- "sha256": "bc2a6eb86ab74048434c37a4eece6d634bcbe3b2795e402cee94f6a5726f60ea"
92
+ "sha256": "a59e83cf4adb2669a9b98008e3d3a0cba991a35cbff97bc604fc82fe81cfd49f"
94
93
  },
95
94
  {
96
95
  "module": "fabric_package",
@@ -102,7 +101,7 @@
102
101
  "fabric_jsvalue",
103
102
  "fabric_secrets"
104
103
  ],
105
- "sha256": "495d2fa83a9053c15cd4f276704b0acb91dbd27d5d255c84ecbf35a2ca8dce46",
104
+ "sha256": "09e5b4d20564ccb318f5a5e4f33df0359873fa8239cf4f5fcd21c8af481fd211",
106
105
  "data": [
107
106
  "fabric-package.schema.json"
108
107
  ]
@@ -112,7 +111,7 @@
112
111
  "file": "fabric_base.py",
113
112
  "layer": "L3",
114
113
  "imports": [],
115
- "sha256": "35098da3eb568c0fb4330a3a4dcb34a9982f48e9500a03e3db6786a9b15b2f7c"
114
+ "sha256": "684533b3a2aa3acd9b9e645a7a443427d279408f9f12f13456a0a991d57954ce"
116
115
  },
117
116
  {
118
117
  "module": "fabric_platform",
@@ -164,7 +163,7 @@
164
163
  "fabric_paths",
165
164
  "fabric_time"
166
165
  ],
167
- "sha256": "26e4214c668c687e1b055cbce46ed2c21c185c17c0929d15b646c9ca63992698"
166
+ "sha256": "ce685cb9fdfd62ea75fff8b1b2be12a2ba758da783e4bfb4dcebe47bcbeb832b"
168
167
  },
169
168
  {
170
169
  "module": "fabric_backups",
@@ -175,7 +174,7 @@
175
174
  "fabric_paths",
176
175
  "fabric_usage"
177
176
  ],
178
- "sha256": "21febe1599b870fc575bd00d352970b97947f981a8ab03a66dcfa1d20a1e4d3f"
177
+ "sha256": "ce042e49fc32600ef81d550603b4655153a1c4b13520b1edc04b9b9f358f4b91"
179
178
  },
180
179
  {
181
180
  "module": "fabric_descriptor",
@@ -188,7 +187,7 @@
188
187
  "fabric_secrets",
189
188
  "fabric_usage"
190
189
  ],
191
- "sha256": "542ff462e1a06baaf485a80d2ee702cf57a20ddec329fc3dc5b24b98b7dea6c3"
190
+ "sha256": "43c59437502a1af6c6305f0d4dddfbb9e616e81441d6ad7137f9d96b7a918a06"
192
191
  },
193
192
  {
194
193
  "module": "fabric_auth",
@@ -200,7 +199,7 @@
200
199
  "fabric_paths",
201
200
  "fabric_platform"
202
201
  ],
203
- "sha256": "f28b02c889c79effa5b81d4181ff02e36beaea6a24b14e46ee1a543b5dc85ab6"
202
+ "sha256": "55794587750f6c9f40935b74295d83d7096cb4b26a0b36ac292334cd87d8f853"
204
203
  },
205
204
  {
206
205
  "module": "fabric_events",
@@ -211,7 +210,7 @@
211
210
  "fabric_paths",
212
211
  "fabric_protocols"
213
212
  ],
214
- "sha256": "dc3cf24040e09c92d40ad03a24b77dbb79ccf9a4eff258b9200c53a9df7e9047"
213
+ "sha256": "0086886c2c29dbd5c9d152be9d375c5bdf4a29f89b8095baff8490c2bcd64e47"
215
214
  },
216
215
  {
217
216
  "module": "fabric_logs",
@@ -233,7 +232,7 @@
233
232
  "fabric_paths",
234
233
  "fabric_secrets"
235
234
  ],
236
- "sha256": "9a75b3848e2dd2c1c4395f3f9f24291e97c2be8ec581aea67159755da6593600"
235
+ "sha256": "a2dbf15aa1c4eb9de42996b413103fa4814afd2e4e66d1ab7315f30e06ab6841"
237
236
  },
238
237
  {
239
238
  "module": "fabric_service",
@@ -268,18 +267,19 @@
268
267
  "fabric_secrets",
269
268
  "fabric_service"
270
269
  ],
271
- "sha256": "df78e0c25ea37f406e051e35640d49c61feef25327c953aa124052ac856a9155"
270
+ "sha256": "26e21ec29c016000f8ca8053b7b489184854a73be1b7fdc0a18d12990203db9b"
272
271
  },
273
272
  {
274
273
  "module": "fabric_interop",
275
274
  "file": "fabric_interop.py",
276
275
  "layer": "L3",
277
276
  "imports": [
277
+ "fabric_base",
278
278
  "fabric_delegation",
279
279
  "fabric_service",
280
280
  "fabric_time"
281
281
  ],
282
- "sha256": "b30d24972242cbbe6c69a9ce45d0ee5acf7666ce7dcc93e0a75feb2d5d0d4dce"
282
+ "sha256": "67a78026ad434bb638c8230b6bfadc9cbe67561842ae7493c77d912855f38d61"
283
283
  },
284
284
  {
285
285
  "module": "fabric_hub",
@@ -289,7 +289,7 @@
289
289
  "fabric_estate",
290
290
  "fabric_service"
291
291
  ],
292
- "sha256": "13a78794b97aa5c8d4628199cc8e20fe2d5448d9c04b58eed3322f994e15ff7f"
292
+ "sha256": "b9ac852e601b1d54cf61351677a628afc69faeed7d1fc74ebe541c1cf38e0c2a"
293
293
  },
294
294
  {
295
295
  "module": "fabric_board_shapes",
@@ -298,18 +298,30 @@
298
298
  "imports": [
299
299
  "fabric_identifiers"
300
300
  ],
301
- "sha256": "fcc9bef27b03a6e88c5914c60e736e11e8003907f38190b94462e7c8385b094a"
301
+ "sha256": "a8daefdc9283219206875b5d964b49552b6b3ba7e69c925abe08a44afc91c234"
302
+ },
303
+ {
304
+ "module": "fabric_board_link",
305
+ "file": "fabric_board_link.py",
306
+ "layer": "L4",
307
+ "imports": [
308
+ "fabric_board_shapes",
309
+ "fabric_hub",
310
+ "fabric_service"
311
+ ],
312
+ "sha256": "b5bff994cb615c6a4bb0d88d020e3a59504166180e1fa1aea3be93224f2aeccb"
302
313
  },
303
314
  {
304
315
  "module": "fabric_board_session",
305
316
  "file": "fabric_board_session.py",
306
317
  "layer": "L4",
307
318
  "imports": [
319
+ "fabric_board_link",
308
320
  "fabric_board_shapes",
309
321
  "fabric_hub",
310
322
  "fabric_service"
311
323
  ],
312
- "sha256": "7a352e6442d8ab4c31ba401bc55670e0e7b54495d793d08652114c6eba706917"
324
+ "sha256": "878ceed970a84087a320fd8eb971c210613a0fa2c524b68793fb32042910581e"
313
325
  },
314
326
  {
315
327
  "module": "fabric_board_fixture",
@@ -331,7 +343,7 @@
331
343
  "fabric_board_session",
332
344
  "fabric_board_shapes"
333
345
  ],
334
- "sha256": "c9600d24552a858f0bef8a0a7dd3fd05759c90c36e6b31f282aa01ae2d7698eb"
346
+ "sha256": "0f075894b3e352194fcaf3fc7d08dee4e9f1c215e859769ed85fa5010e4a1599"
335
347
  },
336
348
  {
337
349
  "module": "fabric_http",
@@ -340,7 +352,7 @@
340
352
  "imports": [
341
353
  "fabric_jsvalue"
342
354
  ],
343
- "sha256": "679954d16a433c47889ec858c1e13de4ae0b682e6901d69bc23990cc610fdf20"
355
+ "sha256": "5d7f72af3a73fdbe8c1f487ecf60cef23a7c46289eba542b03aff4706b8218d4"
344
356
  },
345
357
  {
346
358
  "module": "fabric_openrouter",
@@ -401,7 +413,7 @@
401
413
  "fabric-secrets",
402
414
  "fabric-time"
403
415
  ],
404
- "sha256": "01a1c8bc31a64b31438122bd3f7258cac2e130e0e7cf964b2b9f5c24e97b5113"
416
+ "sha256": "912b1ceab57ed20f946986bf14ae2faf41fb8ea539e818164496874f3749ef65"
405
417
  },
406
418
  {
407
419
  "module": "fabric-delegation",
@@ -412,7 +424,7 @@
412
424
  "fabric-estate",
413
425
  "fabric-jsvalue"
414
426
  ],
415
- "sha256": "4ab54a3dc13f887933551eb88443b777f282b451777992664e83f6d22eb54d89"
427
+ "sha256": "c27c84aca9d0374c8930eabc82b8c5d2ad66b3a936d7cff324ddd49dbd1f9618"
416
428
  },
417
429
  {
418
430
  "module": "fabric-share",
@@ -435,9 +447,10 @@
435
447
  "imports": [
436
448
  "fabric-delegation",
437
449
  "fabric-estate",
438
- "fabric-jsvalue"
450
+ "fabric-jsvalue",
451
+ "fabric-time"
439
452
  ],
440
- "sha256": "070d4fefe14aa56bbfbe668a4877c4697f6d087c01c012339438964178fb272b"
453
+ "sha256": "117d4374c9e95c930a38de7adbd4323774798f4fe6ec6f24afcd6f2c7298ca44"
441
454
  },
442
455
  {
443
456
  "module": "fabric-package",
@@ -448,7 +461,7 @@
448
461
  "fabric-jsvalue",
449
462
  "fabric-secrets"
450
463
  ],
451
- "sha256": "3751721f3001c17674e09101e19d2fe54ffac2bf8d0d0d29a8092d6eea3caece",
464
+ "sha256": "b9cc4b0e213dc2a606cd57303e4c61c65fbc8dd8e1a863e1419fd4c781261086",
452
465
  "data": [
453
466
  "fabric-package.schema.json"
454
467
  ]
@@ -496,7 +509,7 @@
496
509
  "fabric-base",
497
510
  "fabric-paths"
498
511
  ],
499
- "sha256": "2726869f3d03725783f611aec67e5925af4322b3bd20346a4fcb4e3fd9e18237"
512
+ "sha256": "ac219ab0a326d5c43c7c4c255e0c3843d4794de795a60e3af661e7d5350ea052"
500
513
  },
501
514
  {
502
515
  "module": "fabric-usage",
@@ -534,7 +547,7 @@
534
547
  "fabric-secrets",
535
548
  "fabric-usage"
536
549
  ],
537
- "sha256": "c94d4c6857c325f19a396d355b1570f3f5d97e6f0c9ee2938f9048f74c7fc682"
550
+ "sha256": "b9304be4cba4fedddc6a0da83eef861f045691c8309ff614a5522946af4069b0"
538
551
  },
539
552
  {
540
553
  "module": "fabric-auth",
@@ -547,7 +560,7 @@
547
560
  "fabric-platform",
548
561
  "fabric-usage"
549
562
  ],
550
- "sha256": "b6f469876a8264898b08ff2e398ab967aa99d3997fcbef4df8fd35ea2e04494a"
563
+ "sha256": "3ea6796470fcd829bc72a772fb7e4c37532a09d1e37ff41592dcf1a1a3074ca2"
551
564
  },
552
565
  {
553
566
  "module": "fabric-events",
@@ -580,7 +593,7 @@
580
593
  "fabric-paths",
581
594
  "fabric-secrets"
582
595
  ],
583
- "sha256": "74ddab15b514243fd0f09d44f2747d9bd80cae9089ef98a7a00f548ab6215c34"
596
+ "sha256": "9d61c1a17538a5e2453e33e5ae347337336748041bc054478a96dd51f3d4fc51"
584
597
  },
585
598
  {
586
599
  "module": "fabric-service",
@@ -623,7 +636,7 @@
623
636
  "fabric-jsvalue",
624
637
  "fabric-service"
625
638
  ],
626
- "sha256": "5cf7b5c63062198abb379b1024f74e30bf9f4ca7a07fb6d065f6ee05760c79c4"
639
+ "sha256": "81c0b09045ada54f6645f40d935c0de06119793631b3240b1a613f4f2afd9d84"
627
640
  },
628
641
  {
629
642
  "module": "fabric-hub",
@@ -642,18 +655,30 @@
642
655
  "imports": [
643
656
  "fabric-identifiers"
644
657
  ],
645
- "sha256": "8bc697bf222d8178905540e97f951957772a1135369d52da99f7d1e91c7ca413"
658
+ "sha256": "ad1094397540862b104d9317d6902031d35e64b16c12bf849fb883e12cb78d45"
659
+ },
660
+ {
661
+ "module": "fabric-board-link",
662
+ "file": "fabric-board-link.mjs",
663
+ "layer": "L4",
664
+ "imports": [
665
+ "fabric-board-shapes",
666
+ "fabric-hub",
667
+ "fabric-service"
668
+ ],
669
+ "sha256": "4cd6d4e21713a38c8e56f7d59db3148638b8c27c08e774d96a0f6283c6049e0a"
646
670
  },
647
671
  {
648
672
  "module": "fabric-board-session",
649
673
  "file": "fabric-board-session.mjs",
650
674
  "layer": "L4",
651
675
  "imports": [
676
+ "fabric-board-link",
652
677
  "fabric-board-shapes",
653
678
  "fabric-hub",
654
679
  "fabric-service"
655
680
  ],
656
- "sha256": "f08c00647fd308d25448f4bd4563a092d8605a4e07e64671a375e16feff0f8db"
681
+ "sha256": "744a8c9a518c27f2ddfd20b1b22afebc3ccc4f59aeeb7a38d7c12c2ddcae158d"
657
682
  },
658
683
  {
659
684
  "module": "fabric-board-fixture",
@@ -675,7 +700,7 @@
675
700
  "fabric-board-session",
676
701
  "fabric-board-shapes"
677
702
  ],
678
- "sha256": "87ae681a3c991c9aed40fb71289c19cd6da33ad6ebbec6858e51f031e8a7ab7b"
703
+ "sha256": "9e7bfe4d412521982224ef12bebfc2ff255eeeaf8d96cf40234ac18de68e7a59"
679
704
  },
680
705
  {
681
706
  "module": "fabric-http",
@@ -1517,6 +1542,76 @@
1517
1542
  "fabric-openrouter.mjs": "f8f0168691f968b7cd85f36aa98e2167e88cc44f1104ff514fd0c7699b339253",
1518
1543
  "fabric-package.schema.json": "6b688152984e294b806ffaf3483e6fa2e55cd0d9205bb5cba85f646868d90d58",
1519
1544
  "share-registration.schema.json": "82ef3e8703dd6653b84ba9fdbaec2f366e062596da981b1823be3804fcb65b90"
1545
+ },
1546
+ "0.41.0": {
1547
+ "fabric_jsvalue.py": "0cd4eab0a5d6ae35d097f7c59a08dc29173cb61c561c49e5291a8dad15d36779",
1548
+ "fabric_time.py": "588f383da4ac6a243ea95b6ffc3a0aa99ca94245732dc4937734f190b7af4ae9",
1549
+ "fabric_identifiers.py": "0fd814d521ac3aa39907458265870753046a73f48af3d8581ab864b93b211607",
1550
+ "fabric_secrets.py": "68a0b5e9e90c468ec9ac67b2f0fd1848e08813d6ec1ec14a2a47337eb1a98911",
1551
+ "fabric_crypto.py": "9c34aee20dbe4d6742e4fdbaab68ceb934bbe7dbd3a904c0010824ace16cdeaa",
1552
+ "fabric_estate.py": "50cc12166a00b680ba5b2e458200912d7bcfbef70bd73ec4edf57c7fcfa9b687",
1553
+ "fabric_delegation.py": "92ff745fb76ebb5856f9bb55f7c46936035f1ae836056c71065b7bb6276b35e7",
1554
+ "fabric_share.py": "78506fe1a60829c525dbf6266a0aa0749a2164290ed94da8249a20b4e9be5605",
1555
+ "fabric_ceremonies.py": "a59e83cf4adb2669a9b98008e3d3a0cba991a35cbff97bc604fc82fe81cfd49f",
1556
+ "fabric_package.py": "09e5b4d20564ccb318f5a5e4f33df0359873fa8239cf4f5fcd21c8af481fd211",
1557
+ "fabric_base.py": "684533b3a2aa3acd9b9e645a7a443427d279408f9f12f13456a0a991d57954ce",
1558
+ "fabric_platform.py": "8b0cd89193bc55da204a4a1850665c96929c6778523a8715b8156c5643745288",
1559
+ "fabric_paths.py": "0d87e572bde2b930391b27aa370d808e093ce45cfba6148706f5318219906d30",
1560
+ "fabric_protocols.py": "9f418eef2d64796067d213f36a967978486e632c9acac50e216dd22cb898216c",
1561
+ "fabric_lock.py": "ba2399d2137c7a7791b7133b9db9cca36693f4eb7e30955b25a75ade814e95ba",
1562
+ "fabric_usage.py": "ce685cb9fdfd62ea75fff8b1b2be12a2ba758da783e4bfb4dcebe47bcbeb832b",
1563
+ "fabric_backups.py": "ce042e49fc32600ef81d550603b4655153a1c4b13520b1edc04b9b9f358f4b91",
1564
+ "fabric_descriptor.py": "43c59437502a1af6c6305f0d4dddfbb9e616e81441d6ad7137f9d96b7a918a06",
1565
+ "fabric_auth.py": "55794587750f6c9f40935b74295d83d7096cb4b26a0b36ac292334cd87d8f853",
1566
+ "fabric_events.py": "0086886c2c29dbd5c9d152be9d375c5bdf4a29f89b8095baff8490c2bcd64e47",
1567
+ "fabric_logs.py": "86dc55bfafa2a57264722e2403510a249b95de0e4a722b2e4bc3948e3bd93da9",
1568
+ "fabric_supervisors.py": "a2dbf15aa1c4eb9de42996b413103fa4814afd2e4e66d1ab7315f30e06ab6841",
1569
+ "fabric_service.py": "3c8f69e139ee6fe714cad78c30de1a076ac7fbf9f7f419cd2cd131e95d889f6a",
1570
+ "fabric_profiles.py": "26e21ec29c016000f8ca8053b7b489184854a73be1b7fdc0a18d12990203db9b",
1571
+ "fabric_interop.py": "67a78026ad434bb638c8230b6bfadc9cbe67561842ae7493c77d912855f38d61",
1572
+ "fabric_hub.py": "b9ac852e601b1d54cf61351677a628afc69faeed7d1fc74ebe541c1cf38e0c2a",
1573
+ "fabric_board_shapes.py": "a8daefdc9283219206875b5d964b49552b6b3ba7e69c925abe08a44afc91c234",
1574
+ "fabric_board_link.py": "b5bff994cb615c6a4bb0d88d020e3a59504166180e1fa1aea3be93224f2aeccb",
1575
+ "fabric_board_session.py": "878ceed970a84087a320fd8eb971c210613a0fa2c524b68793fb32042910581e",
1576
+ "fabric_board_fixture.py": "69761ce205ec640762ec9b591c6903e5a87f844e8d423b041681924027e39d1e",
1577
+ "fabric_board.py": "0f075894b3e352194fcaf3fc7d08dee4e9f1c215e859769ed85fa5010e4a1599",
1578
+ "fabric_http.py": "5d7f72af3a73fdbe8c1f487ecf60cef23a7c46289eba542b03aff4706b8218d4",
1579
+ "fabric_openrouter.py": "2017d898c17001d7275f58267de653be7ecf6acd17ad8d9b24ecb7a43e5617d4",
1580
+ "fabric-jsvalue.mjs": "dfbdb8c41584972c9389750a41719374a1cfc5652ed438dd1623025190b0106e",
1581
+ "fabric-time.mjs": "3ff932069038a720df1c68c6492976906737b2e67e5c12d9c81c418597f661de",
1582
+ "fabric-identifiers.mjs": "a18c2a501a4aa170bfd3d99e571ad6b7662649b4d3b9d2a540c002ea42811bbf",
1583
+ "fabric-secrets.mjs": "2f7baaebfd08daf8b9c9ae1b75ba8ca04997d9dbf113897b4fb1464391c2d66d",
1584
+ "fabric-crypto.mjs": "038e03689701e3c9721a1e7f8e0a4d02a52d6a5d1661b0dc84035edc3ebbfcf6",
1585
+ "fabric-estate.mjs": "912b1ceab57ed20f946986bf14ae2faf41fb8ea539e818164496874f3749ef65",
1586
+ "fabric-delegation.mjs": "c27c84aca9d0374c8930eabc82b8c5d2ad66b3a936d7cff324ddd49dbd1f9618",
1587
+ "fabric-share.mjs": "d40a7405d7bd4c3213ed691330b7549afe8e023db0753b582e249714e672010d",
1588
+ "fabric-ceremonies.mjs": "117d4374c9e95c930a38de7adbd4323774798f4fe6ec6f24afcd6f2c7298ca44",
1589
+ "fabric-package.mjs": "b9cc4b0e213dc2a606cd57303e4c61c65fbc8dd8e1a863e1419fd4c781261086",
1590
+ "fabric-base.mjs": "17a92f5e9b71a855648e39e06388bad7f1b969605bd7b1f534ddf67b41a2fb5d",
1591
+ "fabric-platform.mjs": "1349e3638c21caf7da7937ef6a5dfeefe05a8ee733520f0d581624095efeb388",
1592
+ "fabric-paths.mjs": "e6f5e2ce7c8e7a1452d6ee69977489f4c09ca6f1d3100df9c303274f0b7b16b1",
1593
+ "fabric-protocols.mjs": "45277a794ef40f37599b25dd6ceebc3fa3e60a4cd51caf33e56e48eba8600920",
1594
+ "fabric-lock.mjs": "ac219ab0a326d5c43c7c4c255e0c3843d4794de795a60e3af661e7d5350ea052",
1595
+ "fabric-usage.mjs": "e413569620bbc8221bc59e24b27e22d1483825ed18457801ed58d54a57de8114",
1596
+ "fabric-backups.mjs": "c504b4ce85b8ed1e926683da93a70693fd8d23a7935f9b57c950e24304a0fa92",
1597
+ "fabric-descriptor.mjs": "b9304be4cba4fedddc6a0da83eef861f045691c8309ff614a5522946af4069b0",
1598
+ "fabric-auth.mjs": "3ea6796470fcd829bc72a772fb7e4c37532a09d1e37ff41592dcf1a1a3074ca2",
1599
+ "fabric-events.mjs": "c463d6ffcae24229a5c608d8fcea4268d2ccc5024b19fa10e5a452284068fa71",
1600
+ "fabric-logs.mjs": "58467e5719c16e099d05bbedec47a95712506ab03c33f3cd4be1252e8498a946",
1601
+ "fabric-supervisors.mjs": "9d61c1a17538a5e2453e33e5ae347337336748041bc054478a96dd51f3d4fc51",
1602
+ "fabric-service.mjs": "fd31188c1709b0cebbcea995fc817ad7b6ad4fe21f2af12f65d001309f6baacc",
1603
+ "fabric-profiles.mjs": "314376cf2deb87f235fb18b11d3b532e211f585b9af0a9302b5f4cc39971b532",
1604
+ "fabric-interop.mjs": "81c0b09045ada54f6645f40d935c0de06119793631b3240b1a613f4f2afd9d84",
1605
+ "fabric-hub.mjs": "c005115a864cfd67daa4862097bb14acfe5a60bf653897e5bf8a570dd80f1070",
1606
+ "fabric-board-shapes.mjs": "ad1094397540862b104d9317d6902031d35e64b16c12bf849fb883e12cb78d45",
1607
+ "fabric-board-link.mjs": "4cd6d4e21713a38c8e56f7d59db3148638b8c27c08e774d96a0f6283c6049e0a",
1608
+ "fabric-board-session.mjs": "744a8c9a518c27f2ddfd20b1b22afebc3ccc4f59aeeb7a38d7c12c2ddcae158d",
1609
+ "fabric-board-fixture.mjs": "83c4b7e33ee47b68385faf2569d38d5c8a0c5cb0f8656090f41e1b0eed2f436e",
1610
+ "fabric-board.mjs": "9e7bfe4d412521982224ef12bebfc2ff255eeeaf8d96cf40234ac18de68e7a59",
1611
+ "fabric-http.mjs": "f886bcb49c4353d039387ac9568738dda26697a94dd07fc6a6204500f0bc27bf",
1612
+ "fabric-openrouter.mjs": "f8f0168691f968b7cd85f36aa98e2167e88cc44f1104ff514fd0c7699b339253",
1613
+ "fabric-package.schema.json": "6b688152984e294b806ffaf3483e6fa2e55cd0d9205bb5cba85f646868d90d58",
1614
+ "share-registration.schema.json": "82ef3e8703dd6653b84ba9fdbaec2f366e062596da981b1823be3804fcb65b90"
1520
1615
  }
1521
1616
  },
1522
1617
  "data": {
@@ -264,6 +264,15 @@ def make_handler(svc: Service):
264
264
  content_type="text/html; charset=utf-8")
265
265
  self._send(404, {"error": "Not found."})
266
266
 
267
+ def _length(self, cap: int) -> "int | None":
268
+ """The body's declared length, 0..cap; anything else answers 400 and reads nothing (finding 17)."""
269
+ raw = (self.headers.get("Content-Length") or "0").strip()
270
+ if raw.isdigit() and raw.isascii() and int(raw) <= cap:
271
+ return int(raw)
272
+ self.close_connection = True # an unread body must not be taken for the next request
273
+ self._send(400, {"error": "Content-Length must be a whole number of bytes up to %d." % cap})
274
+ return None
275
+
267
276
  def do_POST(self) -> None: # noqa: N802
268
277
  if not self._guard():
269
278
  return
@@ -271,10 +280,12 @@ def make_handler(svc: Service):
271
280
  if url.path == "/mcp":
272
281
  if not self._token_ok():
273
282
  return
274
- length = min(int(self.headers.get("Content-Length") or 0), 1048576)
283
+ length = self._length(1048576)
284
+ if length is None:
285
+ return
275
286
  try:
276
287
  message = json.loads(self.rfile.read(length) or b"null")
277
- except ValueError:
288
+ except (ValueError, RecursionError):
278
289
  return self._send(400, {"jsonrpc": "2.0", "id": None, "error": {"code": -32700, "message": "Parse error."}})
279
290
  try:
280
291
  with svc.drain.work():
@@ -300,11 +311,18 @@ def make_handler(svc: Service):
300
311
  return self._send(401, {"error": "Sign in first."})
301
312
  if self.headers.get("X-Fabric-Request") != "1":
302
313
  return self._send(403, {"error": "Missing request header."})
303
- length = min(int(self.headers.get("Content-Length") or 0), 65536)
304
- body = json.loads(self.rfile.read(length) or b"{}")
305
- event = svc.log.append(body.get("kind", "demo.note"), body.get("level", "info"),
306
- body.get("text", "A note from the sample service."),
307
- notify=bool(body.get("notify")), link=body.get("link"))
314
+ length = self._length(65536)
315
+ if length is None:
316
+ return
317
+ try:
318
+ body = json.loads(self.rfile.read(length) or b"{}")
319
+ if not isinstance(body, dict):
320
+ raise ValueError("not an object")
321
+ event = svc.log.append(body.get("kind", "demo.note"), body.get("level", "info"),
322
+ body.get("text", "A note from the sample service."),
323
+ notify=bool(body.get("notify")), link=body.get("link"))
324
+ except (ValueError, RecursionError, fs.ServiceError) as exc: # finding 17: a 400, never a crash
325
+ return self._send(400, {"error": "The note is a JSON object the event log takes: %s" % exc})
308
326
  return self._send(200, event)
309
327
  self._send(404, {"error": "Not found."})
310
328
 
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: creating-fabric-agents
3
- description: Use when designing and building a NEW agent or provider that must be Fabric-compatible from its first commit, «создай агента, совместимого с фабрикой Passion Code», «новый агент под Fabric», "create a fabric-compatible agent", "build a new Fabric provider", "fabric-ready agent from scratch", «агент в облаке организации», "which models and OpenRouter key for a new Fabric agent". Runs the intake grill (capability, named consumer, workflow-or-agent, MCP/A2A/local-runner profile, effect declarations, where it runs, models, who pays, how it learns), distils source projects into a knowledge pack whose recorded failures become planted eval fixtures, scaffolds the pinned contract bundle, and sets the two-clock eval expectation with the conformance report. NOT for adapting an existing project (use adapting-projects-to-fabric), building the Fabric host or orchestrator, or generic agent design where Fabric compatibility is not part of the request.
3
+ description: Use when designing and building a NEW agent or provider that must be Fabric-compatible from its first commit, «создай агента, совместимого с фабрикой Passion Code», «новый агент под Fabric», "create a fabric-compatible agent", "build a new Fabric provider", "fabric-ready agent from scratch", «агент в облаке организации», "which models and OpenRouter key for a new Fabric agent". Runs the intake grill (capability, named consumer, workflow or agent, profile, effects, where it runs, models, who pays, how it learns), turns source projects' recorded failures into planted eval fixtures, scaffolds the pinned contract bundle and sets the canary expectation. NOT for adapting an existing project (adapting-projects-to-fabric), making an agent a local or online Fabric service with a dashboard (building-fabric-services), a coding session working through Fabric or its board (working-with-fabric), the Fabric host or orchestrator, or agent design without Fabric.
4
4
  license: AGPL-3.0-only OR LicenseRef-PassionCode-Commercial
5
5
  compatibility: Requires filesystem access and Python 3.9+. Exact schema checks additionally need git, Node.js, pnpm, and the pinned fabric-agent-contract checkout (a public repository). Works without those tools in an explicitly degraded structural-check mode. Ships in one plugin with adapting-projects-to-fabric, whose scripts it reuses.
6
6
  metadata:
7
7
  author: PassionCode.ai
8
- version: "0.40.0"
8
+ version: "0.41.0"
9
9
  contract-version: "0.1.0"
10
10
  contract-commit: "c55f2d5a11c9a0197e958e87212fca7ae1154769"
11
11
  ---
@@ -24,6 +24,10 @@ Use this skill to design and build a new provider. Do not use it to:
24
24
 
25
25
  - adapt a project that already has a stable API, MCP/A2A surface, or CLI: that is
26
26
  `adapting-projects-to-fabric`, and entering there skips nothing;
27
+ - run an agent as a local or online service with a dashboard on its own: that is
28
+ `building-fabric-services` (step 4 hands over to it for a new agent that needs one);
29
+ - work in a project through Fabric from a coding session (the board, claims): that is
30
+ `working-with-fabric`;
27
31
  - design the Fabric host, registry, scheduler, admission service, or binding runtime;
28
32
  - build a generic agent with no Fabric requirement: nothing here helps a project that
29
33
  will never be a provider;
@@ -99,30 +103,21 @@ authored now: it grows from real traces once the provider runs, and the step-1 f
99
103
  are its seed because a source project's recorded failures count as production.
100
104
 
101
105
  **For a PassionCode.ai repository**, the new agent's repository follows the organization's
102
- [repository standard](https://github.com/passioncode-ai/fabric-workspace/blob/main/knowledge/repository-standard.md) (`knowledge/repository-standard.md`
103
- in the organization's knowledge base; a clone has it at `fabric-workspace/knowledge/`) from its
104
- first commit:
105
-
106
- - `LICENSE`, `COMMERCIAL-LICENSE.md` and `CLA.md` copied byte for byte from the knowledge base's
107
- `templates/`, and `AGPL-3.0-only OR LicenseRef-PassionCode-Commercial` in every manifest and
108
- every SKILL.md `license:`; `SECURITY.md` when the repository is public;
109
- - a README whose first heading is the full name, with `## Quick start for a new teammate`
110
- (Install; Configure, key names only; MCP, the registration command and one proving tool call,
111
- verified with a real client in a temporary config; Develop) and `## License`;
112
- - an `AGENTS.md` that opens with the template's *Read first* block and closes with *After work*,
113
- and a `CLAUDE.md` whose first line is `@AGENTS.md`.
114
-
115
- **Every credential the agent uses comes from Project Observatory, by name**, from its first
116
- commit: the README's Configure section lists key NAMES; the agent finds them with
117
- `observatory_credentials` and runs with `use_secret.py run --vault-only` (a long-running
118
- service: `use_secret.py serve`), with `OBSERVATORY_VAULT_ONLY=1` in its environment. No `.env`
119
- of its own, no key file beside its data, no value in code, configuration or a commit. A
120
- workflow names the keys it needs in its checkpoint (`credentials`), never their values.
121
-
122
- org-index `scripts/check_format.py` reports 0 findings for it before it is called done. **An agent
123
- someone builds for themselves is not a PassionCode.ai repository:** its licence is its owner's
124
- choice, nothing about it is published or listed by the organization, and none of these files is
125
- required of it, though the verified MCP quick start is still how anyone learns to drive it.
106
+ repository standard (`knowledge/repository-standard.md`) from its first commit: the licence files,
107
+ the README quick start verified with a real client, `AGENTS.md` and `CLAUDE.md`, as
108
+ [the operator channel and the repository standard](references/operator-channel-and-repository.md)
109
+ lists them. An agent someone builds for themselves is not a PassionCode.ai repository: its licence
110
+ is its owner's choice and none of those files is required of it.
111
+
112
+ **Every credential the agent uses is read by name, never held as a value**, from its first commit:
113
+ the README's Configure section lists key NAMES. With Project Observatory installed, the agent finds
114
+ them with `observatory_credentials` and runs under
115
+ `python3 "$(project-observatory full-path)/tools/use_secret.py" run --vault-only <project> <NAME> -- <command>`
116
+ (a long-running service: `use_secret.py serve`), with `OBSERVATORY_VAULT_ONLY=1` in its environment.
117
+ Without it, the person's OS keychain or secret manager injects the key into the agent's environment
118
+ at start. Either way: no `.env` of its own, no key file beside its data, no value in argv, code,
119
+ configuration or a commit. A workflow names the keys it needs in its checkpoint (`credentials`),
120
+ never their values.
126
121
 
127
122
  ## Step 3: scaffold the provider bundle
128
123
 
@@ -193,31 +188,11 @@ purpose. Then record one expectation the report must carry:
193
188
  ## Step 6: propose the operator channel
194
189
 
195
190
  If the agent has a human stop (a choice, an approval, a confirmation) or emits `notify: true`
196
- events, propose its **operator channel** to the operator once, now. The channel is the agent's
197
- own messenger channel, first Telegram, that sends those events and answers its stops with
198
- buttons: `fabric-operator-channel/0.1` (contract DEC-0034,
199
- `docs/specification/operator-channel.md`), whose rule OC-11 this step follows. Give the
200
- operator's four steps:
201
-
202
- 1. create a bot with @BotFather;
203
- 2. put its token into the secret store (Project Observatory) under the name the agent reads
204
- (for example `EXAMPLE_AGENT_TELEGRAM_BOT_TOKEN`), never into a chat, a file or the bundle;
205
- 3. run the agent's link command;
206
- 4. type the code it shows in the chat with the bot.
207
-
208
- In a group shared with other bots the channel follows OC-14…OC-17 (DEC-0035): it stays silent
209
- unless addressed (`/command@ThisBot`, a reply to its own message or a press of its own button; a
210
- bare `/command` in a group is not addressed), and a channel nobody receives on is `degraded`
211
- (`receiver-missing`). Say so in the proposal when the operator means to bind a shared group.
212
-
213
- Record the answer (`accepted`, `declined` or `later`) in the agent's state and in the
214
- report, and do not ask again; an agent that serves `surfaces.operatorChannel` also shows it as
215
- `proposal` in its status document. Creating the bot, storing the token and enabling the channel are the
216
- operator's action: never create the bot, ask for or store the token's value, or enable the
217
- channel yourself. The default pin carries DEC-0034 and DEC-0035: a served status document is checked against
218
- the pinned `schemas/operator-channel-status.schema.json`; the channel's runtime rules have no
219
- probe rule here yet, so report them `NOT_RUN`. An agent with neither stops nor notify
220
- events skips this step.
191
+ events, propose its operator channel (`fabric-operator-channel/0.1`, OC-11) to the operator once,
192
+ now, as the shared reference linked at step 2 describes: the
193
+ operator's four steps, the answer recorded and never asked again, and the bot, the token and
194
+ enabling the channel left to the operator. An agent with neither stops nor notify events skips
195
+ this step.
221
196
 
222
197
  ## Resilience and autonomy
223
198
 
@@ -239,12 +214,6 @@ operator channel answer (step 6); and the exact next command. Never summarize th
239
214
 
240
215
  ## Dashboard handoff: also for consumers
241
216
 
242
- When handing a registered service dashboard to a person, or writing the generated
243
- agent's completion/notification instructions, read and apply
244
- [dashboard links](references/dashboard-links.md): use the host's `open_link`,
245
- check the target device and host, and run the bundled output gate before delivery.
246
- An installed host failure never means browser fallback. This applies in Claude
247
- Code, Codex and other providers; it needs no host-specific hook. MCP unavailable:
248
- report the unresolved capability or use an approved project resolver; no automatic
249
- client configuration. Python unavailable: perform the reference's manual checks
250
- and report the executable gate NOT_RUN. Headless agents need no dashboard.
217
+ When handing a registered service dashboard to a person, or writing the generated agent's
218
+ completion or notification instructions, read and apply [dashboard links](references/dashboard-links.md)
219
+ and run its output gate before delivery, in any host. Headless agents need no dashboard.
@@ -83,8 +83,10 @@ or instructions alone do not prove all final answers from every agent are filter
83
83
  path is required. Skills must be activated/loaded; install does not intercept every answer.
84
84
  - MCP absent: report unresolved host capability once, use the project's approved
85
85
  resolver/CLI if available. Do not write machine or agent MCP config automatically.
86
- - Python absent: perform the comparisons above manually; mark the executable gate
87
- NOT_RUN. Do not label the output mechanically validated.
86
+ - Python absent: perform the comparisons above manually, including the gate's own rules (a
87
+ path with a `.` or `..` segment, an encoded or backslash separator, or a query or fragment
88
+ name or value that reads as a credential, such as `code`, `key`, `auth` or `api_key`, is
89
+ refused); mark the executable gate NOT_RUN. Do not label the output mechanically validated.
88
90
 
89
91
  Syntax is owned by Fabric Dashboards and `@passioncode-ai/fabric-service-host`:
90
92
  [ADR-0005](https://github.com/passioncode-ai/fabric-dashboards/blob/51a7a80acf42781d7bec304cc87c655d48cc309b/docs/adr/0005-service-links.md).