@passioncode-ai/fabric-agent-adapter 0.36.0 → 0.37.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,29 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.37.0 - 2026-10-19
4
+
5
+ ### Added
6
+
7
+ - **`creating-fabric-agents` carries what the estate learned about building agents** (FAA-58, the operator's request
8
+ of 2026-10-19): four new references every new agent starts from.
9
+ - `where-agents-run.md`: this machine, a personal cloud, an organization, Enterprise; contexts (`personal`,
10
+ `org:<id>`) with one instance per context and no secret, spend or journal crossing; connecting a machine (nearby
11
+ code, headless enroll token); sharing an agent into an organization; running while the laptop is closed; selling
12
+ an agent (a paid agent in its developer's organization, a partner's setup).
13
+ - `models-and-providers.md`: lanes with a fallback of another vendor and an open-vendor model where users' content is
14
+ read; a dated starting choice from the OpenRouter catalog; several kinds of input and output; budgets that survive
15
+ reasoning; one OpenRouter key per agent and context with its ceiling, read from the environment; measuring a choice.
16
+ - `orchestration-and-learning.md`: workflow first; the work graph of durable jobs with intent keys, effects observed,
17
+ limits as pauses (DEC-0087); calling other agents within a narrower grant and budget; stops for a person; learning
18
+ loops (decisions with reasons, one trace per turn, failures as planted fixtures first, history replayed, learnings
19
+ proposed and never self-approved); the loop guard.
20
+ - `practices.md`: the rules production agents taught us, each with its check: judges and evals, numbers, money,
21
+ people in the loop, reliability, shipping.
22
+ - The intake grill asks **Where does it run, for whom?**, **Which models?**, **Who pays?** and **How does it learn?**;
23
+ the knowledge intake links the four references. `test/validate.py` holds the rows, the links and each reference's
24
+ checklist (`KnowledgePackTests`); eval scenario `agent-for-a-personal-and-an-organization-cloud`; three trigger
25
+ queries.
26
+
3
27
  ## 0.36.0 - 2026-10-19
4
28
 
5
29
  Repinned to Fabric Agent Contract `07042181bfae2a481aa0da1a5651f24c76669c48` (DEC-0084 to DEC-0088); `d8146cf` stays
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@passioncode-ai/fabric-agent-adapter",
3
- "version": "0.36.0",
3
+ "version": "0.37.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.36.0",
6
+ "version": "0.37.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.36.0"
8
+ version: "0.37.0"
9
9
  contract-version: "0.1.0"
10
10
  contract-commit: "07042181bfae2a481aa0da1a5651f24c76669c48"
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.36.0"
21
+ version: "0.37.0"
22
22
  contract-version: "0.1.0"
23
23
  extension: "fabric-service/0.1"
24
24
  extension-commit: "07042181bfae2a481aa0da1a5651f24c76669c48"
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: creating-fabric-agents
3
- description: Use when designing and building a NEW agent or provider that must be Fabric-compatible from its first commit — «создай агента, совместимого с фабрикой Passion Code», «новый агент под Fabric», "create a fabric-compatible agent", "build a new Fabric provider", "fabric-ready agent from scratch". Runs the intake grill (capability, named consumer, workflow-or-agent, MCP/A2A/local-runner profile, effect declarations), distils source projects into a knowledge pack whose recorded failures become planted eval fixtures, scaffolds the pinned contract bundle, and sets the two-clock eval expectation with the conformance report. NOT for adapting an existing project (use adapting-projects-to-fabric), building the Fabric host or orchestrator, or generic agent design where Fabric compatibility is not part of the request.
3
+ description: Use when designing and building a NEW agent or provider that must be Fabric-compatible from its first commit, «создай агента, совместимого с фабрикой Passion Code», «новый агент под Fabric», "create a fabric-compatible agent", "build a new Fabric provider", "fabric-ready agent from scratch", «агент в облаке организации», "which models and OpenRouter key for a new Fabric agent". Runs the intake grill (capability, named consumer, workflow-or-agent, MCP/A2A/local-runner profile, effect declarations, where it runs, models, who pays, how it learns), distils source projects into a knowledge pack whose recorded failures become planted eval fixtures, scaffolds the pinned contract bundle, and sets the two-clock eval expectation with the conformance report. NOT for adapting an existing project (use adapting-projects-to-fabric), building the Fabric host or orchestrator, or generic agent design where Fabric compatibility is not part of the request.
4
4
  license: AGPL-3.0-only OR LicenseRef-PassionCode-Commercial
