ai-capability-framework 1.0.0-rc.3 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/CHANGELOG.md +97 -103
  2. package/CODE_OF_CONDUCT.md +11 -13
  3. package/CONTRIBUTING.md +40 -43
  4. package/GOVERNANCE.md +34 -35
  5. package/README.md +99 -63
  6. package/ROADMAP.md +12 -12
  7. package/SECURITY.md +15 -15
  8. package/dist/audit/ledger.d.ts.map +1 -1
  9. package/dist/audit/ledger.js +2 -1
  10. package/dist/audit/records.d.ts.map +1 -1
  11. package/dist/audit/records.js +2 -1
  12. package/dist/audit/types.d.ts +4 -1
  13. package/dist/audit/types.d.ts.map +1 -1
  14. package/dist/aws/dynamodb-stores.d.ts +2 -7
  15. package/dist/aws/dynamodb-stores.d.ts.map +1 -1
  16. package/dist/aws/dynamodb-stores.js +56 -5
  17. package/dist/aws/testing.d.ts.map +1 -1
  18. package/dist/aws/testing.js +9 -0
  19. package/dist/cli.d.ts +6 -6
  20. package/dist/cli.d.ts.map +1 -1
  21. package/dist/cli.js +77 -7
  22. package/dist/evals-live/index.d.ts +2 -2
  23. package/dist/evals-live/index.d.ts.map +1 -1
  24. package/dist/evals-live/index.js +1 -1
  25. package/dist/evals-live/live-eval-runner.d.ts +49 -1
  26. package/dist/evals-live/live-eval-runner.d.ts.map +1 -1
  27. package/dist/evals-live/live-eval-runner.js +246 -4
  28. package/dist/evals-live/types.d.ts +62 -9
  29. package/dist/evals-live/types.d.ts.map +1 -1
  30. package/dist/index.d.ts +0 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +0 -1
  33. package/dist/runtime/actions.d.ts +2 -0
  34. package/dist/runtime/actions.d.ts.map +1 -1
  35. package/dist/runtime/actions.js +200 -55
  36. package/dist/runtime/index.d.ts +1 -1
  37. package/dist/runtime/index.d.ts.map +1 -1
  38. package/dist/runtime/stores.d.ts +2 -7
  39. package/dist/runtime/stores.d.ts.map +1 -1
  40. package/dist/runtime/stores.js +12 -0
  41. package/dist/runtime/types.d.ts +25 -6
  42. package/dist/runtime/types.d.ts.map +1 -1
  43. package/docs/action-lifecycle.md +38 -32
  44. package/docs/adapter-roadmap.md +51 -49
  45. package/docs/adapters.md +14 -15
  46. package/docs/ai-sdk-runtime.md +36 -39
  47. package/docs/anthropic-runtime.md +29 -32
  48. package/docs/api/public-api-policy.md +59 -0
  49. package/docs/api.md +354 -371
  50. package/docs/architecture/current-state.md +28 -31
  51. package/docs/audit/index.md +29 -29
  52. package/docs/aws/cloudwatch-telemetry.md +5 -7
  53. package/docs/aws/dynamodb-single-table.md +8 -9
  54. package/docs/aws/kms-redaction.md +5 -6
  55. package/docs/aws/overview.md +5 -5
  56. package/docs/aws/production-reference.md +13 -14
  57. package/docs/aws/step-functions-approval.md +7 -9
  58. package/docs/aws-runtime.md +24 -25
  59. package/docs/capability-manifests.md +17 -21
  60. package/docs/control-plane/overview.md +2 -2
  61. package/docs/control-plane.md +24 -27
  62. package/docs/controls/index.md +19 -22
  63. package/docs/core/capability-manifests.md +4 -5
  64. package/docs/core/entity-manifests.md +5 -5
  65. package/docs/eval-runner.md +29 -31
  66. package/docs/evalops.md +13 -14
  67. package/docs/evals/golden-tests.md +4 -5
  68. package/docs/evals/overview.md +3 -3
  69. package/docs/evals/replay-and-trace-to-golden.md +19 -20
  70. package/docs/evals.md +19 -20
  71. package/docs/evidence.md +22 -23
  72. package/docs/gemini-runtime.md +31 -33
  73. package/docs/getting-started/anthropic-quickstart.md +61 -0
  74. package/docs/getting-started/concepts.md +9 -10
  75. package/docs/getting-started/gemini-quickstart.md +62 -0
  76. package/docs/getting-started/installation.md +3 -3
  77. package/docs/getting-started/openai-quickstart.md +61 -0
  78. package/docs/getting-started/provider-neutral-quickstart.md +106 -0
  79. package/docs/getting-started/quickstart.md +2 -2
  80. package/docs/getting-started.md +23 -20
  81. package/docs/glossary.md +31 -48
  82. package/docs/governance/gate.md +28 -30
  83. package/docs/governance/impact-and-compatibility.md +2 -3
  84. package/docs/governance/index.md +53 -54
  85. package/docs/governance/lifecycle.md +4 -5
  86. package/docs/governance/overview.md +2 -3
  87. package/docs/governance/risk-compiler.md +4 -5
  88. package/docs/host-responsibilities.md +6 -8
  89. package/docs/implementation-notes/baseline-gaps.md +15 -18
  90. package/docs/index.md +21 -6
  91. package/docs/interoperability.md +9 -9
  92. package/docs/langchain-runtime.md +27 -31
  93. package/docs/live-evals.md +68 -32
  94. package/docs/mcp-server-runtime.md +36 -40
  95. package/docs/memory.md +35 -36
  96. package/docs/migration-0.1-to-1.0.md +14 -9
  97. package/docs/observability/overview.md +2 -3
  98. package/docs/observability-runtime.md +35 -39
  99. package/docs/openai-responses.md +36 -37
  100. package/docs/openai-runtime.md +41 -46
  101. package/docs/openai-walkthrough.md +24 -28
  102. package/docs/policy-broker.md +9 -10
  103. package/docs/provenance.md +30 -29
  104. package/docs/providers/anthropic.md +5 -5
  105. package/docs/providers/choose-a-runtime.md +37 -0
  106. package/docs/providers/conformance.md +14 -15
  107. package/docs/providers/gemini.md +5 -5
  108. package/docs/providers/mcp.md +2 -3
  109. package/docs/providers/openai.md +2 -2
  110. package/docs/providers/semantic-kernel.md +2 -2
  111. package/docs/providers.md +43 -38
  112. package/docs/public/license-exceptions.md +187 -0
  113. package/docs/public/npm-release-preflight.md +112 -0
  114. package/docs/public-framework/compatibility-policy.md +12 -13
  115. package/docs/public-framework/deprecation-policy.md +8 -8
  116. package/docs/public-framework/final-certification-matrix.md +104 -0
  117. package/docs/public-framework/license-decision.md +20 -0
  118. package/docs/public-framework/release-process.md +46 -16
  119. package/docs/public-framework/security-disclosure.md +4 -5
  120. package/docs/public-framework/v1-certification.md +102 -15
  121. package/docs/release.md +200 -122
  122. package/docs/runtime/action-lifecycle.md +3 -3
  123. package/docs/runtime/policy-broker.md +4 -4
  124. package/docs/runtime/runtime-overview.md +4 -5
  125. package/docs/runtime/tool-result-envelope.md +7 -7
  126. package/docs/runtime.md +90 -93
  127. package/docs/security/overview.md +4 -4
  128. package/docs/security/security-packs.md +24 -26
  129. package/docs/security/trust-taint-redaction.md +42 -47
  130. package/docs/semantic-kernel-runtime.md +35 -37
  131. package/docs/spec.md +95 -101
  132. package/docs/start-here.md +18 -20
  133. package/examples/01-basic-read-capability/README.md +3 -4
  134. package/examples/02-prepare-approve-commit/README.md +6 -6
  135. package/examples/03-multi-provider-tools/README.md +2 -2
  136. package/examples/04-mcp-server/README.md +4 -5
  137. package/examples/05-langchain-langgraph-bridge/README.md +4 -5
  138. package/examples/06-vercel-ai-sdk-bridge/README.md +5 -7
  139. package/examples/07-policy-broker-custom-auth/README.md +4 -4
  140. package/examples/08-aws-step-functions-approval/README.md +4 -5
  141. package/examples/09-security-packs-promptfoo/README.md +4 -4
  142. package/examples/10-trace-to-golden/README.md +2 -2
  143. package/examples/11-control-plane/README.md +4 -5
  144. package/examples/aws/README.md +5 -8
  145. package/examples/control-plane/README.md +8 -9
  146. package/examples/control-plane/fixtures/control-plane.seed.json +8 -32
  147. package/examples/control-plane/public/app.js +57 -18
  148. package/examples/control-plane/public/index.html +15 -6
  149. package/examples/control-plane/server.mjs +15 -3
  150. package/examples/eval-results/public.results.passing.json +6 -21
  151. package/examples/providers/ai-sdk-next/README.md +11 -8
  152. package/examples/providers/anthropic-claude/README.md +5 -6
  153. package/examples/providers/gemini/README.md +6 -6
  154. package/examples/providers/langchain-agent/README.md +3 -4
  155. package/examples/providers/langgraph-tool-node/README.md +7 -7
  156. package/examples/providers/mcp/README.md +8 -8
  157. package/examples/providers/provider-conformance/README.md +3 -3
  158. package/examples/providers/semantic-kernel-mcp/README.md +6 -6
  159. package/examples/providers/semantic-kernel-openapi/README.md +6 -7
  160. package/examples/runtime-support-billing/README.md +8 -9
  161. package/examples/runtime-support-billing/support-billing-runtime.mjs +8 -4
  162. package/examples/scheduling/capabilities/scheduling.availability.get.yaml +2 -2
  163. package/examples/scheduling/capabilities/scheduling.invite.prepare.yaml +2 -2
  164. package/examples/scheduling/capabilities/scheduling.invite.send.yaml +2 -2
  165. package/examples/scheduling/entities/AvailabilitySlot.yaml +2 -2
  166. package/examples/scheduling/entities/MeetingInvite.yaml +2 -2
  167. package/examples/scheduling/evals/scheduling.invite.prepare.valid.yaml +3 -1
  168. package/examples/semantic-kernel-mcp/README.md +11 -12
  169. package/examples/semantic-kernel-openapi/README.md +8 -8
  170. package/examples/support/capabilities/support.refund.commit_case.yaml +3 -3
  171. package/examples/support/capabilities/support.refund.prepare_case.yaml +2 -2
  172. package/examples/support/capabilities/support.ticket.get.yaml +2 -2
  173. package/examples/support/entities/Ticket.yaml +0 -1
  174. package/examples/support/eval-results/support.results.passing.json +3 -12
  175. package/examples/support/evals/support.refund.prepare_case.approval_required.yaml +3 -1
  176. package/examples/support/evals/support.refund.prepare_case.valid.yaml +3 -2
  177. package/examples/support/memory/support.agent.preferences.json +2 -6
  178. package/examples/support/openai/context.support_agent.json +1 -4
  179. package/examples/support/provenance/support.refund.summary.provenance.json +2 -6
  180. package/examples/support/replay/support.refund.approval_required.trace.json +4 -14
  181. package/package.json +22 -5
  182. package/schemas/audit/action-record.schema.json +4 -1
  183. package/schemas/aws/approval-task.schema.json +8 -1
  184. package/schemas/conformance/conformance-case.schema.json +18 -2
  185. package/schemas/conformance/conformance-report.schema.json +17 -2
  186. package/schemas/conformance/provider-target-matrix.schema.json +35 -4
  187. package/schemas/controls/control-decision.schema.json +7 -1
  188. package/schemas/eval-case.schema.json +8 -1
  189. package/schemas/eval-result.schema.json +8 -1
  190. package/schemas/evidence/evidence-pack.schema.json +34 -5
  191. package/schemas/governance/compatibility-diff.schema.json +8 -1
  192. package/schemas/governance/lifecycle-transition.schema.json +10 -1
  193. package/schemas/governance/risk-compilation-result.schema.json +9 -1
  194. package/schemas/provenance/generated-content-provenance.schema.json +3 -1
  195. package/schemas/replay/replay-result.schema.json +16 -2
  196. package/schemas/replay/replay-trace.schema.json +11 -2
  197. package/schemas/security/context-segment.schema.json +21 -12
  198. package/schemas/security/redaction-policy.schema.json +4 -1
  199. package/schemas/security-packs/coverage-report.schema.json +17 -2
  200. package/schemas/security-packs/security-case-suite.schema.json +11 -1
  201. package/schemas/tool-result-envelope.schema.json +9 -1
  202. package/security-packs/approval_bypass.yaml +12 -2
  203. package/security-packs/capability_spoofing.yaml +17 -3
  204. package/security-packs/cost_amplification.yaml +21 -4
  205. package/security-packs/cross_tenant_access.yaml +16 -3
  206. package/security-packs/insecure_output_rendering.yaml +15 -4
  207. package/security-packs/mcp_tool_abuse.yaml +17 -3
  208. package/security-packs/memory_scope_violation.yaml +19 -4
  209. package/security-packs/prompt_injection_direct.yaml +19 -4
  210. package/security-packs/prompt_injection_indirect.yaml +18 -3
  211. package/security-packs/provider_payload_exposure.yaml +26 -4
  212. package/security-packs/retrieval_poisoning.yaml +5 -2
  213. package/security-packs/schema_confusion.yaml +17 -3
  214. package/security-packs/sensitive_data_disclosure.yaml +22 -5
  215. package/security-packs/tool_exfiltration.yaml +20 -4
  216. package/security-packs/tool_result_poisoning.yaml +19 -4
  217. package/security-packs/unsafe_commit_attempt.yaml +6 -3
