@passioncode-ai/fabric-agent-adapter 0.61.0 → 0.63.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 (53) hide show
  1. package/CHANGELOG.md +201 -0
  2. package/README.md +6 -3
  3. package/SECURITY.md +3 -1
  4. package/package.json +1 -1
  5. package/plugins/fabric-agent-adapter/.claude-plugin/plugin.json +1 -1
  6. package/plugins/fabric-agent-adapter/hooks/hooks.json +1 -1
  7. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/SKILL.md +4 -1
  8. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/references/provider-entry.md +4 -2
  9. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/scripts/fabric_provider.py +1 -1
  10. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/scripts/fabric_secrets.py +57 -0
  11. package/plugins/fabric-agent-adapter/skills/building-fabric-services/SKILL.md +11 -9
  12. package/plugins/fabric-agent-adapter/skills/building-fabric-services/recipes/support-agent/README.md +56 -8
  13. package/plugins/fabric-agent-adapter/skills/building-fabric-services/recipes/support-agent/channel-agent.example.json +103 -0
  14. package/plugins/fabric-agent-adapter/skills/building-fabric-services/recipes/support-agent/config.example.json +1 -0
  15. package/plugins/fabric-agent-adapter/skills/building-fabric-services/recipes/support-agent/support_agent.py +160 -19
  16. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/connectors.md +4 -2
  17. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/delegation.md +2 -2
  18. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/estate-record.md +2 -0
  19. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/lifecycle.md +4 -2
  20. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/migrating-a-service.md +6 -4
  21. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/package.md +2 -2
  22. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/protocol.md +4 -2
  23. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/remote-placement.md +16 -3
  24. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/check_service.py +18 -2
  25. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/check_service_rules.py +33 -3
  26. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/dashboard_kit.py +2 -0
  27. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-auth.mjs +10 -1
  28. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-delegation.mjs +3 -1
  29. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-descriptor.mjs +33 -3
  30. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-http.mjs +14 -2
  31. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-secrets.mjs +57 -0
  32. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-service.mjs +3 -0
  33. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_auth.py +18 -3
  34. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_descriptor.py +55 -4
  35. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_estate.py +1 -1
  36. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_http.py +5 -0
  37. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_secrets.py +57 -0
  38. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_service.py +4 -0
  39. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/kit.json +193 -13
  40. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/sample-remote-service.mjs +2 -0
  41. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/sample_service.py +42 -4
  42. package/plugins/fabric-agent-adapter/skills/creating-fabric-agents/SKILL.md +2 -2
  43. package/plugins/fabric-agent-adapter/skills/creating-fabric-agents/references/agents-that-answer-people.md +5 -2
  44. package/plugins/fabric-agent-adapter/skills/creating-fabric-agents/references/practices.md +46 -0
  45. package/plugins/fabric-agent-adapter/skills/working-with-fabric/SKILL.md +16 -15
  46. package/plugins/fabric-agent-adapter/skills/working-with-fabric/references/native-host-hooks.md +7 -1
  47. package/plugins/fabric-agent-adapter/skills/working-with-fabric/references/on-demand-session.md +209 -0
  48. package/plugins/fabric-agent-adapter/skills/working-with-fabric/references/project-board.md +34 -6
  49. package/plugins/fabric-agent-adapter/skills/working-with-fabric/references/session-hooks.md +29 -5
  50. package/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/fabric_session_cli.py +362 -7
  51. package/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/fabric_session_env.py +35 -6
  52. package/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/fabric_session_hosts.py +4 -1
  53. package/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/fabric_session_mail.py +8 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fabric-service-kit",
3
- "version": "0.61.0",
3
+ "version": "0.63.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,7 +31,7 @@
31
31
  "file": "fabric_secrets.py",
32
32
  "layer": "L0",
33
33
  "imports": [],
34
- "sha256": "1d0191f0ec108fdc68345056b8c574b1f691509d1c353e41d98bfd58a59e8d3c"
34
+ "sha256": "3939aa8658a92ca387e9f0259538c4849fc407e429355ef9b4829460107a8597"
35
35
  },
36
36
  {
37
37
  "module": "fabric_crypto",
@@ -89,7 +89,7 @@
89
89
  "fabric_jsvalue",
90
90
  "fabric_time"
91
91
  ],
92
- "sha256": "b3cd56dcb86e04d252980322ac8054da1aaef24ac64690f7aa80e7c765ee6f60"
92
+ "sha256": "0737ae1d1bb12586bae49de1f15ef1348bc207b5007cced9dad4c55bb5870874"
93
93
  },
94
94
  {
95
95
  "module": "fabric_mandate",
@@ -270,7 +270,7 @@
270
270
  "fabric_secrets",
271
271
  "fabric_usage"
272
272
  ],
273
- "sha256": "a6d7a4a38186f7ef527d16218bbf96e39e255f9547be668adcfbec063dabb7ed"
273
+ "sha256": "0e7b44eef7983c2dffc433173c4e376facb181279d4bfdffa9ae8028216984c0"
274
274
  },
275
275
  {
276
276
  "module": "fabric_context",
@@ -297,7 +297,7 @@
297
297
  "fabric_paths",
298
298
  "fabric_platform"
299
299
  ],
300
- "sha256": "71115d18c67b7b806cb57b64b77e01ad97fc0e63e6f49ee850f778123617d905"
300
+ "sha256": "74ccc10239b65a3567cec5213a7b344cbd88d6eee1fd1c5f7be1d6daf985993c"
301
301
  },
302
302
  {
303
303
  "module": "fabric_events",
@@ -354,7 +354,7 @@
354
354
  "fabric_time",
355
355
  "fabric_usage"
356
356
  ],
357
- "sha256": "a2e813469a47d4d3eea996628635c8903007498bdb6a1ae032a7a5ce6f49fe2f"
357
+ "sha256": "4b13f90aa26881fbfe0d9f3077fbb3552f3ce0a3c59279d6baa92df872867d8d"
358
358
  },
359
359
  {
360
360
  "module": "fabric_profiles",
@@ -484,7 +484,7 @@
484
484
  "imports": [
485
485
  "fabric_jsvalue"
486
486
  ],
487
- "sha256": "80e22ae0bba91de13a94d64b595108b39c58f16f7b4137f3a48bdd9503f424fe"
487
+ "sha256": "861e8e0978e303455dd6ff4a1b98a8b258600320f2870af0644384196fb03679"
488
488
  },
489
489
  {
490
490
  "module": "fabric_openrouter",
@@ -525,7 +525,7 @@
525
525
  "file": "fabric-secrets.mjs",
526
526
  "layer": "L0",
527
527
  "imports": [],
528
- "sha256": "6ad8ab18ac899ecc2384e8ec6a3fb689b92be3b9a5ce3a59b92a37d52da5d766"
528
+ "sha256": "5822a7e25ecf2e87b5bab4f99c1074af7379d8b49e2784283b5d7d8c25022cde"
529
529
  },
530
530
  {
531
531
  "module": "fabric-crypto",
@@ -607,7 +607,7 @@
607
607
  "fabric-mandate",
608
608
  "fabric-paths"
609
609
  ],
610
- "sha256": "04eaf6cd1786d4309a253a27dbdb05e27b408cb511aa41b1633a96634b775e65"
610
+ "sha256": "f1b6d156d050f8ceb9a21daaad8d39ab5de5d32e4cfe03817909388fca8ad27e"
611
611
  },
612
612
  {
613
613
  "module": "fabric-share",
@@ -762,7 +762,7 @@
762
762
  "fabric-secrets",
763
763
  "fabric-usage"
764
764
  ],
765
- "sha256": "243bbce42989f67c4c5ec6b7659e201b3f9a1c08c71d429d88ec934d870f5104"
765
+ "sha256": "7c0ef7d245c037eb9e859ab481f6e66fb3e5ef2cf6d1e0a8d32b6d303097ca43"
766
766
  },
