@passioncode-ai/fabric-agent-adapter 0.71.0 → 0.72.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.72.0 (2026-11-06)
4
+
5
+ ### Changed
6
+
7
+ - working-with-fabric: a run Fabric started on a board request whose `com.enroll` is refused `not_authorized` asks the
8
+ operator with `fabric_question_ask` (`about: board.gate.<capability>`, the same `commandId`) at every slot state,
9
+ not only when the slot reads `absent` at generation 0; `com.reply` stays only for that state, since at any other a
10
+ holder enrolled on the slot (a service of the Project, or after CO-506 a session) may take the request back. After
11
+ CO-506 a refusal comes from the reason Fabric's `board.own-respond` names (such as an organization's machine, a
12
+ missing live credential, a standing denial, a full ask queue), and a run that stayed silent then left the request to
13
+ «На проверке» without the gate's reason (FAA-241; Fabric main `4f3c742a`, which says the same in
14
+ `board.read-at-start` and `com.enroll`'s description). The exit contract's step 3,
15
+ `references/on-demand-session.md`, `references/project-board.md` (a live session too) and both scenario evals
16
+ (`a-dispatched-run-whose-enroll-is-refused`, `answer-as-responder-or-reply`) say so; the gate question names what
17
+ opens the gate, or at a held slot what takes the request: before CO-506, a Fabric release with it, and the service
18
+ enrolling again; once CO-506 shipped, the reason Fabric's `board.own-respond` names and what lifts it; the exit
19
+ contract stays under Hermes' 4000 characters (3996 at its longest).
20
+
3
21
  ## 0.71.0 (2026-11-06)
4
22
 
5
23
  The contract pin moves to `eac1a594` (`v0.1.0+2026-11-06.1`) from `3830a33` (`v0.1.0+2026-10-27.6`); between them
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@passioncode-ai/fabric-agent-adapter",
3
- "version": "0.71.0",
3
+ "version": "0.72.0",
4
4
  "description": "Create Fabric-compatible agents, run them as always-alive local services with dashboards (fabric-service/0.1), and adapt existing projects to the Fabric Agent Contract. This package is the installer CLI.",