@@ -1,9 +1,8 @@
1
1
  # AICF Control Plane Example
2
2
 
3
- This is a public-safe local reference app for the optional AICF control-plane
4
- subpath. It shows capability review, governance status, eval/security coverage,
5
- policy decisions, approvals, controls, replay metadata, and evidence export
6
- without credentials.
3
+ This is a public-safe local reference app for the optional AICF control-plane subpath.
4
+ It shows capability review, governance status, eval/security coverage, policy decisions,
5
+ approvals, controls, replay metadata, and evidence export without credentials.
7
6
 
8
7
  The example uses:
9
8
 
@@ -12,9 +11,9 @@ The example uses:
12
11
  - mutable local state in `.aicf/control-plane-state.json`;
13
12
  - a fake local development user.
14
13
 
15
- Production deployments must enforce real authentication, tenant/account
16
- authorization, approval identity, durable storage, audit retention, and side
17
- effects outside this example.
14
+ Production deployments must enforce real authentication, tenant/account authorization,
15
+ approval identity, durable storage, audit retention, and side effects outside this
16
+ example.
18
17
 
19
18
  ## Run
20
19
 
@@ -41,5 +40,5 @@ PORT=4300 node examples/control-plane/server.mjs
41
40
  - redacted replay index;
42
41
  - evidence export with refs, hashes, and summaries only.