767
767
  {
768
768
  "module": "fabric-context",
@@ -790,7 +790,7 @@
790
790
  "fabric-platform",
791
791
  "fabric-usage"
792
792
  ],
793
- "sha256": "782c2aa732f8320f604194660117640a7ea145e12b8155c04e88cef7c516a5b3"
793
+ "sha256": "10ff37a39f9e3adb4d0f05db66c45f49b10eef582e9220c213907964109d7e52"
794
794
  },
795
795
  {
796
796
  "module": "fabric-events",
@@ -845,7 +845,7 @@
845
845
  "fabric-supervisors",
846
846
  "fabric-usage"
847
847
  ],
848
- "sha256": "6aa673657427211b491a9b63f94b9847a7e6aa3ee1b7353e1af11f46469803a3"
848
+ "sha256": "297fef11ac76dc831d12d24c5581b7a93587c300c20664db703b3f924c0f9f1a"
849
849
  },
850
850
  {
851
851
  "module": "fabric-profiles",
@@ -967,7 +967,7 @@
967
967
  "file": "fabric-http.mjs",
968
968
  "layer": "L4",
969
969
  "imports": [],
970
- "sha256": "9f899829073470b9c2b449605a9371b773848eec4e3a0122ed4ccde5eddcdb4b"
970
+ "sha256": "96aa1730c79cb9a68dcc94642513eb1e88f0c2d99a45ca505c042e8c601d0436"
971
971
  },
