@passioncode-ai/fabric-agent-adapter 0.35.1 → 0.35.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/package.json +1 -1
- package/plugins/fabric-agent-adapter/.claude-plugin/plugin.json +1 -1
- package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/SKILL.md +1 -1
- package/plugins/fabric-agent-adapter/skills/building-fabric-services/SKILL.md +1 -1
- package/plugins/fabric-agent-adapter/skills/creating-fabric-agents/SKILL.md +4 -2
- package/plugins/fabric-agent-adapter/skills/creating-fabric-agents/references/resilience-and-autonomy.md +58 -11
- package/plugins/fabric-agent-adapter/skills/working-with-fabric/SKILL.md +2 -2
- package/plugins/fabric-agent-adapter/skills/working-with-fabric/references/project-board.md +3 -2
- package/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/fabric_session.py +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.35.3 - 2026-10-19
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **`creating-fabric-agents`, resilience and autonomy, third pass**: a rerun calls read-only tools until its open
|
|
8
|
+
outcomes are reconciled; idempotency keys cover content as well as the run; every tool's input schema is pinned to
|
|
9
|
+
the domain schema by a test.
|
|
10
|
+
- **`creating-fabric-agents`, text for people** (FAA-52): the intake grill asks whether the agent writes text a person
|
|
11
|
+
reads; if it does, its prompt forbids the em dash (U+2014) and any substitute for it, and a test fails on U+2014 in
|
|
12
|
+
its output from the first commit. The resilience reference gains *Text for people* (the rule, its exact exceptions,
|
|
13
|
+
a portable check, `accept` rewriting or refusing a model's slip) and a checklist line; a new eval scenario covers it.
|
|
14
|
+
`test/validate.py` fails a tree where the grill, the reference or the scenario loses it.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **The resilience reference numbered two rules 9** under *Secrets and confinement*; the second is 10.
|
|
19
|
+
|
|
20
|
+
## 0.35.2 - 2026-10-18
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- **`creating-fabric-agents` → resilience and autonomy, second pass**: retries moved at most once and only before the
|
|
25
|
+
first byte, a persisted `Retry-After`; deciding for a waiting peer and releasing a lease with its commit; live-only,
|
|
26
|
+
exactly-once hand-overs; protocols ported from shared vectors; bytecode cleared before mutation runs; blocking work
|
|
27
|
+
off request workers and interruptible socket waits; bounded recursive parsing, content-addressed revocation, no
|
|
28
|
+
refresh of a person's own credentials. From the same retrospective's later answers (2026-10-17/18).
|
|
29
|
+
|
|
3
30
|
## 0.35.1 - 2026-10-17
|
|
4
31
|
|
|
5
32
|
### Added
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@passioncode-ai/fabric-agent-adapter",
|
|
3
|
-
"version": "0.35.
|
|
3
|
+
"version": "0.35.3",
|
|
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.35.
|
|
6
|
+
"version": "0.35.3",
|
|
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.35.
|
|
8
|
+
version: "0.35.3"
|
|
9
9
|
contract-version: "0.1.0"
|
|
10
10
|
contract-commit: "d8146cfb0a1c74fc6432284c4356bb0c864b37b5"
|
|
11
11
|
---
|
|
@@ -18,7 +18,7 @@ license: AGPL-3.0-only OR LicenseRef-PassionCode-Commercial
|
|
|
18
18
|
compatibility: Python 3.9+ or Node.js 20+ for the kits; 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.
|
|
19
19
|
metadata:
|
|
20
20
|
author: PassionCode.ai
|
|
21
|
-
version: "0.35.
|
|
21
|
+
version: "0.35.3"
|
|
22
22
|
contract-version: "0.1.0"
|
|
23
23
|
extension: "fabric-service/0.1"
|
|
24
24
|
extension-commit: "d8146cfb0a1c74fc6432284c4356bb0c864b37b5"
|
|
@@ -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.35.
|
|
8
|
+
version: "0.35.3"
|
|
9
9
|
contract-version: "0.1.0"
|
|
10
10
|
contract-commit: "d8146cfb0a1c74fc6432284c4356bb0c864b37b5"
|
|
11
11
|
---
|
|
@@ -53,6 +53,7 @@ No file is created until every row has an answer. An answer of "later" fails the
|
|
|
53
53
|
| **Which profile?** | `mcp` when Fabric owns planning and retries and the capability has a schema; `a2a` when the provider owns its task lifecycle end to end; `local-runner` when it is a terminal agent Fabric drives. When unsure, the sibling skill's profile-selection reference is the decision record |
|
|
54
54
|
| **What effects?** | declare anything money-, deletion-, or publication-adjacent now — the host's floor and grants are designed against these declarations, and one discovered late invalidates the admission |
|
|
55
55
|
| **Which tenancy?** | record whether the agent assumes one operator; the assumption is cheap to write down and expensive to excavate |
|
|
56
|
+
| **Text for people?** | if it writes anything a person reads (a reply, a message, a post, a report, a UI string), its prompt forbids the em dash (U+2014) and any substitute for it, and a test fails on U+2014 in new output, from the first commit (the resilience reference, *Text for people*) |
|
|
56
57
|
|
|
57
58
|
## Step 1 — the knowledge intake
|
|
58
59
|
|
|
@@ -207,7 +208,8 @@ Before the first stage that calls a model or spends money, read
|
|
|
207
208
|
[resilience and autonomy](references/resilience-and-autonomy.md) and design its answers in:
|
|
208
209
|
a limit pauses and resumes, every model answer passes the call site's own acceptance, fallbacks
|
|
209
210
|
and checkers cross vendors, spend is a persisted ledger with idempotency keys, open questions
|
|
210
|
-
become recorded decisions,
|
|
211
|
+
become recorded decisions, every fix has a test seen failing, and text a person reads carries no
|
|
212
|
+
em dash (U+2014), held by its prompt and a test. Report its checklist with a
|
|
211
213
|
file and a test per line, or `NOT_RUN` where the agent has no such stage.
|
|
212
214
|
|
|
213
215
|
## Completion format
|
|
@@ -14,6 +14,7 @@ mechanism that held after the fix. Every rule is cheaper to build in than to ret
|
|
|
14
14
|
- Verification you can believe
|
|
15
15
|
- Operations that survive restarts
|
|
16
16
|
- Secrets and confinement
|
|
17
|
+
- Text for people
|
|
17
18
|
- Checklist
|
|
18
19
|
|
|
19
20
|
## Limits are pauses
|
|
@@ -40,6 +41,10 @@ mechanism that held after the fix. Every rule is cheaper to build in than to ret
|
|
|
40
41
|
the next one. Retries there stalled a waiting user. Stagger many resumes; bound each worker's
|
|
41
42
|
working set (a narrow time window, a prefix), so one stop does not become a burst.
|
|
42
43
|
|
|
44
|
+
8. **Move a refused request to another account at most once, and only before any byte reached the
|
|
45
|
+
client** — a replay after streaming began duplicated output. Persist a provider's `Retry-After`
|
|
46
|
+
across restarts; a check inside the hold answers the stored observation instead of probing.
|
|
47
|
+
|
|
43
48
|
## Model answers are untrusted until accepted
|
|
44
49
|
|
|
45
50
|
1. **"Answered" is not "usable".** Each call site has its own `accept(text)` — the parser the
|
|
@@ -92,7 +97,10 @@ mechanism that held after the fix. Every rule is cheaper to build in than to ret
|
|
|
92
97
|
7. **Reuse what was paid for.** A restarted stage looks up the job's successful call with the
|
|
93
98
|
same route, prompt version and inputs before calling again (one restart made 117 paid calls
|
|
94
99
|
where 49 sufficed). Cache keys are content plus definition, never an identity alone.
|
|
95
|
-
8. **
|
|
100
|
+
8. **A rerun after an interruption calls read-only tools until its open outcomes are reconciled**;
|
|
101
|
+
an idempotency key covers the content as well as the run, so a retried run that asks a new
|
|
102
|
+
question is not refused as a conflict.
|
|
103
|
+
9. **Deny spending tools by enumerated name, and test the list**: a provider's newer tools were
|
|
96
104
|
missing from a deny list while older ones were denied.
|
|
97
105
|
|
|
98
106
|
## Autonomy: decide, record, continue
|
|
@@ -117,9 +125,17 @@ mechanism that held after the fix. Every rule is cheaper to build in than to ret
|
|
|
117
125
|
6. **Background chores never hold a finished command open**, unattended runs skip them, and an
|
|
118
126
|
unattended `--yes` never reverses a "no" a person saved.
|
|
119
127
|
|
|
128
|
+
7. **When a peer waits on your decision, make it**, mark it reversible, record it where the work
|
|
129
|
+
lives and reply naming the record; a platform once built nothing for days waiting on a
|
|
130
|
+
definition. Release a coordination lease in the same step as the commit that used it, the
|
|
131
|
+
failure path included.
|
|
132
|
+
8. **Hand work over only while it is alive**, and claim each hand-over exactly once by an exclusive
|
|
133
|
+
create; a forgotten workflow was handed over twice.
|
|
134
|
+
|
|
120
135
|
## Verification you can believe
|
|
121
136
|
|
|
122
|
-
1. **A test counts once it was watched failing against a planted defect
|
|
137
|
+
1. **A test counts once it was watched failing against a planted defect** (clear bytecode caches
|
|
138
|
+
first — stale bytecode reported mutants killed); a mutation battery
|
|
123
139
|
asserts its own reach ("no tests ran" is not "all plants survived"). Exercise every guard
|
|
124
140
|
with a must-catch and a must-pass case.
|
|
125
141
|
2. **Write expectations out; never compute them from the code under test**, and run a reference
|
|
@@ -141,7 +157,9 @@ mechanism that held after the fix. Every rule is cheaper to build in than to ret
|
|
|
141
157
|
9. **Probe live after every deploy on every consumer channel**, not the default one; read the
|
|
142
158
|
nightly full-suite result first when resuming work, and release from a full local run, not a
|
|
143
159
|
selected subset.
|
|
144
|
-
10. **
|
|
160
|
+
10. **Port a protocol from the contract's shared vectors, never its prose** — vendored with a hash
|
|
161
|
+
per file and run case by case; a prose port accepted a year-0000 date the vectors refused.
|
|
162
|
+
11. **Read an external contract from its raw documentation or a recorded live snapshot**, never
|
|
145
163
|
from a summarising fetch; fail closed on a field nobody documented.
|
|
146
164
|
|
|
147
165
|
## Operations that survive restarts
|
|
@@ -178,6 +196,10 @@ mechanism that held after the fix. Every rule is cheaper to build in than to ret
|
|
|
178
196
|
11. **Admit work only when the machine can carry it** — free disk, swap, a cap on concurrent
|
|
179
197
|
sessions — and say why when you defer.
|
|
180
198
|
|
|
199
|
+
12. **Keep blocking work off the workers that answer requests**, never let a read wait behind a long
|
|
200
|
+
transaction, and log a transaction held long with the step that held it. Every blocking network
|
|
201
|
+
wait is interruptible from outside, with its deadline on the socket, not between frames.
|
|
202
|
+
|
|
181
203
|
## Secrets and confinement
|
|
182
204
|
|
|
183
205
|
1. **A secret never enters an environment, argv, URL or log a child can read.** Hand it over a
|
|
@@ -191,17 +213,42 @@ mechanism that held after the fix. Every rule is cheaper to build in than to ret
|
|
|
191
213
|
before merge: a `;` once let a private path reach a public branch.
|
|
192
214
|
5. **Freeze every input at acceptance**, nested references included: copy it by hash and work on
|
|
193
215
|
the copy, so a file swapped between acceptance and use is never read.
|
|
194
|
-
6. **
|
|
216
|
+
6. **Pin every tool's input schema to the domain schema with a test.** A save tool that silently
|
|
217
|
+
dropped unknown fields once stored an agent set to send without the guards it was given.
|
|
218
|
+
7. **Treat what a run wrote as untrusted** before the service copies, reads or renders it: a
|
|
195
219
|
regular file whose real path is inside the run's own tree.
|
|
196
|
-
|
|
220
|
+
8. **An artefact missing a secret refuses to start**, never runs unauthenticated: validation rejects
|
|
197
221
|
placeholder-shaped values, and a test renders the configuration without the value and expects
|
|
198
222
|
an error.
|
|
199
|
-
|
|
223
|
+
9. **Widen an access configuration first, code second**, so nothing is over-scoped even briefly.
|
|
224
|
+
|
|
225
|
+
10. **Bound every recursive parse of untrusted input** (a depth limit, tested at the limit and one
|
|
226
|
+
above). Revoke or retire by a content-addressed reference, never a reusable name: a re-keyed
|
|
227
|
+
machine keeps its key id. Never refresh a person's own credentials as a side effect; renew only
|
|
228
|
+
what you own.
|
|
229
|
+
|
|
230
|
+
## Text for people
|
|
231
|
+
|
|
232
|
+
1. **Text a person reads carries no em dash** (U+2014) and no substitute for it: not `--`, not a
|
|
233
|
+
spaced hyphen used as a dash. The operator reads it as the mark of machine-written text. Use a
|
|
234
|
+
full stop, a comma, a colon or parentheses, or rewrite the sentence. This covers replies,
|
|
235
|
+
messages, posts, mail, reports, captions and UI strings, in every language.
|
|
236
|
+
2. **Exceptions are exact, never stylistic:** exact quotations, code, commands, paths and
|
|
237
|
+
historical records keep the character as they are.
|
|
238
|
+
3. **The rule lives in the prompt and in a test.** The prompt of every lane that writes for people
|
|
239
|
+
states it; a test feeds that lane's output (and every fixed template) through a check that
|
|
240
|
+
fails on U+2014, for example `assert "\u2014" not in text`, and is seen failing on a planted
|
|
241
|
+
dash. A spaced hyphen cannot be told from a range or a minus by a pattern: the prompt and a
|
|
242
|
+
reviewer carry that half, the check does not guess.
|
|
243
|
+
4. **A model's slip is rewritten or refused, never shipped.** When an accepted answer still holds U+2014, the
|
|
244
|
+
call site's `accept` rewrites it or retries once, then refuses; it never sends the dash on.
|
|
200
245
|
|
|
201
246
|
## Checklist
|
|
202
247
|
|
|
203
|
-
Before the first release, answer each with a file and a test: where a limit pauses and resumes;
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
248
|
+
Before the first release, answer each with a file and a test: where a limit pauses and resumes; what
|
|
249
|
+
`accept` each model call has; which vendors its fallback and checker use; where the attempt ledger
|
|
250
|
+
and idempotency keys live; what happens to an unknown outcome; which waits are durable; who owns the
|
|
251
|
+
run lock; what the next start sweeps; how a cancel reaches paid inner work; which outputs are
|
|
252
|
+
capped; how a secret reaches a child; which test was seen failing for each fix; and, for an agent
|
|
253
|
+
that writes text for people, where its prompt says no em dash and which test fails on U+2014 in its
|
|
254
|
+
output.
|
|
@@ -19,7 +19,7 @@ compatibility: >-
|
|
|
19
19
|
this plugin; Codex/Kimi use command hooks; Hermes/OpenCode/OpenClaw/Pi use native context plugins after opt-in.
|
|
20
20
|
metadata:
|
|
21
21
|
author: PassionCode.ai
|
|
22
|
-
version: "0.35.
|
|
22
|
+
version: "0.35.3"
|
|
23
23
|
---
|
|
24
24
|
|
|
25
25
|
# Working with Fabric
|
|
@@ -105,7 +105,7 @@ and its answer is an error that names what Fabric waits for — never a fake suc
|
|
|
105
105
|
|---|---|---|
|
|
106
106
|
| Fabric is not running, or its hub is closed | no live hub | Step 1; Settings → Agent access in Fabric says why a hub is closed |
|
|
107
107
|
| Fabric's hub could not be verified | foreign protocol, dead pid, token outside Fabric's folder | send nothing; ask the person to open Fabric |
|
|
108
|
-
| the folder is not a project | no project holds this folder | the
|
|
108
|
+
| the folder is not a project | no project holds this folder yet | Fabric with automatic project admission creates or attaches the Project during enrollment; an older Fabric needs the person to open it (+ Project → Open a project) |
|
|
109
109
|
| waiting for the operator to allow this coding agent | the consent prompt is on their screen | tell the person; call again in a moment; never loop fast |
|
|
110
110
|
| denied | the operator said no | stop; the denial stands until they clear it in Agent access |
|
|
111
111
|
| connecting | enrollment in progress | call again in a moment |
|
|
@@ -134,8 +134,9 @@ personal data or private path in a body or an artifact reference: name a vault s
|
|
|
134
134
|
- Never enroll a second session from a hook or a script: a `fabric-mcp` started outside the agent's own connection
|
|
135
135
|
enrolls a new session, and Fabric ends a binding's oldest live session past eight — the agent's own. The plugin's
|
|
136
136
|
hooks and `watch-mail` only rejoin (`--rejoin-only`).
|
|
137
|
-
- Never attach a folder
|
|
138
|
-
|
|
137
|
+
- Never attach a folder or create a Project through a side channel to make enrollment succeed. Fabric's own
|
|
138
|
+
enrollment admits an eligible Git folder and records the Project it creates or attaches. If the answer is still
|
|
139
|
+
"the folder is not a project", report it; never write another product's registry or improvise a second admission path.
|
|
139
140
|
|
|
140
141
|
## Not yet available
|
|
141
142
|
|
|
@@ -63,7 +63,7 @@ WATCH_MAX_BACKOFF_S = 900
|
|
|
63
63
|
SESSION_ID = re.compile(r"[A-Za-z0-9._:-]{1,128}")
|
|
64
64
|
LOOPBACK_ORIGIN = re.compile(r"http://127\.0\.0\.1:(\d{1,5})")
|
|
65
65
|
LOCAL_ORIGIN = re.compile(r'"origin": "http://(?:127\.0\.0\.1|localhost)')
|
|
66
|
-
VERSION = "0.35.
|
|
66
|
+
VERSION = "0.35.3"
|
|
67
67
|
HOSTS = {"claude": "Claude Code", "codex": "Codex", "kimi": "Kimi Code",
|
|
68
68
|
"hermes": "Hermes", "opencode": "OpenCode", "openclaw": "OpenClaw", "pi": "Pi"}
|
|
69
69
|
NATIVE_PLUGIN_HOSTS = frozenset(("hermes", "opencode", "openclaw", "pi"))
|