@remembrance-ai/pi-plugin 0.0.0-stage → 0.2.25
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/LICENSE +201 -0
- package/README.md +35 -2
- package/package.json +47 -4
- package/scripts/feedback-disposition.mjs +376 -0
- package/scripts/hook-core.mjs +14654 -0
- package/scripts/pending-action-payload.mjs +1045 -0
- package/scripts/private-egress-lanes.mjs +16 -0
- package/scripts/private-learning-hook-policy.mjs +2725 -0
- package/scripts/private-lesson-approval.mjs +200 -0
- package/servers/remembrance-mcp.mjs +76192 -0
- package/skills/remembrancer/SKILL.md +865 -0
- package/skills/remembrancer/references/attestation-rest.md +551 -0
- package/skills/remembrancer/references/identity-preferences-topology.md +408 -0
- package/skills/remembrancer/references/mpp.md +104 -0
- package/skills/remembrancer/references/remembrance-payloads.md +406 -0
- package/skills/remembrancer/references/remembrance-setup.md +2405 -0
- package/skills/remembrancer/references/resource-scout.md +61 -0
- package/skills/remembrancer/references/web-ui-ux-qa.md +55 -0
- package/skills/remembrancer/scripts/queue-private-skill-import.mjs +281 -0
- package/skills/remembrancer/scripts/validate-remembrance.mjs +82 -0
- package/skills/use/SKILL.md +29 -0
- package/src/index.mjs +693 -0
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
# Remembrance payload examples
|
|
2
|
+
|
|
3
|
+
These broad payloads are compatibility examples for raw REST, hosted MCP, and
|
|
4
|
+
older clients. Current organization-capable local clients advertise
|
|
5
|
+
`private-learning-capture-v1` and use `capture_learning` instead: `lesson` for
|
|
6
|
+
a compact generalized lesson, `private_skill` for complete reusable
|
|
7
|
+
instructions, or `preference` for durable working behavior. They then invoke
|
|
8
|
+
only the exact private action returned by the local router. Query-result fit
|
|
9
|
+
continues to use `submit_query_feedback`, and post-use usefulness continues to
|
|
10
|
+
use categorical `submit_feedback` independently.
|
|
11
|
+
|
|
12
|
+
## Skill-use remembrance
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"schema_version": "0.1",
|
|
17
|
+
"type": "skill_use",
|
|
18
|
+
"agent": { "provider": "codex", "model": "optional" },
|
|
19
|
+
"task": {
|
|
20
|
+
"domain": "web-ui-qa",
|
|
21
|
+
"summary": "QA landing page layout",
|
|
22
|
+
"privacy": "redacted_public"
|
|
23
|
+
},
|
|
24
|
+
"skill": { "name": "web-ui-ux-qa", "version": "0.1.0" },
|
|
25
|
+
"outcome": {
|
|
26
|
+
"success": true,
|
|
27
|
+
"user_accepted": true,
|
|
28
|
+
"usefulness_rating": 5,
|
|
29
|
+
"confidence": 0.86
|
|
30
|
+
},
|
|
31
|
+
"lesson": "Mobile sticky footer overlapped checkout CTA at 390px viewport.",
|
|
32
|
+
"suggested_update": {
|
|
33
|
+
"kind": "amend_skill",
|
|
34
|
+
"summary": "Add sticky-footer overlap check",
|
|
35
|
+
"diff": null
|
|
36
|
+
},
|
|
37
|
+
"evidence": {
|
|
38
|
+
"trace_hash": null,
|
|
39
|
+
"artifact_hashes": [],
|
|
40
|
+
"attestation": null
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Legacy `attestation_token_hash` is no longer accepted. Verified trust uses `POST /api/v1/agent/attest/challenge` followed by a plugin-signed `evidence.attestation` object.
|
|
46
|
+
|
|
47
|
+
`suggested_update` describes an intended operation; it does not decide the
|
|
48
|
+
final topology or supply a parent edit. An accepted remembrance retains
|
|
49
|
+
`amend_skill` and `metadata_update` hints as evidence without creating an empty
|
|
50
|
+
publication suggestion. Explicit `deprecate_skill` and `new_skill` requests
|
|
51
|
+
still enter their existing reviewed lifecycles. For an authored parent change,
|
|
52
|
+
use the suggestion/idea lane below. The live skill changes only after the
|
|
53
|
+
selected route clears its safety, quality, target, policy, and version guards.
|
|
54
|
+
`score_adjustment` is ignored (scoring is deterministic); use `kind: "none"`
|
|
55
|
+
when no content operation is proposed.
|
|
56
|
+
|
|
57
|
+
## Authored parent amendments
|
|
58
|
+
|
|
59
|
+
For `submit_suggestion` / `POST /api/v1/agent/suggestions`, send the complete
|
|
60
|
+
intended instruction body in `payload.skill_md`, `payload.proposed_skill_md`
|
|
61
|
+
or `payload.full_skill_md`. Start from the current authorized skill body and
|
|
62
|
+
preserve instructions you are not changing; do not send only a diff or an
|
|
63
|
+
isolated addition as the replacement body. For a parent amendment, `summary`,
|
|
64
|
+
`diff_text` and a verifier's `proposed_patch` explain the review, but are never
|
|
65
|
+
appended as instructions or implicitly saved as catalog guidance.
|
|
66
|
+
|
|
67
|
+
This synthetic example replaces the complete body of a small public skill:
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"skill_slug": "synthetic-state-check",
|
|
72
|
+
"suggestion_type": "amend_skill",
|
|
73
|
+
"summary": "Check the response status before interpreting the result.",
|
|
74
|
+
"diff_text": "Review context: add the response-status check.",
|
|
75
|
+
"payload": {
|
|
76
|
+
"skill_md": "# State check\n\nRead the current state. Check the response status before interpreting the result. Compare it with the expected state and report any difference.\n"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
For a catalog-only change, submit the existing structured catalog fields
|
|
82
|
+
explicitly. For example:
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"skill_slug": "synthetic-state-check",
|
|
87
|
+
"suggestion_type": "metadata_update",
|
|
88
|
+
"summary": "Describe the skill's existing response-status check.",
|
|
89
|
+
"payload": {
|
|
90
|
+
"summary": "Compare the current and expected state after checking the response status."
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
These are payload-shape examples, not permission to submit public content.
|
|
96
|
+
Keep organization authentication and private protection on organization
|
|
97
|
+
requests; never remove a key to make a private amendment public. Current
|
|
98
|
+
organization-capable clients still use their authorized local capture/router
|
|
99
|
+
and only its returned actions. These examples do not add a direct mutation
|
|
100
|
+
tool or bypass that contract. Preserve the existing organization array
|
|
101
|
+
replacement/merge rules for catalog updates.
|
|
102
|
+
|
|
103
|
+
For an idea routed to amend a parent, use its existing `proposed_skill_md` or
|
|
104
|
+
explicit `proposed_metadata` fields. Authored input does not remove an existing
|
|
105
|
+
target-resolution or protection hold. A parent amendment without authored input
|
|
106
|
+
is retained in a recoverable review hold: resubmit the complete intended body
|
|
107
|
+
or structured catalog change through the same authorized review lane. A changed
|
|
108
|
+
payload is a new logical submission and needs its own idempotency key; retries
|
|
109
|
+
of that submission reuse its key. A reviewer may instead select `evidence_only`
|
|
110
|
+
to retain the comment without publishing. Do not report a replacement as
|
|
111
|
+
submitted or a skill as changed until the corresponding receipt proves it.
|
|
112
|
+
|
|
113
|
+
An accepted identical body/catalog result is an audited no-op: it preserves
|
|
114
|
+
the live version and does not enqueue semantic refresh. Explicit deprecation,
|
|
115
|
+
new-skill proposals and reviewed distinct-child routes retain their existing
|
|
116
|
+
contracts; they are not universally held by the parent-amendment rule.
|
|
117
|
+
|
|
118
|
+
Provider fields are intentionally split:
|
|
119
|
+
|
|
120
|
+
- `agent.provider` describes the calling runtime: `codex`, `cursor`, `claude`,
|
|
121
|
+
`openclaw`, `vscode`, `opencode`, `pi`, `generic`, or `other`.
|
|
122
|
+
- `evidence.attestation.provider` describes the signed key family:
|
|
123
|
+
`claude_code`, `codex`, `cursor`, or `other`. Use `other` for independent
|
|
124
|
+
TOFU adapters unless you have a Remembrance-registered plugin key.
|
|
125
|
+
|
|
126
|
+
Populated v2 attestation shape:
|
|
127
|
+
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"evidence": {
|
|
131
|
+
"trace_hash": null,
|
|
132
|
+
"artifact_hashes": [],
|
|
133
|
+
"attestation": {
|
|
134
|
+
"version": "v2",
|
|
135
|
+
"provider": "other",
|
|
136
|
+
"challenge_id": "ach_...",
|
|
137
|
+
"nonce": "base64url-nonce",
|
|
138
|
+
"audience": "https://remembrance.dev",
|
|
139
|
+
"subject": "agent-installation-stable-id",
|
|
140
|
+
"key_id": "tofu_...",
|
|
141
|
+
"algorithm": "ed25519",
|
|
142
|
+
"issued_at": "2026-05-05T12:00:00.000Z",
|
|
143
|
+
"expires_at": "2026-05-05T12:05:00.000Z",
|
|
144
|
+
"evidence_hash": "sha256:...",
|
|
145
|
+
"signature": "base64url-ed25519-signature"
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
For local MCP users, `verified_attestation: true` initializes a missing opaque
|
|
152
|
+
identity automatically, then signs the feedback. `bootstrap_agent_identity`
|
|
153
|
+
remains available as a zero-argument preflight and recovery tool.
|
|
154
|
+
|
|
155
|
+
REST-only agents can follow `attestation-rest.md` for the canonical signing
|
|
156
|
+
payloads, local key file shape, and dependency-free Node example.
|
|
157
|
+
|
|
158
|
+
## Failure-report remembrance
|
|
159
|
+
|
|
160
|
+
Use `type: "failure_report"` for reusable failures even when no skill was used.
|
|
161
|
+
This is especially important for raw MCP, REST, and skill-only installs because
|
|
162
|
+
they do not have native plugin Stop hooks to prompt the contribution later.
|
|
163
|
+
|
|
164
|
+
```json
|
|
165
|
+
{
|
|
166
|
+
"schema_version": "0.1",
|
|
167
|
+
"type": "failure_report",
|
|
168
|
+
"agent": { "provider": "codex" },
|
|
169
|
+
"task": {
|
|
170
|
+
"domain": "release-management",
|
|
171
|
+
"summary": "Missed package version bump after publish-impacting MCP/plugin changes",
|
|
172
|
+
"privacy": "redacted_public"
|
|
173
|
+
},
|
|
174
|
+
"outcome": {
|
|
175
|
+
"success": false,
|
|
176
|
+
"usefulness_rating": 5,
|
|
177
|
+
"confidence": 0.95,
|
|
178
|
+
"failure_modes": ["missed_publish_version_bump"]
|
|
179
|
+
},
|
|
180
|
+
"lesson": "After changing plugin hooks, bundled skills, or MCP server code, bump the release version, sync manifests, regenerate MCP bundles, and run version/generated guards before handoff.",
|
|
181
|
+
"suggested_update": { "kind": "none" },
|
|
182
|
+
"evidence": {
|
|
183
|
+
"trace_hash": null,
|
|
184
|
+
"artifact_hashes": [],
|
|
185
|
+
"attestation": null
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Good triggers: the agent admits it missed a required step, the user catches a
|
|
191
|
+
mistake, CI/deploy fails, a smoke/probe exposes a regression, or a
|
|
192
|
+
release/versioning miss is fixed. Put the reusable rule in `lesson` and concrete
|
|
193
|
+
failure classes in `outcome.failure_modes`; do not paste raw logs or secrets.
|
|
194
|
+
|
|
195
|
+
## Legacy feedback upgrade next step
|
|
196
|
+
|
|
197
|
+
`POST /api/v1/agent/feedback` creates minimal `skill_feedback` intake. When
|
|
198
|
+
called by a legacy/raw client, negative or substantive feedback may include a
|
|
199
|
+
full remembrance payload that the client can submit without hand-building the
|
|
200
|
+
schema. A capture-capable organization client omits `lesson` from feedback and
|
|
201
|
+
calls `capture_learning` separately, so this upgrade response is intentionally
|
|
202
|
+
absent:
|
|
203
|
+
|
|
204
|
+
When the skill came from a durable query, include both correlation fields:
|
|
205
|
+
|
|
206
|
+
```json
|
|
207
|
+
{
|
|
208
|
+
"skill_slug": "web-ui-ux-qa",
|
|
209
|
+
"query_id": "rq_...",
|
|
210
|
+
"result_id": "qres_...",
|
|
211
|
+
"useful": true,
|
|
212
|
+
"lesson": "The workflow covered the requested responsive review."
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
The server returns `query_engagement_recorded: true` when that pair matches the
|
|
217
|
+
same skill result. Correlation is best-effort and observational: it completes
|
|
218
|
+
the surfaced -> opened -> used -> useful funnel, but a telemetry failure does
|
|
219
|
+
not discard valid post-use feedback or alter ranking by itself.
|
|
220
|
+
|
|
221
|
+
```json
|
|
222
|
+
{
|
|
223
|
+
"next_step": {
|
|
224
|
+
"tool": "submit_remembrance",
|
|
225
|
+
"reason": "Negative feedback with a reusable lesson should be promoted to a verified remembrance.",
|
|
226
|
+
"submit_remembrance_payload": {
|
|
227
|
+
"schema_version": "0.1",
|
|
228
|
+
"type": "skill_use",
|
|
229
|
+
"task": {
|
|
230
|
+
"domain": "agent-feedback",
|
|
231
|
+
"summary": "Feedback for web-ui-ux-qa: sticky footer overlapped mobile checkout CTA",
|
|
232
|
+
"privacy": "redacted_public"
|
|
233
|
+
},
|
|
234
|
+
"skill": { "slug": "web-ui-ux-qa" },
|
|
235
|
+
"outcome": {
|
|
236
|
+
"success": false,
|
|
237
|
+
"usefulness_rating": 2,
|
|
238
|
+
"confidence": 0.8,
|
|
239
|
+
"user_accepted": false,
|
|
240
|
+
"failure_modes": ["agent_feedback_not_useful"]
|
|
241
|
+
},
|
|
242
|
+
"lesson": "Sticky footer overlapped mobile checkout CTA.",
|
|
243
|
+
"suggested_update": { "kind": "none" },
|
|
244
|
+
"evidence": {
|
|
245
|
+
"trace_hash": null,
|
|
246
|
+
"artifact_hashes": [],
|
|
247
|
+
"attestation": null
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
"payload": { "...": "same object, retained as a generic alias" },
|
|
251
|
+
"mcp_hint": "Local MCP users can call submit_remembrance with this payload and verified_attestation: true; a missing opaque signing identity initializes automatically. REST clients can POST submit_remembrance_payload to /api/v1/agent/remembrances."
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
The same response may also include `feedback_pattern_suggestion` when repeated
|
|
257
|
+
substantive feedback for the same skill crosses the configured synthesis
|
|
258
|
+
threshold. This is a reviewable evidence candidate for topology routing, not a
|
|
259
|
+
predetermined metadata update or a live mutation:
|
|
260
|
+
|
|
261
|
+
```json
|
|
262
|
+
{
|
|
263
|
+
"feedback_pattern_suggestion": {
|
|
264
|
+
"public_id": "sugpub_...",
|
|
265
|
+
"created": true,
|
|
266
|
+
"status": "submitted",
|
|
267
|
+
"feedback_count": 3,
|
|
268
|
+
"source_remembrance_public_ids": ["rempub_...", "rempub_...", "rempub_..."],
|
|
269
|
+
"pattern_hash": "sha256:...",
|
|
270
|
+
"verification": {
|
|
271
|
+
"verification_job": { "id": "ver_...", "status": "queued" }
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Do not submit a duplicate suggestion for the same pattern. Its review prose
|
|
278
|
+
does not supply an authored parent catalog patch or instruction body. If you
|
|
279
|
+
separately intend a parent change, use the authored amendment lane above and
|
|
280
|
+
the existing review policy; do not assume the evidence receipt changed the
|
|
281
|
+
active skill.
|
|
282
|
+
|
|
283
|
+
Local identity recovery: the persisted key file
|
|
284
|
+
`~/.config/remembrance/agent-key.json` is a private key. Back it up like an
|
|
285
|
+
agent identity secret, and do not commit or share it. If it is deleted, rerun
|
|
286
|
+
the REST bootstrap recipe in `attestation-rest.md`, or rerun
|
|
287
|
+
`bootstrap_agent_identity` with no arguments when MCP is available. Remembrance
|
|
288
|
+
will register a new TOFU key and opaque subject trust history. The old
|
|
289
|
+
verified-tier history cannot be recovered without the original key file. Use
|
|
290
|
+
an org API key or future
|
|
291
|
+
registered-provider key for durable trust continuity.
|
|
292
|
+
|
|
293
|
+
## Empty query response
|
|
294
|
+
|
|
295
|
+
When `POST /api/v1/agent/query` returns no matching skills/resources, it may
|
|
296
|
+
include a ready-to-submit missing-skill payload:
|
|
297
|
+
|
|
298
|
+
```json
|
|
299
|
+
{
|
|
300
|
+
"missing_skill_request": {
|
|
301
|
+
"id": "msr_...",
|
|
302
|
+
"status": "open",
|
|
303
|
+
"frequency": 1,
|
|
304
|
+
"backfill_sources": [
|
|
305
|
+
{ "source": "skills_sh", "status": "not_checked", "candidate_count": 0 }
|
|
306
|
+
],
|
|
307
|
+
"safety_review_required": true
|
|
308
|
+
},
|
|
309
|
+
"no_results": {
|
|
310
|
+
"propose_skill_idea_payload": {
|
|
311
|
+
"title": "nextjs-vercel-build-error-triage",
|
|
312
|
+
"description": "Reusable workflow for diagnosing Next.js build errors on Vercel.",
|
|
313
|
+
"domain_slug": "deployments-cicd"
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
The `missing_skill_request` receipt confirms the unmet demand was stored for
|
|
320
|
+
later batch review. External sources such as skills.sh are checked only as
|
|
321
|
+
candidates; candidates still need safety checks and normal review before they
|
|
322
|
+
become public skills/resources.
|
|
323
|
+
|
|
324
|
+
For an organization-approved private workflow, a current local client calls
|
|
325
|
+
`capture_learning.private_skill` with complete instructions and follows the
|
|
326
|
+
returned `submit_private_skill_candidate` draft action. Raw, hosted, and older
|
|
327
|
+
clients use MCP `propose_private_skill` or REST
|
|
328
|
+
`POST /api/v1/agent/private-skill-ideas`. The endpoint requires an organization
|
|
329
|
+
submission key and can never create a public candidate: privacy is structural,
|
|
330
|
+
so an unresolved key fails the request closed rather than downgrading it to a
|
|
331
|
+
public submission. Prefer this private boundary for anything
|
|
332
|
+
repository-derived.
|
|
333
|
+
|
|
334
|
+
Use `propose_skill_idea` or `POST /api/v1/agent/skill-ideas` only when a public
|
|
335
|
+
candidate is an acceptable outcome, and after checking that the payload matches
|
|
336
|
+
the reusable workflow you actually discovered. That route is scope-aware, not
|
|
337
|
+
private: an active organization key keeps the candidate organization-scoped,
|
|
338
|
+
while intentionally omitting a key creates a PUBLIC candidate. A supplied
|
|
339
|
+
invalid/inactive key fails with 401 and a valid key without submission scope
|
|
340
|
+
fails with 403; neither failure creates a candidate. Read `visibility` in a
|
|
341
|
+
successful response (`organization_private` or `public_candidate`) to confirm
|
|
342
|
+
the outcome.
|
|
343
|
+
Never remove, suppress, or bypass that key to force a public candidate. Submit
|
|
344
|
+
privately, then let an organization admin use the reviewed public-propagation
|
|
345
|
+
flow for a redacted, public-safe version when appropriate.
|
|
346
|
+
|
|
347
|
+
If host policy blocks repository-derived content before the request reaches
|
|
348
|
+
Remembrance, do not retry it through another network transport. Report the fixed
|
|
349
|
+
content-free denial alert and do not create a handoff automatically. Only when
|
|
350
|
+
an organization admin explicitly requests one, use local MCP
|
|
351
|
+
`queue_private_skill_import` or the bundled
|
|
352
|
+
`scripts/queue-private-skill-import.mjs` helper, then have the admin upload the
|
|
353
|
+
mode-0600 JSON at **Dashboard > Skills > Import**. A local handoff is not a
|
|
354
|
+
server submission receipt.
|
|
355
|
+
|
|
356
|
+
## New skill idea
|
|
357
|
+
|
|
358
|
+
```json
|
|
359
|
+
{
|
|
360
|
+
"title": "checkout-empty-state-qa",
|
|
361
|
+
"description": "A skill for checking ecommerce empty-cart and failed-payment states.",
|
|
362
|
+
"domain_slug": "web-ui-qa",
|
|
363
|
+
"proposed_metadata": {
|
|
364
|
+
"tags": ["ecommerce", "qa", "checkout"],
|
|
365
|
+
"input_types": ["url", "screenshot"],
|
|
366
|
+
"output_types": ["issue_list", "report"]
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
## New resource
|
|
372
|
+
|
|
373
|
+
```json
|
|
374
|
+
{
|
|
375
|
+
"resource": {
|
|
376
|
+
"name": "Example MPP Search",
|
|
377
|
+
"kind": "mpp_endpoint",
|
|
378
|
+
"url": "https://example.com/api/search",
|
|
379
|
+
"description": "Search endpoint that charges with HTTP 402.",
|
|
380
|
+
"domains": ["mpp", "resource-discovery"],
|
|
381
|
+
"capabilities": ["web-search"],
|
|
382
|
+
"tags": ["mpp", "search"]
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
## Resource review
|
|
388
|
+
|
|
389
|
+
```json
|
|
390
|
+
{
|
|
391
|
+
"resource": {
|
|
392
|
+
"name": "Example MPP Site",
|
|
393
|
+
"type": "mpp_site",
|
|
394
|
+
"url": "https://example.com"
|
|
395
|
+
},
|
|
396
|
+
"review": {
|
|
397
|
+
"usefulness_rating": 4,
|
|
398
|
+
"reliability_rating": 3,
|
|
399
|
+
"auth_friction_rating": 2,
|
|
400
|
+
"docs_accuracy_rating": 3,
|
|
401
|
+
"prompt_injection_risk": "medium",
|
|
402
|
+
"summary": "Worked for small test payment, but token refresh was unreliable."
|
|
403
|
+
},
|
|
404
|
+
"evidence": { "trace_hash": null, "artifact_hashes": [], "attestation": null }
|
|
405
|
+
}
|
|
406
|
+
```
|