@passioncode-ai/passioncode 0.2.49 → 0.2.51

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 (34) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +12 -0
  3. package/SECURITY.md +3 -0
  4. package/bin/passioncode.js +12 -4
  5. package/family.json +1 -1
  6. package/lib/doctor.js +118 -16
  7. package/lib/releases.js +59 -7
  8. package/lib/setup.js +77 -10
  9. package/lib/trains.js +38 -0
  10. package/package.json +2 -1
  11. package/payload/.claude-plugin/marketplace.json +2 -2
  12. package/payload/manifest.json +8 -8
  13. package/payload/plugins/fabric-agent-adapter/.claude-plugin/plugin.json +1 -1
  14. package/payload/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/SKILL.md +3 -3
  15. package/payload/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/references/provider-entry.md +18 -7
  16. package/payload/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/scripts/adapt_project.py +2 -2
  17. package/payload/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/scripts/fabric_provider.py +25 -5
  18. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/SKILL.md +2 -2
  19. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/delegation.md +3 -1
  20. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/interop.md +5 -1
  21. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/protocol.md +5 -3
  22. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-actions.mjs +2 -1
  23. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-protocols.mjs +5 -3
  24. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_actions.py +2 -1
  25. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_protocols.py +4 -2
  26. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/kit.json +95 -5
  27. package/payload/plugins/fabric-agent-adapter/skills/creating-fabric-agents/SKILL.md +3 -3
  28. package/payload/plugins/fabric-agent-adapter/skills/creating-fabric-agents/references/agents-that-answer-people.md +11 -5
  29. package/payload/plugins/fabric-agent-adapter/skills/working-with-fabric/SKILL.md +9 -9
  30. package/payload/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/fabric_session_env.py +1 -1
  31. package/payload/plugins/passioncode/.claude-plugin/plugin.json +1 -1
  32. package/payload/plugins/passioncode/hooks/session-start.js +3 -1
  33. package/payload/plugins/passioncode/skills/setting-up-passioncode/SKILL.md +4 -0
  34. package/trains/organization-r1.json +13 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@passioncode-ai/passioncode",
3
- "version": "0.2.49",
3
+ "version": "0.2.51",
4
4
  "description": "Set up PassionCode.ai on a computer with one command — the apps from their verified releases, their MCP servers for every coding agent and the PassionCode.ai skills — and check and repair it with the same command or `doctor`.",