972
972
  {
973
973
  "module": "fabric-openrouter",
@@ -4686,6 +4686,186 @@
4686
4686
  "fabric-openrouter.mjs": "6041f3ab30f516658e1dbab4897a651cc8509b2136cfa8e769802c6b40ec2f35",
4687
4687
  "fabric-package.schema.json": "2ba799f576fad0f608029223c4ccccd122152f1c5dbfa8ce8b31cd63ac92ad44",
4688
4688
  "share-registration.schema.json": "34b3997eeaf936ebc861342a23045634a7c18c19f01d7ed4198310d81989f5b0"
4689
+ },
4690
+ "0.62.0": {
4691
+ "fabric_jsvalue.py": "052f1b40bab18600b3731dbdca27cbff17588c21d9458fa6241efd1340d0e09a",
4692
+ "fabric_time.py": "588f383da4ac6a243ea95b6ffc3a0aa99ca94245732dc4937734f190b7af4ae9",
4693
+ "fabric_identifiers.py": "0fd814d521ac3aa39907458265870753046a73f48af3d8581ab864b93b211607",
4694
+ "fabric_secrets.py": "3939aa8658a92ca387e9f0259538c4849fc407e429355ef9b4829460107a8597",
4695
+ "fabric_crypto.py": "9c34aee20dbe4d6742e4fdbaab68ceb934bbe7dbd3a904c0010824ace16cdeaa",
4696
+ "fabric_base.py": "f62bcc2ed9912660fa875d27a09f60867260cc4925f79873501fd9620be59611",
4697
+ "fabric_platform.py": "a9350dff55ef0fb3a23cdb4d0320a15868b15a8deb10d2eb74d72c58740c284b",
4698
+ "fabric_paths.py": "8a1ee742f80f436e9f28c61b4f049a9545de2a9e0d66bfc61faa6ee5d1ba3734",
4699
+ "fabric_estate_rules.py": "8b36a7f4108d9c2b1fb38c8bff344778c807bed631a99b4a563ecb0a49c10b1c",
4700
+ "fabric_estate.py": "b3cd56dcb86e04d252980322ac8054da1aaef24ac64690f7aa80e7c765ee6f60",
4701
+ "fabric_mandate.py": "fb19ce5359606bd6e3352ab02b2a12f49605ec6e5c49b55cce1f79c831325044",
4702
+ "fabric_delegation.py": "716f0ff7ac01095f54b24970beac1962128e8ff33026b243fc0467876142ab03",
4703
+ "fabric_share.py": "da36a466426fc29dd7dd40013167f3959a18375f8fedd228bf64f298cec1040c",
4704
+ "fabric_ceremonies.py": "a59e83cf4adb2669a9b98008e3d3a0cba991a35cbff97bc604fc82fe81cfd49f",
4705
+ "fabric_package_schema.py": "e623f0408d38e3343ed66222fb812907c6c52e1a286eb1c1176ab2e64640c9ad",
4706
+ "fabric_package.py": "1f2b9e73b2b32a7e1e887d4b69f87c6e21b4d1227ad924a235334223e6dd51ca",
4707
+ "fabric_protocols.py": "42529a7df4d753544d2e37a18ec81266d6e1e80477cb8558a3ab521416d45791",
4708
+ "fabric_actions.py": "ae21d1199614c4f74d1dcd1e0a87107a9d52434cd9e2d64aa24a7b1e196fb723",
4709
+ "fabric_connections.py": "7de55cb7d808f756d650effabfaa12027d40a5bd5d2f6d448c32969d47529ecb",
4710
+ "fabric_a2a.py": "8b01502131215bb4de1c01866187c56e99b791543923ed8577535573db33b919",
4711
+ "fabric_page_links.py": "1b57ea573c550e2f90d1ec3edcc655917ceaa0db9dd1635fccf422ec3024d25e",
4712
+ "fabric_lock.py": "dfaf92a7086cbb097d832a305869b7964e2d2a9da0e3365c8ec1685a7bb4fef9",
4713
+ "fabric_usage.py": "5cc2e03ccc5b06e81987ed7bc3eead7a7e6cbf1a7cb8e05c6c64315eed9d91b6",
4714
+ "fabric_backups.py": "1f3f0d7ecf361b29e9101e07f1c53e5dc304d598bf26fd59ec89f16b9fed2420",
4715
+ "fabric_descriptor.py": "0e7b44eef7983c2dffc433173c4e376facb181279d4bfdffa9ae8028216984c0",
4716
+ "fabric_context.py": "6ae311ddc7217a4aff915e7ce2646486931acd128462b7bebe4a52bbb5fbb6c7",
4717
+ "fabric_auth.py": "a7028fa6f8b1c24bc9e2c89adbce8ecb0ae01579d27b1ec4f625ae635e3f17b9",
4718
+ "fabric_events.py": "cd94b186e2a8f8cb4ad2b6bd44d83ec5021933075e28c5d655f387f16dff42b8",
4719
+ "fabric_logs.py": "86dc55bfafa2a57264722e2403510a249b95de0e4a722b2e4bc3948e3bd93da9",
4720
+ "fabric_supervisors.py": "3c5b2e8c310738720b1c1b779be4710e90251013d9be4c68f9952edc0bf55d5f",
4721
+ "fabric_service.py": "4b13f90aa26881fbfe0d9f3077fbb3552f3ce0a3c59279d6baa92df872867d8d",
4722
+ "fabric_profiles.py": "26e21ec29c016000f8ca8053b7b489184854a73be1b7fdc0a18d12990203db9b",
4723
+ "fabric_interop_rules.py": "9bdb7989e57b9d0b0d15eb9982d396499823a5e2c528230b71c67866c736e0f5",
4724
+ "fabric_interop.py": "d27e31834611a37cf2a117746f2f60fc187ccc48718eb546ff923c5d0fce7dea",
4725
+ "fabric_hub.py": "b9ac852e601b1d54cf61351677a628afc69faeed7d1fc74ebe541c1cf38e0c2a",
4726
+ "fabric_board_shapes.py": "0a0e8d3d40e33dfd8c457aedb85330b2ff25f8c49a33eb6cbd5a5cc8a5007f7e",
4727
+ "fabric_board_link.py": "052bc3c474ece835bb428c37ca864810d04e394d991ddb9c93989a7a825073a5",
4728
+ "fabric_board_slots.py": "92b065e3df935547cf46653245f1129e4a1f8b59b0a41e8fa9ffdc41596ee592",
4729
+ "fabric_board_session.py": "1fd3c3884f3044b56a40f78b33ff88dcac9272284f6681ea359c662879826f7e",
4730
+ "fabric_board_fixture.py": "69761ce205ec640762ec9b591c6903e5a87f844e8d423b041681924027e39d1e",
4731
+ "fabric_board.py": "f86c40b8291f8c818f6924910f4022b013d5fd107abaf8825dd0aa6c5e418638",
4732
+ "fabric_http.py": "861e8e0978e303455dd6ff4a1b98a8b258600320f2870af0644384196fb03679",
4733
+ "fabric_openrouter.py": "d06a40f83f2fb8bd441ab3485ae882f1fbdd9cd7a9c1ec175eb47cb8ae2cce81",
4734
+ "fabric-jsvalue.mjs": "dfbdb8c41584972c9389750a41719374a1cfc5652ed438dd1623025190b0106e",
4735
+ "fabric-time.mjs": "3ff932069038a720df1c68c6492976906737b2e67e5c12d9c81c418597f661de",
4736
+ "fabric-identifiers.mjs": "a18c2a501a4aa170bfd3d99e571ad6b7662649b4d3b9d2a540c002ea42811bbf",
4737
+ "fabric-secrets.mjs": "5822a7e25ecf2e87b5bab4f99c1074af7379d8b49e2784283b5d7d8c25022cde",
4738
+ "fabric-crypto.mjs": "038e03689701e3c9721a1e7f8e0a4d02a52d6a5d1661b0dc84035edc3ebbfcf6",
4739
+ "fabric-base.mjs": "7804b2df7715dbbf9702a9b61b6b8cef2110f9a52b04cabd8fb0a66458d87512",
4740
+ "fabric-platform.mjs": "a8119d95ebba4d589a9e401f5d6fc8dda62d59d44e4c1ff811d97fac3771ac0c",
4741
+ "fabric-paths.mjs": "aa630d611e748a899e7043480f4a4e46b444f2e15ff945f30c2fbef21c1ceea5",
4742
+ "fabric-estate-rules.mjs": "7476be71174aa5b1026134f2b335abf647feaa55584e2f9de8618e3054aa8e1e",
4743
+ "fabric-estate.mjs": "e8a2e62d2313121e6cb502f6e6abad94d1d546a44b4d9b3ce2be29e7808e8cf3",
4744
+ "fabric-mandate.mjs": "b70f3de03a659e60bba7b5a0580b3582825cd7b8a8e30a28c79621919ec5b7bb",
4745
+ "fabric-delegation.mjs": "f1b6d156d050f8ceb9a21daaad8d39ab5de5d32e4cfe03817909388fca8ad27e",
4746
+ "fabric-share.mjs": "bfb26581c21ad984c2a337da02429f9f3a165cc582f8ba48de4d3dfb7d163a59",
4747
+ "fabric-ceremonies.mjs": "117d4374c9e95c930a38de7adbd4323774798f4fe6ec6f24afcd6f2c7298ca44",
4748
+ "fabric-package-schema.mjs": "cd28092375db0fc21ffab1f0bb7794f7f8979ee08c64d3b9faf4b3845357caa6",
4749
+ "fabric-package.mjs": "8cfb32eebbd4e1bcf28a6e4437344ae2dd54479b0e7c820f002e9f94ab9ecaad",
4750
+ "fabric-protocols.mjs": "5fd8765fdd3e507cc85c108492682bf5cbb4ae08873245c50374fb01d33c75e4",
4751
+ "fabric-actions.mjs": "06e42f5e24c96311d5417d0d1effa93479ef7128a7ab139903b2bcf59253f6be",
4752
+ "fabric-connections.mjs": "303432e547ce563e90ca9ffcd827f5612f51d3582929834e1add0fdaf6485dcc",
4753
+ "fabric-a2a.mjs": "51b72fe1d80649d659fcad3a8f96370db3476c4a7b30cbabd8522c138be69346",
4754
+ "fabric-page-links.mjs": "a8834926e9d4bbf7c4857f551451d2ebf6ac8873bbccaaf89c5e30cf45b17ee6",
4755
+ "fabric-lock.mjs": "02cf833c97a07a8b3c788f9c93f70c4b9c9066efa25318dccf0038e0fc79717f",
4756
+ "fabric-usage.mjs": "1c4d18004639409624ac3516a02f2b60bbf55abdb612e9a96c37e83666eb87a7",
4757
+ "fabric-backups.mjs": "cfd8c9085e3d597a783099c2bd2ffe2f3faa0daaadab46dedd30523894cfeb06",
4758
+ "fabric-descriptor.mjs": "7c0ef7d245c037eb9e859ab481f6e66fb3e5ef2cf6d1e0a8d32b6d303097ca43",
4759
+ "fabric-context.mjs": "1112d695e872f9825cbc94f08484974bff3880087bc29b8be59f885f03e8f7be",
4760
+ "fabric-auth.mjs": "10ff37a39f9e3adb4d0f05db66c45f49b10eef582e9220c213907964109d7e52",
4761
+ "fabric-events.mjs": "c463d6ffcae24229a5c608d8fcea4268d2ccc5024b19fa10e5a452284068fa71",
4762
+ "fabric-logs.mjs": "58467e5719c16e099d05bbedec47a95712506ab03c33f3cd4be1252e8498a946",
4763
+ "fabric-supervisors.mjs": "d45c38de0cb3ed85e083496c2d3c51dab004454accdd87f4762a512a6d442573",
4764
+ "fabric-service.mjs": "297fef11ac76dc831d12d24c5581b7a93587c300c20664db703b3f924c0f9f1a",
4765
+ "fabric-profiles.mjs": "314376cf2deb87f235fb18b11d3b532e211f585b9af0a9302b5f4cc39971b532",
4766
+ "fabric-interop-rules.mjs": "b4e386c359a48e49ffff8a842215760c18a7c98a0af4754a808a35fb2820d458",
4767
+ "fabric-interop.mjs": "989040aed33b2712a258244192bdf70e811a51076aa1b62f2adc2a6db051dbed",
4768
+ "fabric-hub.mjs": "c005115a864cfd67daa4862097bb14acfe5a60bf653897e5bf8a570dd80f1070",
4769
+ "fabric-board-shapes.mjs": "c1db7b7bd0d58d82bb6d8dfbc3cd1547a256a333052d367e82ff1b3edf2804d7",
4770
+ "fabric-board-link.mjs": "6e7d51f4fd9730d93455f50dd30e97907b8b9e1ca65a1d69f036f2e8ec05cc0d",
4771
+ "fabric-board-slots.mjs": "fc77a3c6e62aa18575568bef4f703cce2edaba8cef648813ebcdbb21bdc27a11",
4772
+ "fabric-board-session.mjs": "18555962e5f6d18080a3e7971c4c6640452542f6042d07917e7ebc073721c415",
4773
+ "fabric-board-fixture.mjs": "83c4b7e33ee47b68385faf2569d38d5c8a0c5cb0f8656090f41e1b0eed2f436e",
4774
+ "fabric-board.mjs": "15fbb4441fcf7d2f285375b75de64ad6cffea129c515084c110245376b07775f",
4775
+ "fabric-http.mjs": "96aa1730c79cb9a68dcc94642513eb1e88f0c2d99a45ca505c042e8c601d0436",
4776
+ "fabric-openrouter.mjs": "6041f3ab30f516658e1dbab4897a651cc8509b2136cfa8e769802c6b40ec2f35",
4777
+ "fabric-package.schema.json": "2ba799f576fad0f608029223c4ccccd122152f1c5dbfa8ce8b31cd63ac92ad44",
4778
+ "share-registration.schema.json": "34b3997eeaf936ebc861342a23045634a7c18c19f01d7ed4198310d81989f5b0"
4779
+ },
4780
+ "0.63.0": {
4781
+ "fabric_jsvalue.py": "052f1b40bab18600b3731dbdca27cbff17588c21d9458fa6241efd1340d0e09a",
4782
+ "fabric_time.py": "588f383da4ac6a243ea95b6ffc3a0aa99ca94245732dc4937734f190b7af4ae9",
4783
+ "fabric_identifiers.py": "0fd814d521ac3aa39907458265870753046a73f48af3d8581ab864b93b211607",
4784
+ "fabric_secrets.py": "3939aa8658a92ca387e9f0259538c4849fc407e429355ef9b4829460107a8597",
4785
+ "fabric_crypto.py": "9c34aee20dbe4d6742e4fdbaab68ceb934bbe7dbd3a904c0010824ace16cdeaa",
4786
+ "fabric_base.py": "f62bcc2ed9912660fa875d27a09f60867260cc4925f79873501fd9620be59611",
4787
+ "fabric_platform.py": "a9350dff55ef0fb3a23cdb4d0320a15868b15a8deb10d2eb74d72c58740c284b",
4788
+ "fabric_paths.py": "8a1ee742f80f436e9f28c61b4f049a9545de2a9e0d66bfc61faa6ee5d1ba3734",
4789
+ "fabric_estate_rules.py": "8b36a7f4108d9c2b1fb38c8bff344778c807bed631a99b4a563ecb0a49c10b1c",
4790
+ "fabric_estate.py": "0737ae1d1bb12586bae49de1f15ef1348bc207b5007cced9dad4c55bb5870874",
4791
+ "fabric_mandate.py": "fb19ce5359606bd6e3352ab02b2a12f49605ec6e5c49b55cce1f79c831325044",
4792
+ "fabric_delegation.py": "716f0ff7ac01095f54b24970beac1962128e8ff33026b243fc0467876142ab03",
4793
+ "fabric_share.py": "da36a466426fc29dd7dd40013167f3959a18375f8fedd228bf64f298cec1040c",
4794
+ "fabric_ceremonies.py": "a59e83cf4adb2669a9b98008e3d3a0cba991a35cbff97bc604fc82fe81cfd49f",
4795
+ "fabric_package_schema.py": "e623f0408d38e3343ed66222fb812907c6c52e1a286eb1c1176ab2e64640c9ad",
4796
+ "fabric_package.py": "1f2b9e73b2b32a7e1e887d4b69f87c6e21b4d1227ad924a235334223e6dd51ca",
4797
+ "fabric_protocols.py": "42529a7df4d753544d2e37a18ec81266d6e1e80477cb8558a3ab521416d45791",
4798
+ "fabric_actions.py": "ae21d1199614c4f74d1dcd1e0a87107a9d52434cd9e2d64aa24a7b1e196fb723",
4799
+ "fabric_connections.py": "7de55cb7d808f756d650effabfaa12027d40a5bd5d2f6d448c32969d47529ecb",
4800
+ "fabric_a2a.py": "8b01502131215bb4de1c01866187c56e99b791543923ed8577535573db33b919",
4801
+ "fabric_page_links.py": "1b57ea573c550e2f90d1ec3edcc655917ceaa0db9dd1635fccf422ec3024d25e",
4802
+ "fabric_lock.py": "dfaf92a7086cbb097d832a305869b7964e2d2a9da0e3365c8ec1685a7bb4fef9",
4803
+ "fabric_usage.py": "5cc2e03ccc5b06e81987ed7bc3eead7a7e6cbf1a7cb8e05c6c64315eed9d91b6",
4804
+ "fabric_backups.py": "1f3f0d7ecf361b29e9101e07f1c53e5dc304d598bf26fd59ec89f16b9fed2420",
4805
+ "fabric_descriptor.py": "0e7b44eef7983c2dffc433173c4e376facb181279d4bfdffa9ae8028216984c0",
4806
+ "fabric_context.py": "6ae311ddc7217a4aff915e7ce2646486931acd128462b7bebe4a52bbb5fbb6c7",
4807
+ "fabric_auth.py": "74ccc10239b65a3567cec5213a7b344cbd88d6eee1fd1c5f7be1d6daf985993c",
4808
+ "fabric_events.py": "cd94b186e2a8f8cb4ad2b6bd44d83ec5021933075e28c5d655f387f16dff42b8",
4809
+ "fabric_logs.py": "86dc55bfafa2a57264722e2403510a249b95de0e4a722b2e4bc3948e3bd93da9",
4810
+ "fabric_supervisors.py": "3c5b2e8c310738720b1c1b779be4710e90251013d9be4c68f9952edc0bf55d5f",
4811
+ "fabric_service.py": "4b13f90aa26881fbfe0d9f3077fbb3552f3ce0a3c59279d6baa92df872867d8d",
4812
+ "fabric_profiles.py": "26e21ec29c016000f8ca8053b7b489184854a73be1b7fdc0a18d12990203db9b",
4813
+ "fabric_interop_rules.py": "9bdb7989e57b9d0b0d15eb9982d396499823a5e2c528230b71c67866c736e0f5",
4814
+ "fabric_interop.py": "d27e31834611a37cf2a117746f2f60fc187ccc48718eb546ff923c5d0fce7dea",
4815
+ "fabric_hub.py": "b9ac852e601b1d54cf61351677a628afc69faeed7d1fc74ebe541c1cf38e0c2a",
4816
+ "fabric_board_shapes.py": "0a0e8d3d40e33dfd8c457aedb85330b2ff25f8c49a33eb6cbd5a5cc8a5007f7e",
4817
+ "fabric_board_link.py": "052bc3c474ece835bb428c37ca864810d04e394d991ddb9c93989a7a825073a5",
4818
+ "fabric_board_slots.py": "92b065e3df935547cf46653245f1129e4a1f8b59b0a41e8fa9ffdc41596ee592",
4819
+ "fabric_board_session.py": "1fd3c3884f3044b56a40f78b33ff88dcac9272284f6681ea359c662879826f7e",
4820
+ "fabric_board_fixture.py": "69761ce205ec640762ec9b591c6903e5a87f844e8d423b041681924027e39d1e",
4821
+ "fabric_board.py": "f86c40b8291f8c818f6924910f4022b013d5fd107abaf8825dd0aa6c5e418638",
4822
+ "fabric_http.py": "861e8e0978e303455dd6ff4a1b98a8b258600320f2870af0644384196fb03679",
4823
+ "fabric_openrouter.py": "d06a40f83f2fb8bd441ab3485ae882f1fbdd9cd7a9c1ec175eb47cb8ae2cce81",
4824
+ "fabric-jsvalue.mjs": "dfbdb8c41584972c9389750a41719374a1cfc5652ed438dd1623025190b0106e",
4825
+ "fabric-time.mjs": "3ff932069038a720df1c68c6492976906737b2e67e5c12d9c81c418597f661de",
4826
+ "fabric-identifiers.mjs": "a18c2a501a4aa170bfd3d99e571ad6b7662649b4d3b9d2a540c002ea42811bbf",
4827
+ "fabric-secrets.mjs": "5822a7e25ecf2e87b5bab4f99c1074af7379d8b49e2784283b5d7d8c25022cde",
4828
+ "fabric-crypto.mjs": "038e03689701e3c9721a1e7f8e0a4d02a52d6a5d1661b0dc84035edc3ebbfcf6",
4829
+ "fabric-base.mjs": "7804b2df7715dbbf9702a9b61b6b8cef2110f9a52b04cabd8fb0a66458d87512",
4830
+ "fabric-platform.mjs": "a8119d95ebba4d589a9e401f5d6fc8dda62d59d44e4c1ff811d97fac3771ac0c",
4831
+ "fabric-paths.mjs": "aa630d611e748a899e7043480f4a4e46b444f2e15ff945f30c2fbef21c1ceea5",
4832
+ "fabric-estate-rules.mjs": "7476be71174aa5b1026134f2b335abf647feaa55584e2f9de8618e3054aa8e1e",
4833
+ "fabric-estate.mjs": "e8a2e62d2313121e6cb502f6e6abad94d1d546a44b4d9b3ce2be29e7808e8cf3",
4834
+ "fabric-mandate.mjs": "b70f3de03a659e60bba7b5a0580b3582825cd7b8a8e30a28c79621919ec5b7bb",
4835
+ "fabric-delegation.mjs": "f1b6d156d050f8ceb9a21daaad8d39ab5de5d32e4cfe03817909388fca8ad27e",
4836
+ "fabric-share.mjs": "bfb26581c21ad984c2a337da02429f9f3a165cc582f8ba48de4d3dfb7d163a59",
4837
+ "fabric-ceremonies.mjs": "117d4374c9e95c930a38de7adbd4323774798f4fe6ec6f24afcd6f2c7298ca44",
4838
+ "fabric-package-schema.mjs": "cd28092375db0fc21ffab1f0bb7794f7f8979ee08c64d3b9faf4b3845357caa6",
4839
+ "fabric-package.mjs": "8cfb32eebbd4e1bcf28a6e4437344ae2dd54479b0e7c820f002e9f94ab9ecaad",
4840
+ "fabric-protocols.mjs": "5fd8765fdd3e507cc85c108492682bf5cbb4ae08873245c50374fb01d33c75e4",
4841
+ "fabric-actions.mjs": "06e42f5e24c96311d5417d0d1effa93479ef7128a7ab139903b2bcf59253f6be",
4842
+ "fabric-connections.mjs": "303432e547ce563e90ca9ffcd827f5612f51d3582929834e1add0fdaf6485dcc",
4843
+ "fabric-a2a.mjs": "51b72fe1d80649d659fcad3a8f96370db3476c4a7b30cbabd8522c138be69346",
4844
+ "fabric-page-links.mjs": "a8834926e9d4bbf7c4857f551451d2ebf6ac8873bbccaaf89c5e30cf45b17ee6",
4845
+ "fabric-lock.mjs": "02cf833c97a07a8b3c788f9c93f70c4b9c9066efa25318dccf0038e0fc79717f",
4846
+ "fabric-usage.mjs": "1c4d18004639409624ac3516a02f2b60bbf55abdb612e9a96c37e83666eb87a7",
4847
+ "fabric-backups.mjs": "cfd8c9085e3d597a783099c2bd2ffe2f3faa0daaadab46dedd30523894cfeb06",
4848
+ "fabric-descriptor.mjs": "7c0ef7d245c037eb9e859ab481f6e66fb3e5ef2cf6d1e0a8d32b6d303097ca43",
4849
+ "fabric-context.mjs": "1112d695e872f9825cbc94f08484974bff3880087bc29b8be59f885f03e8f7be",
4850
+ "fabric-auth.mjs": "10ff37a39f9e3adb4d0f05db66c45f49b10eef582e9220c213907964109d7e52",
4851
+ "fabric-events.mjs": "c463d6ffcae24229a5c608d8fcea4268d2ccc5024b19fa10e5a452284068fa71",
4852
+ "fabric-logs.mjs": "58467e5719c16e099d05bbedec47a95712506ab03c33f3cd4be1252e8498a946",
4853
+ "fabric-supervisors.mjs": "d45c38de0cb3ed85e083496c2d3c51dab004454accdd87f4762a512a6d442573",
4854
+ "fabric-service.mjs": "297fef11ac76dc831d12d24c5581b7a93587c300c20664db703b3f924c0f9f1a",
4855
+ "fabric-profiles.mjs": "314376cf2deb87f235fb18b11d3b532e211f585b9af0a9302b5f4cc39971b532",
4856
+ "fabric-interop-rules.mjs": "b4e386c359a48e49ffff8a842215760c18a7c98a0af4754a808a35fb2820d458",
4857
+ "fabric-interop.mjs": "989040aed33b2712a258244192bdf70e811a51076aa1b62f2adc2a6db051dbed",
4858
+ "fabric-hub.mjs": "c005115a864cfd67daa4862097bb14acfe5a60bf653897e5bf8a570dd80f1070",
4859
+ "fabric-board-shapes.mjs": "c1db7b7bd0d58d82bb6d8dfbc3cd1547a256a333052d367e82ff1b3edf2804d7",
4860
+ "fabric-board-link.mjs": "6e7d51f4fd9730d93455f50dd30e97907b8b9e1ca65a1d69f036f2e8ec05cc0d",
4861
+ "fabric-board-slots.mjs": "fc77a3c6e62aa18575568bef4f703cce2edaba8cef648813ebcdbb21bdc27a11",
4862
+ "fabric-board-session.mjs": "18555962e5f6d18080a3e7971c4c6640452542f6042d07917e7ebc073721c415",
4863
+ "fabric-board-fixture.mjs": "83c4b7e33ee47b68385faf2569d38d5c8a0c5cb0f8656090f41e1b0eed2f436e",
4864
+ "fabric-board.mjs": "15fbb4441fcf7d2f285375b75de64ad6cffea129c515084c110245376b07775f",
4865
+ "fabric-http.mjs": "96aa1730c79cb9a68dcc94642513eb1e88f0c2d99a45ca505c042e8c601d0436",
4866
+ "fabric-openrouter.mjs": "6041f3ab30f516658e1dbab4897a651cc8509b2136cfa8e769802c6b40ec2f35",
4867
+ "fabric-package.schema.json": "2ba799f576fad0f608029223c4ccccd122152f1c5dbfa8ce8b31cd63ac92ad44",
4868
+ "share-registration.schema.json": "34b3997eeaf936ebc861342a23045634a7c18c19f01d7ed4198310d81989f5b0"
4689
4869
  }