5
5
  compatibility: Requires filesystem access and Python 3.9+. Exact schema checks additionally need git, Node.js, pnpm, and the pinned fabric-agent-contract checkout (a public repository). Works without those tools in an explicitly degraded structural-check mode. Ships in one plugin with adapting-projects-to-fabric, whose scripts it reuses.
6
6
  metadata:
7
7
  author: PassionCode.ai
8
- version: "0.36.0"
8
+ version: "0.37.0"
9
9
  contract-version: "0.1.0"
10
10
  contract-commit: "07042181bfae2a481aa0da1a5651f24c76669c48"
11
11
  ---
@@ -52,7 +52,10 @@ No file is created until every row has an answer. An answer of "later" fails the
52
52
  | **Workflow or agent?** | if every step can be named now, build a deterministic workflow behind the capability and skip the autonomy — an agent buys flexibility with latency, cost, and a new failure class, and that price needs a reason |
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
- | **Which tenancy?** | record whether the agent assumes one operator; the assumption is cheap to write down and expensive to excavate |
55
+ | **Where does it run, for whom?** | this machine, the person's cloud or an organization's, and in which contexts (`personal`, `org:<id>`): one instance per context, its secrets, spend and journal never crossing into another. Record which capabilities need the person's machine and what they answer when it is off (references/where-agents-run.md) |
56
+ | **Which models?** | per lane (planning, replies, volume work, media): a primary, a fallback of another vendor, an open-vendor model where it reads what users send, the input kinds each reads, declared as classes in the profile (references/models-and-providers.md) |
57
+ | **Who pays?** | one key per agent and context with its own ceiling, from the estate's key manager, read from the environment; checked before every call; a personal key never pays for an organization |
58
+ | **How does it learn?** | decisions recorded with reasons, one trace per turn, every failure a planted fixture first, history replayed, learnings proposed and never self-approved (references/orchestration-and-learning.md) |
56
59
  | **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*) |
57
60
 
58
61
  ## Step 1 — the knowledge intake
@@ -73,6 +76,20 @@ Skipping this step because there is no prior art is legal; skipping it because r
73
76
  is slower than generating is how the same collector truncates at the same row limit
74
77
  twice.
75
78
 
79
+ Every new agent also starts from what the estate already learned, whether or not it has
80
+ prior art of its own:
81
+
82
+ - [practices.md](references/practices.md): the rules production agents taught us, each with
83
+ the check that catches it (judges and evals, numbers, money, people in the loop,
84
+ reliability, shipping). Organization members also read the knowledge base's
85
+ `knowledge/agent-practices.md` and add to it what this agent learns.
86
+ - [where-agents-run.md](references/where-agents-run.md): this machine, a personal cloud, an
87
+ organization; contexts; connecting a machine; sharing into an organization; selling.
88
+ - [models-and-providers.md](references/models-and-providers.md): lanes, a starting model
89
+ choice, several kinds of input and output, budgets, OpenRouter keys.
90
+ - [orchestration-and-learning.md](references/orchestration-and-learning.md): the work graph,
91
+ calling other agents, stops for a person, learning loops, the loop guard.
92
+
76
93
  ## Step 2 — the project skeleton
77
94
 
78
95
  Create the minimal project: repository, `README.md` naming the capability and its