5
5
  "scripts": {
6
6
  "test": "python3 test/validate.py && python3 -m unittest discover -s test -q && node --test 'test/*.test.mjs'"
@@ -3,7 +3,7 @@
3
3
  "name": "fabric-agent-adapter",
4
4
  "displayName": "Fabric Agent Adapter",
5
5
  "description": "Create new Fabric-compatible agents, build them as always-alive local services with dashboards (fabric-service/0.1), and adapt existing projects to the Fabric Agent Contract through evidence-backed MCP, A2A, or local-runner provider bundles; and teach a coding agent to work in a project through Fabric (fabric-mcp, fabric_whoami, claim and release), with Claude Code session hooks.",
6
- "version": "0.71.0",
6
+ "version": "0.72.0",
7
7
  "author": {
8
8
  "name": "PassionCode.ai",
9
9
  "url": "https://passioncode.ai/"
@@ -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.
6
6
  metadata:
7
7
  author: PassionCode.ai
8
- version: "0.71.0"
8
+ version: "0.72.0"
9
9
  contract-version: "0.1.0"
10
10
  contract-commit: "eac1a594aa131851f079da8bb7b2149e1951f35f"
11
11
  ---
@@ -14,7 +14,7 @@ license: AGPL-3.0-only OR LicenseRef-PassionCode-Commercial
14
14
  compatibility: Python 3.9+ or Node.js 20+ for the kits (Node.js 22+ for a Linux service's instance lock); the probe needs Python 3.9+. launchd steps are macOS-only; Linux services install a systemd user unit and Windows ones a per-user Scheduled Task with the kits' writers. Dashboard handoff optionally uses Fabric Dashboards MCP link/host_status/open; without it, report unresolved host capability. The contract checkout is optional.
15
15
  metadata:
16
16
  author: PassionCode.ai
17
- version: "0.71.0"
17
+ version: "0.72.0"
18
18
  contract-version: "0.1.0"
19
19
  extension: "fabric-service/0.1"
20
20
  extension-commit: "eac1a594aa131851f079da8bb7b2149e1951f35f"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fabric-service-kit",
3
- "version": "0.71.0",
3
+ "version": "0.72.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
  {
@@ -5676,6 +5676,96 @@
5676
5676
  "fabric-openrouter.mjs": "6041f3ab30f516658e1dbab4897a651cc8509b2136cfa8e769802c6b40ec2f35",
5677
5677
  "fabric-package.schema.json": "2ba799f576fad0f608029223c4ccccd122152f1c5dbfa8ce8b31cd63ac92ad44",
5678
5678
  "share-registration.schema.json": "34b3997eeaf936ebc861342a23045634a7c18c19f01d7ed4198310d81989f5b0"
5679
+ },
5680
+ "0.72.0": {
5681
+ "fabric_jsvalue.py": "052f1b40bab18600b3731dbdca27cbff17588c21d9458fa6241efd1340d0e09a",
5682
+ "fabric_time.py": "588f383da4ac6a243ea95b6ffc3a0aa99ca94245732dc4937734f190b7af4ae9",
5683
+ "fabric_identifiers.py": "0fd814d521ac3aa39907458265870753046a73f48af3d8581ab864b93b211607",
5684
+ "fabric_secrets.py": "53c5df8d6f2c87433c288853bfaad9a43f544789bdf1e39bda8d3ff14485c89d",
5685
+ "fabric_crypto.py": "9c34aee20dbe4d6742e4fdbaab68ceb934bbe7dbd3a904c0010824ace16cdeaa",
5686
+ "fabric_base.py": "f62bcc2ed9912660fa875d27a09f60867260cc4925f79873501fd9620be59611",
5687
+ "fabric_platform.py": "a9350dff55ef0fb3a23cdb4d0320a15868b15a8deb10d2eb74d72c58740c284b",
5688
+ "fabric_paths.py": "8a1ee742f80f436e9f28c61b4f049a9545de2a9e0d66bfc61faa6ee5d1ba3734",
5689
+ "fabric_estate_rules.py": "8b36a7f4108d9c2b1fb38c8bff344778c807bed631a99b4a563ecb0a49c10b1c",
5690
+ "fabric_estate.py": "0737ae1d1bb12586bae49de1f15ef1348bc207b5007cced9dad4c55bb5870874",
5691
+ "fabric_mandate.py": "fb19ce5359606bd6e3352ab02b2a12f49605ec6e5c49b55cce1f79c831325044",
5692
+ "fabric_delegation.py": "716f0ff7ac01095f54b24970beac1962128e8ff33026b243fc0467876142ab03",
5693
+ "fabric_share.py": "da36a466426fc29dd7dd40013167f3959a18375f8fedd228bf64f298cec1040c",
5694
+ "fabric_ceremonies.py": "a59e83cf4adb2669a9b98008e3d3a0cba991a35cbff97bc604fc82fe81cfd49f",
5695
+ "fabric_package_schema.py": "e623f0408d38e3343ed66222fb812907c6c52e1a286eb1c1176ab2e64640c9ad",
5696
+ "fabric_package.py": "1f2b9e73b2b32a7e1e887d4b69f87c6e21b4d1227ad924a235334223e6dd51ca",
5697
+ "fabric_protocols.py": "077c6f03f3b887a2e22d9ce6b5bd3750199d71a29d4c82b1d5af8a615b509d93",
5698
+ "fabric_actions.py": "ae21d1199614c4f74d1dcd1e0a87107a9d52434cd9e2d64aa24a7b1e196fb723",
5699
+ "fabric_connections.py": "7de55cb7d808f756d650effabfaa12027d40a5bd5d2f6d448c32969d47529ecb",
5700
+ "fabric_a2a.py": "8b01502131215bb4de1c01866187c56e99b791543923ed8577535573db33b919",
5701
+ "fabric_page_links.py": "1b57ea573c550e2f90d1ec3edcc655917ceaa0db9dd1635fccf422ec3024d25e",
5702
+ "fabric_lock.py": "dfaf92a7086cbb097d832a305869b7964e2d2a9da0e3365c8ec1685a7bb4fef9",
5703
+ "fabric_usage.py": "5cc2e03ccc5b06e81987ed7bc3eead7a7e6cbf1a7cb8e05c6c64315eed9d91b6",
5704
+ "fabric_backups.py": "1f3f0d7ecf361b29e9101e07f1c53e5dc304d598bf26fd59ec89f16b9fed2420",
5705
+ "fabric_descriptor.py": "c08c91ca0960c694ed7677e7e9247d6307c7b63f37a7e614db022c080cd92ccc",
5706
+ "fabric_context.py": "6ae311ddc7217a4aff915e7ce2646486931acd128462b7bebe4a52bbb5fbb6c7",
5707
+ "fabric_auth.py": "74ccc10239b65a3567cec5213a7b344cbd88d6eee1fd1c5f7be1d6daf985993c",
5708
+ "fabric_events.py": "cd94b186e2a8f8cb4ad2b6bd44d83ec5021933075e28c5d655f387f16dff42b8",
5709
+ "fabric_logs.py": "86dc55bfafa2a57264722e2403510a249b95de0e4a722b2e4bc3948e3bd93da9",
5710
+ "fabric_supervisors.py": "3c5b2e8c310738720b1c1b779be4710e90251013d9be4c68f9952edc0bf55d5f",
5711
+ "fabric_service.py": "4b13f90aa26881fbfe0d9f3077fbb3552f3ce0a3c59279d6baa92df872867d8d",
5712
+ "fabric_profiles.py": "26e21ec29c016000f8ca8053b7b489184854a73be1b7fdc0a18d12990203db9b",
5713
+ "fabric_interop_rules.py": "9bdb7989e57b9d0b0d15eb9982d396499823a5e2c528230b71c67866c736e0f5",
5714
+ "fabric_interop.py": "d27e31834611a37cf2a117746f2f60fc187ccc48718eb546ff923c5d0fce7dea",
5715
+ "fabric_hub.py": "b9ac852e601b1d54cf61351677a628afc69faeed7d1fc74ebe541c1cf38e0c2a",
5716
+ "fabric_board_shapes.py": "0a0e8d3d40e33dfd8c457aedb85330b2ff25f8c49a33eb6cbd5a5cc8a5007f7e",
5717
+ "fabric_board_link.py": "052bc3c474ece835bb428c37ca864810d04e394d991ddb9c93989a7a825073a5",
5718
+ "fabric_board_slots.py": "92b065e3df935547cf46653245f1129e4a1f8b59b0a41e8fa9ffdc41596ee592",
5719
+ "fabric_board_session.py": "1fd3c3884f3044b56a40f78b33ff88dcac9272284f6681ea359c662879826f7e",
5720
+ "fabric_board_fixture.py": "69761ce205ec640762ec9b591c6903e5a87f844e8d423b041681924027e39d1e",
5721
+ "fabric_board.py": "f86c40b8291f8c818f6924910f4022b013d5fd107abaf8825dd0aa6c5e418638",
5722
+ "fabric_http.py": "8b443477dc29d5a1fe908b9dccaf68f05fab837eae0670074051a1dd2dfb71ad",
5723
+ "fabric_openrouter.py": "d06a40f83f2fb8bd441ab3485ae882f1fbdd9cd7a9c1ec175eb47cb8ae2cce81",
5724
+ "fabric-jsvalue.mjs": "dfbdb8c41584972c9389750a41719374a1cfc5652ed438dd1623025190b0106e",
5725
+ "fabric-time.mjs": "3ff932069038a720df1c68c6492976906737b2e67e5c12d9c81c418597f661de",
5726
+ "fabric-identifiers.mjs": "a18c2a501a4aa170bfd3d99e571ad6b7662649b4d3b9d2a540c002ea42811bbf",
5727
+ "fabric-secrets.mjs": "5822a7e25ecf2e87b5bab4f99c1074af7379d8b49e2784283b5d7d8c25022cde",
5728
+ "fabric-crypto.mjs": "038e03689701e3c9721a1e7f8e0a4d02a52d6a5d1661b0dc84035edc3ebbfcf6",
5729
+ "fabric-base.mjs": "7804b2df7715dbbf9702a9b61b6b8cef2110f9a52b04cabd8fb0a66458d87512",
5730
+ "fabric-platform.mjs": "a8119d95ebba4d589a9e401f5d6fc8dda62d59d44e4c1ff811d97fac3771ac0c",
5731
+ "fabric-paths.mjs": "aa630d611e748a899e7043480f4a4e46b444f2e15ff945f30c2fbef21c1ceea5",
5732
+ "fabric-estate-rules.mjs": "7476be71174aa5b1026134f2b335abf647feaa55584e2f9de8618e3054aa8e1e",
5733
+ "fabric-estate.mjs": "e8a2e62d2313121e6cb502f6e6abad94d1d546a44b4d9b3ce2be29e7808e8cf3",
5734
+ "fabric-mandate.mjs": "b70f3de03a659e60bba7b5a0580b3582825cd7b8a8e30a28c79621919ec5b7bb",
5735
+ "fabric-delegation.mjs": "8f63a63aab9a8746b7f664720b87e9398137d01b8d50880974d5070038e414a0",
5736
+ "fabric-share.mjs": "bfb26581c21ad984c2a337da02429f9f3a165cc582f8ba48de4d3dfb7d163a59",
5737
+ "fabric-ceremonies.mjs": "117d4374c9e95c930a38de7adbd4323774798f4fe6ec6f24afcd6f2c7298ca44",
5738
+ "fabric-package-schema.mjs": "cd28092375db0fc21ffab1f0bb7794f7f8979ee08c64d3b9faf4b3845357caa6",
5739
+ "fabric-package.mjs": "8cfb32eebbd4e1bcf28a6e4437344ae2dd54479b0e7c820f002e9f94ab9ecaad",
5740
+ "fabric-protocols.mjs": "a560b7d6eb0d26204c5536711c3dda9daae90cc91e07cdc75412e75c86272767",
5741
+ "fabric-actions.mjs": "06e42f5e24c96311d5417d0d1effa93479ef7128a7ab139903b2bcf59253f6be",
5742
+ "fabric-connections.mjs": "303432e547ce563e90ca9ffcd827f5612f51d3582929834e1add0fdaf6485dcc",
5743
+ "fabric-a2a.mjs": "51b72fe1d80649d659fcad3a8f96370db3476c4a7b30cbabd8522c138be69346",
5744
+ "fabric-page-links.mjs": "a8834926e9d4bbf7c4857f551451d2ebf6ac8873bbccaaf89c5e30cf45b17ee6",
5745
+ "fabric-lock.mjs": "02cf833c97a07a8b3c788f9c93f70c4b9c9066efa25318dccf0038e0fc79717f",
5746
+ "fabric-usage.mjs": "1c4d18004639409624ac3516a02f2b60bbf55abdb612e9a96c37e83666eb87a7",
5747
+ "fabric-backups.mjs": "cfd8c9085e3d597a783099c2bd2ffe2f3faa0daaadab46dedd30523894cfeb06",
5748
+ "fabric-descriptor.mjs": "7c0ef7d245c037eb9e859ab481f6e66fb3e5ef2cf6d1e0a8d32b6d303097ca43",
5749
+ "fabric-context.mjs": "1112d695e872f9825cbc94f08484974bff3880087bc29b8be59f885f03e8f7be",
5750
+ "fabric-auth.mjs": "10ff37a39f9e3adb4d0f05db66c45f49b10eef582e9220c213907964109d7e52",
5751
+ "fabric-events.mjs": "c463d6ffcae24229a5c608d8fcea4268d2ccc5024b19fa10e5a452284068fa71",
5752
+ "fabric-logs.mjs": "58467e5719c16e099d05bbedec47a95712506ab03c33f3cd4be1252e8498a946",
5753
+ "fabric-supervisors.mjs": "d45c38de0cb3ed85e083496c2d3c51dab004454accdd87f4762a512a6d442573",
5754
+ "fabric-service.mjs": "297fef11ac76dc831d12d24c5581b7a93587c300c20664db703b3f924c0f9f1a",
5755
+ "fabric-profiles.mjs": "314376cf2deb87f235fb18b11d3b532e211f585b9af0a9302b5f4cc39971b532",
5756
+ "fabric-interop-rules.mjs": "b4e386c359a48e49ffff8a842215760c18a7c98a0af4754a808a35fb2820d458",
5757
+ "fabric-interop.mjs": "989040aed33b2712a258244192bdf70e811a51076aa1b62f2adc2a6db051dbed",
5758
+ "fabric-hub.mjs": "c005115a864cfd67daa4862097bb14acfe5a60bf653897e5bf8a570dd80f1070",
5759
+ "fabric-board-shapes.mjs": "c1db7b7bd0d58d82bb6d8dfbc3cd1547a256a333052d367e82ff1b3edf2804d7",
5760
+ "fabric-board-link.mjs": "6e7d51f4fd9730d93455f50dd30e97907b8b9e1ca65a1d69f036f2e8ec05cc0d",
5761
+ "fabric-board-slots.mjs": "fc77a3c6e62aa18575568bef4f703cce2edaba8cef648813ebcdbb21bdc27a11",
5762
+ "fabric-board-session.mjs": "18555962e5f6d18080a3e7971c4c6640452542f6042d07917e7ebc073721c415",
5763
+ "fabric-board-fixture.mjs": "83c4b7e33ee47b68385faf2569d38d5c8a0c5cb0f8656090f41e1b0eed2f436e",
5764
+ "fabric-board.mjs": "15fbb4441fcf7d2f285375b75de64ad6cffea129c515084c110245376b07775f",
5765
+ "fabric-http.mjs": "317d7668c291570d4d93bc73295312f2853eb93940f4cf754a4a4619cb87ace9",
5766
+ "fabric-openrouter.mjs": "6041f3ab30f516658e1dbab4897a651cc8509b2136cfa8e769802c6b40ec2f35",
5767
+ "fabric-package.schema.json": "2ba799f576fad0f608029223c4ccccd122152f1c5dbfa8ce8b31cd63ac92ad44",
5768
+ "share-registration.schema.json": "34b3997eeaf936ebc861342a23045634a7c18c19f01d7ed4198310d81989f5b0"
5679
5769
  }
5680
5770
  },
5681
5771
  "data": {
@@ -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.71.0"
8
+ version: "0.72.0"
9
9
  contract-version: "0.1.0"
10
10
  contract-commit: "eac1a594aa131851f079da8bb7b2149e1951f35f"
11
11
  ---
@@ -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.71.0"
21
+ version: "0.72.0"
22
22
  ---
23
23
 
24
24
  # Working with Fabric
@@ -91,28 +91,35 @@ hook, or a Switchboard before 0.7.8 started the run, the launcher's appended exi
91
91
  `fabric_question_ask` with `kind: access`, `about: board.gate.<capability>`, the `commandId` the contract names (UUID
92
92
  v5 of the name `board.gate` in the request id's namespace, `gate_question_id` in `fabric_session_cli.py`, so every run
93
93
  on that request gets the same question back) and a `text` naming the request (its id, the requesting Project, the
94
- capability), the gate (this Project's `board.respond` grant for that capability) and what opens it (a Fabric
95
- release with CO-506, which grants it at `com.enroll`; on Fabric 0.3.16 nothing else does, since Agent access only
96
- decides a request a service filed; once CO-506 shipped, the reason Fabric's `board.own-respond` log line names and
97
- what lifts it: a machine marked as an organization's (the mark in Fabric's settings), no live credential (the agent
98
- enrolls again) or a standing denial ("Снять отказ" in Agent access); Fabric, thread `1add3c03`, `315c5b54`); it waits for no answer (FAA-224; the tool needs no slot; Fabric keeps the
94
+ capability), the gate (this Project's `board.respond` grant for that capability) and what opens it (on Fabric before CO-506: a Fabric
95
+ release with CO-506, which grants it at `com.enroll`, and at a slot a holder held, the Project's service enrolling again,
96
+ which takes the request itself without opening this gate; on Fabric 0.3.16 nothing else does, since Agent access only
97
+ decides a request a service filed; once CO-506 shipped, at every slot state, the reason Fabric's `board.own-respond`
98
+ log line names and what lifts it: a machine marked as an organization's (the mark in Fabric's settings), no live credential (the agent
99
+ enrolls again), a standing denial ("Снять отказ" in Agent access) or a full ask queue (the
100
+ operator answers the asks that wait, or they expire); Fabric, thread `1add3c03`, `315c5b54`); it waits for no answer (FAA-224; the tool needs no slot; Fabric keeps the
99
101
  `about` with the question and settles no later question by it yet (CO-519), so each gate question reaches the operator and a
100
102
  repeat with the same `commandId` returns the same question: Fabric, thread `1add3c03`, `5b216035`). A question that fails is left (the decline already answered the request), and the closing write's
101
103
  `notes` say so, since then nothing about the gate reached the operator. Then it closes the workflow `done` once
102
- `com.get` reads it answered (step 6), and writes the retro (step 7); in any other state, or with the slot `stale`, `active`, or `absent` at a generation of 1 or more (a holder enrolled on it: a
104
+ `com.get` reads it answered (step 6), and writes the retro (step 7). When the request is not queued, or the slot
105
+ reads `stale`, `active`, or `absent` at a generation of 1 or more (a holder enrolled on it: a
103
106
  service of this Project, or after CO-506 a session; one that stopped cleanly reads `absent`, and a service takes the
104
- request when it rejoins, so a decline would take it from it; Fabric serves a session no `held` flag yet), the error
105
- rule below holds and the request stays as it is (queued, it goes to the operator after two runs with no answer). A
107
+ request when it rejoins, so a decline would take it from it; Fabric serves a session no `held` flag yet), it sends no
108
+ `com.reply` but still asks the operator with the same `fabric_question_ask` (a question answers no request and takes
109
+ nothing from the service; after CO-506 such a refusal comes from the reason `board.own-respond` names (such as an organization's machine, no live
110
+ credential, a standing denial, a full ask queue), so it is never silent: FAA-241, Fabric main `4f3c742a`; a question that fails is named in the
111
+ `notes` of one more in_progress checkpoint), then the error rule below holds and the request stays as it is (a queued request goes to
112
+ the operator after two runs with no answer). A
106
113
  capability listed only by a service's live grant, with no enroll yet, also reads `absent` at generation 0: a run
107
114
  declines it, which a service asking and enrolling at once (ADR-0186) seldom leaves time for.
108
- The target's request no longer waits for the operator on the board (an answered request is settled: no second run,
115
+ After the decline, the target's request no longer waits for the operator on the board (an answered request is settled: no second run,
109
116
  no unmoved or to-operator finding; the question above is what reaches the operator, when Fabric took it); the requester reads the decline, and until it reads and acknowledges it (`com.read_ack`) Fabric