4690
4870
  },
4691
4871
  "data": {
@@ -52,6 +52,8 @@ function handler(req, res) {
52
52
  startedAt, status: 'ready', degraded: [],
53
53
  surfaces: { dashboard: { path: '/', login: true }, events: { path: '/fabric/v1/events' } },
54
54
  summary: [{ label: 'Jobs today', value: events.length }],
55
+ // FAA-199: it says what it uses; this example calls nothing outside itself, so the list is empty.
56
+ extensions: k.connectionsExtension([]),
55
57
  }));
56
58
  }
57
59
  if (req.method === 'GET' && url.pathname === '/fabric/v1/events') {
@@ -8,7 +8,7 @@ once, and `sample.draft` is a job that stops for a titled choice before it compl
8
8
  `register` also writes the service's manifest, which names this descriptor.
9
9
 
10
10
  sample_service.py serve --port 47190 --data-dir DIR [--id sample] [--instance default]
11
- sample_service.py register --port 47190 --data-dir DIR [--services-dir DIR]
11
+ sample_service.py register --port 47190 --data-dir DIR [--services-dir DIR] [--id ID] [--repository URI]
12
12
 
13
13
  Opt-in, off by default: `serve --board-project <Project uuid>` also answers that Project's `sample.echo` requests on
14
14
  Fabric's project board (fabric-project-comms/0.1, FAA-12b) with fabric_board.Responder, from a board.respond grant whose
@@ -40,6 +40,11 @@ import fabric_board as fbd # noqa: E402 - the board responder (opt-in)
40
40
  import fabric_hub as fhb # noqa: E402
41
41
 
42
42
  VERSION = "0.1.0"
43
+ SAMPLE_REPOSITORY = "https://github.com/passioncode-ai/fabric-agent-adapter" # where this sample is built from (FAA-198)
44
+ # FAA-199: what the sample uses, declared so a host draws its chain (DEC-0096): the template it drafts from, and the
45
+ # demo source `serve --degraded` marks failing (a degraded[].source naming an id is that connection failing).
46
+ CONNECTIONS = [{"id": "template", "kind": "model", "target": "sample-template", "purpose": "drafts the notes"},
47
+ {"id": "demo", "kind": "connector", "target": "demo", "purpose": "the source --degraded marks failing"}]
43
48
  # The dashboard is built from the dashboard kit (fabric-dashboard/0.1, DEC-0036) and declares it
44
49
  # in the well-known document only when the kit is there to serve.
45
50
  KIT_DIR = Path(__file__).resolve().parent.parent / "assets" / "dashboard-kit"
@@ -279,7 +284,8 @@ class Service:
279
284
  "mcp": {"path": "/mcp", "transport": "streamable-http", "capabilities": [c["name"] for c in CAPABILITIES]
280
285
  + ([TAKE_BACK["tool"]] if self.board is not None else [])},
281
286
  "usage": {"path": fs.USAGE_PATH}},