5
5
  "bin": {
6
6
  "passioncode": "bin/passioncode.js"
@@ -10,6 +10,7 @@
10
10
  "lib",
11
11
  "payload",
12
12
  "family.json",
13
+ "trains",
13
14
  "README.md",
14
15
  "LICENSE",
15
16
  "COMMERCIAL-LICENSE.md",
@@ -11,7 +11,7 @@
11
11
  "name": "fabric-agent-adapter",
12
12
  "displayName": "Fabric Agent Adapter",
13
13
  "source": "./plugins/fabric-agent-adapter",
14
- "version": "0.56.0",
14
+ "version": "0.57.0",
15
15
  "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.",
16
16
  "author": {
17
17
  "name": "PassionCode.ai",
@@ -35,7 +35,7 @@
35
35
  "name": "passioncode",
36
36
  "displayName": "PassionCode.ai",
37
37
  "source": "./plugins/passioncode",
38
- "version": "0.2.49",
38
+ "version": "0.2.51",
39
39
  "description": "Set up and check PassionCode.ai on a computer with one command (setting-up-passioncode), the organisation's working rules for every contributor's agent (working-in-passioncode), and a once-a-day check that keeps the PassionCode.ai set current.",
40
40
  "author": {
41
41
  "name": "PassionCode.ai",
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "family": "passioncode",
3
- "version": "0.2.49",
3
+ "version": "0.2.51",
4
4
  "release": true,
5
5
  "members": [
6
6
  {
7
7
  "name": "fabric-agent-adapter",
8
8
  "displayName": "Fabric Agent Adapter",
9
9
  "repo": "passioncode-ai/fabric-agent-adapter",
10
- "ref": "v0.56.0",
11
- "commit": "250d5d7a18980bacdfc7ba3bb449794995d4c07d",
12
- "version": "0.56.0",
10
+ "ref": "v0.57.0",
11
+ "commit": "d34fd4691e89372166b517b5c91a29e8c1ba044a",
12
+ "version": "0.57.0",
13
13
  "via": "clone of https://***@github.com/passioncode-ai/fabric-agent-adapter.git",
14
14
  "skills": [
15
15
  "adapting-projects-to-fabric",
@@ -23,7 +23,7 @@
23
23
  "legacyMarketplaces": [
24
24
  "fabric-agent-adapter"
25
25
  ],
26
- "contentHash": "sha256:a27c7b99d9b29039b28aea11680bf1acce43a6c7792b8e80b16310559d424856",
26
+ "contentHash": "sha256:73bc07b767fef71b5e6a09566e73e2536ac45992d7bfeb2f8f00c45bcd682019",
27
27
  "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.",
28
28
  "author": {
29
29
  "name": "PassionCode.ai",
@@ -62,9 +62,9 @@
62
62
  "name": "passioncode",
63
63
  "displayName": "PassionCode.ai",
64
64
  "repo": "passioncode-ai/passioncode",
65
- "ref": "v0.2.49",
65
+ "ref": "v0.2.51",
66
66
  "commit": null,
67
- "version": "0.2.49",
67
+ "version": "0.2.51",
68
68
  "via": "this repository",
69
69
  "skills": [
70
70
  "setting-up-passioncode",
@@ -72,7 +72,7 @@
72
72
  ],
73
73
  "legacyPluginIds": [],
74
74
  "legacyMarketplaces": [],
75
- "contentHash": "sha256:f69e173ef90a590a533a71de1028073a785e59d917a03c1bc0516cdba17698e2",
75
+ "contentHash": "sha256:66330438761bc6a9dfea1f8b6a63751b3db8b23bbe085633739d492832312d0b",
76
76
  "description": "Set up and check PassionCode.ai on a computer with one command (setting-up-passioncode), the organisation's working rules for every contributor's agent (working-in-passioncode), and a once-a-day check that keeps the PassionCode.ai set current.",
77
77
  "author": {
78
78
  "name": "PassionCode.ai",
@@ -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.56.0",
6
+ "version": "0.57.0",
7
7
  "author": {
8
8
  "name": "PassionCode.ai",
9
9
  "url": "https://passioncode.ai/"
@@ -5,9 +5,9 @@ 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.56.0"
8
+ version: "0.57.0"
9
9
  contract-version: "0.1.0"
10
- contract-commit: "00e050ba7429c0c60261cec871779e0fd6aeeb28"
10
+ contract-commit: "3830a3353923e20f826d466610e1c479f120bec0"
11
11
  ---
12
12
 
13
13
  # Adapting projects to Fabric
@@ -76,7 +76,7 @@ Use exactly:
76
76
 
77
77
  - contract version `0.1.0`;
78
78
  - repository `https://github.com/passioncode-ai/fabric-agent-contract`;
79
- - commit `00e050ba7429c0c60261cec871779e0fd6aeeb28`.
79
+ - commit `3830a3353923e20f826d466610e1c479f120bec0`.
80
80
 
81
81
  This is the default for new bundles. When checking an issued legacy bundle, preserve its
82
82
  explicit supported lock and use that exact clean checkout. Never silently upgrade or
@@ -11,6 +11,7 @@ directory:
11
11
  |---|---|
12
12
  | macOS | `~/Library/Application Support/ai.passioncode.fabric/providers/` |
13
13
  | Linux | `${XDG_DATA_HOME:-~/.local/share}/passioncode-fabric/providers/` |
14
+ | Windows | `%LOCALAPPDATA%\passioncode-fabric\providers\` (the same root as the services folder, DEC-0032; `~\AppData\Local` when `LOCALAPPDATA` is unset) |
14
15
  | any | `FABRIC_PROVIDERS_DIR` when set |
15
16
 
16
17
  A service uses a descriptor instead (the `building-fabric-services` skill). One id is a
@@ -49,15 +50,25 @@ It refuses, with one sentence that never quotes a value:
49
50
  credential itself: a token prefix, a private key, a JWT (FAC-SEM-015: a value is
50
51
  checked by its form; name patterns apply to names);
51
52
  - what the pinned `provider.schema.json` refuses: a URL other than `http://127.0.0.1:<port>/mcp` with a port from 100
52
- to 65535, a manifest path that is not an absolute or `~/` path to `fabric-agent.json` (or is a network share, or over
53
- 1024 characters), a shell-string command, more than 32 arguments or one over 1024 characters, more than 64 env
54
- names, a `source.repository` that is not an absolute URI, an `installedAt` that is not an RFC 3339 date-time,
55
- unknown fields. The patterns are the schema's, copied (`test_provider.SchemaParityTests` compares them with a
56
- contract checkout at the pin when `FABRIC_CONTRACT_NEW` names one);
53
+ to 65535, a manifest path that is not an absolute, `~/` or `~\` path to a file named `fabric-agent.json` after
54
+ either separator (DEC-0145; or is a network share, or over 1024 characters), a shell-string command, more than 32
55
+ arguments or one over 1024 characters, more than 64 env names, a `source.repository` that is not an absolute URI, an
56
+ `installedAt` that is not an RFC 3339 date-time, unknown fields. The patterns are the schema's, copied
57
+ (`test_provider.SchemaParityTests` compares them with a contract checkout at the pin when `FABRIC_CONTRACT_NEW` names
58
+ one, as the contract job of the nightly CI does), and the reader is held to every `provider.schema.json` fixture of
59
+ the pin (`test/fixtures/contract/provider-fixtures.json`, `test_provider.ContractFixtureTests`);
57
60
  - a `source.repository` with a `user:password@` or a value shaped like a credential: it names the repository, never
58
- reaches it (since 0.49.3, as the service kit's descriptor check).
61
+ reaches it (since 0.49.3, as the service kit's descriptor check);
62
+ - a manifest whose name follows a backslash (`C:\Agents\example\fabric-agent.json`). The reader,
63
+ `validate_provider_entry`, accepts it since DEC-0145 (`MANIFEST_PATTERN`, the schema's), but a reader that has not
64
+ re-pinned to DEC-0145 refuses the entry, Fabric's registry among them (CT-192), so the writer does not emit it until
65
+ the oldest Fabric release in use reads it (the release after v0.3.15, CO-479). Write the path with `/` before the name. A manifest under the home folder
66
+ (`~/Agents/example/fabric-agent.json`) is read by every Fabric release; one with a drive letter
67
+ (`C:/Agents/example/fabric-agent.json`) only by Fabric after v0.3.15, whose registry took the repin (CO-479): v0.3.15
68
+ and earlier read only a manifest under `~/` or `/`, so not `~\` either.
59
69
 
60
- `validate` also checks that the file is named `<id>.json` (FAC-SEM-014, slug half).
70
+ `validate` also checks that the file is named `<id>.json` (FAC-SEM-014, slug half): the stem is what follows the last
71
+ `/` or `\`, on every platform (CT-193).
61
72
  From Python: `write_provider_entry(entry)`, `remove_provider_entry(id)`,
62
73
  `validate_provider_entry(entry)`, `manifest_problems(entry)`, `providers_dir()`.
63
74
 
@@ -22,10 +22,10 @@ import fabric_secrets as _secrets # noqa: E402 - the contract's credential dete
22
22
 
23
23
  CONTRACT_VERSION = "0.1.0"
24
24
  CONTRACT_REPOSITORY = "https://github.com/passioncode-ai/fabric-agent-contract"
25
- CONTRACT_COMMIT = "00e050ba7429c0c60261cec871779e0fd6aeeb28"
25
+ CONTRACT_COMMIT = "3830a3353923e20f826d466610e1c479f120bec0"
26
26
  # #region supported-contract-revisions — docs: README.md#contract-pin
27
27
  # Only this declaration may name a legacy revision in live files.
28
- SUPPORTED_CONTRACT_COMMITS = (CONTRACT_COMMIT, "1197a90dc4b57152cabcc71ad17db7559f35a27f", "e6c4fc16b415eec3190dd34d924d269405359dc9", "a3a66eb0052043847f6556348e37d34ca873a629", "52c7d798b9f4eb784eb4e29e717038a8912c759d", "2f020a696453ae299b123517f14957f6a1354379", "87d384ffce2757081b7ab227e5dad3dddd08328f", "0a4ce773c4b9e6bec40c6387eb3f988af7152c0e", "e742016dc396aa31e5a13a893489e43f15786c69", "bfa9a67aa3c6cb808c093e7d83cd59799f1ee7d0", "c55f2d5a11c9a0197e958e87212fca7ae1154769", "07042181bfae2a481aa0da1a5651f24c76669c48", "d8146cfb0a1c74fc6432284c4356bb0c864b37b5", "82e163665e156a08aa3b92e4711015582c06162c", "1636fa97262f4a26e2086572d540c2ee701e0010", "f00a7685e3861c27f7899c033fb850a145a1708f", "a046f57cf46ea9e3da57ff8ce6a3ed4d26d8774b", "fe55fc67cba1a9e34a736da7d148d4fe2a8fbfa0", "b291bf09e0a9f9fd3c16cf540832cd021203b7d1", "0cacd08b0e95b6abf131eae1206b60792138bc3c", "2eb91c00e852d9c31d804310d38fad91589fcbac", "8e49fbd5fbbf230e32c1969cd24ac3c22422f0a5", "a83bec6b47776af688402c18efec507143061f68", "52da526d7cc1e063d74c5b520dbc03d0ace15246", "78b2da018d2c4bd9ac1bde1dc3b7f1a110a175f5", "623bf61358c339cb10297807b3f024b5d9f1f327", "23f9fda4c05f8a3852246ee98d4f2adf74ed0875", "9091d3d6606b0c4b5591a38c3674356a01fd7f55", "df55c8c54a23251342a7ee57ba95642b7eb39e61", "2ce392291c6668598d12cd38327e24696b5ca15c")
28
+ SUPPORTED_CONTRACT_COMMITS = (CONTRACT_COMMIT, "00e050ba7429c0c60261cec871779e0fd6aeeb28", "1197a90dc4b57152cabcc71ad17db7559f35a27f", "e6c4fc16b415eec3190dd34d924d269405359dc9", "a3a66eb0052043847f6556348e37d34ca873a629", "52c7d798b9f4eb784eb4e29e717038a8912c759d", "2f020a696453ae299b123517f14957f6a1354379", "87d384ffce2757081b7ab227e5dad3dddd08328f", "0a4ce773c4b9e6bec40c6387eb3f988af7152c0e", "e742016dc396aa31e5a13a893489e43f15786c69", "bfa9a67aa3c6cb808c093e7d83cd59799f1ee7d0", "c55f2d5a11c9a0197e958e87212fca7ae1154769", "07042181bfae2a481aa0da1a5651f24c76669c48", "d8146cfb0a1c74fc6432284c4356bb0c864b37b5", "82e163665e156a08aa3b92e4711015582c06162c", "1636fa97262f4a26e2086572d540c2ee701e0010", "f00a7685e3861c27f7899c033fb850a145a1708f", "a046f57cf46ea9e3da57ff8ce6a3ed4d26d8774b", "fe55fc67cba1a9e34a736da7d148d4fe2a8fbfa0", "b291bf09e0a9f9fd3c16cf540832cd021203b7d1", "0cacd08b0e95b6abf131eae1206b60792138bc3c", "2eb91c00e852d9c31d804310d38fad91589fcbac", "8e49fbd5fbbf230e32c1969cd24ac3c22422f0a5", "a83bec6b47776af688402c18efec507143061f68", "52da526d7cc1e063d74c5b520dbc03d0ace15246", "78b2da018d2c4bd9ac1bde1dc3b7f1a110a175f5", "623bf61358c339cb10297807b3f024b5d9f1f327", "23f9fda4c05f8a3852246ee98d4f2adf74ed0875", "9091d3d6606b0c4b5591a38c3674356a01fd7f55", "df55c8c54a23251342a7ee57ba95642b7eb39e61", "2ce392291c6668598d12cd38327e24696b5ca15c")
29
29
  # #endregion supported-contract-revisions
30
30
  INTEROP_KEY = "https://fabric.passioncode.ai/agent-contract/extensions/interop/0.1"
31
31
  MCP_REVISION = "2026-07-28"
@@ -41,6 +41,9 @@ PROTOCOL = "fabric-provider/0.1"
41
41
  URL_PATTERN = r"^http://127\.0\.0\.1:([1-9][0-9]{2,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])/mcp$"
42
42
  LOCAL_PATH_PATTERN = "^(~[\\\\/]|/(?![\\\\/])|[A-Za-z]:[\\\\/])[^\\u0000]*$"
43
43
  LOCAL_PATH_MAX = 1024
44
+ # DEC-0145 (CT-192): the manifest is named fabric-agent.json after either separator, so a Windows path names it too. The
45
+ # schema's pattern is a search, not a whole-value match; it is applied with its `$` read as \Z (R1, below).
46
+ MANIFEST_PATTERN = r"(^|[\\/])fabric-agent\.json$"
44
47
  ARGV_MAX_ITEMS = 32
45
48
  ARGV_MAX_ITEM = 1024
46
49
  ENV_MAX = 64
@@ -55,6 +58,9 @@ _URI_PASSWORD = re.compile(r"^(?:(?:[Hh][Tt][Tt][Pp][Ss]?|[Ww][Ss][Ss]?|[Ff][Tt]
55
58
  _SECRET_REF = re.compile(r"^secret-ref:([A-Za-z0-9][A-Za-z0-9._/:@-]{0,255})\Z")
56
59
  _LOCAL_PATH = re.compile(LOCAL_PATH_PATTERN)
57
60
  _URL = re.compile(URL_PATTERN)
61
+ _MANIFEST = re.compile(MANIFEST_PATTERN[:-1] + r"\Z")
62
+ # The manifest's name after a backslash: valid since DEC-0145, but no writer emits it until every reader accepts it.
63
+ _MANIFEST_AFTER_BACKSLASH = re.compile(r"\\fabric-agent\.json\Z")
58
64
  # format: uri (RFC 3986 absolute URI): a scheme, a colon, then no whitespace or control character.
59
65
  _URI = re.compile(r"^[A-Za-z][A-Za-z0-9+.-]*:[^\s\x00-\x1f\x7f]+\Z")
60
66
  # format: date-time (RFC 3339).
@@ -89,6 +95,10 @@ def services_dir() -> Path:
89
95
  home = Path.home()
90
96
  if sys.platform == "darwin":
91
97
  return home / "Library/Application Support/ai.passioncode.fabric/services"
98
+ if sys.platform == "win32":
99
+ # provider.md "Where the directory is" (DEC-0032): LOCALAPPDATA, never the roaming APPDATA.
100
+ local = os.environ.get("LOCALAPPDATA")
101
+ return (Path(local) if local else home / "AppData" / "Local") / "passioncode-fabric" / "services"
92
102
  return Path(os.environ.get("XDG_DATA_HOME") or str(home / ".local/share")) / "passioncode-fabric/services"
93
103
 
94
104
 
@@ -128,8 +138,9 @@ def validate_provider_entry(entry: Any) -> List[str]:
128
138
  problems.append("summary is at most 200 characters")
129
139
  manifest = entry["manifest"]
130
140
  if (not isinstance(manifest, str) or len(manifest) > LOCAL_PATH_MAX or not _LOCAL_PATH.fullmatch(manifest)
131
- or not re.search(r"(^|/)fabric-agent\.json\Z", manifest)):
132
- problems.append("manifest is an absolute or ~/ path to fabric-agent.json, at most %d characters, never a network share" % LOCAL_PATH_MAX)
141
+ or not _MANIFEST.search(manifest)):
142
+ problems.append("manifest is an absolute, ~/ or ~\\ path to fabric-agent.json (the name after either separator), at most %d characters, "
143
+ "never a network share" % LOCAL_PATH_MAX)
133
144
  if "source" in entry:
134
145
  source = entry["source"]
135
146
  if not isinstance(source, dict) or not set(source) <= {"repository"}:
@@ -237,8 +248,15 @@ def _service_ids(directory: Path) -> Dict[str, str]:
237
248
  def write_provider_entry(entry: Dict[str, Any], directory: Optional[Path] = None, services: Optional[Path] = None) -> Path:
238
249
  """Installer-only. Refuses an invalid entry and an id that is already a service (FAC-SEM-013)."""
239
250
  problems = validate_provider_entry(entry)
240
- if not problems:
241
- problems = manifest_problems(entry)
251
+ if problems:
252
+ raise ProviderError("Provider entry is invalid: %s." % "; ".join(problems))
253
+ if _MANIFEST_AFTER_BACKSLASH.search(entry["manifest"]):
254
+ # provider.md (DEC-0145): a reader before DEC-0145, Fabric's registry among them, refuses this entry until it
255
+ # re-pins (CT-192), so the writer does not emit it yet.
256
+ raise ProviderError("The manifest's name follows a backslash, which a reader that has not re-pinned to DEC-0145 refuses (CT-192). "
257
+ "Write the path with / before the name: ~/.../fabric-agent.json, which every Fabric release reads, or "
258
+ "C:/.../fabric-agent.json, which Fabric reads only after v0.3.15 (its repin, CO-479).")
259
+ problems = manifest_problems(entry)
242
260
  if problems:
243
261
  raise ProviderError("Provider entry is invalid: %s." % "; ".join(problems))
244
262
  clash = _service_ids(services or services_dir()).get(entry["id"])
@@ -301,7 +319,9 @@ def main(argv: Optional[List[str]] = None) -> int:
301
319
  if args.command == "validate":
302
320
  entry = json.loads(args.path.read_text(encoding="utf-8"))
303
321
  problems = validate_provider_entry(entry)
304
- if isinstance(entry, dict) and entry.get("id") != args.path.stem:
322
+ # CT-193 (FAC-SEM-014): the stem is what follows the last / or \ and loses .json, on every platform.
323
+ stem = re.sub(r"\.json\Z", "", re.sub(r"^.*[\\/]", "", str(args.path), flags=re.S))
324
+ if isinstance(entry, dict) and entry.get("id") != stem:
305
325
  problems.append("the file name %s is not <id>.json for %s (FAC-SEM-014)" % (args.path.name, entry.get("id")))
306
326
  if not problems:
307
327
  problems = manifest_problems(entry)
@@ -14,10 +14,10 @@ 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.56.0"
17
+ version: "0.57.0"
18
18
  contract-version: "0.1.0"
19
19
  extension: "fabric-service/0.1"
20
- extension-commit: "00e050ba7429c0c60261cec871779e0fd6aeeb28"
20
+ extension-commit: "3830a3353923e20f826d466610e1c479f120bec0"
21
21
  ---
22
22
 
23
23
  # Building Fabric services
@@ -110,7 +110,9 @@ issuer's fault, `issuer-unavailable` (DEC-0045); a gate without a trusted issuer
110
110
  DEC-0121 adds three codes to the one set, each 403: `operator-decision-required` (a `relayed` action called without the
111
111
  operator's decision), `decision-invalid` (a decision for another action or object, outside its 24 hours, or malformed)
112
112
  and `human-step-required`, which carries `data.humanStep` (`sign-in`, `consent`, `payment`, `secret`,
113
- `spend-above-limit`, `passkey`) and `data.url` (an https URL or a path on the service's origin) beside `detail`.
113
+ `spend-above-limit`, `passkey`, and since DEC-0142 `comparison`: a comparison of codes between two people or the choice
114
+ to share without one; a reader pinned before DEC-0142 refuses a whole declaration that names it, and a caller that validates the refusal
115
+ against a `delegation-refusal.schema.json` pinned before DEC-0142 refuses that refusal) and `data.url` (an https URL or a path on the service's origin) beside `detail`.
114
116
  `refusal_from_action` / `refusalFromAction` turn an action decision into that refusal; a service's own fault never
115
117
  reaches the caller and reads as `unknown-state`, but for `mandate-capability-missing` (DEC-0141 MJ-1): the caller
116
118
  reads `operator-decision-required` with that `data.detail`, since no mandate covers the step and only a decision does. Since 0.51.0 the `operator-decision-required` message (free text in
@@ -161,7 +161,11 @@ dialog is one of those checks; an instruction that names the action satisfies it
161
161
  |---|---|---|
162
162
  | `none` | an act on the caller's own account: refresh, read, retry or cancel its own job | the caller's own act |
163
163
  | `relayed` | a decision on another party's proposal or draft, a send, a publish, a deletion, a spend within a limit, a restore, a policy change | the operator's act when a T0 or T1 caller carries a valid decision; else a refusal below |
164
- | `human` with `humanStep` | `sign-in`, `consent`, `payment`, `secret`, `spend-above-limit`, `passkey` (AP-4): they stay the person's | `human-step-required` with `data.humanStep` and `data.url`, the direct link to that step |
164
+ | `human` with `humanStep` | `sign-in`, `consent`, `payment`, `secret`, `spend-above-limit`, `passkey`, `comparison` (a comparison of codes between two people or the choice to share without one, DEC-0142) (AP-4): they stay the person's | `human-step-required` with `data.humanStep` and `data.url`, the direct link to that step |
165
+
166
+ Declare `comparison` only to readers at or after DEC-0142: a reader pinned before it (a 0.56.0 or older kit, Fabric
167
+ Dashboards before 0.8.9) refuses the whole declaration, every action in it, and FAC-SEM-142 then reads it as not declared. Fabric's hub reads no declaration and forwards the step unchanged
168
+ (CT-186).
165
169
 
166
170
  ```python
167
171
  server = fi.McpToolServer("example-agent", "1.0.0", jobs=jobs, authorize=gate,
@@ -1,6 +1,6 @@
1
1
  # fabric-service/0.1: wire reference
2
2
 
3
- Pinned to `fabric-agent-contract` commit `00e050ba7429c0c60261cec871779e0fd6aeeb28`
3
+ Pinned to `fabric-agent-contract` commit `3830a3353923e20f826d466610e1c479f120bec0`
4
4
  (`docs/specification/service.md`, DEC-0015; the usage report DEC-0021; Windows and Linux supervision
5
5
  DEC-0032 and DEC-0033; the operator channel DEC-0034 and DEC-0035; the embedded dashboard DEC-0036;
6
6
  delegation and the operator session's lifetime DEC-0039; the meter's call window DEC-0041; session handoff DEC-0042;
@@ -23,8 +23,10 @@ DEC-0124; the operator's mandate `mandate/1`, handed on narrowed with a task DEC
23
23
  operator's agents, its `source` on a mandate and a decision DEC-0126; context hub keys and the organizations an estate
24
24
  record pins DEC-0127 and DEC-0128; the family and the agent network named DEC-0130 and DEC-0137; a reply delivered to
25
25
  the sender it answers, or to whom it names DEC-0135; a hand-over adds no naming list the scope in force leaves out
26
- DEC-0136; a job's step under the mandate read under the job's own capability DEC-0141. The organization's member list, draft exchange, relay and the machines' report, DEC-0129, DEC-0131 to DEC-0134,
27
- reach the kit only as protocol register entries). The contract's schemas are normative;
26
+ DEC-0136; a job's step under the mandate read under the job's own capability DEC-0141; a person's comparison of codes as a human
27
+ step DEC-0142. The organization's member list, draft exchange, relay and the machines' report, DEC-0129, DEC-0131 to
28
+ DEC-0134 and DEC-0139, an organization's adaptation DEC-0138 and the peer share DEC-0142, reach the kit only as
29
+ protocol register entries). The contract's schemas are normative;
28
30
  this page is the working summary. Extension key:
29
31
  `https://fabric.passioncode.ai/agent-contract/extensions/service/0.1`.
30
32
 
@@ -37,7 +37,8 @@ export const DECISION_INVALID = 'decision-invalid';
37
37
  export const HUMAN_STEP_REQUIRED = 'human-step-required';
38
38
  export const APPROVAL_REQUIRED = 'approval-required';
39
39
  export const GATES = Object.freeze(['none', 'relayed', 'human']);
40
- export const HUMAN_STEPS = Object.freeze(['sign-in', 'consent', 'payment', 'secret', 'spend-above-limit', 'passkey']);
40
+ /** AP-4's steps a person takes; `comparison` (DEC-0142) is a comparison of codes between two people. */
41
+ export const HUMAN_STEPS = Object.freeze(['sign-in', 'consent', 'payment', 'secret', 'spend-above-limit', 'passkey', 'comparison']);
41
42
  export const MAX_ACTIONS = 128;
42
43
  /** How far ahead of the service's clock a decision's `at` may be (the contract's CLOCK_SKEW_SECONDS). */
43
44
  export const CLOCK_SKEW_SECONDS = 60;
@@ -10,10 +10,12 @@ export const PROTOCOL_REVISIONS = new Map(Object.entries({
10
10
  'access-log': ['1'], approval: ['1'], 'activity-summary': ['1'], 'agent-directory': ['1'], 'call-record': ['1'], 'coding-agents': ['1'], 'credential-decision': ['1'], 'credential-request': ['1'], 'credential-revocation': ['1'], 'enroll-token': ['1'], entitlement: ['1'], 'entitlement-key-set': ['1'], 'estate-record': ['1'], 'execution-packet': ['1'],
11
11
  'fabric-actions': ['0.1'], 'fabric-activity': ['0.1'], 'fabric-agent-call': ['1'], 'fabric-connections': ['0.1'], 'fabric-credential-envelope': ['1'], 'fabric-load': ['0.1'], 'fabric-dashboard': ['0.1'], 'fabric-delegation': ['0.1'], 'fabric-device': ['0.1'],
12
12
  'fabric-interop': ['0.1', '0.2'], 'fabric-local-channel': ['0.1'], 'fabric-local-runner': ['0.1'], 'fabric-machine-report': ['1'], 'fabric-operator-channel': ['0.1'],
13
- 'fabric-package': ['1'], 'fabric-project-comms': ['0.1'], 'fabric-proposal': ['1'], 'fabric-provider': ['0.1'], 'fabric-relay': ['0.1'],
13
+ 'fabric-package': ['1'],
14
+ 'fabric-peer-share': ['1'], 'fabric-peer-share-envelope': ['1'], 'fabric-peer-share-report': ['1'], 'fabric-project-comms': ['0.1'], 'fabric-proposal': ['1'], 'fabric-provider': ['0.1'], 'fabric-relay': ['0.1'],
14
15
  'fabric-secret-envelope': ['1'], 'fabric-service': ['0.1'], 'fabric-settings-backup': ['1'], heartbeat: ['1'], 'learning-note': ['1'], 'machine-report': ['1'], mandate: ['1'],
15
- memory: ['0.1'], 'node-summary': ['1'], 'operator-source': ['1'], 'org-authority': ['1'], 'org-authority-draft': ['1'],
16
- 'org-key-set': ['1'], 'org-key-set-draft': ['1'], 'org-membership': ['1'], 'org-root-registration': ['1'], 'pairing-message': ['1'], pipeline: ['0.1'], 'repair-request': ['1'], 'repair-result': ['1'],
16
+ memory: ['0.1'], 'node-summary': ['1'], 'operator-source': ['1'], 'org-adaptation': ['1'], 'org-adaptation-receipt': ['1'], 'org-authority': ['1'], 'org-authority-draft': ['1'],
17
+ 'org-key-set': ['1'], 'org-key-set-draft': ['1'], 'org-membership': ['1'], 'org-root-registration': ['1'], 'pairing-message': ['1'],
18
+ 'peer-share-deletion': ['1'], 'peer-share-frame': ['1'], 'peer-share-revocation': ['1'], pipeline: ['0.1'], 'repair-request': ['1'], 'repair-result': ['1'],
17
19
  'revocation-delta': ['1'], 'session-handoff': ['1'], 'service-load': ['1'],
18
20
  'share-registration': ['1'], 'share-registration-receipt': ['1'], 'support-quality-daily': ['1'], 'window-lease': ['1'],
19
21
  }));
@@ -51,7 +51,8 @@ DECISION_INVALID = "decision-invalid"
51
51
  HUMAN_STEP_REQUIRED = "human-step-required"
52
52
  APPROVAL_REQUIRED = "approval-required"
53
53
  GATES = ("none", "relayed", "human")
54
- HUMAN_STEPS = ("sign-in", "consent", "payment", "secret", "spend-above-limit", "passkey")
54
+ #: AP-4's steps a person takes; `comparison` (DEC-0142) is a comparison of codes between two people.
55
+ HUMAN_STEPS = ("sign-in", "consent", "payment", "secret", "spend-above-limit", "passkey", "comparison")
55
56
  MAX_ACTIONS = 128
56
57
  #: How far ahead of the service's clock a decision's `at` may be (the contract's CLOCK_SKEW_SECONDS).
57
58
  CLOCK_SKEW_SECONDS = 60
@@ -17,11 +17,13 @@ PROTOCOL_REVISIONS: Dict[str, Tuple[str, ...]] = {
17
17
  "entitlement-key-set": ("1",), "estate-record": ("1",), "execution-packet": ("1",),
18
18
  "fabric-actions": ("0.1",), "fabric-activity": ("0.1",), "fabric-agent-call": ("1",), "fabric-connections": ("0.1",), "fabric-credential-envelope": ("1",), "fabric-load": ("0.1",), "fabric-dashboard": ("0.1",), "fabric-delegation": ("0.1",), "fabric-device": ("0.1",),
19
19
  "fabric-interop": ("0.1", "0.2"), "fabric-local-channel": ("0.1",), "fabric-local-runner": ("0.1",), "fabric-machine-report": ("1",),
20
- "fabric-operator-channel": ("0.1",), "fabric-package": ("1",), "fabric-project-comms": ("0.1",), "fabric-proposal": ("1",),
20
+ "fabric-operator-channel": ("0.1",), "fabric-package": ("1",),
21
+ "fabric-peer-share": ("1",), "fabric-peer-share-envelope": ("1",), "fabric-peer-share-report": ("1",), "fabric-project-comms": ("0.1",), "fabric-proposal": ("1",),
21
22
  "fabric-provider": ("0.1",), "fabric-relay": ("0.1",), "fabric-secret-envelope": ("1",), "fabric-service": ("0.1",),
22
23
  "fabric-settings-backup": ("1",), "heartbeat": ("1",), "learning-note": ("1",), "machine-report": ("1",), "mandate": ("1",), "memory": ("0.1",), "node-summary": ("1",),
23
- "operator-source": ("1",), "org-authority": ("1",), "org-authority-draft": ("1",), "org-key-set": ("1",), "org-key-set-draft": ("1",),
24
+ "operator-source": ("1",), "org-adaptation": ("1",), "org-adaptation-receipt": ("1",), "org-authority": ("1",), "org-authority-draft": ("1",), "org-key-set": ("1",), "org-key-set-draft": ("1",),
24
25
  "org-membership": ("1",), "org-root-registration": ("1",), "pairing-message": ("1",),
26
+ "peer-share-deletion": ("1",), "peer-share-frame": ("1",), "peer-share-revocation": ("1",),
25
27
  "pipeline": ("0.1",), "repair-request": ("1",), "repair-result": ("1",), "revocation-delta": ("1",), "session-handoff": ("1",), "service-load": ("1",), "share-registration": ("1",),
26
28
  "share-registration-receipt": ("1",), "support-quality-daily": ("1",), "window-lease": ("1",),
27
29
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fabric-service-kit",
3
- "version": "0.56.0",
3
+ "version": "0.57.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
  {
@@ -174,7 +174,7 @@
174
174
  "imports": [
175
175
  "fabric_secrets"
176
176
  ],
177
- "sha256": "f9f508eb8785ec13d1ad80c023b98a96f49a40b0e124fbecba19a8057af80551"
177
+ "sha256": "42529a7df4d753544d2e37a18ec81266d6e1e80477cb8558a3ab521416d45791"
178
178
  },
179
179
  {
180
180
  "module": "fabric_actions",
@@ -186,7 +186,7 @@
186
186
  "fabric_mandate",
187
187
  "fabric_time"
188
188
  ],
189
- "sha256": "0efe81c7b73c63963348fb4936a3816a961d3424416abd5823fbeb1aa2cb0bbf"
189
+ "sha256": "ae21d1199614c4f74d1dcd1e0a87107a9d52434cd9e2d64aa24a7b1e196fb723"
190
190
  },
191
191
  {
192
192
  "module": "fabric_connections",
@@ -661,7 +661,7 @@
661
661
  "imports": [
662
662
  "fabric-secrets"
663
663
  ],
664
- "sha256": "f0d9f6bd25320788e41a993aa730dafaafaa1713df806f6616c52a59ed578f67"
664
+ "sha256": "5fd8765fdd3e507cc85c108492682bf5cbb4ae08873245c50374fb01d33c75e4"
665
665
  },
666
666
  {
667
667
  "module": "fabric-actions",
@@ -673,7 +673,7 @@
673
673
  "fabric-mandate",
674
674
  "fabric-time"
675
675
  ],
676
- "sha256": "35f34dccb6c4feb482b0b169f53682f9690b32012481bef3869e487e9637af09"
676
+ "sha256": "06e42f5e24c96311d5417d0d1effa93479ef7128a7ab139903b2bcf59253f6be"
677
677
  },
678
678
  {
679
679
  "module": "fabric-connections",
@@ -4228,6 +4228,96 @@
4228
4228
  "fabric-openrouter.mjs": "6041f3ab30f516658e1dbab4897a651cc8509b2136cfa8e769802c6b40ec2f35",
4229
4229
  "fabric-package.schema.json": "2ba799f576fad0f608029223c4ccccd122152f1c5dbfa8ce8b31cd63ac92ad44",
4230
4230
  "share-registration.schema.json": "34b3997eeaf936ebc861342a23045634a7c18c19f01d7ed4198310d81989f5b0"
4231
+ },
4232
+ "0.57.0": {
4233
+ "fabric_jsvalue.py": "12888a2c934a885d35999ac9782eaedc8d04946d9775213344a235a8814d3d28",
4234
+ "fabric_time.py": "588f383da4ac6a243ea95b6ffc3a0aa99ca94245732dc4937734f190b7af4ae9",
4235
+ "fabric_identifiers.py": "0fd814d521ac3aa39907458265870753046a73f48af3d8581ab864b93b211607",
4236
+ "fabric_secrets.py": "1d0191f0ec108fdc68345056b8c574b1f691509d1c353e41d98bfd58a59e8d3c",
4237
+ "fabric_crypto.py": "9c34aee20dbe4d6742e4fdbaab68ceb934bbe7dbd3a904c0010824ace16cdeaa",
4238
+ "fabric_base.py": "f62bcc2ed9912660fa875d27a09f60867260cc4925f79873501fd9620be59611",
4239
+ "fabric_platform.py": "a9350dff55ef0fb3a23cdb4d0320a15868b15a8deb10d2eb74d72c58740c284b",
4240
+ "fabric_paths.py": "8a1ee742f80f436e9f28c61b4f049a9545de2a9e0d66bfc61faa6ee5d1ba3734",
4241
+ "fabric_estate_rules.py": "8b36a7f4108d9c2b1fb38c8bff344778c807bed631a99b4a563ecb0a49c10b1c",
4242
+ "fabric_estate.py": "b3cd56dcb86e04d252980322ac8054da1aaef24ac64690f7aa80e7c765ee6f60",
4243
+ "fabric_mandate.py": "050c43d0166a7dfba82e29c4e978f05c364cf6da06d0a781bd023a566777c17b",
4244
+ "fabric_delegation.py": "716f0ff7ac01095f54b24970beac1962128e8ff33026b243fc0467876142ab03",
4245
+ "fabric_share.py": "da36a466426fc29dd7dd40013167f3959a18375f8fedd228bf64f298cec1040c",
4246
+ "fabric_ceremonies.py": "a59e83cf4adb2669a9b98008e3d3a0cba991a35cbff97bc604fc82fe81cfd49f",
4247
+ "fabric_package_schema.py": "e623f0408d38e3343ed66222fb812907c6c52e1a286eb1c1176ab2e64640c9ad",
4248
+ "fabric_package.py": "ff533f1b3f92b4ea0f532fcec50b68c610d47549930eef8ad5247692a64dfb3c",
4249
+ "fabric_protocols.py": "42529a7df4d753544d2e37a18ec81266d6e1e80477cb8558a3ab521416d45791",
4250
+ "fabric_actions.py": "ae21d1199614c4f74d1dcd1e0a87107a9d52434cd9e2d64aa24a7b1e196fb723",
4251
+ "fabric_connections.py": "7de55cb7d808f756d650effabfaa12027d40a5bd5d2f6d448c32969d47529ecb",
4252
+ "fabric_a2a.py": "8b01502131215bb4de1c01866187c56e99b791543923ed8577535573db33b919",
4253
+ "fabric_page_links.py": "1b57ea573c550e2f90d1ec3edcc655917ceaa0db9dd1635fccf422ec3024d25e",
4254
+ "fabric_lock.py": "ba2399d2137c7a7791b7133b9db9cca36693f4eb7e30955b25a75ade814e95ba",
4255
+ "fabric_usage.py": "5cc2e03ccc5b06e81987ed7bc3eead7a7e6cbf1a7cb8e05c6c64315eed9d91b6",
4256
+ "fabric_backups.py": "1f3f0d7ecf361b29e9101e07f1c53e5dc304d598bf26fd59ec89f16b9fed2420",
4257
+ "fabric_descriptor.py": "a6d7a4a38186f7ef527d16218bbf96e39e255f9547be668adcfbec063dabb7ed",
4258
+ "fabric_context.py": "6ae311ddc7217a4aff915e7ce2646486931acd128462b7bebe4a52bbb5fbb6c7",
4259
+ "fabric_auth.py": "71115d18c67b7b806cb57b64b77e01ad97fc0e63e6f49ee850f778123617d905",
4260
+ "fabric_events.py": "cd94b186e2a8f8cb4ad2b6bd44d83ec5021933075e28c5d655f387f16dff42b8",
4261
+ "fabric_logs.py": "86dc55bfafa2a57264722e2403510a249b95de0e4a722b2e4bc3948e3bd93da9",
4262
+ "fabric_supervisors.py": "3c5b2e8c310738720b1c1b779be4710e90251013d9be4c68f9952edc0bf55d5f",
4263
+ "fabric_service.py": "a2e813469a47d4d3eea996628635c8903007498bdb6a1ae032a7a5ce6f49fe2f",
4264
+ "fabric_profiles.py": "26e21ec29c016000f8ca8053b7b489184854a73be1b7fdc0a18d12990203db9b",
4265
+ "fabric_interop_rules.py": "82c079a4d9421ea2cd10c1dfa8e1c447b80d5e0dcc8d52d52415bf028e34c91e",
4266
+ "fabric_interop.py": "8f7e43bf01fa5e969d7d819f4b0188b9acfd846f6f85a37ea139e550d61e4e6c",
4267
+ "fabric_hub.py": "b9ac852e601b1d54cf61351677a628afc69faeed7d1fc74ebe541c1cf38e0c2a",
4268
+ "fabric_board_shapes.py": "0a0e8d3d40e33dfd8c457aedb85330b2ff25f8c49a33eb6cbd5a5cc8a5007f7e",
4269
+ "fabric_board_link.py": "e8d2310e5f53c75e4bf642c3d980b2faba692731eaf56ec245cea05446e38bef",
4270
+ "fabric_board_slots.py": "a3c705cded822103703a6c2d734bcd505fcd1d6c0293150c77dfa266fd416d53",
4271
+ "fabric_board_session.py": "9032c04fbafb63fd93809b494518aaa039215abef973ad181d960350beb56a9f",
4272
+ "fabric_board_fixture.py": "69761ce205ec640762ec9b591c6903e5a87f844e8d423b041681924027e39d1e",
4273
+ "fabric_board.py": "34c1200860040aa61cdd35f911f70d34d64b4a5cd91f892328d1169e4a89d8cd",
4274
+ "fabric_http.py": "80e22ae0bba91de13a94d64b595108b39c58f16f7b4137f3a48bdd9503f424fe",
4275
+ "fabric_openrouter.py": "d06a40f83f2fb8bd441ab3485ae882f1fbdd9cd7a9c1ec175eb47cb8ae2cce81",
4276
+ "fabric-jsvalue.mjs": "dfbdb8c41584972c9389750a41719374a1cfc5652ed438dd1623025190b0106e",
4277
+ "fabric-time.mjs": "3ff932069038a720df1c68c6492976906737b2e67e5c12d9c81c418597f661de",
4278
+ "fabric-identifiers.mjs": "a18c2a501a4aa170bfd3d99e571ad6b7662649b4d3b9d2a540c002ea42811bbf",
4279
+ "fabric-secrets.mjs": "6ad8ab18ac899ecc2384e8ec6a3fb689b92be3b9a5ce3a59b92a37d52da5d766",
4280
+ "fabric-crypto.mjs": "038e03689701e3c9721a1e7f8e0a4d02a52d6a5d1661b0dc84035edc3ebbfcf6",
4281
+ "fabric-base.mjs": "7804b2df7715dbbf9702a9b61b6b8cef2110f9a52b04cabd8fb0a66458d87512",
4282
+ "fabric-platform.mjs": "a8119d95ebba4d589a9e401f5d6fc8dda62d59d44e4c1ff811d97fac3771ac0c",
4283
+ "fabric-paths.mjs": "aa630d611e748a899e7043480f4a4e46b444f2e15ff945f30c2fbef21c1ceea5",
4284
+ "fabric-estate-rules.mjs": "7476be71174aa5b1026134f2b335abf647feaa55584e2f9de8618e3054aa8e1e",
4285
+ "fabric-estate.mjs": "e8a2e62d2313121e6cb502f6e6abad94d1d546a44b4d9b3ce2be29e7808e8cf3",
4286
+ "fabric-mandate.mjs": "deaab2bfb929d1bd35ae1bad71e7b9ad9902cc23b8eb51819ed592fd80eddf95",
4287
+ "fabric-delegation.mjs": "04eaf6cd1786d4309a253a27dbdb05e27b408cb511aa41b1633a96634b775e65",
4288
+ "fabric-share.mjs": "bfb26581c21ad984c2a337da02429f9f3a165cc582f8ba48de4d3dfb7d163a59",
4289
+ "fabric-ceremonies.mjs": "117d4374c9e95c930a38de7adbd4323774798f4fe6ec6f24afcd6f2c7298ca44",
4290
+ "fabric-package-schema.mjs": "cd28092375db0fc21ffab1f0bb7794f7f8979ee08c64d3b9faf4b3845357caa6",
4291
+ "fabric-package.mjs": "13913ea6d12056c3a31b8222b6c4aab8395941fe519913692e1a06d8672e1c88",
4292
+ "fabric-protocols.mjs": "5fd8765fdd3e507cc85c108492682bf5cbb4ae08873245c50374fb01d33c75e4",
4293
+ "fabric-actions.mjs": "06e42f5e24c96311d5417d0d1effa93479ef7128a7ab139903b2bcf59253f6be",
4294
+ "fabric-connections.mjs": "303432e547ce563e90ca9ffcd827f5612f51d3582929834e1add0fdaf6485dcc",
4295
+ "fabric-a2a.mjs": "51b72fe1d80649d659fcad3a8f96370db3476c4a7b30cbabd8522c138be69346",
4296
+ "fabric-page-links.mjs": "a8834926e9d4bbf7c4857f551451d2ebf6ac8873bbccaaf89c5e30cf45b17ee6",
4297
+ "fabric-lock.mjs": "ac219ab0a326d5c43c7c4c255e0c3843d4794de795a60e3af661e7d5350ea052",
4298
+ "fabric-usage.mjs": "1c4d18004639409624ac3516a02f2b60bbf55abdb612e9a96c37e83666eb87a7",
4299
+ "fabric-backups.mjs": "cfd8c9085e3d597a783099c2bd2ffe2f3faa0daaadab46dedd30523894cfeb06",
4300
+ "fabric-descriptor.mjs": "243bbce42989f67c4c5ec6b7659e201b3f9a1c08c71d429d88ec934d870f5104",
4301
+ "fabric-context.mjs": "1112d695e872f9825cbc94f08484974bff3880087bc29b8be59f885f03e8f7be",
4302
+ "fabric-auth.mjs": "782c2aa732f8320f604194660117640a7ea145e12b8155c04e88cef7c516a5b3",
4303
+ "fabric-events.mjs": "c463d6ffcae24229a5c608d8fcea4268d2ccc5024b19fa10e5a452284068fa71",
4304
+ "fabric-logs.mjs": "58467e5719c16e099d05bbedec47a95712506ab03c33f3cd4be1252e8498a946",
4305
+ "fabric-supervisors.mjs": "d45c38de0cb3ed85e083496c2d3c51dab004454accdd87f4762a512a6d442573",
4306
+ "fabric-service.mjs": "6aa673657427211b491a9b63f94b9847a7e6aa3ee1b7353e1af11f46469803a3",
4307
+ "fabric-profiles.mjs": "314376cf2deb87f235fb18b11d3b532e211f585b9af0a9302b5f4cc39971b532",
4308
+ "fabric-interop-rules.mjs": "e4f8b133138e27353a7976c0360bd1653c90daed43b3f843f85a19f14f5e9221",
4309
+ "fabric-interop.mjs": "ee7e6d32be1f42e6d21a943b8886652352408c49c6404d9749b8a02dc3901e92",
4310
+ "fabric-hub.mjs": "c005115a864cfd67daa4862097bb14acfe5a60bf653897e5bf8a570dd80f1070",
4311
+ "fabric-board-shapes.mjs": "c1db7b7bd0d58d82bb6d8dfbc3cd1547a256a333052d367e82ff1b3edf2804d7",
4312
+ "fabric-board-link.mjs": "b1ac329b65b679193b94b81fe735922e14427ed540ba910b1a815ce3447e3220",
4313
+ "fabric-board-slots.mjs": "43eb7ceb6c62989a4eb4b2089d1808e2c3cf8f873fcf9216fcb4c285e5b39eb4",
4314
+ "fabric-board-session.mjs": "04aa920b24a379157c55ebe3de516eb8b46bd0b0db50e4b883528d4ede7ed978",
4315
+ "fabric-board-fixture.mjs": "83c4b7e33ee47b68385faf2569d38d5c8a0c5cb0f8656090f41e1b0eed2f436e",
4316
+ "fabric-board.mjs": "0d75c3e27a0b791bdbc35b2e93b3299e5831d3ab3003ce441e6268397e32b448",
4317
+ "fabric-http.mjs": "9f899829073470b9c2b449605a9371b773848eec4e3a0122ed4ccde5eddcdb4b",
4318
+ "fabric-openrouter.mjs": "6041f3ab30f516658e1dbab4897a651cc8509b2136cfa8e769802c6b40ec2f35",
4319
+ "fabric-package.schema.json": "2ba799f576fad0f608029223c4ccccd122152f1c5dbfa8ce8b31cd63ac92ad44",
4320
+ "share-registration.schema.json": "34b3997eeaf936ebc861342a23045634a7c18c19f01d7ed4198310d81989f5b0"
4231
4321
  }
4232
4322
  },
4233
4323
  "data": {
@@ -5,9 +5,9 @@ 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.56.0"
8
+ version: "0.57.0"
9
9
  contract-version: "0.1.0"
10
- contract-commit: "00e050ba7429c0c60261cec871779e0fd6aeeb28"
10
+ contract-commit: "3830a3353923e20f826d466610e1c479f120bec0"
11
11
  ---
12
12
 
13
13
  # Creating Fabric-compatible agents
@@ -139,7 +139,7 @@ python3 <plugin-dir>/skills/adapting-projects-to-fabric/scripts/adapt_project.py
139
139
  The effect class is declared, never defaulted: ask the author what the agent does outside itself when the request
140
140
  does not say. Cost presets are only for a run whose cost varies; their amounts come from the author or measured runs.
141
141
 
142
- Pin exactly contract `0.1.0` at commit `00e050ba7429c0c60261cec871779e0fd6aeeb28` and
142
+ Pin exactly contract `0.1.0` at commit `3830a3353923e20f826d466610e1c479f120bec0` and
143
143
  read the pinned guide before implementing protocol details. If this skill is installed
144
144
  without its sibling, the scaffolder is absent: create the bundle by hand from the pinned
145
145
  contract's `docs/guides/connecting-compatible-agents.md` and mark the structural check
@@ -42,12 +42,18 @@ to a person at the first refusal (the refused draft is not kept), where this pag
42
42
  (`/fabric/v1/events`; building-fabric-services, `references/events-and-notifications.md`): counts and codes only, the
43
43
  judge model and rubric version, and `notMeasured` naming every family not computed that day. A metric not measured is
44
44
  null and named, never 0. The day goes in the event's `data` (`{schema, value}`, as `fabric_events.py` writes it), at
45
- level `info` and without a notification. Until the contract carries the schema (A7), the producer names and pins its
46
- own: `data.schema` is the absolute URI of the payload schema the agent publishes, and `data.value` stays within
45
+ level `info` and without a notification. `data.value` is valid against the contract's
46
+ `support-quality-daily.schema.json` (`support-quality-daily/1`, DEC-0095), `data.schema` is the absolute URI of the
47
+ producer's published copy of it (the contract's conformance row for this producer), and the value stays within
47
48
  DEC-0070's bounds (at most 32 members, each a scalar, a list of scalars or a flat object; per-lane counts as objects
48
- such as `laneFailures` and `laneRecovered`; building-fabric-services, `references/protocol.md`). Check: the producer's
49
- day passes `make_event`; a planted day that writes 0 for a family not computed fails; and a test runs every
50
- `notMeasured` name the producer can emit through the published name pattern, iterating the producer's own list.
49
+ such as `laneFailures` and `laneRecovered`; building-fabric-services, `references/protocol.md`). A judge's
50
+ calibration, `calibration {week, labelled, helped}` with `calibrationChecks` beside it (DEC-0144), goes in only once
51
+ every reader of the feed it knows of has adopted DEC-0144: the producer then re-publishes its copy from DEC-0144's
52
+ bytes (CT-188), and leaves the calibration out when the judge or the rubric changed after the labelled week. A
53
+ reader validates against its own pinned copy, never one fetched by `$id`: the bytes under the unchanged `$id`
54
+ widened. Check: the producer's day passes `make_event` and validates against the producer's pinned copy of the
55
+ schema; a planted day that writes 0 for a family not computed fails; and a test runs every `notMeasured` name the
56
+ producer can emit through the published name pattern, iterating the producer's own list.
51
57
 
52
58
  ## Model lanes
53
59