110
117
  shows it on the requester's Project in «На проверке» as an answer nobody read,
111
118
  and the closing write's `notes` say the request was declined until CO-506.
112
119
  Fabric's dispatcher counts an answered request as settled and starts no second run for it. Once CO-506 ships
113
120
  (Fabric's `main` `027cb809`) a session's own Project grants it at `com.enroll` itself, and this branch is taken only
114
121
  where CO-506 grants nothing (a machine marked as an organization's, no live credential for the session or its runner,
115
- or a standing denial of that ask); the reply then names CO-506 though it shipped, and the real gate is that grant (left open in FAA-215).
122
+ a standing denial of that ask, or a full ask queue); the reply then names CO-506 though it shipped, and the real gate is that grant (left open in FAA-215).
116
123
  FAA-219; Fabric's answer in board thread `1add3c03` (option (b), 2026-11-05), the responder's run's rule plus the
117
124
  slot condition, which Fabric's `board.read-at-start` took from the adapter (FAA-231, main `dbfbfce4`, in no release
118
125
  yet);
@@ -191,16 +191,16 @@ generation of 1 or more: a holder enrolled on it), do
191
191
  not reply on the request: tell the person and leave it queued. A session whose own `com.enroll` is refused
192
192
  `not_authorized` has no route to the grant before Fabric's CO-506: when its capability's slot is `absent` at generation 0,