282
- extensions=fs.dashboard_extension() if (KIT_DIR / "fabric-dashboard.css").is_file() else None,
287
+ extensions=dict(fs.dashboard_extension() if (KIT_DIR / "fabric-dashboard.css").is_file() else {},
288
+ **fs.connections_extension(CONNECTIONS, degraded=self.degraded, states={"template": "ok"})),
283
289
  # DEC-0067: listed only when the board is on — a host pinned before DEC-0067 refuses the member.
284
290
  # DEC-0126 OA-7: a server serving a relayed action reads `source`, so it lists operator-source/1 too.
285
291
  protocols=self.mcp.well_known_protocols(["fabric-service/0.1", "fabric-project-comms/0.1"]) if self.board is not None else None,
@@ -540,7 +546,7 @@ def write_manifest(args: argparse.Namespace, data: Path, board: bool = False) ->
540
546
 
541
547
  def register(args: argparse.Namespace) -> int:
542
548
  data = Path(args.data_dir)
543
- manifest = write_manifest(args, data, board=bool(getattr(args, "board_project", None)))
549
+ manifest = data / "fabric-agent.json" # written below, once the descriptor is known to be accepted
544
550
  descriptor = {
545
551
  "protocol": fs.PROTOCOL, "id": args.id, "instance": args.instance, "name": args.name,
546
552
  "summary": "Sample fabric-service/0.1 service.",
@@ -550,11 +556,40 @@ def register(args: argparse.Namespace) -> int:
550
556
  else {"manager": "none"},
551
557
  "paths": {"data": str(data), "logs": []},
552
558
  "fabricManifest": str(manifest),
559
+ "source": {"repository": args.repository},
553
560
  # DEC-0061: who installed it, by role and never by name — a person runs this register command.
554
561
  "installedAt": fs.now_iso(), "installedBy": {"by": "person", "role": "operator", "tool": "sample_service.py register %s" % VERSION},
555
562
  }