43
42
 
44
- The app never displays raw prompts, provider payloads, transcripts, secrets,
45
- stack traces, tenant IDs, account IDs, or sensitive tool outputs.
43
+ The app never displays raw prompts, provider payloads, transcripts, secrets, stack
44
+ traces, tenant IDs, account IDs, or sensitive tool outputs.
@@ -28,11 +28,7 @@
28
28
  "refHash": "sha256:example-tenant"
29
29
  },
30
30
  "redaction": {
31
- "fieldsRedacted": [
32
- "account",
33
- "subject",
34
- "tenant"
35
- ],
31
+ "fieldsRedacted": ["account", "subject", "tenant"],
36
32
  "hashAlgorithm": "sha256",
37
33
  "mode": "redacted"
38
34
  },
@@ -72,11 +68,7 @@
72
68
  "refHash": "sha256:example-tenant"
73
69
  },
74
70
  "redaction": {
75
- "fieldsRedacted": [
76
- "account",
77
- "subject",
78
- "tenant"
79
- ],
71
+ "fieldsRedacted": ["account", "subject", "tenant"],
80
72
  "hashAlgorithm": "sha256",
81
73
  "mode": "redacted"
82
74
  },
@@ -107,9 +99,7 @@
107
99
  "capabilityId": "support.refund.prepare_case",
108
100
  "preparedActionId": "prepared_refund_example_1",
109
101
  "status": "pending",
110
- "requiredReasonCodes": [
111
- "approval_required"
112
- ],
102
+ "requiredReasonCodes": ["approval_required"],
113
103
  "requestedBy": {
114
104
  "actorType": "user",
115
105
  "refHash": "sha256:example-subject"
@@ -167,13 +157,8 @@
167
157
  "model": "mock-responses"
168
158
  },