193
193
  it answers the request once that it cannot be taken now and why, does no work on it without the slot, then asks the
194
- operator once with `fabric_question_ask` (`kind: access`, `about: board.gate.<capability>`, the `commandId` that
194
+ operator once (at any other slot state it sends no reply and still asks, FAA-241) with `fabric_question_ask` (`kind: access`, `about: board.gate.<capability>`, the `commandId` that
195
195
  `python3 <skill-dir>/scripts/fabric_session.py gate-id <request>` prints, the same a run uses, and a `text` naming the request, the gate and what
196
196
  opens it; without Python, no `commandId` can be made: tell the person only), tells the person (the question stays
197
197
  filed even when that is the operator: Fabric keeps its `about` and settles nothing by it yet, CO-519), and stops handling
198
- that request without waiting (Fabric's `board.read-at-start` rule and `com.enroll`'s own tool description said the
199
- same, slot condition included, at main `603da12f`, `dbfbfce4` and `12d57bdd`; since main `4f3c742a` they also ask the
200
- operator at the other slot states, which the adapter takes in 0.72.0, FAA-241; in no Fabric release yet: on Fabric
201
- 0.3.16 this rule wins). Never write "it stays queued" in a reply: the reply itself ends the queue. A
198
+ that request without waiting (Fabric's `board.read-at-start` rule and `com.enroll`'s own tool description say the
199
+ same since main `4f3c742a`: the question since `603da12f` (CO-517) in the rule and `12d57bdd` in the description, the slot condition since
200
+ `dbfbfce4` and `12d57bdd`; in no Fabric release yet, and
201
+ on Fabric 0.3.16 this rule wins). Never write "it stays queued" in a reply: the reply itself ends the queue. A
202
202
  run Fabric started on a board request has no person in its chat to tell: with the slot `absent` at generation 0 it declines,
203
- asks for a resend and asks the operator with `fabric_question_ask`; otherwise it leaves the request queued ([on-demand session](on-demand-session.md), step 3).
203
+ asks for a resend and asks the operator with `fabric_question_ask`; otherwise it leaves the request queued and still asks ([on-demand session](on-demand-session.md), step 3).
204
204
 
205
205
  ## Replying
206
206
 
@@ -268,7 +268,8 @@ answer for a merge, a release or the end of the task; the finished result goes l
268
268
  thread. A state with its nearest date is an answer (the operator's rule of 2026-11-04, board thread `11646774`): to a
269
269
  request it moves the request to `answered` as any participant reply does (above), so where your Project's service
270
270
  responder should still do the work, tell the person and leave the request queued instead (a session's own refused
271
- `com.enroll` with its slot `absent` at generation 0 answers once that it cannot be taken now, above). To an announcement the state is its **row** line. A responder holding the request's slot gives its state in the turn
271
+ `com.enroll` with its slot `absent` at generation 0 answers once that it cannot be taken now, and at any slot state asks
272
+ the operator, above). To an announcement the state is its **row** line. A responder holding the request's slot gives its state in the turn
272
273
  it claims by a `com.progress` note or a fenced reply, neither of which answers the request, and settles it with
273
274
  `com.complete` (DEC-0152 SA-6, proposed). Fabric's `fabric_whoami` gives a state as a `com.reply` and a slot holder's as a
274
275
  `com.progress` since Fabric 0.3.16 (`fff4b6d9`); the responder's exception above is this page's.
@@ -137,7 +137,7 @@ DISPATCH_IF = (
137
137
  " Other values: no run; say so in the request's thread and stop. The run:")
138
138
  #: The conditional contract at its longest (a 64-character handoff and a session id) is held under Hermes' 4000
139
139
  #: characters by test_a_native_bridge_is_always_told_the_contract_and_writes_no_record; measure before adding words
140
- #: (3996 in 0.68.0 and in 0.69.0, 3999 in 0.71.0: a new rule takes its characters back from the text around it).
140
+ #: (3996 in 0.68.0 and in 0.69.0, 3999 in 0.71.0, 3996 in 0.72.0: a new rule takes its characters back from the text around it).
141
141
  DISPATCH_CONTRACT = (
142
142
  " Do that "
143
143
  "request and end; never wait for a person. 1. `fabric_whoami`, then the packet "
@@ -150,7 +150,7 @@ DISPATCH_CONTRACT = (
150
150
  "no lease: end the run without touching the request. 3. `com.status` once ("
151
151
  "epoch, generation); `com.enroll` (the capability), `com.claim` (the request), "
152
152
  "`com.accept` and `com.effect_begin` before an effect; a not_authorized enroll: no slot, no work and, if queued and its `com.status` slot `absent` at generation 0, one `com.reply` (replyTo it) "
153
- "declining until Fabric's CO-506 (resend then), next `fabric_question_ask` {{kind: access, about: board.gate.<capability>, commandId: {gate}, text: the request, its gate, what opens it}}, then step 6 (done) once `com.get` reads answered, and 7; left accepted by an earlier run: `com.responder_replace` (`expectedGeneration`) and its transfer; resolve `outcome_unknown` only with "
153
+ "declining until CO-506 (resend then), either way `fabric_question_ask` {{kind: access, about: board.gate.<capability>, commandId: {gate}, text: the request, its gate, what opens it}}, then step 6 (done) once `com.get` reads answered, and 7; left accepted by an earlier run: `com.responder_replace` (`expectedGeneration`) and its transfer; resolve `outcome_unknown` only with "
154
154
  "`com.reconcile` and an observed result. After the lease, claim and reply: an in_progress checkpoint (`workflowId`, "
155
155
  "`leaseId`). Every checkpoint repeats `goal`, `constraints`, `artifacts` and `credentials` of "
156
156
  "`checkpoint.body` (not the answer's top-level `credentials` or the accept's "
@@ -305,7 +305,7 @@ def dispatch_contract(dispatch: Dict[str, str], session_id: Any = None, conditio
305
305
 
306
306
 
307
307
  def gate_question_id(request: str) -> str:
308
- """The `commandId` of the run's one question to the operator about a request it declined at the gate: UUID v5 of the
308
+ """The `commandId` of the run's one question to the operator about a request whose `com.enroll` was refused at the gate: UUID v5 of the
309
309
  name `board.gate` in the request id's namespace, so every run on that request asks the same question (Fabric,
310
310
  thread 1add3c03, a58b4280; FAA-224)."""
311
311
  import uuid # only the exit contract needs it; the other hooks never pay for the import
@@ -826,7 +826,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
826
826
  if argv[:1] == ["install-host-hooks"]:
827
827
  return install_host_hooks_cli(argv[1:])
828
828
  if argv[:1] == ["gate-id"]:
829
- # the commandId of the one operator question about a request declined at the gate, for a session that is not
829
+ # the commandId of the one operator question about a request whose enroll was refused, for a session that is not
830
830
  # a run (Fabric's board.read-at-start from its CO-517 asks every session; FAA-224)
831
831
  if len(argv) != 2 or not re.fullmatch(_DISPATCH_VALUE["request"], argv[1]):
832
832
  print("usage: fabric_session.py gate-id <board request id, a UUID>", file=sys.stderr)
@@ -58,7 +58,7 @@ SESSION_ID = re.compile(r"[A-Za-z0-9._:-]{1,128}")
58
58
  LOOPBACK_ORIGIN = re.compile(r"http://127\.0\.0\.1:(\d{1,5})")
59
59
 
60
60
 
61
- VERSION = "0.71.0"
61
+ VERSION = "0.72.0"
62
62
 
63
63
 
64
64
  HOSTS = {"claude": "Claude Code", "codex": "Codex", "kimi": "Kimi Code",