563
+ # A refused descriptor leaves no manifest naming it (0.62.0 unit reading 1).
564
+ problems = fs.validate_descriptor(descriptor)
565
+ refusal = ("Descriptor is invalid: %s." % "; ".join(problems) if problems
566
+ else fs.source_refusal(descriptor, Path(args.services_dir) if args.services_dir else None))
567
+ if refusal:
568
+ print(refusal, file=sys.stderr)
569
+ return 1
570
+ services = Path(args.services_dir) if args.services_dir else None
571
+ installed = fs.descriptor_path(args.id, args.instance, services)
572
+ try: # what a failed rewrite puts back (unit reading 4)
573
+ old = installed.read_bytes() if installed.exists() else None
574
+ except OSError as exc: # one it could not put back is never replaced (product reading 5)
575
+ print("The installed descriptor %s cannot be read (%s); nothing was written." % (installed, exc.strerror or exc), file=sys.stderr)
576
+ return 1
556
577
  try:
557
- path = fs.write_descriptor(descriptor, Path(args.services_dir) if args.services_dir else None)
578
+ path = fs.write_descriptor(descriptor, services)
579
+ # After the descriptor, so a refusal of any kind (a port claim too) leaves no manifest naming it (unit reading 2);
580
+ # a manifest that cannot be written takes a new descriptor back with it (unit reading 3).
581
+ try:
582
+ write_manifest(args, data, board=bool(getattr(args, "board_project", None)))
583
+ except OSError as exc:
584
+ undo = ""
585
+ try:
586
+ if old is None:
587
+ fs.remove_descriptor(args.id, args.instance, services)
588
+ else:
589
+ fs.atomic_write(installed, old, 0o600) # its bytes, 0600 as every descriptor the kit writes
590
+ except OSError as again: # said in the same line, never a traceback (seam reading 5)
591
+ undo = "; %s could not be %s either: %s" % (installed, "removed" if old is None else "put back", again.strerror or again)
592
+ raise fs.ServiceError("The manifest %s cannot be written: %s%s." % (manifest, exc.strerror or exc, undo))
558
593
  except fs.ServiceError as exc:
559
594
  print(str(exc), file=sys.stderr)
560
595
  return 1
@@ -584,6 +619,9 @@ def build_parser() -> argparse.ArgumentParser:
584
619
  p.add_argument("--board-project", help="the Project the service will answer on the board: lists its take-back "
585
620
  "tool in the manifest (serve with the same --board-project)")
586
621
  p.add_argument("--services-dir")
622
+ # FAA-198: the repository its code is built from, which a new descriptor names; the sample's own by default.
623
+ # The descriptor runs this sample's code whatever --id names, so its repository is this one by default.
624
+ p.add_argument("--repository", default=SAMPLE_REPOSITORY, help="the repository its code is built from")
587
625
  p.add_argument("--label")
588
626
  p.add_argument("--plist")
589
627
  return parser
@@ -5,7 +5,7 @@ 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.61.0"
8
+ version: "0.63.0"
9
9
  contract-version: "0.1.0"
10
10
  contract-commit: "3830a3353923e20f826d466610e1c479f120bec0"
11
11
  ---
@@ -91,7 +91,7 @@ prior art of its own:
91
91
 
92
92
  - [practices.md](references/practices.md): the rules production agents taught us, each with
93
93
  the check that catches it (judges and evals, numbers, money, people in the loop,
94
- reliability, shipping). Organization members also read the knowledge base's
94
+ reliability, shipping, agents on a channel people write to). Organization members also read the knowledge base's
95
95
  `knowledge/agent-practices.md` and add to it what this agent learns.
96
96
  - [where-agents-run.md](references/where-agents-run.md): this machine, a personal cloud, an
97
97
  organization; contexts; connecting a machine; sharing into an organization; selling.
@@ -1,7 +1,8 @@
1
1
  # Agents that answer people: what they carry from the first release
2
2
 
3
3
  **Load this when the agent you are building answers people**: private chats, mail, store reviews, group chats, any
4
- channel where a person asks and the agent writes back. Every item below is a part of the agent, built and tested in its
4
+ channel where a person asks and the agent writes back. An agent on such a channel also follows the channel-agent
5
+ standard: [practices](practices.md#agents-on-a-channel-people-write-to). Every item below is a part of the agent, built and tested in its
5
6
  first release, not a later improvement. Each comes from the sources below: what the quality standard requires (A1,
6
7
  A5), and what an audit of five production agents found working or failing (P1 to P8). The practices are field
7
8
  evidence: one estate, five agents, no control; their numbers are that estate's, never a forecast.
@@ -18,7 +19,9 @@ per-channel targets, A3 (the rubric), A4 (the judge and its calibration), A6 (an
18
19
  default) and the rest of its checks that caught real defects, and the practices' other items of P1, P3, P5, P6, P7 and
19
20
  P8. Read both sources before you design the reply pipeline. The kit's support-agent recipe (building-fabric-services,
20
21
  `recipes/support-agent/`) is one draft-and-check step of such an agent, not the agent: used alone it hands the message
21
- to a person at the first refusal (the refused draft is not kept), where this page repairs, researches and holds.
22
+ to a person at the first refusal; with a repairing `on_handoff` it rewrites a refused draft once (`repair=`, a
23
+ spent repair being `fallback: true`: a second refusal, a declined repair or no knowledge on the retry; a `model:*`
24
+ outage during the repair is a plain hand-off), and research and the hold stay this page's.
22
25
 
23
26
  ## Contents
24
27
 