169
159
  "capabilitySlice": {
170
- "capabilityIds": [
171
- "support.ticket.get",
172
- "support.refund.prepare_case"
173
- ],
174
- "excludedCapabilityIds": [
175
- "support.refund.commit_case"
176
- ],
160
+ "capabilityIds": ["support.ticket.get", "support.refund.prepare_case"],
161
+ "excludedCapabilityIds": ["support.refund.commit_case"],
177
162
  "hash": "sha256:example-support-slice"
178
163
  },
179
164
  "capabilityVersions": {
@@ -184,10 +169,7 @@
184
169
  "contextHash": "sha256:example-support-context",
185
170
  "userInputSummary": "Synthetic user asks to prepare a refund case.",
186
171
  "decisionContext": {
187
- "permissions": [
188
- "ticket.read",
189
- "refund.case.create"
190
- ],
172
+ "permissions": ["ticket.read", "refund.case.create"],
191
173
  "autonomyTier": "A2",
192
174
  "riskCeiling": "medium"
193
175
  }
@@ -225,17 +207,11 @@
225
207
  "preparedActionId": "prepared_refund_example_1",
226
208
  "capabilityId": "support.refund.prepare_case",
227
209
  "status": "pending",
228
- "requiredReasonCodes": [
229
- "approval_required"
230
- ]
210
+ "requiredReasonCodes": ["approval_required"]
231
211
  }
232
212
  ],
233
213
  "redaction": {
234
- "fieldsRedacted": [
235
- "account",
236
- "subject",
237
- "tenant"
238
- ],
214
+ "fieldsRedacted": ["account", "subject", "tenant"],
239
215
  "hashAlgorithm": "sha256",
240
216
  "mode": "redacted"
241
217
  }
@@ -14,9 +14,13 @@ navButtons.forEach((button) => {
14
14
  });
15
15
  });
16
16
 
17
- document.querySelector("#capabilityFilter").addEventListener("input", () => renderCatalogue());
17
+ document
18
+ .querySelector("#capabilityFilter")
19
+ .addEventListener("input", () => renderCatalogue());
18
20
  document.querySelector("#exportEvidence").addEventListener("click", exportEvidence);
19
- document.querySelector("#createGlobalKillSwitch").addEventListener("click", createGlobalKillSwitch);
21
+ document
22
+ .querySelector("#createGlobalKillSwitch")
23
+ .addEventListener("click", createGlobalKillSwitch);
20
24
 
21
25
  await refresh();
22
26
 
