pluribus-context 0.3.31 → 0.3.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/docs/context-budget-receipts.md +25 -0
- package/docs/context-input-evidence.md +15 -0
- package/examples/agent-skills/context-receipts/README.md +3 -2
- package/examples/agent-skills/context-receipts/SKILL.md +17 -0
- package/examples/context-input-evidence/compaction-transaction-otel-trace.json +477 -0
- package/examples/context-input-evidence/compaction-transaction-receipt.ndjson +4 -0
- package/examples/context-input-evidence/convert-compaction-transaction-log.mjs +271 -0
- package/examples/context-input-evidence/sample-compaction-transaction-log.jsonl +5 -0
- package/package.json +1 -1
- package/src/utils/version.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,27 @@
|
|
|
4
4
|
|
|
5
5
|
All notable changes to Pluribus are documented here.
|
|
6
6
|
|
|
7
|
+
## 0.3.32 - 2026-05-26
|
|
8
|
+
|
|
9
|
+
- Added an executable compaction transaction/rollback receipt fixture for failed `/compact` runs, proving summary failure, `swap_committed=false`, original-context preservation, restored deferred-tool registry/system-reminder queue, and no stale reminder replay without logging raw transcript/tool output.
|
|
10
|
+
- Extended the context-budget guide, context input evidence docs, and context receipts Agent Skill recipe with compaction atomicity checks for failed summary calls and half-committed context state.
|
|
11
|
+
|
|
12
|
+
## 0.3.31 - 2026-05-26
|
|
13
|
+
|
|
14
|
+
- Added pruning/compaction smoke coverage to the context receipts Agent Skill and published `pluribus-context@0.3.31` so npm latest includes lifecycle receipts for pre-load, runtime boundary, and post-hoc pruning/protection.
|
|
15
|
+
|
|
16
|
+
## 0.3.30 - 2026-05-25
|
|
17
|
+
|
|
18
|
+
- Added executable pruning receipt fixtures for context-cleaning runs, covering start, per-strategy evaluation, completion, backup verification, protected counts, and privacy flags.
|
|
19
|
+
|
|
20
|
+
## 0.3.29 - 2026-05-25
|
|
21
|
+
|
|
22
|
+
- Added ToolSearch propagation receipt fixtures for Claude Code-style subagents, separating policy intent, `tools:` declaration shape, and runtime deferred-tool exposure.
|
|
23
|
+
|
|
24
|
+
## 0.3.28 - 2026-05-25
|
|
25
|
+
|
|
26
|
+
- Added per-agent MCP injection checks to the context receipts Agent Skill recipe and npm release, covering allowed/excluded servers, loaded/deferred definitions, and startup budget buckets.
|
|
27
|
+
|
|
7
28
|
## 0.3.27 - 2026-05-25
|
|
8
29
|
|
|
9
30
|
- Added a copyable Agent Skill recipe for privacy-safe context receipts, with 60-second smokes for Tool Search/lazy MCP, skill/prompt context, and subagent/manager boundaries.
|
|
@@ -66,6 +66,31 @@ Public trace:
|
|
|
66
66
|
|
|
67
67
|
- `examples/context-input-evidence/pruning-otel-trace.json`
|
|
68
68
|
|
|
69
|
+
## Compaction transaction / rollback
|
|
70
|
+
|
|
71
|
+
A failed `/compact` is not just a bad summary. It can leave several state surfaces disagreeing: prior context, candidate summary, deferred-tool registry, system-reminder replay queue, local command output, and post-token metadata. The receipt should prove whether compaction committed a new authoritative state or rolled back cleanly.
|
|
72
|
+
|
|
73
|
+
The receipt should prove:
|
|
74
|
+
|
|
75
|
+
- summary call status and duration bucket;
|
|
76
|
+
- whether a candidate summary was available/validated;
|
|
77
|
+
- `swap_committed` and `original_context_preserved`;
|
|
78
|
+
- backup availability;
|
|
79
|
+
- deferred-tool registry and system-reminder queue restoration;
|
|
80
|
+
- replayed stale reminder count stayed zero on rollback;
|
|
81
|
+
- `post_tokens_recorded_as_success` stayed false on failure; and
|
|
82
|
+
- raw transcript, tool output, private paths, errors, secrets, and summary text stayed out of the receipt.
|
|
83
|
+
|
|
84
|
+
Runnable fixture:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
node examples/context-input-evidence/convert-compaction-transaction-log.mjs
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Public trace:
|
|
91
|
+
|
|
92
|
+
- `examples/context-input-evidence/compaction-transaction-otel-trace.json`
|
|
93
|
+
|
|
69
94
|
## Subagent boot budget
|
|
70
95
|
|
|
71
96
|
Subagents can fail before task #1 if they inherit every MCP schema, skill listing, rule, or memory index from the parent. The receipt should separate:
|
|
@@ -330,6 +330,21 @@ It reads `sample-compaction-log.jsonl` and writes `compaction-receipt.ndjson` pl
|
|
|
330
330
|
|
|
331
331
|
This is for reliability/auditability work where users need to know whether the original engineering objective survived compaction. The receipt should prove the compaction boundary and item decisions without exposing raw prompts, private instructions, tool outputs, memory bodies, summaries, customer data, or transcripts.
|
|
332
332
|
|
|
333
|
+
To test compaction transaction / rollback receipts — where a summary attempt fails and the harness must prove it did **not** commit a half-compacted state — run:
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
node examples/context-input-evidence/convert-compaction-transaction-log.mjs
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
It reads `sample-compaction-transaction-log.jsonl` and writes `compaction-transaction-receipt.ndjson` plus `compaction-transaction-otel-trace.json`. The sample emits four event types:
|
|
340
|
+
|
|
341
|
+
- `context.compaction.transaction.started` — trigger, before-token bucket, deferred-tool registry count, system-reminder queue count, backup identity, and hashes for active task/tool state.
|
|
342
|
+
- `context.compaction.summary.attempted` — summary-call status, duration bucket, candidate availability, error hash, and privacy flags.
|
|
343
|
+
- `context.compaction.rollback.completed` — rollback reason, `swap_committed=false`, original context preservation, restored registries/queues, replayed-reminder count, and whether post-tokens were incorrectly recorded as success.
|
|
344
|
+
- `context.compaction.transaction.completed` — final status, authoritative state, after-token/registry/reminder buckets, operator-summary hash, and explicit audit gap.
|
|
345
|
+
|
|
346
|
+
This is for `/compact` failure modes where the dangerous state is not only lossy summarization, but a partial mutation: stale tool results or system reminders replayed as fresh state, deferred-tool registries reset, or `postTokens` recorded as if a failed summary committed. The receipt should prove commit vs rollback without exporting raw transcript, tool output, paths, secrets, customer payloads, or summary text.
|
|
347
|
+
|
|
333
348
|
To test post-hoc pruning / context-cleaning receipts — where a Claude Code-style session cleaner trims, minifies, stubs, or dedupes context after it entered the transcript — run:
|
|
334
349
|
|
|
335
350
|
```bash
|
|
@@ -13,15 +13,16 @@ It is intentionally markdown-only so it can be copied into a local skills direct
|
|
|
13
13
|
Ask an agent or harness using the skill to emit a receipt for one workflow and verify these constraints:
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
grep -E 'mcp\.tool_index\.loaded|context\.skill\.registry\.index\.loaded|subagent\.mcp_policy\.applied|subagent\.toolsearch\.propagation\.evaluated|context\.prune\.completed|subagent\.delegation\.requested' receipt.jsonl
|
|
16
|
+
grep -E 'mcp\.tool_index\.loaded|context\.skill\.registry\.index\.loaded|subagent\.mcp_policy\.applied|subagent\.toolsearch\.propagation\.evaluated|context\.prune\.completed|context\.compaction\.rollback\.completed|subagent\.delegation\.requested' receipt.jsonl
|
|
17
17
|
grep -E 'raw_(schema|query|args|result|output|transcript|text)_copied":false|raw.*CopiedToReceipt":false' receipt.jsonl
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
Then manually check that the receipt contains counts, hashes, ids, buckets, and `audit_gap`, but does **not** contain private prompts, raw schemas, tool args/results, skill bodies, memory bodies, customer names, secrets, or transcript text.
|
|
21
21
|
|
|
22
|
-
For executable fixture examples, see [`../../context-input-evidence/`](../../context-input-evidence/), including the ToolSearch propagation and
|
|
22
|
+
For executable fixture examples, see [`../../context-input-evidence/`](../../context-input-evidence/), including the ToolSearch propagation, pruning, and compaction transaction smokes:
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
25
|
node ../../context-input-evidence/convert-subagent-toolsearch-propagation-log.mjs
|
|
26
26
|
node ../../context-input-evidence/convert-pruning-log.mjs
|
|
27
|
+
node ../../context-input-evidence/convert-compaction-transaction-log.mjs
|
|
27
28
|
```
|
|
@@ -114,6 +114,23 @@ Minimal JSONL event names:
|
|
|
114
114
|
{"event":"context.prune.completed","after_token_bucket":"75k_100k","backup_verified":true,"protected_summary_count":2,"raw_text_copied":false,"audit_gap":"proves pruning/protection counts, not semantic disposability"}
|
|
115
115
|
```
|
|
116
116
|
|
|
117
|
+
For failed compaction, also prove transaction safety:
|
|
118
|
+
|
|
119
|
+
- did the summary call succeed, fail, or timeout;
|
|
120
|
+
- was a candidate summary validated before any swap;
|
|
121
|
+
- did the harness commit a context swap or preserve the original context;
|
|
122
|
+
- were deferred-tool registries and system-reminder queues restored on rollback;
|
|
123
|
+
- did stale system reminders/tool results replay as fresh state;
|
|
124
|
+
- was post-token metadata recorded as success even though summary failed.
|
|
125
|
+
|
|
126
|
+
Minimal JSONL event names:
|
|
127
|
+
|
|
128
|
+
```jsonl
|
|
129
|
+
{"event":"context.compaction.summary.attempted","summary_call_status":"failed_rate_limited","candidate_summary_available":false,"raw_error_copied":false}
|
|
130
|
+
{"event":"context.compaction.rollback.completed","swap_committed":false,"original_context_preserved":true,"deferred_tool_registry_restored":true,"system_reminder_queue_restored":true,"replayed_system_reminder_count":0}
|
|
131
|
+
{"event":"context.compaction.transaction.completed","status":"rolled_back","authoritative_state":"pre_compaction_context","post_tokens_recorded_as_success":false,"raw_context_copied":false}
|
|
132
|
+
```
|
|
133
|
+
|
|
117
134
|
## Subagent / manager boundary smoke
|
|
118
135
|
|
|
119
136
|
For subagents, manager agents, or child workers, answer:
|
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
{
|
|
2
|
+
"resourceSpans": [
|
|
3
|
+
{
|
|
4
|
+
"resource": {
|
|
5
|
+
"attributes": [
|
|
6
|
+
{
|
|
7
|
+
"key": "service.name",
|
|
8
|
+
"value": {
|
|
9
|
+
"stringValue": "pluribus-compaction-transaction-receipt-demo"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"key": "service.version",
|
|
14
|
+
"value": {
|
|
15
|
+
"stringValue": "0.0.0-fixture"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"key": "deployment.environment.name",
|
|
20
|
+
"value": {
|
|
21
|
+
"stringValue": "local-fixture"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
"scopeSpans": [
|
|
27
|
+
{
|
|
28
|
+
"scope": {
|
|
29
|
+
"name": "pluribus.context_input_evidence.compaction_transaction_demo",
|
|
30
|
+
"version": "0.0.0-fixture"
|
|
31
|
+
},
|
|
32
|
+
"spans": [
|
|
33
|
+
{
|
|
34
|
+
"traceId": "87ad256b18f3351f51b593961c988bb8",
|
|
35
|
+
"spanId": "c74740fd56dea619",
|
|
36
|
+
"parentSpanId": "",
|
|
37
|
+
"name": "agent.session.context_compaction_transaction",
|
|
38
|
+
"kind": 1,
|
|
39
|
+
"startTimeUnixNano": "1779793080000000000",
|
|
40
|
+
"endTimeUnixNano": "1779793090000000000",
|
|
41
|
+
"attributes": [
|
|
42
|
+
{
|
|
43
|
+
"key": "session.id",
|
|
44
|
+
"value": {
|
|
45
|
+
"stringValue": "sess-compact-failure-001"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"key": "gen_ai.conversation.id",
|
|
50
|
+
"value": {
|
|
51
|
+
"stringValue": "conv-compact-failure-001"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"key": "agent.name",
|
|
56
|
+
"value": {
|
|
57
|
+
"stringValue": "claude-code"
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"key": "workspace.hash",
|
|
62
|
+
"value": {
|
|
63
|
+
"stringValue": "sha256:7beaf7a791c25a7a084ba436e7056c92e574ee7c4f0c46aa70dc77b77693aca0"
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"key": "gen_ai.request.model",
|
|
68
|
+
"value": {
|
|
69
|
+
"stringValue": "claude-opus-4.6"
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"key": "context.compaction.transaction.id_hash",
|
|
74
|
+
"value": {
|
|
75
|
+
"stringValue": "sha256:805db5aa5360"
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"key": "context.compaction.transaction.status",
|
|
80
|
+
"value": {
|
|
81
|
+
"stringValue": "rolled_back"
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"key": "context.compaction.swap_committed",
|
|
86
|
+
"value": {
|
|
87
|
+
"boolValue": false
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"key": "context.compaction.original_context_preserved",
|
|
92
|
+
"value": {
|
|
93
|
+
"boolValue": true
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
],
|
|
97
|
+
"events": [
|
|
98
|
+
{
|
|
99
|
+
"name": "context.compaction.transaction.started",
|
|
100
|
+
"timeUnixNano": "1779793080000000000",
|
|
101
|
+
"attributes": [
|
|
102
|
+
{
|
|
103
|
+
"key": "session.id",
|
|
104
|
+
"value": {
|
|
105
|
+
"stringValue": "sess-compact-failure-001"
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"key": "gen_ai.conversation.id",
|
|
110
|
+
"value": {
|
|
111
|
+
"stringValue": "conv-compact-failure-001"
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"key": "agent.name",
|
|
116
|
+
"value": {
|
|
117
|
+
"stringValue": "claude-code"
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"key": "context.compaction.transaction.id_hash",
|
|
122
|
+
"value": {
|
|
123
|
+
"stringValue": "sha256:805db5aa5360"
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"key": "context.compaction.attempt",
|
|
128
|
+
"value": {
|
|
129
|
+
"intValue": "1"
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"key": "context.compaction.trigger",
|
|
134
|
+
"value": {
|
|
135
|
+
"stringValue": "manual_slash_compact"
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"key": "context.compaction.reason",
|
|
140
|
+
"value": {
|
|
141
|
+
"stringValue": "context_window_pressure"
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"key": "context.compaction.token_count.before_bucket",
|
|
146
|
+
"value": {
|
|
147
|
+
"stringValue": "under_200k"
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"key": "context.compaction.context_window_bucket",
|
|
152
|
+
"value": {
|
|
153
|
+
"stringValue": "over_200k"
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"key": "context.compaction.deferred_tool_registry.count_bucket",
|
|
158
|
+
"value": {
|
|
159
|
+
"stringValue": "under_100"
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"key": "context.compaction.system_reminder_queue.count_bucket",
|
|
164
|
+
"value": {
|
|
165
|
+
"stringValue": "under_25"
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"key": "context.compaction.backup.id_hash",
|
|
170
|
+
"value": {
|
|
171
|
+
"stringValue": "sha256:5eeefe35b7bf"
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"key": "context.compaction.active_task.hash",
|
|
176
|
+
"value": {
|
|
177
|
+
"stringValue": "sha256:82147db072d020ce2ac8b662fc0296ff4d648fb7f44a891317ae993aa4afa632"
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"key": "context.compaction.recent_tool_output.hash",
|
|
182
|
+
"value": {
|
|
183
|
+
"stringValue": "sha256:361345a74863bc83520ad833fa352e7efd3e8765fc4ebea221aaaab5e64be887"
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"key": "context.compaction.deferred_tools.hash",
|
|
188
|
+
"value": {
|
|
189
|
+
"stringValue": "sha256:5aea705e426312000671b8d9a939170e50a1aa4d0ce6adf7a724c85b9c799971"
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"key": "privacy.raw_prompt_recorded",
|
|
194
|
+
"value": {
|
|
195
|
+
"boolValue": false
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"key": "privacy.raw_tool_output_recorded",
|
|
200
|
+
"value": {
|
|
201
|
+
"boolValue": false
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"key": "privacy.raw_tool_registry_recorded",
|
|
206
|
+
"value": {
|
|
207
|
+
"boolValue": false
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"key": "privacy.raw_context_recorded",
|
|
212
|
+
"value": {
|
|
213
|
+
"boolValue": false
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
]
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"name": "context.compaction.summary.attempted",
|
|
220
|
+
"timeUnixNano": "1779793088000000000",
|
|
221
|
+
"attributes": [
|
|
222
|
+
{
|
|
223
|
+
"key": "session.id",
|
|
224
|
+
"value": {
|
|
225
|
+
"stringValue": "sess-compact-failure-001"
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
"key": "gen_ai.conversation.id",
|
|
230
|
+
"value": {
|
|
231
|
+
"stringValue": "conv-compact-failure-001"
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
"key": "context.compaction.transaction.id_hash",
|
|
236
|
+
"value": {
|
|
237
|
+
"stringValue": "sha256:805db5aa5360"
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
"key": "context.compaction.summary.call_status",
|
|
242
|
+
"value": {
|
|
243
|
+
"stringValue": "failed_rate_limited"
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
"key": "context.compaction.summary.duration_bucket",
|
|
248
|
+
"value": {
|
|
249
|
+
"stringValue": "under_15s"
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
"key": "context.compaction.summary.candidate_available",
|
|
254
|
+
"value": {
|
|
255
|
+
"boolValue": false
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
"key": "context.compaction.summary.error_hash",
|
|
260
|
+
"value": {
|
|
261
|
+
"stringValue": "sha256:d294b4e487433a21ae31f3d50335e2a38d0754d878f17f8d565d024eb58980be"
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
"key": "context.compaction.summary.candidate_hash",
|
|
266
|
+
"value": {
|
|
267
|
+
"stringValue": ""
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
"key": "privacy.raw_error_recorded",
|
|
272
|
+
"value": {
|
|
273
|
+
"boolValue": false
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
"key": "privacy.raw_summary_recorded",
|
|
278
|
+
"value": {
|
|
279
|
+
"boolValue": false
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
"key": "privacy.raw_context_recorded",
|
|
284
|
+
"value": {
|
|
285
|
+
"boolValue": false
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
]
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
"name": "context.compaction.rollback.completed",
|
|
292
|
+
"timeUnixNano": "1779793089000000000",
|
|
293
|
+
"attributes": [
|
|
294
|
+
{
|
|
295
|
+
"key": "session.id",
|
|
296
|
+
"value": {
|
|
297
|
+
"stringValue": "sess-compact-failure-001"
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
"key": "gen_ai.conversation.id",
|
|
302
|
+
"value": {
|
|
303
|
+
"stringValue": "conv-compact-failure-001"
|
|
304
|
+
}
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
"key": "context.compaction.transaction.id_hash",
|
|
308
|
+
"value": {
|
|
309
|
+
"stringValue": "sha256:805db5aa5360"
|
|
310
|
+
}
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
"key": "context.compaction.rollback.reason",
|
|
314
|
+
"value": {
|
|
315
|
+
"stringValue": "summary_call_failed_before_validation"
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
"key": "context.compaction.swap_committed",
|
|
320
|
+
"value": {
|
|
321
|
+
"boolValue": false
|
|
322
|
+
}
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
"key": "context.compaction.original_context_preserved",
|
|
326
|
+
"value": {
|
|
327
|
+
"boolValue": true
|
|
328
|
+
}
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
"key": "context.compaction.backup_available",
|
|
332
|
+
"value": {
|
|
333
|
+
"boolValue": true
|
|
334
|
+
}
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
"key": "context.compaction.deferred_tool_registry_restored",
|
|
338
|
+
"value": {
|
|
339
|
+
"boolValue": true
|
|
340
|
+
}
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
"key": "context.compaction.system_reminder_queue_restored",
|
|
344
|
+
"value": {
|
|
345
|
+
"boolValue": true
|
|
346
|
+
}
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
"key": "context.compaction.replayed_system_reminder.count_bucket",
|
|
350
|
+
"value": {
|
|
351
|
+
"stringValue": "zero"
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
"key": "context.compaction.post_tokens_recorded_as_success",
|
|
356
|
+
"value": {
|
|
357
|
+
"boolValue": false
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
"key": "context.compaction.rollback.note_hash",
|
|
362
|
+
"value": {
|
|
363
|
+
"stringValue": "sha256:c3a100a46da5c02c2534fd4cac32b9e6df189f082b7fd60e5645bdb3d2f15f15"
|
|
364
|
+
}
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
"key": "privacy.raw_rollback_note_recorded",
|
|
368
|
+
"value": {
|
|
369
|
+
"boolValue": false
|
|
370
|
+
}
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
"key": "privacy.raw_tool_output_recorded",
|
|
374
|
+
"value": {
|
|
375
|
+
"boolValue": false
|
|
376
|
+
}
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
"key": "privacy.raw_context_recorded",
|
|
380
|
+
"value": {
|
|
381
|
+
"boolValue": false
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
]
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
"name": "context.compaction.transaction.completed",
|
|
388
|
+
"timeUnixNano": "1779793090000000000",
|
|
389
|
+
"attributes": [
|
|
390
|
+
{
|
|
391
|
+
"key": "session.id",
|
|
392
|
+
"value": {
|
|
393
|
+
"stringValue": "sess-compact-failure-001"
|
|
394
|
+
}
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
"key": "gen_ai.conversation.id",
|
|
398
|
+
"value": {
|
|
399
|
+
"stringValue": "conv-compact-failure-001"
|
|
400
|
+
}
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
"key": "context.compaction.transaction.id_hash",
|
|
404
|
+
"value": {
|
|
405
|
+
"stringValue": "sha256:805db5aa5360"
|
|
406
|
+
}
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
"key": "context.compaction.transaction.status",
|
|
410
|
+
"value": {
|
|
411
|
+
"stringValue": "rolled_back"
|
|
412
|
+
}
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
"key": "context.compaction.authoritative_state",
|
|
416
|
+
"value": {
|
|
417
|
+
"stringValue": "pre_compaction_context"
|
|
418
|
+
}
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
"key": "context.compaction.token_count.after_bucket",
|
|
422
|
+
"value": {
|
|
423
|
+
"stringValue": "under_200k"
|
|
424
|
+
}
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
"key": "context.compaction.deferred_tool_registry.after_count_bucket",
|
|
428
|
+
"value": {
|
|
429
|
+
"stringValue": "under_100"
|
|
430
|
+
}
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
"key": "context.compaction.system_reminder_queue.after_count_bucket",
|
|
434
|
+
"value": {
|
|
435
|
+
"stringValue": "under_25"
|
|
436
|
+
}
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
"key": "context.compaction.audit_gap",
|
|
440
|
+
"value": {
|
|
441
|
+
"stringValue": "proves transaction boundary and rollback flags, not semantic completeness of the preserved context"
|
|
442
|
+
}
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
"key": "context.compaction.operator_summary.hash",
|
|
446
|
+
"value": {
|
|
447
|
+
"stringValue": "sha256:f55024c1bc84cc2a3d5fc2ccf2fc355cd9d0e9987ee53d2da7f879d749dc29af"
|
|
448
|
+
}
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
"key": "privacy.raw_operator_summary_recorded",
|
|
452
|
+
"value": {
|
|
453
|
+
"boolValue": false
|
|
454
|
+
}
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
"key": "privacy.raw_prompt_recorded",
|
|
458
|
+
"value": {
|
|
459
|
+
"boolValue": false
|
|
460
|
+
}
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
"key": "privacy.raw_context_recorded",
|
|
464
|
+
"value": {
|
|
465
|
+
"boolValue": false
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
]
|
|
469
|
+
}
|
|
470
|
+
]
|
|
471
|
+
}
|
|
472
|
+
]
|
|
473
|
+
}
|
|
474
|
+
]
|
|
475
|
+
}
|
|
476
|
+
]
|
|
477
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
{"trace_id":"87ad256b18f3351f51b593961c988bb8","span_id":"c74740fd56dea619","name":"context.compaction.transaction.started","time":"2026-05-26T10:58:00.000Z","attributes":{"session.id":"sess-compact-failure-001","gen_ai.conversation.id":"conv-compact-failure-001","agent.name":"claude-code","context.compaction.transaction.id_hash":"sha256:805db5aa5360","context.compaction.attempt":1,"context.compaction.trigger":"manual_slash_compact","context.compaction.reason":"context_window_pressure","context.compaction.token_count.before_bucket":"under_200k","context.compaction.context_window_bucket":"over_200k","context.compaction.deferred_tool_registry.count_bucket":"under_100","context.compaction.system_reminder_queue.count_bucket":"under_25","context.compaction.backup.id_hash":"sha256:5eeefe35b7bf","context.compaction.active_task.hash":"sha256:82147db072d020ce2ac8b662fc0296ff4d648fb7f44a891317ae993aa4afa632","context.compaction.recent_tool_output.hash":"sha256:361345a74863bc83520ad833fa352e7efd3e8765fc4ebea221aaaab5e64be887","context.compaction.deferred_tools.hash":"sha256:5aea705e426312000671b8d9a939170e50a1aa4d0ce6adf7a724c85b9c799971","privacy.raw_prompt_recorded":false,"privacy.raw_tool_output_recorded":false,"privacy.raw_tool_registry_recorded":false,"privacy.raw_context_recorded":false}}
|
|
2
|
+
{"trace_id":"87ad256b18f3351f51b593961c988bb8","span_id":"c74740fd56dea619","name":"context.compaction.summary.attempted","time":"2026-05-26T10:58:08.000Z","attributes":{"session.id":"sess-compact-failure-001","gen_ai.conversation.id":"conv-compact-failure-001","context.compaction.transaction.id_hash":"sha256:805db5aa5360","context.compaction.summary.call_status":"failed_rate_limited","context.compaction.summary.duration_bucket":"under_15s","context.compaction.summary.candidate_available":false,"context.compaction.summary.error_hash":"sha256:d294b4e487433a21ae31f3d50335e2a38d0754d878f17f8d565d024eb58980be","context.compaction.summary.candidate_hash":"","privacy.raw_error_recorded":false,"privacy.raw_summary_recorded":false,"privacy.raw_context_recorded":false}}
|
|
3
|
+
{"trace_id":"87ad256b18f3351f51b593961c988bb8","span_id":"c74740fd56dea619","name":"context.compaction.rollback.completed","time":"2026-05-26T10:58:09.000Z","attributes":{"session.id":"sess-compact-failure-001","gen_ai.conversation.id":"conv-compact-failure-001","context.compaction.transaction.id_hash":"sha256:805db5aa5360","context.compaction.rollback.reason":"summary_call_failed_before_validation","context.compaction.swap_committed":false,"context.compaction.original_context_preserved":true,"context.compaction.backup_available":true,"context.compaction.deferred_tool_registry_restored":true,"context.compaction.system_reminder_queue_restored":true,"context.compaction.replayed_system_reminder.count_bucket":"zero","context.compaction.post_tokens_recorded_as_success":false,"context.compaction.rollback.note_hash":"sha256:c3a100a46da5c02c2534fd4cac32b9e6df189f082b7fd60e5645bdb3d2f15f15","privacy.raw_rollback_note_recorded":false,"privacy.raw_tool_output_recorded":false,"privacy.raw_context_recorded":false}}
|
|
4
|
+
{"trace_id":"87ad256b18f3351f51b593961c988bb8","span_id":"c74740fd56dea619","name":"context.compaction.transaction.completed","time":"2026-05-26T10:58:10.000Z","attributes":{"session.id":"sess-compact-failure-001","gen_ai.conversation.id":"conv-compact-failure-001","context.compaction.transaction.id_hash":"sha256:805db5aa5360","context.compaction.transaction.status":"rolled_back","context.compaction.authoritative_state":"pre_compaction_context","context.compaction.token_count.after_bucket":"under_200k","context.compaction.deferred_tool_registry.after_count_bucket":"under_100","context.compaction.system_reminder_queue.after_count_bucket":"under_25","context.compaction.audit_gap":"proves transaction boundary and rollback flags, not semantic completeness of the preserved context","context.compaction.operator_summary.hash":"sha256:f55024c1bc84cc2a3d5fc2ccf2fc355cd9d0e9987ee53d2da7f879d749dc29af","privacy.raw_operator_summary_recorded":false,"privacy.raw_prompt_recorded":false,"privacy.raw_context_recorded":false}}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
4
|
+
import { dirname, join, resolve } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const inputPath = process.argv[2] ? resolve(process.argv[2]) : join(here, 'sample-compaction-transaction-log.jsonl');
|
|
9
|
+
const receiptPath = process.argv[3] ? resolve(process.argv[3]) : join(here, 'compaction-transaction-receipt.ndjson');
|
|
10
|
+
const tracePath = process.argv[4] ? resolve(process.argv[4]) : join(here, 'compaction-transaction-otel-trace.json');
|
|
11
|
+
|
|
12
|
+
function sha256(value) {
|
|
13
|
+
return `sha256:${createHash('sha256').update(value ?? '').digest('hex')}`;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function hashRef(value) {
|
|
17
|
+
return sha256(value ?? '').slice(0, 19);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function readJsonl(path) {
|
|
21
|
+
return readFileSync(path, 'utf8')
|
|
22
|
+
.trim()
|
|
23
|
+
.split('\n')
|
|
24
|
+
.filter(Boolean)
|
|
25
|
+
.map((line, index) => {
|
|
26
|
+
try {
|
|
27
|
+
return JSON.parse(line);
|
|
28
|
+
} catch (error) {
|
|
29
|
+
throw new Error(`Invalid JSONL at ${path}:${index + 1}: ${error.message}`);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function unixNano(isoTimestamp) {
|
|
35
|
+
return `${BigInt(Date.parse(isoTimestamp)) * 1_000_000n}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function otelValue(value) {
|
|
39
|
+
if (typeof value === 'boolean') return { boolValue: value };
|
|
40
|
+
if (typeof value === 'number' && Number.isInteger(value)) return { intValue: String(value) };
|
|
41
|
+
if (typeof value === 'number') return { doubleValue: value };
|
|
42
|
+
if (value == null) return { stringValue: '' };
|
|
43
|
+
return { stringValue: String(value) };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function attributesToOtel(attributes) {
|
|
47
|
+
return Object.entries(attributes).map(([key, value]) => ({ key, value: otelValue(value) }));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function tokenBucket(value) {
|
|
51
|
+
if (value < 1_000) return 'under_1k';
|
|
52
|
+
if (value < 10_000) return 'under_10k';
|
|
53
|
+
if (value < 50_000) return 'under_50k';
|
|
54
|
+
if (value < 100_000) return 'under_100k';
|
|
55
|
+
if (value < 200_000) return 'under_200k';
|
|
56
|
+
return 'over_200k';
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function countBucket(value) {
|
|
60
|
+
if (value === 0) return 'zero';
|
|
61
|
+
if (value <= 5) return 'under_5';
|
|
62
|
+
if (value <= 25) return 'under_25';
|
|
63
|
+
if (value <= 100) return 'under_100';
|
|
64
|
+
if (value <= 500) return 'under_500';
|
|
65
|
+
return 'over_500';
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function durationBucket(value) {
|
|
69
|
+
if (value < 1_000) return 'under_1s';
|
|
70
|
+
if (value < 5_000) return 'under_5s';
|
|
71
|
+
if (value < 15_000) return 'under_15s';
|
|
72
|
+
if (value < 60_000) return 'under_60s';
|
|
73
|
+
return 'over_60s';
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const records = readJsonl(inputPath);
|
|
77
|
+
const session = records.find((record) => record.type === 'session.start');
|
|
78
|
+
const start = records.find((record) => record.type === 'context.compaction.transaction.started');
|
|
79
|
+
const attempt = records.find((record) => record.type === 'context.compaction.summary.attempted');
|
|
80
|
+
const rollback = records.find((record) => record.type === 'context.compaction.rollback.completed');
|
|
81
|
+
const completed = records.find((record) => record.type === 'context.compaction.transaction.completed');
|
|
82
|
+
|
|
83
|
+
if (!session || !start || !attempt || !rollback || !completed) {
|
|
84
|
+
throw new Error(`Expected session.start, transaction.started, summary.attempted, rollback.completed, and transaction.completed records in ${inputPath}`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const traceSeed = `${session.session_id}:${start.transaction_id}:compaction-transaction`;
|
|
88
|
+
const traceId = sha256(traceSeed).replace('sha256:', '').slice(0, 32);
|
|
89
|
+
const spanId = sha256(`${traceSeed}:span`).replace('sha256:', '').slice(0, 16);
|
|
90
|
+
const transactionIdHash = hashRef(start.transaction_id);
|
|
91
|
+
|
|
92
|
+
const startEvent = {
|
|
93
|
+
trace_id: traceId,
|
|
94
|
+
span_id: spanId,
|
|
95
|
+
name: 'context.compaction.transaction.started',
|
|
96
|
+
time: start.time,
|
|
97
|
+
attributes: {
|
|
98
|
+
'session.id': session.session_id,
|
|
99
|
+
'gen_ai.conversation.id': session.conversation_id,
|
|
100
|
+
'agent.name': session.agent,
|
|
101
|
+
'context.compaction.transaction.id_hash': transactionIdHash,
|
|
102
|
+
'context.compaction.attempt': start.attempt,
|
|
103
|
+
'context.compaction.trigger': start.trigger,
|
|
104
|
+
'context.compaction.reason': start.reason,
|
|
105
|
+
'context.compaction.token_count.before_bucket': tokenBucket(start.context_token_count_before),
|
|
106
|
+
'context.compaction.context_window_bucket': tokenBucket(start.context_window_tokens),
|
|
107
|
+
'context.compaction.deferred_tool_registry.count_bucket': countBucket(start.deferred_tool_registry_count),
|
|
108
|
+
'context.compaction.system_reminder_queue.count_bucket': countBucket(start.pending_system_reminder_count),
|
|
109
|
+
'context.compaction.backup.id_hash': hashRef(start.backup_id),
|
|
110
|
+
'context.compaction.active_task.hash': sha256(start.raw_active_task),
|
|
111
|
+
'context.compaction.recent_tool_output.hash': sha256(start.raw_recent_tool_output),
|
|
112
|
+
'context.compaction.deferred_tools.hash': sha256(start.raw_deferred_tools),
|
|
113
|
+
'privacy.raw_prompt_recorded': false,
|
|
114
|
+
'privacy.raw_tool_output_recorded': false,
|
|
115
|
+
'privacy.raw_tool_registry_recorded': false,
|
|
116
|
+
'privacy.raw_context_recorded': false
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const attemptEvent = {
|
|
121
|
+
trace_id: traceId,
|
|
122
|
+
span_id: spanId,
|
|
123
|
+
name: 'context.compaction.summary.attempted',
|
|
124
|
+
time: attempt.time,
|
|
125
|
+
attributes: {
|
|
126
|
+
'session.id': session.session_id,
|
|
127
|
+
'gen_ai.conversation.id': session.conversation_id,
|
|
128
|
+
'context.compaction.transaction.id_hash': transactionIdHash,
|
|
129
|
+
'context.compaction.summary.call_status': attempt.summary_call_status,
|
|
130
|
+
'context.compaction.summary.duration_bucket': durationBucket(attempt.summary_duration_ms),
|
|
131
|
+
'context.compaction.summary.candidate_available': attempt.candidate_summary_available,
|
|
132
|
+
'context.compaction.summary.error_hash': sha256(attempt.raw_error),
|
|
133
|
+
'context.compaction.summary.candidate_hash': attempt.candidate_summary_text ? sha256(attempt.candidate_summary_text) : '',
|
|
134
|
+
'privacy.raw_error_recorded': false,
|
|
135
|
+
'privacy.raw_summary_recorded': false,
|
|
136
|
+
'privacy.raw_context_recorded': false
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const rollbackEvent = {
|
|
141
|
+
trace_id: traceId,
|
|
142
|
+
span_id: spanId,
|
|
143
|
+
name: 'context.compaction.rollback.completed',
|
|
144
|
+
time: rollback.time,
|
|
145
|
+
attributes: {
|
|
146
|
+
'session.id': session.session_id,
|
|
147
|
+
'gen_ai.conversation.id': session.conversation_id,
|
|
148
|
+
'context.compaction.transaction.id_hash': transactionIdHash,
|
|
149
|
+
'context.compaction.rollback.reason': rollback.rollback_reason,
|
|
150
|
+
'context.compaction.swap_committed': rollback.swap_committed,
|
|
151
|
+
'context.compaction.original_context_preserved': rollback.original_context_preserved,
|
|
152
|
+
'context.compaction.backup_available': rollback.backup_available,
|
|
153
|
+
'context.compaction.deferred_tool_registry_restored': rollback.deferred_tool_registry_restored,
|
|
154
|
+
'context.compaction.system_reminder_queue_restored': rollback.system_reminder_queue_restored,
|
|
155
|
+
'context.compaction.replayed_system_reminder.count_bucket': countBucket(rollback.replayed_system_reminder_count),
|
|
156
|
+
'context.compaction.post_tokens_recorded_as_success': rollback.post_tokens_recorded_as_success,
|
|
157
|
+
'context.compaction.rollback.note_hash': sha256(rollback.raw_rollback_note),
|
|
158
|
+
'privacy.raw_rollback_note_recorded': false,
|
|
159
|
+
'privacy.raw_tool_output_recorded': false,
|
|
160
|
+
'privacy.raw_context_recorded': false
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const completedEvent = {
|
|
165
|
+
trace_id: traceId,
|
|
166
|
+
span_id: spanId,
|
|
167
|
+
name: 'context.compaction.transaction.completed',
|
|
168
|
+
time: completed.time,
|
|
169
|
+
attributes: {
|
|
170
|
+
'session.id': session.session_id,
|
|
171
|
+
'gen_ai.conversation.id': session.conversation_id,
|
|
172
|
+
'context.compaction.transaction.id_hash': transactionIdHash,
|
|
173
|
+
'context.compaction.transaction.status': completed.status,
|
|
174
|
+
'context.compaction.authoritative_state': completed.authoritative_state,
|
|
175
|
+
'context.compaction.token_count.after_bucket': tokenBucket(completed.context_token_count_after),
|
|
176
|
+
'context.compaction.deferred_tool_registry.after_count_bucket': countBucket(completed.deferred_tool_registry_count_after),
|
|
177
|
+
'context.compaction.system_reminder_queue.after_count_bucket': countBucket(completed.pending_system_reminder_count_after),
|
|
178
|
+
'context.compaction.audit_gap': completed.audit_gap,
|
|
179
|
+
'context.compaction.operator_summary.hash': sha256(completed.raw_operator_summary),
|
|
180
|
+
'privacy.raw_operator_summary_recorded': false,
|
|
181
|
+
'privacy.raw_prompt_recorded': false,
|
|
182
|
+
'privacy.raw_context_recorded': false
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
const events = [startEvent, attemptEvent, rollbackEvent, completedEvent]
|
|
187
|
+
.sort((left, right) => Date.parse(left.time) - Date.parse(right.time));
|
|
188
|
+
|
|
189
|
+
writeFileSync(receiptPath, `${events.map((event) => JSON.stringify(event)).join('\n')}\n`);
|
|
190
|
+
|
|
191
|
+
const trace = {
|
|
192
|
+
resourceSpans: [
|
|
193
|
+
{
|
|
194
|
+
resource: {
|
|
195
|
+
attributes: attributesToOtel({
|
|
196
|
+
'service.name': 'pluribus-compaction-transaction-receipt-demo',
|
|
197
|
+
'service.version': '0.0.0-fixture',
|
|
198
|
+
'deployment.environment.name': 'local-fixture'
|
|
199
|
+
})
|
|
200
|
+
},
|
|
201
|
+
scopeSpans: [
|
|
202
|
+
{
|
|
203
|
+
scope: {
|
|
204
|
+
name: 'pluribus.context_input_evidence.compaction_transaction_demo',
|
|
205
|
+
version: '0.0.0-fixture'
|
|
206
|
+
},
|
|
207
|
+
spans: [
|
|
208
|
+
{
|
|
209
|
+
traceId,
|
|
210
|
+
spanId,
|
|
211
|
+
parentSpanId: '',
|
|
212
|
+
name: 'agent.session.context_compaction_transaction',
|
|
213
|
+
kind: 1,
|
|
214
|
+
startTimeUnixNano: unixNano(start.time),
|
|
215
|
+
endTimeUnixNano: unixNano(completed.time),
|
|
216
|
+
attributes: attributesToOtel({
|
|
217
|
+
'session.id': session.session_id,
|
|
218
|
+
'gen_ai.conversation.id': session.conversation_id,
|
|
219
|
+
'agent.name': session.agent,
|
|
220
|
+
'workspace.hash': sha256(session.workspace),
|
|
221
|
+
'gen_ai.request.model': session.model,
|
|
222
|
+
'context.compaction.transaction.id_hash': transactionIdHash,
|
|
223
|
+
'context.compaction.transaction.status': completed.status,
|
|
224
|
+
'context.compaction.swap_committed': rollback.swap_committed,
|
|
225
|
+
'context.compaction.original_context_preserved': rollback.original_context_preserved
|
|
226
|
+
}),
|
|
227
|
+
events: events.map((event) => ({
|
|
228
|
+
name: event.name,
|
|
229
|
+
timeUnixNano: unixNano(event.time),
|
|
230
|
+
attributes: attributesToOtel(event.attributes)
|
|
231
|
+
}))
|
|
232
|
+
}
|
|
233
|
+
]
|
|
234
|
+
}
|
|
235
|
+
]
|
|
236
|
+
}
|
|
237
|
+
]
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
writeFileSync(tracePath, `${JSON.stringify(trace, null, 2)}\n`);
|
|
241
|
+
|
|
242
|
+
const forbiddenRawStrings = [
|
|
243
|
+
'Acme-Co',
|
|
244
|
+
'sk_live_private_compact_txn',
|
|
245
|
+
'alice@example.com',
|
|
246
|
+
'/private/work/acme',
|
|
247
|
+
'customer retry payload',
|
|
248
|
+
'internal-acme-prod-admin',
|
|
249
|
+
'Restored /private/work/acme',
|
|
250
|
+
'payment payload'
|
|
251
|
+
];
|
|
252
|
+
const exportedText = `${events.map((event) => JSON.stringify(event)).join('\n')}\n${JSON.stringify(trace)}`;
|
|
253
|
+
const rawTextCopiedToReceipt = forbiddenRawStrings.some((value) => exportedText.includes(value));
|
|
254
|
+
|
|
255
|
+
const summary = {
|
|
256
|
+
schema: 'pluribus.compactionTransactionReceipt.demo.v0',
|
|
257
|
+
eventCount: events.length,
|
|
258
|
+
status: completed.status,
|
|
259
|
+
swapCommitted: rollback.swap_committed,
|
|
260
|
+
originalContextPreserved: rollback.original_context_preserved,
|
|
261
|
+
backupAvailable: rollback.backup_available,
|
|
262
|
+
deferredToolRegistryRestored: rollback.deferred_tool_registry_restored,
|
|
263
|
+
systemReminderQueueRestored: rollback.system_reminder_queue_restored,
|
|
264
|
+
postTokensRecordedAsSuccess: rollback.post_tokens_recorded_as_success,
|
|
265
|
+
rawTextCopiedToReceipt,
|
|
266
|
+
receiptPath: 'examples/context-input-evidence/compaction-transaction-receipt.ndjson',
|
|
267
|
+
tracePath: 'examples/context-input-evidence/compaction-transaction-otel-trace.json',
|
|
268
|
+
lesson: 'Failed compaction should emit a transaction receipt that proves summary failure did not commit a context swap or replay stale tool/system-reminder state.'
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
console.log(JSON.stringify(summary, null, 2));
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{"type":"session.start","time":"2026-05-26T10:57:00.000Z","session_id":"sess-compact-failure-001","conversation_id":"conv-compact-failure-001","agent":"claude-code","workspace":"/private/work/acme-checkout","model":"claude-opus-4.6"}
|
|
2
|
+
{"type":"context.compaction.transaction.started","time":"2026-05-26T10:58:00.000Z","transaction_id":"compact-txn-2026-05-26-private-acme","attempt":1,"trigger":"manual_slash_compact","reason":"context_window_pressure","context_token_count_before":151400,"context_window_tokens":200000,"deferred_tool_registry_count":43,"pending_system_reminder_count":19,"backup_id":"backup-private-acme-before-compact","raw_active_task":"Fix Acme-Co checkout retry loop; never expose sk_live_private_compact_txn or customer email alice@example.com.","raw_recent_tool_output":"Read /private/work/acme/src/payments.ts returned Stripe token sk_live_private_compact_txn and customer retry payload.","raw_deferred_tools":"github,postgres,slack,internal-acme-prod-admin"}
|
|
3
|
+
{"type":"context.compaction.summary.attempted","time":"2026-05-26T10:58:08.000Z","transaction_id":"compact-txn-2026-05-26-private-acme","summary_call_status":"failed_rate_limited","summary_duration_ms":8200,"candidate_summary_available":false,"raw_error":"429 rate limit while summarizing Acme-Co checkout incident with private token sk_live_private_compact_txn","candidate_summary_text":""}
|
|
4
|
+
{"type":"context.compaction.rollback.completed","time":"2026-05-26T10:58:09.000Z","transaction_id":"compact-txn-2026-05-26-private-acme","rollback_reason":"summary_call_failed_before_validation","swap_committed":false,"original_context_preserved":true,"backup_available":true,"deferred_tool_registry_restored":true,"system_reminder_queue_restored":true,"replayed_system_reminder_count":0,"post_tokens_recorded_as_success":false,"raw_rollback_note":"Restored /private/work/acme session state; do not replay stale tool results or payment payload."}
|
|
5
|
+
{"type":"context.compaction.transaction.completed","time":"2026-05-26T10:58:10.000Z","transaction_id":"compact-txn-2026-05-26-private-acme","status":"rolled_back","authoritative_state":"pre_compaction_context","context_token_count_after":151400,"deferred_tool_registry_count_after":43,"pending_system_reminder_count_after":19,"audit_gap":"proves transaction boundary and rollback flags, not semantic completeness of the preserved context","raw_operator_summary":"Compaction failed safely; active task still contains Acme-Co private checkout details and must not be logged."}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pluribus-context",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.32",
|
|
4
4
|
"description": "AI context and rules sync CLI for Claude.md, Claude Code, Cursor, and Copilot instructions, with privacy-safe context receipts that prove what memory, tools, skills, compactions, and security findings crossed agent boundaries without logging raw content.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://github.com/caioribeiroclw-pixel/pluribus#readme",
|
package/src/utils/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.3.
|
|
1
|
+
export const VERSION = '0.3.32'
|