@@ -0,0 +1,105 @@
1
+ # Models and providers: which model for which lane, and how it is paid
2
+
3
+ An agent has lanes: the part that plans and calls tools, the part that writes to a person, the part that classifies a
4
+ thousand items a day, the part that reads an image. Each lane gets its model on purpose, a fallback from another vendor,
5
+ and a budget that survives a verbose model. Most agents reach models through OpenRouter, one key per agent.
6
+
7
+ Normative rules: the Fabric Agent Contract's `runners.md` (*Runner and model profiles*, DEC-0046: model classes, the
8
+ resolution order request > agent > binding > policy), DEC-0083 (a lane that reads user content runs on an open-vendor
9
+ model, FAC-SEM-112) and `openrouter-attribution.md` (FAC-SEM-098). The kit that resolves profiles is
10
+ `building-fabric-services/scripts/fabric_profiles.py` (references/profiles.md there).
11
+
12
+ ## Contents
13
+
14
+ - [Lanes, not one model](#lanes-not-one-model)
15
+ - [A starting choice](#a-starting-choice)
16
+ - [Several kinds of input and output](#several-kinds-of-input-and-output)
17
+ - [Ids, budgets and deadlines](#ids-budgets-and-deadlines)
18
+ - [OpenRouter: one key per agent](#openrouter-one-key-per-agent)
19
+ - [Measuring a choice](#measuring-a-choice)
20
+ - [The checklist](#the-checklist)
21
+
22
+ ## Lanes, not one model
23
+
24
+ - **Big model where it pays, light model where volume is.** The strongest model for low-volume reasoning: an agent
25
+ that plans and calls tools, research, a judge. A light, cheap model for high-volume work: classification,
26
+ extraction to JSON, reranking, summaries, periodic jobs, routine chat.
27
+ - **Every lane has a fallback from another vendor** (the prefix before `/` differs), and the config loader refuses a
28
+ profile without one. One vendor's outage or policy change must not take the whole agent down.
29
+ - **A lane that reads what users send runs on an open-vendor model** as its primary, or as its fallback when the
30
+ primary is closed (DEC-0083: declare `reads: ["user-content"]` on the profile; FAC-SEM-112 refuses a route without
31
+ one). Closed vendors refuse or hedge on whole topics; the lane must still handle the worst message it receives.
32
+ - **A judge is another vendor than the writer.** A model grading its own family rates its own habits.
33
+ - **Declare classes, not names, in the agent's profile** (`modelClasses`): the policy and the binding narrow them, and
34
+ the host resolves the model. A hard-coded model name in code is a release to change it.
35
+
36
+ ## A starting choice
37
+
38
+ As of 2026-10, all on OpenRouter, ordered from strongest to lightest. Prices and modalities change: read the catalog
39
+ (`GET https://openrouter.ai/api/v1/models`, `architecture.input_modalities`, `pricing`) before you rely on them.
40
+
41
+ | Model | Input | Good for |
42
+ |---|---|---|
43
+ | `xiaomi/mimo-v2.6-pro` | text, image, video, audio | an agent that plans and calls tools; replies to people; video and audio input |
44
+ | `anthropic/claude-haiku-5.5` | text, image, file | code generated inside a product, internal tasks; test it on your users' topics before a reply lane |
45
+ | `google/gemini-3.8-flash` | text, image, video, file, audio | audio and video input; costs more per token |
46
+ | `qwen/qwen3.8-flash` | text, image, video | a fallback of another vendor for short answers |
47
+ | `deepseek/deepseek-v4.1-flash` | text, image | classification, extraction, triage, periodic jobs, reading screenshots; always the newest `-flash`, never `-pro` |
48
+
49
+ Embeddings, speech to text and text to speech are separate choices: keep the one measured on your data, and never
50
+ change an embedding model without re-indexing every stored vector (search silently turns into noise).
51
+
52
+ ## Several kinds of input and output
53
+
54
+ - **Input.** A model's name does not tell you what it reads: check `input_modalities` in the catalog. Send the medium
55
+ itself (an image, an audio clip) to a model that reads it, rather than a description another model wrote.
56
+ - **A checker that cannot see a medium must not judge it.** A text-only judge refuses an audio or image candidate
57
+ instead of scoring its file name.
58
+ - **Generated media** (images, video, voice, music, 3D) go through one media service that picks the provider, records
59
+ the cost and keeps the original, not through provider SDKs scattered across the agent. Check the input against the
60
+ provider's limits (media type, length, size) before a paid stage.
61
+ - **Long documents** translated or rewritten in one call come back cut off without an error: send them in sections and
62
+ check that each section's end arrived.
63
+
64
+ ## Ids, budgets and deadlines
65
+
66
+ - **Model ids are configuration**, read at start from one place; a changed default applies to new installs, and an
67
+ installed agent keeps its own until it is told.
68
+ - **Set the default per job explicitly.** Never let the order of a catalog choose it.
69
+ - **Reasoning spends the output budget.** With reasoning on and a tight `max_tokens`, a light model returns empty
70
+ content (`finish_reason: length`). Leave the budget generous, or turn reasoning off for short outputs where the
71
+ model allows it; some models refuse to turn it off.
72
+ - **An empty answer is neither a refusal nor a success.** Retry with a larger budget or the fallback; never ship it.
73
+ - **A fixed output budget must survive a verbose model**, and a deadline sized for one model times out another: count
74
+ partial and timed-out attempts per model before choosing either.
75
+ - **A probe with `max_tokens: 1` proves routing and permission, not quality.**
76
+
77
+ ## OpenRouter: one key per agent
78
+
79
+ - **Each agent spends its own key, with its own ceiling.** The key is minted for that agent (and that project) by the
80
+ estate's key manager, with a monthly limit; it is never pasted by a person into a file, a prompt or a command line.
81
+ Read it from the environment the service manager or the session gives the agent (Fabric Switchboard hands an agent
82
+ the key of the project it starts in).
83
+ - **An organization's instance spends the organization's key** under its grant; a personal key never pays for an
84
+ organization's work.
85
+ - **Check every attempt against the ceiling before it is sent,** retries included, estimating at the full output
86
+ budget; record the actual cost each call returns (`usage: {include: true}`).
87
+ - **Show spend.** An agent's interface shows spend per day, per provider and per model for 30 days; spend nobody sees
88
+ is spend nobody controls.
89
+ - **Unknown cost is `null`, never 0** (DEC-0087, `fabric-interop/0.2`).
90
+ - **Attribution is off by default.** A product may send OpenRouter's attribution headers only with its operator's
91
+ setting and only for requests it originates (FAC-SEM-098); an agent a user built keeps the user's own.
92
+
93
+ ## Measuring a choice
94
+
95
+ Choose a model on the agent's own real inputs, under its own key: a set of real cases (including the worst ones it
96
+ will see), a score the code computes where it can, a judge of another vendor where it cannot, the date and the key
97
+ scope recorded next to the default. Re-run it when you change the model, the prompt or the provider.
98
+
99
+ ## The checklist
100
+
101
+ - Each lane: primary, fallback of another vendor, open-vendor where it reads user content, a declared class.
102
+ - Each lane's input modalities checked in the catalog; media generation through one media service.
103
+ - Budgets that survive reasoning; empty answers retried, never shipped.
104
+ - One key per agent and context, read from the environment, with a ceiling checked before every call.
105
+ - The choice measured on real inputs, recorded with its date.
@@ -0,0 +1,100 @@
1
+ # Orchestration and learning: how the agent works, and how it gets better
2
+
3
+ An agent is a loop: it takes work, plans, calls tools or other agents, stops for a person where it must, finishes or
4
+ fails honestly, and learns from what happened. This page is the design of that loop. The agent's internal loop (tool
5
+ calls, routing, memory, sub-agents) is designed in depth with `agent-orchestrator`, and its evals with `agent-evals`
6
+ (agent-stack); this page is what a Fabric agent must get right whichever way it is built.
7
+
8
+ Normative rules: the Fabric Agent Contract's `interop.md` (jobs, *Limits and uncertain effects*, DEC-0087),
9
+ `pipeline.md` (`pipeline/0.1`), `memory-and-learning.md` (proposals, retrospectives, the loop guard) and
10
+ `delegation.md` (grants and spend when one agent calls another).
11
+
12
+ ## Contents
13
+
14
+ - [Workflow first, autonomy where it pays](#workflow-first-autonomy-where-it-pays)
15
+ - [The work graph](#the-work-graph)
16
+ - [Calling other agents](#calling-other-agents)
17
+ - [Stops for a person](#stops-for-a-person)
18
+ - [Learning loops](#learning-loops)
19
+ - [The loop guard](#the-loop-guard)
20
+ - [The checklist](#the-checklist)
21
+
22
+ ## Workflow first, autonomy where it pays
23
+
24
+ If every step can be named, build a deterministic workflow behind the capability; let a model decide only where the
25
+ input really varies (the intake grill's *Workflow or agent?*). An orchestrator is the part that owns the plan: it cuts
26
+ work into steps, routes each to the cheapest lane that can do it (models-and-providers.md), runs independent steps in
27
+ parallel, and is the only part that decides to retry, wait, ask a person or give up.
28
+
29
+ ## The work graph
30
+
31
+ - **Every step is a durable job** with a stable id that survives a restart (`fabric-interop/0.1` jobs; the kit's
32
+ `JobStore`). A step's state lives on disk, not in a process's memory.
33
+ - **Every step has an idempotency key derived from its intent**, never a clock or a random value
34
+ (`intent_idempotency_key({agentId, capability, input})`): a resend after a restart is the same request.
35
+ - **Effects run once.** A step that pays, sends or publishes records its intent before the call and its observed
36
+ result after; when the answer was lost it ends `outcome-unknown` and is reconciled by observing, never re-run under
37
+ a new key.
38
+ - **Limits are pauses, not failures.** A provider quota that will reset keeps the job `working` with
39
+ `quota-exhausted until <instant>`; one that needs a person ends `quota-exhausted` with `retryable: false`
40
+ (`jobs.pause`, `jobs.quota_exhausted`).
41
+ - **The caller acts on each answer as `job_caller_action` says**: poll, wait until, answer a question, resend under the
42
+ same key, ask a person, reconcile. It never "submits anew".
43
+ - **Count what is unknown.** A step whose cost, tokens or outcome nobody measured reports `null` and names it.
44
+
45
+ ## Calling other agents
46
+
47
+ - Call another agent's capability through Fabric, never its keys or its database. Its spend is metered under the grant
48
+ you hold; a child call can only narrow scope, effects, data, deadline and depth, never widen them.
49
+ - Hold a finite budget for the whole parent operation and allocate children within it; a child whose financial outcome
50
+ is unknown keeps its share reserved.
51
+ - A child that is unavailable answers with an explicit denial; never fall back to a privileged account to get it done.
52
+ - Record parent and child ids, so one operation can be followed end to end; refuse cycles.
53
+
54
+ ## Stops for a person
55
+
56
+ - **Show who decides each stop.** The person's queue holds only the person's stops; an agent's own decisions are
57
+ recorded, not queued for approval.
58
+ - **An approval holds the work, it does not refuse it.** Work above an approval line waits with its estimate and an
59
+ approval request, and resumes the moment it is granted.
60
+ - **An agent never approves its own spend**, its own proposal, or its own acceptance checker.
61
+ - **A promise of a person is a handoff.** If a reply says "a person will get back to you", the agent opens the handoff
62
+ that makes it true.
63
+ - **Tell the person once per change.** A message to an operator goes out for a failure that lasts, for money, or for a
64
+ decision only they can make; one case once, the same case never repeated.
65
+
66
+ ## Learning loops
67
+
68
+ An agent gets better only through loops that are recorded and checked, never by rewriting itself in place:
69
+
70
+ 1. **Record every decision with its reason**: the option chosen, the ones passed over, and why. This is what a review,
71
+ a retrospective and the next model read.
72
+ 2. **Keep one trace id per turn** with its model calls, tools, cost and outcome, stored where it outlives the
73
+ platform's own logs.
74
+ 3. **Turn every failure into a check before it is fixed**: a planted fixture with the exact defect, watched failing,
75
+ then the fix. A known defect not yet fixed is an expected-failure test that names its backlog row.
76
+ 4. **Replay the real history** through the current agent before calling a change right; evals hold the questions you
77
+ thought of, the history holds the ones users asked.
78
+ 5. **Propose, never self-approve.** A learning (goal, failed attempt, verified correction, cause, evidence, scope,
79
+ proposed change) is a proposal to the project's memory; a person or an independent check promotes it. It never
80
+ changes the running revision or its own checker (`memory-and-learning.md`).
81
+ 6. **Share what generalises.** A practice that held in two projects becomes a lesson other agents find (practices.md);
82
+ a practice in one project stays in its own knowledge pack.
83
+
84
+ Memory is cited, bounded and scoped: a retrieval names the revisions it used, absence of a result is not proof of
85
+ absence, and project memory never crosses into another context.
86
+
87
+ ## The loop guard
88
+
89
+ Count entries per stage and hypothesis. A third entry into the same stage with the same hypothesis stops the step as
90
+ `loop-guarded`; it resumes only with a changed hypothesis, dependency, plan or a person's decision. Switching the
91
+ model, the runtime or the account does not reset a logic loop.
92
+
93
+ ## The checklist
94
+
95
+ - Each step: a durable job, a key derived from its intent, its effect recorded before and observed after.
96
+ - Limits paused or stopped with `quota-exhausted`; lost answers `outcome-unknown`; callers act as `job_caller_action`.
97
+ - Child calls through Fabric, within the parent's budget and narrower grant.
98
+ - The person's queue holds only their stops; no self-approval.
99
+ - Decisions with reasons, one trace per turn, failures turned into fixtures, history replayed, learnings proposed.
100
+ - A loop guard on every stage.
@@ -0,0 +1,103 @@
1
+ # Practices that agents in production taught us
2
+
3
+ Each rule below was learned from a measured failure of a real agent, and each names the check that now catches it.
4
+ Read it before you design an agent's judge, model choice, spend or stops, and again before you call the agent
5
+ finished. Organization members have the full page with every receipt: the PassionCode knowledge base,
6
+ `knowledge/agent-practices.md` in fabric-workspace (add yours there, under its lease, by pull request).
7
+
8
+ ## Contents
9
+
10
+ - [Judges and evals](#judges-and-evals)
11
+ - [Numbers and data](#numbers-and-data)
12
+ - [Money](#money)
13
+ - [People in the loop](#people-in-the-loop)
14
+ - [Reliability](#reliability)
15
+ - [Shipping](#shipping)
16
+
17
+ ## Judges and evals
18
+
19
+ - **A judge passes nothing until it has failed planted bad output.** Write fixtures with known defects (an invented
20
+ fact, a missing citation, a wrong number) and watch the judge fail each one. Check: a fixture suite that must fail.
21
+ - **Code-proven defects veto the model's score.** What a program can prove (a citation id missing from the sources, a
22
+ quote not found in its source) fails the output whatever the model judge said.
23
+ - **The judge is another vendor than the writer.**
24
+ - **In-sample fixtures prove the checks, not the calibration.** Calibrate a judge on cases it was not written with.
25
+ - **A checker reads what the drafter read**, with the time of each input; a checker that sees newer data than the
26
+ drafter marks correct answers wrong.
27
+ - **A close score is not a verdict.** Scores drift run to run even at temperature 0; set the pass line with a margin
28
+ measured on repeated runs.
29
+ - **A judge that cannot answer is an error, not a pass**, and a verdict missing a required field is no verdict; never
30
+ fill it with a default.
31
+ - **A judge that cannot see a medium refuses it.**
32
+ - **A judge without the agent's material must not judge facts**: it calls real features invented.
33
+ - **Read a sample of a new judge's failures before reporting its rates.**
34
+ - **A model judge not yet calibrated speaks as advice beside the verdict**, and its misses raise no alert until a person
35
+ has calibrated that check.
36
+ - **A green full suite is not certification.** Before a release, independent readers take the diff (the unit, what
37
+ reaches it, what the docs and users see).
38
+ - **Watch a new negative assertion fail before you trust it**: remove the fix, run the test, keep the failing run.
39
+ - **Replay the real history before calling it right.**
40
+
41
+ ## Numbers and data
42
+
43
+ - **What was not measured is "not measured", never 0.** Payloads name their unmeasured fields; a missing number is
44
+ `null`.
45
+ - **The answering model states numbers from the facts; it never works them out.** Totals, savings and percentages are
46
+ computed by code and handed to the model.
47
+ - **The producer's schema is the consumer's test fixture, pinned to a commit.**
48
+ - **Over an open vocabulary, list what may stand, never what may not.** A deny-list over free text misses the next
49
+ variant.
50
+ - **Re-pin a golden output only with the measured diff.**
51
+ - **Budget a checker's context from what the runner really sends**, and a context budget that drops content says what
52
+ it dropped.
53
+ - **Deleting a source item removes it from every stored derived artifact** (reports, summaries, caches).
54
+
55
+ ## Money
56
+
57
+ - **Check every attempt against the cap before it is sent, retries included.**
58
+ - **Each agent spends its own key, with its own ceiling**; never another agent's key, never a person's personal key for
59
+ an organization's work.
60
+ - **Spend that is not shown is spend nobody controls.**
61
+ - **A recorded status is not proof of payment**: act on money only after the payment provider or the chain confirms it.
62
+ - **The paid call sends exactly the spec its recorded intent names.**
63
+ - **A test run never holds a route to a paid key** unless the test hands it one.
64
+ - **An agent cannot approve its own spend.**
65
+
66
+ ## People in the loop
67
+
68
+ - **Count what a channel to a person actually sends** before trusting its rules; a notifier that sends a hundred
69
+ messages a day is ignored.
70
+ - **Show who decides each stop**, and keep the person's queue to the person's stops.
71
+ - **An approval holds the work; it does not refuse it.**
72
+ - **Record every agent decision with its reason.**
73
+ - **A fallback sent instead of a rejected reply must stand alone**, and never append a fixed text in one language to a
74
+ reply in another.
75
+ - **An answer that promises a person is a handoff, or nobody comes.**
76
+ - **A watcher gives the agent its own latency before it calls a person.**
77
+ - **A pause a person makes survives the agent's own sync.**
78
+ - **Response-time targets are per channel**: a private chat in seconds, mail in hours, store reviews in a day.
79
+ - **Text for people carries no em dash (U+2014)**, held by the prompt and a test (resilience-and-autonomy.md).
80
+
81
+ ## Reliability
82
+
83
+ - **One empty answer is evidence of absence, not a broken run**; an empty answer from a free provider hands the request
84
+ to the next provider.
85
+ - **Check inputs against the provider's contract before a paid stage.**
86
+ - **A step sent back for a fix continues its own session.**
87
+ - **Health names output that should have reached a person and has not.**
88
+ - **Every start sweeps the liveness markers of processes that are gone.**
89
+ - **A shared run gate holds its lock for the whole command**, never check-then-release.
90
+ - **Never source a service's env file in a shell.**
91
+ - **A log sink never fails a call.**
92
+ - **Parallelism is tested by counting overlapping work, not by the clock.**
93
+ - **A reply agent never sends the same reply twice in a row.**
94
+ - **Do not trust a hosted CI schedule to start; wake the workflow by a push**, and check that it ran.
95
+
96
+ ## Shipping
97
+
98
+ - **A release smoke goes through the code the change touched**, not a version flag.
99
+ - **A deploy is accepted on the bytes it serves**, hashed against the build, not on the deploy command's exit.
100
+ - **Measure a size budget on a build from the commit you ship.**
101
+ - **A changed default model is not a changed installed agent.**
102
+ - **Start a long verification suite only above a disk floor.**
103
+ - **Agents that number rows in one register need a gate that fails on a duplicate id.**
@@ -0,0 +1,112 @@
1
+ # Where an agent runs: this machine, a personal cloud, an organization
2
+
3
+ An agent built with this skill can run on the person's own machine, in their personal cloud, or in an organization's
4
+ cloud, and the same agent can serve the person and several organizations at once. Decide where it runs at the intake
5
+ grill (*Where does it run?*), because it decides where its secrets live, who pays for its calls, whose journal records
6
+ it, and what happens when the person's laptop is closed.
7
+
8
+ The normative rules are the Fabric Agent Contract's, at the commit this plugin pins: `docs/specification/contexts.md`
9
+ (contexts), `estate-record.md` (machines and placements), `share-registration.md` (sharing into an organization),
10
+ `entitlement.md` (what an order entitles), `ceremonies.md` (adding a machine). This page says how to design for them.
11
+
12
+ ## Contents
13
+
14
+ - [The places](#the-places)
15
+ - [Contexts: one agent, the person and each organization](#contexts-one-agent-the-person-and-each-organization)
16
+ - [Connecting a machine or a cloud to the estate](#connecting-a-machine-or-a-cloud-to-the-estate)
17
+ - [Sharing an agent into an organization](#sharing-an-agent-into-an-organization)
18
+ - [Running while the laptop is closed](#running-while-the-laptop-is-closed)
19
+ - [Selling an agent](#selling-an-agent)
20
+ - [The checklist](#the-checklist)
21
+
22
+ ## The places
23
+
24
+ | Where | What it is | Typical agent |
25
+ |---|---|---|
26
+ | **This machine** | the person's computer, Fabric and its services local; free and open source | a coding helper, a personal assistant that may stop when the laptop sleeps |
27
+ | **Personal cloud** | the person's own always-on machine in PassionCode's cloud (or the same stack self-hosted), one more machine of their estate | an agent that answers mail at night, a scheduled digest, a bot |
28
+ | **Organization** | the organization's cloud, its members' machines enrolled into it, its own server holding members, grants and usage | a support agent, an internal analyst, an agent the organization bought |
29
+ | **Enterprise** | an organization's dedicated cloud with personal onboarding | the same agents under the enterprise's own boundary |
30
+
31
+ Every step up is paid as cloud only: the person or the organization pays for the cloud its agents run in, and the
32
+ order says which hosting it holds (`personal-cloud`, `org-cloud`, `enterprise-cloud` in `entitlement/1`). An agent never
33
+ checks a price; it may read whether its context's entitlement is current and degrade honestly when it is not.
34
+
35
+ ## Contexts: one agent, the person and each organization
36
+
37
+ A context is `personal` or `org:<orgId>`, compared exactly as written. Design every agent as if it will run in more
38
+ than one:
39
+
40
+ - **One instance per context.** On a machine an agent runs once per (agent, context). The personal instance and an
41
+ organization's instance are two instances with two state folders, two journals and two sets of secrets; never one
42
+ process that switches. In the estate record a placement names its `context`, and an organization's placement names
43
+ the share grant it runs under (FAC-SEM-074, FAC-SEM-111).
44
+ - **Secrets stay in their context.** An organization's instance fills its secret slots from the organization's own
45
+ machine and vault; a personal secret never reaches it, and the person's personal keys never pay for organization
46
+ work.
47
+ - **Spend and usage stay in their context.** Every call is metered under the grant it runs under; the organization
48
+ sees its instance's usage (`grant.usage`) and nothing of the person's personal work.
49
+ - **Contexts are never linked.** Nothing the agent sends to one organization names the person's personal context or
50
+ another organization: no shared ids, no shared logs, no "also used by" field.
51
+ - **Access is the grant, not a label.** What an organization's instance may do is its grant's capabilities, effect
52
+ ceiling, data classes, spend windows and expiry. A named level ("read only") is a preset that fills those fields.
53
+
54
+ ## Connecting a machine or a cloud to the estate
55
+
56
+ A person's machines form their estate; an estate record signed with the person's passkey lists every machine, its
57
+ keys, and what runs where. A new machine joins only when a passkey-signed revision lists it:
58
+
59
+ - **Nearby** (a laptop, a phone): the two machines show the same six-digit comparison code; the person confirms it.
60
+ - **Headless** (a cloud machine, a server): Fabric issues an `enroll-token/1`, valid for at most 15 minutes and one use.
61
+ The machine reads it from stdin or a file only its user can read, never from a command-line argument, a URL or a
62
+ log, proves its key with it, and waits until the revision that lists it is signed. The token gives no trust by
63
+ itself. The kit's `fabric_ceremonies.py` checks a token (building-fabric-services, *The estate ceremonies*).
64
+ - **An organization's machine** enrolls into the organization's server: a device certificate names the organization
65
+ (`org.id`), and the machine's collector routes each context's events only to the server of that context.
66
+
67
+ Removing a machine or replacing its key is a revision that revokes what it drops in the same revision (FAC-SEM-114).
68
+ An agent service that applies the estate record verifies each revision with its parent before trusting it.
69
+
70
+ ## Sharing an agent into an organization
71
+
72
+ The person's own agent can work for an organization without being copied into it:
73
+
74
+ 1. Fabric writes a **share grant** into the organization: `context: org:<orgId>`, id `urn:fabric:share:` and 32 random
75
+ hex digits, one agent (`agentRef`) for its whole life, a window, the capabilities and spend the organization may
76
+ use. Moving the share to another agent revokes the grant and mints a new id.
77
+ 2. The person's node sends the organization a **share registration**, so its server knows which agent the grant runs.
78
+ 3. The instance placed in that context runs under the grant; its daily `grant.usage` goes to the organization's
79
+ server, carrying the grant's own context.
80
+
81
+ The kit checks the grant and the usage event (`fabric_share.py`). Revoking the grant stops calls at once where they are
82
+ checked, and removes the instance from the next revision.
83
+
84
+ ## Running while the laptop is closed
85
+
86
+ A cloud agent keeps working with the laptop closed only if everything it needs is in the cloud: its worker, its
87
+ secrets, its data, and a hub that can admit calls. The local Fabric hub is not a cloud hub. Design for it:
88
+
89
+ - Declare what each capability needs and where it is; a capability that needs the person's machine reports
90
+ `pending` or `unavailable` instead of pretending, and queues within a deadline or declines.
91
+ - Never charge for work it cannot deliver on the promised terms.
92
+ - A test that passed on fixtures says nothing about uptime; measure the installed agent in its cloud.
93
+
94
+ ## Selling an agent
95
+
96
+ - **A paid agent** runs in PassionCode's cloud inside its developer's organization (`org:<developer>`); each customer
97
+ organization reaches it through its own credential, which is the credential of an external grant, metered per
98
+ customer. The developer sets the price; the platform earns the cloud.
99
+ - **A partner** builds agents for a company and delivers them as a setup: each agent its own signed package, and one
100
+ organization skill set that requires them, all signed with the partner's key (building-fabric-services, *package*,
101
+ *A partner's setup for a company*). The company pays for the cloud; the partner's own work is between them.
102
+ - Whatever is sold: one signed `fabric-package/1` per version, no secret in it, every effect declared, and the agent's
103
+ spend under the customer's grant, never under the developer's personal key.
104
+
105
+ ## The checklist
106
+
107
+ - Where does each instance run, and in which context? Write it in the knowledge pack.
108
+ - Does any state, secret, log line or cache key cross contexts? It must not.
109
+ - Which capabilities need the person's machine, and what do they answer when it is off?
110
+ - Who pays for each call (which grant, which key)? The person's personal key never pays for an organization.
111
+ - If it joins machines or applies the estate record: tokens from stdin or a 0600 file only, revisions verified with
112
+ their parent.
@@ -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.36.0"
22
+ version: "0.37.0"
23
23
  ---
24
24
 
25
25
  # Working with Fabric
@@ -66,7 +66,7 @@ WATCH_MAX_BACKOFF_S = 900
66
66
  SESSION_ID = re.compile(r"[A-Za-z0-9._:-]{1,128}")
67
67
  LOOPBACK_ORIGIN = re.compile(r"http://127\.0\.0\.1:(\d{1,5})")
68
68
  LOCAL_ORIGIN = re.compile(r'"origin": "http://(?:127\.0\.0\.1|localhost)')
69
- VERSION = "0.36.0"
69
+ VERSION = "0.37.0"
70
70
  HOSTS = {"claude": "Claude Code", "codex": "Codex", "kimi": "Kimi Code",
71
71
  "hermes": "Hermes", "opencode": "OpenCode", "openclaw": "OpenClaw", "pi": "Pi"}
72
72
  NATIVE_PLUGIN_HOSTS = frozenset(("hermes", "opencode", "openclaw", "pi"))