@@ -44,7 +48,9 @@ function renderCatalogue() {
44
48
  const filter = document.querySelector("#capabilityFilter").value.toLowerCase();
45
49
  const rows = document.querySelector("#capabilityRows");
46
50
  rows.innerHTML = "";
47
- for (const capability of snapshot.capabilities.filter((entry) => entry.id.toLowerCase().includes(filter))) {
51
+ for (const capability of snapshot.capabilities.filter((entry) =>
52
+ entry.id.toLowerCase().includes(filter)
53
+ )) {
48
54
  const row = document.createElement("tr");
49
55
  row.dataset.capabilityId = capability.id;
50
56
  row.innerHTML = `
@@ -68,11 +74,16 @@ async function renderCapabilityDetail() {
68
74
  detailPanel.textContent = "No capability selected.";
69
75
  return;
70
76
  }
71
- const detail = await api(`/api/aicf/capabilities/${encodeURIComponent(selectedCapabilityId)}`);
77
+ const detail = await api(
78
+ `/api/aicf/capabilities/${encodeURIComponent(selectedCapabilityId)}`
79
+ );
72
80
  detailPanel.innerHTML = `
73
81
  <h3>${escapeHtml(detail.id)}</h3>
74
82
  <p>${escapeHtml(detail.description)}</p>
75
- <p><strong>Lifecycle:</strong> ${Object.entries(detail.lifecycle).filter(([, value]) => value === true || typeof value === "string").map(([key, value]) => `${escapeHtml(key)}=${escapeHtml(String(value))}`).join(", ")}</p>
83
+ <p><strong>Lifecycle:</strong> ${Object.entries(detail.lifecycle)
84
+ .filter(([, value]) => value === true || typeof value === "string")
85
+ .map(([key, value]) => `${escapeHtml(key)}=${escapeHtml(String(value))}`)
86
+ .join(", ")}</p>
76
87
  <p><strong>Risk:</strong> declared ${escapeHtml(detail.risk.declaredRiskTier)}, inferred ${escapeHtml(detail.risk.inferredMinimumRiskTier)}</p>
77
88
  <p><strong>Input fields:</strong> ${detail.inputProperties.map((name) => `<span class="pill">${escapeHtml(name)}</span>`).join("") || "none"}</p>
78
89
  <p><strong>Related evals:</strong> ${detail.relatedEvalIds.map((id) => `<span class="pill">${escapeHtml(id)}</span>`).join("") || "none"}</p>
@@ -92,7 +103,9 @@ function renderStatus() {
92
103
  <p>${escapeHtml(snapshot.conformance.status)}</p>
93
104
  <p>${snapshot.conformance.summary.passed} passed, ${snapshot.conformance.summary.failed} failed across ${snapshot.conformance.summary.providers} provider target(s).</p>
94
105
  `;
95
- const highRisk = snapshot.capabilities.filter((capability) => ["high", "critical"].includes(capability.riskTier));
106
+ const highRisk = snapshot.capabilities.filter((capability) =>
107
+ ["high", "critical"].includes(capability.riskTier)
108
+ );
96
109
  document.querySelector("#riskStatus").innerHTML = `
97
110
  <h3>Risk Posture</h3>
98
111
  <p>${highRisk.length} high or critical capability(ies).</p>
@@ -116,27 +129,41 @@ function renderLedger() {
116
129
  }
117
130
 
118
131
  function renderApprovals() {
119
- document.querySelector("#actionsList").innerHTML = snapshot.actions.map((action) => `
132
+ document.querySelector("#actionsList").innerHTML =
133
+ snapshot.actions
134
+ .map(
135
+ (action) => `
120
136
  <div class="queue-item">
121
137
  <strong>${escapeHtml(action.actionId)}</strong><br>
122
138
  ${escapeHtml(action.capabilityId)} · <span class="status-${escapeHtml(action.actionState)}">${escapeHtml(action.actionState)}</span>
123
139
  </div>
124
- `).join("") || "No actions.";
140
+ `
141
+ )
142
+ .join("") || "No actions.";
125
143
 
126
- document.querySelector("#approvalsList").innerHTML = snapshot.approvals.map((approval) => `
144
+ document.querySelector("#approvalsList").innerHTML =
145
+ snapshot.approvals
146
+ .map(
147
+ (approval) => `
127
148
  <div class="queue-item">
128
149
  <strong>${escapeHtml(approval.approvalRecordId)}</strong><br>
129
150
  ${escapeHtml(approval.capabilityId)} · <span class="status-${escapeHtml(approval.status)}">${escapeHtml(approval.status)}</span><br>
130
151
  <button data-approve="${escapeHtml(approval.approvalRecordId)}" type="button">Approve</button>
131
152
  <button data-reject="${escapeHtml(approval.approvalRecordId)}" type="button">Reject</button>
132
153
  </div>
133
- `).join("") || "No approvals.";
154
+ `
155
+ )
156
+ .join("") || "No approvals.";
134
157
 
135
158
  document.querySelectorAll("[data-approve]").forEach((button) => {
136
- button.addEventListener("click", () => mutateApproval(button.dataset.approve, "approve"));
159
+ button.addEventListener("click", () =>
160
+ mutateApproval(button.dataset.approve, "approve")
161
+ );
137
162
  });
138
163
  document.querySelectorAll("[data-reject]").forEach((button) => {
139
- button.addEventListener("click", () => mutateApproval(button.dataset.reject, "reject"));
164
+ button.addEventListener("click", () =>
165
+ mutateApproval(button.dataset.reject, "reject")
166
+ );
140
167
  });
141
168
  }
142
169
 
@@ -156,12 +183,17 @@ function renderControls() {
156
183
  }
157
184
 
158
185
  function renderReplay() {
159
- document.querySelector("#replayList").innerHTML = (snapshot.replays ?? []).map((trace) => `
186
+ document.querySelector("#replayList").innerHTML =
187
+ (snapshot.replays ?? [])
188
+ .map(
189
+ (trace) => `
160
190
  <div>
161
191
  <strong>${escapeHtml(trace.traceId)}</strong><br>
162
192
  ${escapeHtml(trace.provider ?? "unknown provider")} · ${escapeHtml(trace.redactionMode)} · ${trace.capabilityIds.map((id) => `<span class="pill">${escapeHtml(id)}</span>`).join("")}
163
193
  </div>
164
- `).join("") || "No replay metadata.";
194
+ `
195
+ )
196
+ .join("") || "No replay metadata.";
165
197
  }
166
198
 
167
199
  async function mutateApproval(id, action) {
@@ -189,16 +221,23 @@ async function exportEvidence() {
189
221
  includeConformance: true,
190
222
  includeReplayIndex: true
191
223
  });
192
- document.querySelector("#evidenceOutput").textContent = JSON.stringify(evidence, null, 2);
224
+ document.querySelector("#evidenceOutput").textContent = JSON.stringify(
225
+ evidence,
226
+ null,
227
+ 2
228
+ );
193
229
  document.querySelector('[data-view="evidence"]').click();
194
230
  }
195
231
 
196
232
  async function api(path, body) {
197
233
  const response = await fetch(path, {
198
234
  body: body === undefined ? undefined : JSON.stringify(body),
199
- headers: body === undefined ? undefined : {
200
- "content-type": "application/json"
201
- },
235
+ headers:
236
+ body === undefined
237
+ ? undefined
238
+ : {
239
+ "content-type": "application/json"
240
+ },
202
241
  method: body === undefined ? "GET" : "POST"
203
242
  });
204
243
  const json = await response.json();
@@ -1,10 +1,10 @@
1
1
  <!doctype html>
2
2
  <html lang="en">
3
3
  <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1">
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
6
  <title>AICF Control Plane</title>
7
- <link rel="stylesheet" href="/styles.css">
7
+ <link rel="stylesheet" href="/styles.css" />
8
8
  </head>
9
9
  <body>
10
10
  <header class="topbar">
@@ -17,7 +17,9 @@
17
17
 
18
18
  <main class="layout">
19
19
  <aside class="sidebar" aria-label="Control plane sections">
20
- <button class="nav active" data-view="catalogue" type="button">Catalogue</button>
20
+ <button class="nav active" data-view="catalogue" type="button">
21
+ Catalogue
22
+ </button>
21
23
  <button class="nav" data-view="status" type="button">Status</button>
22
24
  <button class="nav" data-view="ledger" type="button">Ledger</button>
23
25
  <button class="nav" data-view="approvals" type="button">Approvals</button>
@@ -32,7 +34,12 @@
32
34
  <section id="catalogue" class="view active">
33
35
  <div class="section-header">
34
36
  <h2>Capability Catalogue</h2>
35
- <input id="capabilityFilter" type="search" placeholder="Filter capabilities" aria-label="Filter capabilities">
37
+ <input
38
+ id="capabilityFilter"
39
+ type="search"
40
+ placeholder="Filter capabilities"
41
+ aria-label="Filter capabilities"
42
+ />
36
43
  </div>
37
44
  <div class="grid two">
38
45
  <div>
@@ -99,7 +106,9 @@
99
106
  <section id="controls" class="view">
100
107
  <div class="section-header">
101
108
  <h2>Kill Switches, Budgets, Circuit Breakers</h2>
102
- <button id="createGlobalKillSwitch" type="button">Create Global Read-Only</button>
109
+ <button id="createGlobalKillSwitch" type="button">
110
+ Create Global Read-Only
111
+ </button>
103
112
  </div>
104
113
  <div class="grid three">
105
114
  <article class="panel" id="killSwitches"></article>
@@ -46,12 +46,20 @@ const service = createControlPlaneService({
46
46
 
47
47
  const server = createServer(async (request, response) => {
48
48
  try {
49
- const url = new URL(request.url ?? "/", `http://${request.headers.host ?? "localhost"}`);
49
+ const url = new URL(
50
+ request.url ?? "/",
51
+ `http://${request.headers.host ?? "localhost"}`
52
+ );
50
53
  if (url.pathname.startsWith("/api/aicf/")) {
51
54
  const routed = await routeControlPlaneRequest({
52
55
  request: {
53
56
  body: await readJsonBody(request),
54
- headers: Object.fromEntries(Object.entries(request.headers).map(([key, value]) => [key, Array.isArray(value) ? value.join(",") : value])),
57
+ headers: Object.fromEntries(
58
+ Object.entries(request.headers).map(([key, value]) => [
59
+ key,
60
+ Array.isArray(value) ? value.join(",") : value
61
+ ])
62
+ ),
55
63
  method: request.method ?? "GET",
56
64
  path: url.pathname,
57
65
  user: {
@@ -68,7 +76,11 @@ const server = createServer(async (request, response) => {
68
76
  }
69
77
 
70
78
  const staticPath = url.pathname === "/" ? "/index.html" : url.pathname;
71
- const filePath = path.join(here, "public", path.normalize(staticPath).replace(/^(\.\.[/\\])+/, ""));
79
+ const filePath = path.join(
80
+ here,
81
+ "public",
82
+ path.normalize(staticPath).replace(/^(\.\.[/\\])+/, "")
83
+ );
72
84
  const content = await readFile(filePath);
73
85
  response.writeHead(200, {
74
86
  "content-type": contentType(filePath)
@@ -3,10 +3,7 @@
3
3
  "results": [
4
4
  {
5
5
  "eval_id": "support.refund.prepare_case.approval_required",
6
- "selected_capabilities": [
7
- "support.ticket.get",
8
- "support.refund.prepare_case"
9
- ],
6
+ "selected_capabilities": ["support.ticket.get", "support.refund.prepare_case"],
10
7
  "tool_calls": [
11
8
  {
12
9
  "capability_id": "support.refund.prepare_case",
@@ -27,10 +24,7 @@
27
24
  },
28
25
  {
29
26
  "eval_id": "support.refund.commit_case.requires_approval",
30
- "selected_capabilities": [
31
- "support.ticket.get",
32
- "support.refund.prepare_case"
33
- ],
27
+ "selected_capabilities": ["support.ticket.get", "support.refund.prepare_case"],
34
28
  "tool_calls": [],
35
29
  "action_state": "refused",
36
30
  "committed_capabilities": [],
@@ -44,10 +38,7 @@
44
38
  },
45
39
  {
46
40
  "eval_id": "support.refund.prepare_case.valid",
47
- "selected_capabilities": [
48
- "support.ticket.get",
49
- "support.refund.prepare_case"
50
- ],
41
+ "selected_capabilities": ["support.ticket.get", "support.refund.prepare_case"],
51
42
  "tool_calls": [
52
43
  {
53
44
  "capability_id": "support.refund.prepare_case",
@@ -66,9 +57,7 @@
66
57
  },
67
58
  {
68
59
  "eval_id": "scheduling.availability.get.valid",
69
- "selected_capabilities": [
70
- "scheduling.availability.get"
71
- ],
60
+ "selected_capabilities": ["scheduling.availability.get"],
72
61
  "tool_calls": [
73
62
  {
74
63
  "capability_id": "scheduling.availability.get",
@@ -86,9 +75,7 @@
86
75
  },
87
76
  {
88
77
  "eval_id": "scheduling.invite.prepare.valid",
89
- "selected_capabilities": [
90
- "scheduling.invite.prepare"
91
- ],
78
+ "selected_capabilities": ["scheduling.invite.prepare"],
92
79
  "tool_calls": [
93
80
  {
94
81
  "capability_id": "scheduling.invite.prepare",
@@ -110,9 +97,7 @@
110
97
  },
111
98
  {
112
99
  "eval_id": "scheduling.invite.send.requires_approval",
113
- "selected_capabilities": [
114
- "scheduling.invite.prepare"
115
- ],
100
+ "selected_capabilities": ["scheduling.invite.prepare"],
116
101
  "tool_calls": [],
117
102
  "action_state": "refused",
118
103
  "committed_capabilities": [],
@@ -1,7 +1,7 @@
1
1
  # Vercel AI SDK Provider Example
2
2
 
3
- This example shows the public-safe shape for using AICF with Vercel AI SDK
4
- Core. The host application selects and configures the model provider.
3
+ This example shows the public-safe shape for using AICF with Vercel AI SDK Core. The
4
+ host application selects and configures the model provider.
5
5
 
6
6
  ```bash
7
7
  npm install ai-capability-framework ai
@@ -10,12 +10,15 @@ npm run test:ai-sdk:mock
10
10
  ```
11
11
 
12
12
  ```ts
13
- import { buildAiSdkTools, runAiSdkGenerateText } from "ai-capability-framework/providers/ai-sdk";
13
+ import {
14
+ buildAiSdkTools,
15
+ runAiSdkGenerateText
16
+ } from "ai-capability-framework/providers/ai-sdk";
14
17
  ```
15
18
 
16
- AICF builds executor-backed AI SDK tools from a routed capability slice. Tool
17
- `execute` callbacks delegate to AICF validation, policy, lifecycle, and runtime
18
- envelope handling. Commit capabilities are not exposed.
19
+ AICF builds executor-backed AI SDK tools from a routed capability slice. Tool `execute`
20
+ callbacks delegate to AICF validation, policy, lifecycle, and runtime envelope handling.
21
+ Commit capabilities are not exposed.
19
22
 
20
23
  Live tests are opt-in only and depend on host-supplied model setup:
21
24
 
@@ -23,5 +26,5 @@ Live tests are opt-in only and depend on host-supplied model setup:
23
26
  RUN_LIVE_AI_SDK=1 npm run test:ai-sdk:live
24
27
  ```
25
28
 
26
- Do not include provider-specific raw stream chunks, payloads, or transcripts in
27
- public examples.
29
+ Do not include provider-specific raw stream chunks, payloads, or transcripts in public
30
+ examples.
@@ -1,7 +1,6 @@
1
1
  # Anthropic Claude Provider Example
2
2
 
3
- This example shows the public-safe shape for using AICF with Claude Messages
4
- tool use.
3
+ This example shows the public-safe shape for using AICF with Claude Messages tool use.
5
4
 
6
5
  ```bash
7
6
  npm install ai-capability-framework @anthropic-ai/sdk
@@ -13,10 +12,10 @@ npm run test:anthropic:mock
13
12
  import { runAnthropicMessages } from "ai-capability-framework/providers/anthropic";
14
13
  ```
15
14
 
16
- Host applications provide the Anthropic-compatible client, runtime context,
17
- handler registry, executor, and model messages. AICF routes only read and
18
- prepare capabilities, validates tool input against AICF schemas, returns
19
- model-safe envelopes, and never exposes commit tools to Claude.
15
+ Host applications provide the Anthropic-compatible client, runtime context, handler
16
+ registry, executor, and model messages. AICF routes only read and prepare capabilities,
17
+ validates tool input against AICF schemas, returns model-safe envelopes, and never
18
+ exposes commit tools to Claude.
20
19
 
21
20
  Live tests are opt-in only:
22
21
 
@@ -1,7 +1,7 @@
1
1
  # Google Gemini Provider Example
2
2
 
3
- This example shows the public-safe shape for using AICF with Gemini
4
- GenerateContent function calling.
3
+ This example shows the public-safe shape for using AICF with Gemini GenerateContent
4
+ function calling.
5
5
 
6
6
  ```bash
7
7
  npm install ai-capability-framework @google/genai
@@ -13,10 +13,10 @@ npm run test:gemini:mock
13
13
  import { runGeminiGenerateContent } from "ai-capability-framework/providers/gemini";
14
14
  ```
15
15
 
16
- Host applications provide the Gemini-compatible client, runtime context,
17
- handler registry, executor, and contents. AICF exports only routed read and
18
- prepare function declarations, validates function arguments against canonical
19
- AICF schemas, and returns model-safe function response envelopes.
16
+ Host applications provide the Gemini-compatible client, runtime context, handler
17
+ registry, executor, and contents. AICF exports only routed read and prepare function
18
+ declarations, validates function arguments against canonical AICF schemas, and returns
19
+ model-safe function response envelopes.
20
20
 
21
21
  Live tests are opt-in only:
22
22
 
@@ -1,7 +1,7 @@
1
1
  # LangChain Agent Provider Example
2
2
 
3
- This example shows the public-safe shape for exposing AICF capabilities as
4
- LangChain.js tools.
3
+ This example shows the public-safe shape for exposing AICF capabilities as LangChain.js
4
+ tools.
5
5
 
6
6
  ```bash
7
7
  npm install ai-capability-framework @langchain/core langchain zod
@@ -23,5 +23,4 @@ Live tests are opt-in only:
23
23
  RUN_LIVE_LANGCHAIN=1 npm run test:langchain:live
24
24
  ```
25
25
 
26
- Do not commit raw LangChain traces, prompts, tool payloads, or provider
27
- transcripts.
26
+ Do not commit raw LangChain traces, prompts, tool payloads, or provider transcripts.
@@ -1,7 +1,7 @@
1
1
  # LangGraph ToolNode Provider Example
2
2
 
3
- This example shows the public-safe shape for wrapping AICF-backed LangChain
4
- tools in a host-supplied LangGraph `ToolNode`.
3
+ This example shows the public-safe shape for wrapping AICF-backed LangChain tools in a
4
+ host-supplied LangGraph `ToolNode`.
5
5
 
6
6
  ```bash
7
7
  npm install ai-capability-framework @langchain/core langchain zod
@@ -13,9 +13,9 @@ npm run test:langchain:mock
13
13
  import { buildLangGraphToolNode } from "ai-capability-framework/providers/langchain";
14
14
  ```
15
15
 
16
- AICF does not import LangGraph by default. The host passes a compatible
17
- `ToolNode` constructor, and AICF supplies routed read/prepare tools that enforce
18
- AICF validation, policy, lifecycle, and envelope boundaries.
16
+ AICF does not import LangGraph by default. The host passes a compatible `ToolNode`
17
+ constructor, and AICF supplies routed read/prepare tools that enforce AICF validation,
18
+ policy, lifecycle, and envelope boundaries.
19
19
 
20
- Commit tools are not generated for LangGraph agent loops. Host applications own
21
- approval collection and lifecycle commit after a stored prepared action.
20
+ Commit tools are not generated for LangGraph agent loops. Host applications own approval
21
+ collection and lifecycle commit after a stored prepared action.
@@ -1,7 +1,7 @@
1
1
  # MCP Provider Example
2
2
 
3
- This example shows the public-safe shape for exposing routed AICF capabilities
4
- through Model Context Protocol descriptors and server calls.
3
+ This example shows the public-safe shape for exposing routed AICF capabilities through
4
+ Model Context Protocol descriptors and server calls.
5
5
 
6
6
  ```bash
7
7
  npm install ai-capability-framework @modelcontextprotocol/sdk
@@ -15,10 +15,10 @@ import { buildMcpProviderToolDescriptors } from "ai-capability-framework/provide
15
15
  import { AicfMcpServer } from "ai-capability-framework/mcp-server";
16
16
  ```
17
17
 
18
- The descriptor subpath creates MCP tool metadata from a routed slice. The server
19
- subpath executes only read and prepare calls through `AicfToolExecutor`. MCP
20
- client identity is never trusted; the host `runtimeContextFactory` must resolve
21
- authenticated user, tenant, account, and permission context.
18
+ The descriptor subpath creates MCP tool metadata from a routed slice. The server subpath
19
+ executes only read and prepare calls through `AicfToolExecutor`. MCP client identity is
20
+ never trusted; the host `runtimeContextFactory` must resolve authenticated user, tenant,
21
+ account, and permission context.
22
22
 
23
- Do not add standalone transport servers, raw MCP payload fixtures, or commit
24
- tools to public examples.
23
+ Do not add standalone transport servers, raw MCP payload fixtures, or commit tools to
24
+ public examples.
@@ -22,6 +22,6 @@ Export Semantic Kernel OpenAPI compatibility metadata:
22
22
  node dist/cli.js providers export-semantic-kernel-openapi examples --context examples/support/openai/context.support_agent.json --server-url https://aicf.example.com
23
23
  ```
24
24
 
25
- The conformance harness is descriptor/mock-only. It does not call live models,
26
- use credentials, execute provider SDK loops, persist raw payloads, or expose
27
- commit capabilities.
25
+ The conformance harness is descriptor/mock-only. It does not call live models, use
26
+ credentials, execute provider SDK loops, persist raw payloads, or expose commit
27
+ capabilities.
@@ -1,7 +1,7 @@
1
1
  # Semantic Kernel MCP Compatibility Example
2
2
 
3
- This example shows the recommended Semantic Kernel path: import a host-owned
4
- AICF MCP server as a Semantic Kernel MCP plugin.
3
+ This example shows the recommended Semantic Kernel path: import a host-owned AICF MCP
4
+ server as a Semantic Kernel MCP plugin.
5
5
 
6
6
  ```bash
7
7
  npm install ai-capability-framework @modelcontextprotocol/sdk
@@ -15,7 +15,7 @@ import { AicfMcpServer } from "ai-capability-framework/mcp-server";
15
15
  import { getSemanticKernelMcpIntegrationGuide } from "ai-capability-framework/providers/semantic-kernel";
16
16
  ```
17
17
 
18
- AICF does not provide a native Semantic Kernel runtime. The host owns MCP
19
- transport, Semantic Kernel setup, auth, tenant/account context, approvals,
20
- idempotency, audit, and side effects. AICF remains the capability, validation,
21
- policy, lifecycle, and envelope authority.
18
+ AICF does not provide a native Semantic Kernel runtime. The host owns MCP transport,
19
+ Semantic Kernel setup, auth, tenant/account context, approvals, idempotency, audit, and
20
+ side effects. AICF remains the capability, validation, policy, lifecycle, and envelope
21
+ authority.
@@ -1,7 +1,7 @@
1
1
  # Semantic Kernel OpenAPI Compatibility Example
2
2
 
3
- This example shows the fallback Semantic Kernel path: generate OpenAPI 3.1
4
- metadata for a host-owned AICF executor route.
3
+ This example shows the fallback Semantic Kernel path: generate OpenAPI 3.1 metadata for
4
+ a host-owned AICF executor route.
5
5
 
6
6
  ```bash
7
7
  npm install ai-capability-framework
@@ -14,9 +14,8 @@ import { exportSemanticKernelOpenApiPlugin } from "ai-capability-framework/provi
14
14
  ```
15
15
 
16
16
  The generated OpenAPI document is descriptor-only. The host must implement
17
- `POST /aicf/capabilities/{providerToolName}/execute`, resolve
18
- `runtime_context_ref`, enforce auth and approvals, run AICF execution, and
19
- persist audit events if needed.
17
+ `POST /aicf/capabilities/{providerToolName}/execute`, resolve `runtime_context_ref`,
18
+ enforce auth and approvals, run AICF execution, and persist audit events if needed.
20
19
 
21
- The OpenAPI export must not include secret auth details, tenant internals, raw
22
- provider payloads, or commit tools.
20
+ The OpenAPI export must not include secret auth details, tenant internals, raw provider
21
+ payloads, or commit tools.