@@ -13,6 +13,7 @@ finished. Organization members have the full page with every receipt: the Passio
13
13
  - [People in the loop](#people-in-the-loop)
14
14
  - [Reliability](#reliability)
15
15
  - [Shipping](#shipping)
16
+ - [Agents on a channel people write to](#agents-on-a-channel-people-write-to)
16
17
 
17
18
  ## Judges and evals
18
19
 
@@ -70,6 +71,10 @@ finished. Organization members have the full page with every receipt: the Passio
70
71
  - **Show who decides each stop**, and keep the person's queue to the person's stops.
71
72
  - **An approval holds the work; it does not refuse it.**
72
73
  - **Record every agent decision with its reason.**
74
+ - **The owner's word is done the first time, by the agent**: no command handed to the person to run; on a risk, one
75
+ short question, then a corrected way and the act. Only a human gate (sign-in, a one-time code, payment, a tool that
76
+ refuses the agent) goes to the person, with its reason, after the agent's own routes; money limits and secrets
77
+ stay (the contract's CT-220).
73
78
  - **A fallback sent instead of a rejected reply must stand alone**, and never append a fixed text in one language to a
74
79
  reply in another.
75
80
  - **An answer that promises a person is a handoff, or nobody comes.**
@@ -101,3 +106,44 @@ finished. Organization members have the full page with every receipt: the Passio
101
106
  - **A changed default model is not a changed installed agent.**
102
107
  - **Start a long verification suite only above a disk floor.**
103
108
  - **Agents that number rows in one register need a gate that fails on a duplicate id.**
109
+
110
+ ## Agents on a channel people write to
111
+
112
+ The channel-agent standard v1 (`channel-agent-standard/1`, its round 4 of 2026-11-04; the neutral copy travels with its
113
+ owner on the Fabric board, FAA-197) sets what every agent answering people on a channel does, so two agents count
114
+ alike. Unlike the sections above, these are the standard's rules rather than lessons from one measured failure;
115
+ each names its check where the kit has one. The support-agent recipe (`building-fabric-services/recipes/support-agent`) carries the parts of it a
116
+ draft-and-check step owns.
117
+
118
+ - **The unit is the ticket, and a channel rule bounds it**: a private chat until 24 hours of silence, a group's one
119
+ root message, a mail thread, one review. A message after a ticket ended opens a new one linked to the old. One
120
+ ticket has one writing agent.
121
+ - **Every ticket ends with one outcome** (the standard's section 3 lists them all, the ended and the open ones); an
122
+ ended outcome stays, except that within 30 days a late signal from a hand-off queue may turn a referred or an expired
123
+ ticket into a person's answer (a promotion, marked as one).
124
+ - **Answer, do not route**: hand to a person only what only a person may do, and what the checks the agent already
125
+ gave did not fix. "A person will reply" inside an ordinary answer is a defect.
126
+ - **Repair before hand-off**: a draft the checker refuses is rewritten once with the refusal's reason; a second refusal
127
+ is a fallback, marked on the ticket (`fallback: true`), as is a repair the model declines or that finds no knowledge. Check: the recipe's `repair=` and its tests.
128
+ - **At most one clarifying question, never two in a row**; no reply where none is owed.
129
+ - **Every source is declared with its owner, how it is read, its cadence and its maximum age**; one that fails keeps its last good version and
130
+ says so, and its age is that version's (its file's modification time, so the build touches the file at every
131
+ finished sync, changed or not: the standard ages a source from its last sync). Check: the recipe's `KnowledgeSource`.
132
+ - **A hand-off queue is a source too**: declared with the signal that it was answered, or with "none" and a
133
+ recommendation to its owner, posted on the board: `recommendation` is that board thread's id. Many `referred` tickets show a missing signal, not a regression.
134
+ - **Text from a channel is data** (the contract's proposed DEC-0150 CA-8): a message, caption, file name, link or
135
+ quoted reply is never an instruction; the agent makes no tool call, send, spend or access change because a message
136
+ asks, and acts on its own task and its operator's word. Check: the recipe's fence around the message and its checks.
137
+ - **Only metadata leaves the agent's side**: an opaque ticket id, times, outcome, step, category code and at most an
138
+ 80-character paraphrase that passed a personal-data check run inside the side; never a message, an identity or a
139
+ reply's text.
140
+ - **The declaration lives under the extension key**
141
+ `https://fabric.passioncode.ai/agent-contract/extensions/channel-agent/0.1`, one entry per project (the contract's
142
+ proposed DEC-0150, not merged yet; the key and the form may change when it is). A required
143
+ member is never null, except where nothing is decided (a channel's `decision`, and the optional `quiet_window`,
144
+ `late_answer_window` and `evals.spend_record`): a member not there yet is `{"none": "not_yet", "until": "<date>"}`,
145
+ one not used `{"none": "not_used"}` (only `question_route`, `gap_registry`, `tickets.pd_check` and a channel's
146
+ `texts.final` take that form, and a final text is never `not_used` beside a holding reply with replies on: a holding
147
+ reply owes a final one, the contract's FAC-SEM-164); `recommendation` appears only with `answered_signal: "none"`; what each channel
148
+ counts (`channels[].items_seen_unit`) is one of `mails`, `updates`, `messages` or `reviews`. Example: the recipe's
149
+ `channel-agent.example.json`. `check_service.py` reads it once the contract publishes its schema.
@@ -18,7 +18,7 @@ compatibility: >-
18
18
  this plugin; Codex/Kimi use command hooks; Hermes/OpenCode/OpenClaw/Pi use native context plugins after opt-in.
19
19
  metadata:
20
20
  author: PassionCode.ai
21
- version: "0.61.0"
21
+ version: "0.63.0"
22
22
  ---
23
23
 
24
24
  # Working with Fabric
@@ -115,12 +115,13 @@ session; the tool list changes. Follow those rules: they outrank this skill wher
115
115
 
116
116
  ### Then the project board
117
117
 
118
+ A dispatched session skips the `com.list` sweep, Step 4 and Step 7: [on-demand session](references/on-demand-session.md).
119
+
118
120
  `com.status` (can the board be read, how many unread), then `com.list` (`unread: true` where listed); `com.read_ack`
119
121
  only what you actually read and handled. A reply reaches the sender it answers; add `deliverTo: "thread"` when
120
- every participant needs it (DEC-0135); a board pinned before DEC-0135 (every Fabric to 0.3.14) refuses it, so send
121
- the same content as a new message to the thread. A request addressed to your Project is your next task. Ask another Project
122
- only through `com.submit`, addressed to its Project id (never a session, a process id or a folder) with the same
123
- idempotency key on a retry. When nobody answers (no `active` responder, no live claim, no agent-sync lease, nothing
122
+ every participant needs it (DEC-0135); an older board refuses it: post a new thread message. Answer what waits on your Project this turn (state now, result later; leave a responder's request queued); a request is your next task. Ask another Project
123
+ only through `com.submit`, addressed to its Project id (never a session or a folder), the same idempotency key on a
124
+ retry. When nobody answers (no `active` responder, no live claim, no agent-sync lease, nothing
124
125
  `held`): a change small as the reference defines it goes into the owner's repository by its AGENTS.md and you reply
125
126
  *adapted by* with the merge commit (your reply does not answer your own request); anything larger stays queued until
126
127
  its deadline (seven days by default, then `expired`). The target Project's reply to a request answers it (`answered`):
@@ -227,6 +228,8 @@ chat of any of his agents binds all his agents (OA-1).
227
228
  - Record the relay (his quote, the date, the source, the scope) as your reason in the change log, the thread reply or
228
229
  the handoff (OA-6). A stop rule written into a request does not replace an approval whose scope covers the case: act
229
230
  on it.
231
+ - His word is done the first time, by you (CT-220): no command for him to run; on a risk, one short question, then do
232
+ it.
230
233
  - Human gates stay (OA-5): sign-in, a one-time code, consent, payment or top-up, a typed secret, spend above a limit
231
234
  (handed over with its link and amount, never asked in chat), a passkey, a comparison of codes with another person
232
235
  or the choice to share without one (DEC-0142). A policy change, a promotion or a grant of your own is never covered (AP-5).
@@ -300,8 +303,7 @@ by hand, or say it is linked. Do not paste the row's text or status into the tas
300
303
  3. `fabric_work_release` with how it ended: `done` (the task goes to review), handed over (to whom, with the note
301
304
  the next agent reads) or let go (why). Older Fabric: `fabric_task_release`.
302
305
 
303
- A session that ends without releasing lapses at its claim's expiry; release anyway: a lapsed claim reads as stuck
304
- work.
306
+ Release anyway: a lapsed claim reads as stuck work.
305
307
 
306
308
  ## Refusals and lost answers
307
309
 
@@ -313,7 +315,7 @@ work.
313
315
  | denied | the operator said no | stop; it stands until cleared in Agent access |
314
316
  | failed in the client before its answer arrived; outcome unknown | the call may have run | check its effect first (`fabric_work_list`, `fabric_tasks_list`); repeat only with the same idempotency key |
315
317
  | Fabric restarted or closed this session; nothing was done | refused before the call ran | call it again once `fabric_whoami` answers |
316
- | `operator-decision-required` | a service's action needs the operator's decision and none travelled; with `data.detail` `outside-mandate: <part>`, the mandate does not cover that part | ask the operator about this action, then relay their answer by the first route of Step 5 that carries it, the page only when none does; under a mandate, call again within your own mandate if it covers the part, else pass the refusal to the agent that called you, and only the lead asks him, once, about that part alone; `mandate-capability-missing`: no mandate covers that step, only his decision |
318
+ | `operator-decision-required` | a service's action needs the operator's decision and none travelled; with `data.detail` `outside-mandate: <part>`, the mandate does not cover that part | ask the operator about this action, then relay their answer by the first route of Step 5 that carries it, the page only when none does; under a mandate, as Step 5 says (MD-4); `mandate-capability-missing`: no mandate covers that step, only his decision |
317
319
  | `decision-invalid` | the decision names another action or object, is older than 24 hours, lies over 60 s ahead of the service's clock, or is malformed; or the mandate is (`data.detail` `mandate-malformed`, `-widened`, `-expired`, `-early`, `-not-for-this-call`) | never edit, widen or re-date it; ask the operator again when their words do not cover this call |
318
320
  | `approval-required` with `data.actionDigest` | a caller outside the machine's trust (T2): a chat decision changes nothing | an `approval/1` for that digest through the hub |
319
321
  | `human-step-required` with `data.humanStep` and `data.url` | a human gate of OA-5 (above) stays the person's | hand the person `data.url`: a path on the service's origin as Fabric Dashboards' `open_link` (`fallback=never`), an https URL as it is; never take the step or ask for the secret; continue other work |
@@ -335,9 +337,9 @@ backs the file up first, refuses a file of another shape or one that changed sin
335
337
  it out again. Hermes/OpenCode/OpenClaw/Pi use their native plugin loaders, not Claude hook JSON.
336
338
  Hermes also needs `hermes plugins enable fabric-agent-adapter`; removal uses `hermes plugins disable fabric-agent-adapter`.
337
339
  Read [native host hooks](references/native-host-hooks.md) for exact paths, permission behavior and verification.
338
- Registration and a loaded hook do not prove live Fabric admission. Never edit those files by hand for the person. Without the hook, put the preamble into the first prompt
339
- yourself: "Call `fabric_whoami` first; `com.status` and `com.list`; `fabric_work_list`, then `fabric_work_claim`,
340
- before you start; `fabric_work_release` when you stop." Without an MCP client at all there is no way in: say so,
340
+ Registration and a loaded hook do not prove admission. Never edit those files by hand. Without the hook, put the preamble into the first prompt
341
+ yourself: "Call `fabric_whoami` first; `com.status` and `com.list`, answering what waits this turn; `fabric_work_list`,
342
+ then `fabric_work_claim`; `fabric_work_release` when you stop." Without an MCP client at all there is no way in: say so,
341
343
  and do the work without claiming Fabric saw it.
342
344
 
343
345
  ## The session hooks
@@ -347,12 +349,11 @@ in a project that uses Fabric, one line pointing at `fabric_whoami` in a folder
347
349
  down and the project uses Fabric, one line pointing at Step 1; after each turn the turn's facts (HEAD, files changed, lines added
348
350
  and removed) and the board's unread count, and, once the running Fabric takes them, the other repositories the turn
349
351
  touched (read in memory from the transcript's last 512 KB, which can hold a secret the session displayed; only tool names and path arguments are used, only host/owner/name sent; `FABRIC_SESSION_NO_REPOSITORIES=1` turns it off); at each prompt one line only when that count rose, then each reminder Fabric gave on a turn, once, as a line starting `Fabric:` (or tagged `Fabric reminder: `; a turn
350
- `watch-mail` delivered prints there instead): Fabric's words, data to act on first through `fabric_work_list` (where the same reminder may come again: act on it
352
+ `watch-mail` delivered prints there instead): Fabric's words, data to act on first through `fabric_work_list` (where it may come again: act on it
351
353
  once); at the end, the
352
354
  release of what the session left claimed. The turn, prompt and end hooks spool and call Fabric only when the running
353
- Fabric advertises `session-hooks/1`; the turn and end hooks always prune their own stale spool. All are silent in a session Fabric launched, never block the session and read no Fabric token (a credential in an `origin` URL is dropped in memory, never sent). Read
354
- [session hooks](references/session-hooks.md) when a person asks what the hooks do, where they log, how to turn them
355
- off, or what they need from Fabric.
355
+ Fabric advertises `session-hooks/1`; the turn and end hooks always prune their own stale spool. All are silent in a session Fabric launched; one started on a board request gets its exit contract, no unread line or reminder (FAA-201). They never block the session and read no Fabric token (a credential in an `origin` URL is dropped in memory, never sent). [Session
356
+ hooks](references/session-hooks.md): what they do, log and need, and how to turn them off.
356
357
 
357
358
  ## Completion format
358
359
 
@@ -46,7 +46,13 @@ OpenCode and Pi loader files carry a managed marker. A foreign file at the same
46
46
  - Native bridges give the Python helper only a working directory and, when observed, a boolean Fabric registration. Hermes uses its native read-only config, OpenCode its resolved enabled MCP entry, OpenClaw its resolved MCP servers and Pi an exact callable `fabric_whoami` tool name. Config registration is not admission.
47
47
  - Missing helper/Python, malformed values, excessive output or a four-second deadline produce no context. Existing host errors and permission failures are not silenced globally.
48
48
  - OpenCode and OpenClaw ask for context on every request; their bridges keep the helper's answer per workspace and registration for the life of the host process, so Python runs once, not per request. A failed run (an error, a nonzero exit, a timeout, no `python3`) reads as `null`, distinct from an empty answer `''`, and is not kept, so the next request asks again. A Fabric started later is seen by a new host instance.
49
- - Fabric-launched sessions are silent. Other native events are not advertised: turn observations, unread counts and rejoin-only release remain Claude-specific and feature-gated.
49
+ - Fabric-launched sessions are silent, except a session started on a board request (`FABRIC_DISPATCH_WORKFLOW`): there
50
+ session start prints the exit contract on the condition that the session's own prompt starts with the dispatch line
51
+ naming the same three, launched or not; Codex and Kimi have no prompt hook, so the session checks that line itself
52
+ and the hooks keep no record there. A native bridge gives the hook no session id either and is always told the
53
+ conditional contract
54
+ ([on-demand session](on-demand-session.md)).
55
+ - Other native events are not advertised: turn observations, unread counts and rejoin-only release remain Claude-specific and feature-gated.
50
56
  - A host in Switchboard's catalog may support MCP, proxy or launch while exposing no startup context hook. Never copy this configuration to another host solely because it can launch an agent.
51
57
 
52
58
  ## Verification