pluribus-context 0.3.40 → 0.3.41
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 +4 -0
- package/README.md +1 -1
- package/docs/.nojekyll +0 -0
- package/docs/.well-known/agent-skills/context-receipts/SKILL.md +206 -0
- package/docs/.well-known/agent-skills/index.json +19 -0
- package/docs/.well-known/agent-skills/skill-policy-receipts/SKILL.md +77 -0
- package/docs/index.html +38 -0
- package/docs/receipt-playground.html +250 -0
- package/examples/context-attention-receipts/README.md +41 -0
- package/examples/context-attention-receipts/attention-receipt-fail.json +49 -0
- package/examples/context-attention-receipts/attention-receipt-pass.json +53 -0
- package/examples/context-attention-receipts/check-attention-receipt.mjs +97 -0
- package/package.json +5 -2
- package/skills/context-receipts/README.md +13 -2
- package/skills/context-receipts/SKILL.md +65 -0
- package/src/utils/version.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
All notable changes to Pluribus are documented here.
|
|
6
6
|
|
|
7
|
+
## 0.3.41 - 2026-06-10
|
|
8
|
+
|
|
9
|
+
- Added npm Agent Skills discovery keywords (`agent-skill`, `skillpm`, and `agent-skills-registry`) so `pluribus-context` can be indexed by npm-backed skill package managers while continuing to ship the existing low-authority `skills/*/SKILL.md` recipes.
|
|
10
|
+
|
|
7
11
|
## 0.3.40 - 2026-06-09
|
|
8
12
|
|
|
9
13
|
- Added `pluribus demo tool-surface-diff`, a tiny npm-runnable MCP dynamic-discovery receipt demo for proving discovered, activated, withheld, and blocked runtime tool-surface changes without logging raw schemas, prompts, or results.
|
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ The original sync workflow is still useful: Pluribus can keep project instructio
|
|
|
14
14
|
|
|
15
15
|
It is **not** a persistent memory layer, retrieval system, agent orchestrator, enterprise ContextOps platform, or agent-merging framework. Think evidence for context boundaries: `CLAUDE.md`, `.cursorrules`, `copilot-instructions.md`, `AGENTS.md`, MCP Tool Search, Agent Skills, RAG/code-search, pruning, and compaction — with privacy-safe receipts instead of raw content dumps.
|
|
16
16
|
|
|
17
|
-
**Reviewer shortcut:** evaluating Pluribus for a list, newsletter, package roundup, or tool directory? Use the [Community Review Packet](docs/community-review-packet.md) for copy-paste directory submission fields, safety/removability notes, feedback links, and disposable 60-second smoke tests. If you only run one command for the cross-tool audit, try `npx --yes pluribus-context@latest audit --json --fidelity-report` to see native discovery surfaces, generic fallbacks, load evidence, duplicate-load selection evidence, manual activation requirements, effective context scope, and semantic differences. For the agent-observability wedge, start with [context-budget receipts](docs/context-budget-receipts.md): privacy-safe evidence for what MCP schemas, skills, memory, subagents, CLI help, retrieval chunks, pruning runs, or compaction summaries crossed an agent boundary. It now explicitly covers the "Tool Search fixed MCP bloat" objection: the receipt proves which lane stayed deferred, which tool was expanded, and whether schemas leaked through `messages`/bootstrap anyway. For a 60-second runtime-discovery proof, run `npx --yes pluribus-context@latest demo tool-surface-diff --json`; it validates a receipt for discovered → activated → withheld/blocked MCP tools without raw schemas/prompts/results. If you want the same idea as a copyable skill, use the [context-receipts Agent Skill recipe](skills/context-receipts/). npm `latest` is currently aligned with the GitHub release; the review packet also documents a GitHub-release smoke fallback for future release-lag windows.
|
|
17
|
+
**Reviewer shortcut:** evaluating Pluribus for a list, newsletter, package roundup, or tool directory? Use the [Community Review Packet](docs/community-review-packet.md) for copy-paste directory submission fields, safety/removability notes, feedback links, and disposable 60-second smoke tests. If you only run one command for the cross-tool audit, try `npx --yes pluribus-context@latest audit --json --fidelity-report` to see native discovery surfaces, generic fallbacks, load evidence, duplicate-load selection evidence, manual activation requirements, effective context scope, and semantic differences. For the agent-observability wedge, start with [context-budget receipts](docs/context-budget-receipts.md): privacy-safe evidence for what MCP schemas, skills, memory, subagents, CLI help, retrieval chunks, pruning runs, or compaction summaries crossed an agent boundary. It now explicitly covers the "Tool Search fixed MCP bloat" objection: the receipt proves which lane stayed deferred, which tool was expanded, and whether schemas leaked through `messages`/bootstrap anyway. For a 60-second runtime-discovery proof, run `npx --yes pluribus-context@latest demo tool-surface-diff --json`; it validates a receipt for discovered → activated → withheld/blocked MCP tools without raw schemas/prompts/results. If you are coming from Claude Code, GraphRAG, or memory tooling where retrieval succeeds but the agent ignores it, try the [context attention receipt example](examples/context-attention-receipts/) to prove required context was delivered, acknowledged, and cited before edits. If you want the same idea as a copyable skill, use the [context-receipts Agent Skill recipe](skills/context-receipts/). npm `latest` is currently aligned with the GitHub release; the review packet also documents a GitHub-release smoke fallback for future release-lag windows.
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
package/docs/.nojekyll
ADDED
|
File without changes
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: context-receipts
|
|
3
|
+
description: Emit privacy-safe receipts for context selection, deferral, hydration, compaction, pruning, delegation, usage attribution, and boundary handoffs.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Context Receipts
|
|
7
|
+
|
|
8
|
+
Use this skill when an agent workflow claims to save context by selecting, deferring, hydrating, summarizing, compacting, pruning, delegating, attributing usage, or isolating context.
|
|
9
|
+
|
|
10
|
+
The job is not to log the private content. The job is to emit a small receipt that lets a reviewer answer:
|
|
11
|
+
|
|
12
|
+
> what crossed the context boundary, what stayed out, and what audit gap remains?
|
|
13
|
+
|
|
14
|
+
## Privacy defaults
|
|
15
|
+
|
|
16
|
+
Never include raw prompts, raw tool schemas, raw tool arguments, raw tool results, raw skill bodies, memory bodies, secrets, customer names, or full transcripts in the receipt.
|
|
17
|
+
|
|
18
|
+
Prefer:
|
|
19
|
+
|
|
20
|
+
- stable ids or hashed ids;
|
|
21
|
+
- counts and token/line buckets;
|
|
22
|
+
- categorical reasons;
|
|
23
|
+
- explicit booleans for raw content copied/not copied;
|
|
24
|
+
- before/after context budget buckets;
|
|
25
|
+
- an `audit_gap` field when the receipt proves routing but not semantic correctness.
|
|
26
|
+
|
|
27
|
+
## 60-second Tool Search smoke
|
|
28
|
+
|
|
29
|
+
For MCP Tool Search, lazy tool loading, or progressive disclosure, emit enough evidence to answer these seven checks:
|
|
30
|
+
|
|
31
|
+
1. **Index-only startup:** did the session load a compact tool/server index instead of all full schemas?
|
|
32
|
+
2. **Search/routing:** what hashed query/category or routing reason selected candidate tools?
|
|
33
|
+
3. **Hydration:** which full tool definition was loaded, why, and how many definitions stayed suppressed?
|
|
34
|
+
4. **Call:** which server/tool id was invoked, with argument/result redaction status and success/error status?
|
|
35
|
+
5. **Boundary:** if a manager subagent or child agent was used, did raw child output return to the parent?
|
|
36
|
+
6. **Budget:** what were the startup and post-hydration context-token buckets?
|
|
37
|
+
7. **Audit gap:** what is not proven, such as whether the selected tool was semantically optimal?
|
|
38
|
+
|
|
39
|
+
Minimal JSONL event names:
|
|
40
|
+
|
|
41
|
+
```jsonl
|
|
42
|
+
{"event":"mcp.tool_index.loaded","loaded_server_count":12,"loaded_tool_index_count":84,"full_schema_count":0,"suppressed_tool_count":84,"raw_schema_copied":false,"startup_token_bucket":"lt_1k"}
|
|
43
|
+
{"event":"mcp.tool_search.performed","query_hash":"sha256:...","query_category":"repo_search","candidate_tool_count":5,"selected_tool_id":"github.search_code","raw_query_copied":false}
|
|
44
|
+
{"event":"mcp.tool_definition.loaded","tool_id":"github.search_code","hydrate_reason":"selected_after_tool_search","suppressed_tool_count":83,"definition_token_bucket":"1k_2k","raw_schema_copied":false}
|
|
45
|
+
{"event":"mcp.tool_call.completed","tool_id":"github.search_code","args_hash":"sha256:...","result_token_bucket":"2k_4k","raw_args_copied":false,"raw_result_copied":false,"status":"ok"}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Skill / prompt context smoke
|
|
49
|
+
|
|
50
|
+
For skills, rules, AGENTS.md overlays, or instruction files, answer:
|
|
51
|
+
|
|
52
|
+
- which index/listing entered the session;
|
|
53
|
+
- which full skill/rule/instruction body was selected;
|
|
54
|
+
- which candidates were suppressed and why;
|
|
55
|
+
- whether the body was loaded at session start, after a search, or after an explicit command;
|
|
56
|
+
- source hash, delivered hash, and canonical form when available;
|
|
57
|
+
- whether the skill/instruction text was copied into the receipt.
|
|
58
|
+
|
|
59
|
+
Minimal event names:
|
|
60
|
+
|
|
61
|
+
- `context.skill.registry.index.loaded`
|
|
62
|
+
- `context.skill.registry.skill.read`
|
|
63
|
+
- `context.skill.registry.skill.injected`
|
|
64
|
+
- `context.input.loaded`
|
|
65
|
+
- `context.input.candidate_suppressed`
|
|
66
|
+
|
|
67
|
+
## Per-agent MCP injection smoke
|
|
68
|
+
|
|
69
|
+
For role-specific subagents or per-agent MCP configs, prove the policy boundary before debugging model quality:
|
|
70
|
+
|
|
71
|
+
- which subagent role/session requested tools;
|
|
72
|
+
- which MCP servers were available to that role;
|
|
73
|
+
- which servers were explicitly excluded before boot;
|
|
74
|
+
- whether startup loaded full schemas or only a compact index;
|
|
75
|
+
- how many tool definitions stayed deferred/suppressed; and
|
|
76
|
+
- the startup token bucket after policy was applied.
|
|
77
|
+
|
|
78
|
+
Minimal JSONL event names:
|
|
79
|
+
|
|
80
|
+
```jsonl
|
|
81
|
+
{"event":"subagent.mcp_policy.applied","subagent_role":"testing","available_server_count":2,"available_servers_hash":"sha256:...","excluded_server_count":5,"excluded_servers_hash":"sha256:...","policy_source":"role_config","raw_server_names_copied":false}
|
|
82
|
+
{"event":"subagent.context_boot.evaluated","subagent_role":"testing","loaded_tool_definition_count":0,"deferred_tool_definition_count":48,"startup_token_bucket":"50k_75k","raw_schema_copied":false,"audit_gap":"proves injection boundary, not tool relevance"}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## ToolSearch propagation smoke
|
|
86
|
+
|
|
87
|
+
For subagents that should inherit MCP through `ToolSearch`, distinguish policy, declaration, and runtime filtering:
|
|
88
|
+
|
|
89
|
+
- did the parent/orchestrator intend to expose MCP or exclude it for this subagent?
|
|
90
|
+
- was the subagent spawned immediately or after parent tool calls/orchestration work?
|
|
91
|
+
- was the `tools:` declaration wildcard, explicit include, or exclusion style?
|
|
92
|
+
- was `ToolSearch` declared and was it actually exposed in the subagent tool surface?
|
|
93
|
+
- did MCP servers/tool definitions stay deferred, or did the channel collapse to zero?
|
|
94
|
+
- was the agent registry loaded at session boot, making newly added agent files invisible until restart?
|
|
95
|
+
|
|
96
|
+
Minimal JSONL event names:
|
|
97
|
+
|
|
98
|
+
```jsonl
|
|
99
|
+
{"event":"subagent.toolsearch.propagation.evaluated","spawn_path":"Task","tools_declaration_shape":"enumerated_include","toolsearch_declared":false,"toolsearch_exposed":false,"mcp_servers_available_bucket":"0","deferred_tool_definitions_bucket":"0","filtered_by":"frontmatter_tools_policy_or_runtime_filter","raw_tool_schemas_copied":false}
|
|
100
|
+
{"event":"subagent.toolsearch.matrix.completed","tested_axis":"tools_frontmatter_shape","audit_gap":"proves ToolSearch exposure, not semantic tool relevance or runtime call success"}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Retrieval / code-search smoke
|
|
104
|
+
|
|
105
|
+
For semantic code search, repo RAG, or MCP tools such as Claude Context, separate "search returned" from "agent context loaded":
|
|
106
|
+
|
|
107
|
+
- which index snapshot/version was used, without raw local codebase paths;
|
|
108
|
+
- what query/category/filter identity selected the candidates, without raw query text;
|
|
109
|
+
- which result ids/chunk hashes were returned, with rank, score bucket, stale flag, duplicate marker, path hash/extension, and range bucket;
|
|
110
|
+
- which returned chunks were actually loaded into the agent context;
|
|
111
|
+
- which chunks were suppressed as duplicate, stale, clipped, policy-blocked, or over budget;
|
|
112
|
+
- whether raw code, raw prompts, raw paths, customer names, URLs, secrets, and ticket text stayed out of the receipt;
|
|
113
|
+
- the audit gap: this proves retrieval/loading boundaries, not semantic answer quality.
|
|
114
|
+
|
|
115
|
+
Minimal JSONL event names:
|
|
116
|
+
|
|
117
|
+
```jsonl
|
|
118
|
+
{"event":"code.index.snapshot.used","snapshot_id_hash":"sha256:...","codebase_path_hash":"sha256:...","indexed_chunk_count_bucket":"over_1k","raw_codebase_path_copied":false}
|
|
119
|
+
{"event":"code.search.performed","query_hash":"sha256:...","query_category":"auth_debug","candidate_count_bucket":"over_1k","raw_query_copied":false}
|
|
120
|
+
{"event":"code.search.result.returned","rank":1,"chunk_id_hash":"sha256:...","chunk_text_hash":"sha256:...","path_hash":"sha256:...","score_bucket":"high","stale":false,"raw_code_copied":false}
|
|
121
|
+
{"event":"context.input.loaded","kind":"retrieved_code_chunks","loaded_chunk_count":3,"suppressed_chunk_count":2,"suppression_reasons":["duplicate","stale_snapshot_chunk"],"raw_code_copied":false}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Usage attribution smoke
|
|
125
|
+
|
|
126
|
+
For `/usage`, `/context`, `/doctor`, or other context-budget breakdowns, map each displayed category to evidence that can be reviewed without exposing private content:
|
|
127
|
+
|
|
128
|
+
- what measurement window was used;
|
|
129
|
+
- which categories were attributed, such as skills, subagents, plugins, MCP servers, rules, memory, or project files;
|
|
130
|
+
- which components were loaded, deferred, hydrated, suppressed, pruned, or rolled back;
|
|
131
|
+
- before/after or current token/cost buckets by category;
|
|
132
|
+
- whether raw skill bodies, prompts, MCP schemas, tool outputs, and file paths were excluded;
|
|
133
|
+
- the remaining audit gap, such as not proving semantic usefulness of a high-cost component.
|
|
134
|
+
|
|
135
|
+
Minimal JSONL event names:
|
|
136
|
+
|
|
137
|
+
```jsonl
|
|
138
|
+
{"event":"context.usage.window.measured","window":"current_session","total_token_bucket":"100k_150k","raw_prompts_copied":false}
|
|
139
|
+
{"event":"context.usage.category.attributed","category":"mcp_server","component_hash":"sha256:...","loaded_token_bucket":"10k_25k","deferred_definition_count":42,"hydrated_definition_count":3,"raw_schema_copied":false}
|
|
140
|
+
{"event":"context.usage.breakdown.completed","categories":["skills","subagents","plugins","mcp_server"],"audit_gap":"proves attribution buckets, not whether each component was necessary"}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Pruning / compaction smoke
|
|
144
|
+
|
|
145
|
+
For context-cleaning, pruning, compaction, or doctor/guard tools, answer:
|
|
146
|
+
|
|
147
|
+
- what prescription/trigger started the run;
|
|
148
|
+
- which strategies changed context and which candidates were protected;
|
|
149
|
+
- before/after token and byte buckets;
|
|
150
|
+
- whether summaries, behavioral digests, team messages, and backups were preserved;
|
|
151
|
+
- whether private transcript text, raw tool output, file paths, secrets, and customer text were excluded from the receipt;
|
|
152
|
+
- the remaining audit gap, such as not proving semantic quality of the pruned text.
|
|
153
|
+
|
|
154
|
+
Minimal JSONL event names:
|
|
155
|
+
|
|
156
|
+
```jsonl
|
|
157
|
+
{"event":"context.prune.started","prescription":"balanced","trigger":"manual_dry_run","before_token_bucket":"150k_200k","raw_transcript_copied":false}
|
|
158
|
+
{"event":"context.prune.strategy.evaluated","strategy":"tool-output-trim","candidate_bucket":"10_25","changed_bucket":"5_10","protected_bucket":"1_5","raw_tool_output_copied":false}
|
|
159
|
+
{"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"}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
For failed compaction, also prove transaction safety:
|
|
163
|
+
|
|
164
|
+
- did the summary call succeed, fail, or timeout;
|
|
165
|
+
- was a candidate summary validated before any swap;
|
|
166
|
+
- did the harness commit a context swap or preserve the original context;
|
|
167
|
+
- were deferred-tool registries and system-reminder queues restored on rollback;
|
|
168
|
+
- did stale system reminders/tool results replay as fresh state;
|
|
169
|
+
- was post-token metadata recorded as success even though summary failed.
|
|
170
|
+
|
|
171
|
+
Minimal JSONL event names:
|
|
172
|
+
|
|
173
|
+
```jsonl
|
|
174
|
+
{"event":"context.compaction.summary.attempted","summary_call_status":"failed_rate_limited","candidate_summary_available":false,"raw_error_copied":false}
|
|
175
|
+
{"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}
|
|
176
|
+
{"event":"context.compaction.transaction.completed","status":"rolled_back","authoritative_state":"pre_compaction_context","post_tokens_recorded_as_success":false,"raw_context_copied":false}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Subagent / manager boundary smoke
|
|
180
|
+
|
|
181
|
+
For subagents, manager agents, or child workers, answer:
|
|
182
|
+
|
|
183
|
+
- what task was delegated, by category and hashed objective;
|
|
184
|
+
- what large output was captured by the child, as line/token buckets;
|
|
185
|
+
- what bounded summary returned to the parent;
|
|
186
|
+
- whether raw child output, tool results, or MCP schemas entered the parent context;
|
|
187
|
+
- the remaining audit gap.
|
|
188
|
+
|
|
189
|
+
Minimal event names:
|
|
190
|
+
|
|
191
|
+
- `subagent.delegation.requested`
|
|
192
|
+
- `subagent.tool_output.captured`
|
|
193
|
+
- `subagent.summary.returned`
|
|
194
|
+
- `parent.context_budget.evaluated`
|
|
195
|
+
|
|
196
|
+
## Good receipt test
|
|
197
|
+
|
|
198
|
+
A receipt is useful if a maintainer can debug one of these failures without seeing private content:
|
|
199
|
+
|
|
200
|
+
- the agent never found the right tool/skill;
|
|
201
|
+
- the full definition loaded too early;
|
|
202
|
+
- too many definitions stayed in context;
|
|
203
|
+
- a child/subagent saved no budget because raw output returned to the parent;
|
|
204
|
+
- compaction/pruning happened but no one can prove what was changed, protected, backed up, summarized, or dropped.
|
|
205
|
+
|
|
206
|
+
A receipt is not enough if it only says “Tool Search enabled” or “used subagent”. It must prove the boundary behavior.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://schemas.agentskills.io/discovery/0.2.0/schema.json",
|
|
3
|
+
"skills": [
|
|
4
|
+
{
|
|
5
|
+
"name": "context-receipts",
|
|
6
|
+
"type": "skill-md",
|
|
7
|
+
"description": "Emit privacy-safe receipts for context selection, deferral, hydration, compaction, pruning, delegation, usage attribution, and boundary handoffs.",
|
|
8
|
+
"url": "context-receipts/SKILL.md",
|
|
9
|
+
"digest": "sha256:6d268a5ceac4afa87308ff4c79f01483e2785a8e9bb54e5d3147477e0bf724a1"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"name": "skill-policy-receipts",
|
|
13
|
+
"type": "skill-md",
|
|
14
|
+
"description": "Use when a task must obey a hard project policy, such as \"do not generate tests for internal services\", \"do not call production APIs\", or \"do not edit generated files\". Emits a privacy-safe receipt before writes and after guard checks.",
|
|
15
|
+
"url": "skill-policy-receipts/SKILL.md",
|
|
16
|
+
"digest": "sha256:633b4da097b56da8805476a69d0498602979b7f8c03c57996f886bb9e56ccca8"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skill-policy-receipts
|
|
3
|
+
description: Use when a task must obey a hard project policy, such as "do not generate tests for internal services", "do not call production APIs", or "do not edit generated files". Emits a privacy-safe receipt before writes and after guard checks.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Skill Policy Receipts
|
|
7
|
+
|
|
8
|
+
This Skill turns natural-language guardrails into an inspectable policy receipt.
|
|
9
|
+
|
|
10
|
+
## Preflight: decide before writing
|
|
11
|
+
|
|
12
|
+
Before creating or editing files:
|
|
13
|
+
|
|
14
|
+
1. List intended targets using coarse paths or globs.
|
|
15
|
+
2. For each target, decide `allowed` or `refused`.
|
|
16
|
+
3. Give a short reason.
|
|
17
|
+
4. If any target is refused, stop before writing.
|
|
18
|
+
5. Emit a receipt with `write_started=false` and `stopped_at="policy_refused"`.
|
|
19
|
+
|
|
20
|
+
Receipt shape:
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"receipt_type": "skill.policy.v1",
|
|
25
|
+
"skill": "skill-policy-receipts",
|
|
26
|
+
"policy_scope": "<short policy name>",
|
|
27
|
+
"targets": [
|
|
28
|
+
{
|
|
29
|
+
"target": "<coarse path or glob>",
|
|
30
|
+
"decision": "allowed|refused",
|
|
31
|
+
"reason": "<short reason>"
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"write_started": false,
|
|
35
|
+
"post_write_guard": "not_run",
|
|
36
|
+
"stopped_at": "policy_refused|all_targets_allowed"
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Do not include raw prompts, code, secrets, customer data, stack traces, or full tool output.
|
|
41
|
+
|
|
42
|
+
## Write only after all targets are allowed
|
|
43
|
+
|
|
44
|
+
If every target is allowed:
|
|
45
|
+
|
|
46
|
+
1. Emit or state `stopped_at="all_targets_allowed"`.
|
|
47
|
+
2. Perform the write.
|
|
48
|
+
3. Run the configured post-write guard.
|
|
49
|
+
4. Emit whether the guard passed or failed.
|
|
50
|
+
|
|
51
|
+
Post-write receipt shape:
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"receipt_type": "skill.policy.v1",
|
|
56
|
+
"skill": "skill-policy-receipts",
|
|
57
|
+
"policy_scope": "<short policy name>",
|
|
58
|
+
"write_started": true,
|
|
59
|
+
"post_write_guard": "passed|failed|not_configured",
|
|
60
|
+
"stopped_at": "guard_passed|guard_failed"
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Example policy: no internal-service unit tests
|
|
65
|
+
|
|
66
|
+
Policy:
|
|
67
|
+
|
|
68
|
+
> Do not generate unit tests for internal services. If the requested test imports `internal/`, `@/internal`, or a known private service module, refuse before writing and explain the safer target.
|
|
69
|
+
|
|
70
|
+
Example guard:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
grep -R "from ['\"]\.\./\.\./internal\|from ['\"]@/internal\|require(['\"]@/internal" \
|
|
74
|
+
-- '*test.*' '*spec.*'
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
If the grep finds a match in generated tests, stop and report `post_write_guard="failed"`.
|
package/docs/index.html
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>Pluribus Context Receipts</title>
|
|
7
|
+
<style>
|
|
8
|
+
:root { color-scheme: dark light; --bg:#0b1020; --card:#121a33; --text:#e8ecf8; --muted:#aab4cf; --accent:#8ee6c4; --border:#283454; }
|
|
9
|
+
body { margin:0; font:16px/1.55 system-ui,-apple-system,Segoe UI,sans-serif; background:var(--bg); color:var(--text); }
|
|
10
|
+
main { max-width:880px; margin:0 auto; padding:56px 20px; }
|
|
11
|
+
a { color:var(--accent); }
|
|
12
|
+
.card { background:var(--card); border:1px solid var(--border); border-radius:18px; padding:24px; margin:20px 0; }
|
|
13
|
+
code { background:#060a15; padding:.15rem .35rem; border-radius:6px; }
|
|
14
|
+
</style>
|
|
15
|
+
</head>
|
|
16
|
+
<body>
|
|
17
|
+
<main>
|
|
18
|
+
<h1>Pluribus Context Receipts</h1>
|
|
19
|
+
<p>Privacy-safe evidence for AI context boundaries: what crossed into the agent, what stayed out, and what should stop before edits or tool calls.</p>
|
|
20
|
+
<div class="card">
|
|
21
|
+
<h2>Browser playground</h2>
|
|
22
|
+
<p>Try receipt validation without installing anything or sending data to a server. Current samples cover MCP tool-surface diffs, retrieved-context attention, and CLAUDE.md rule-attention drift.</p>
|
|
23
|
+
<p><a href="receipt-playground.html">Open the receipt playground →</a></p>
|
|
24
|
+
</div>
|
|
25
|
+
<div class="card">
|
|
26
|
+
<h2>CLI quick checks</h2>
|
|
27
|
+
<p><code>npx --yes pluribus-context@latest demo tool-surface-diff --json</code></p>
|
|
28
|
+
<p><code>npx --yes pluribus-context@latest validate</code></p>
|
|
29
|
+
</div>
|
|
30
|
+
<div class="card">
|
|
31
|
+
<h2>Agent Skills discovery</h2>
|
|
32
|
+
<p>Pluribus publishes a well-known Agent Skills index so compatible clients can discover the low-authority <code>context-receipts</code> and <code>skill-policy-receipts</code> skills without scraping GitHub.</p>
|
|
33
|
+
<p><a href=".well-known/agent-skills/index.json">Open <code>/.well-known/agent-skills/index.json</code> →</a></p>
|
|
34
|
+
</div>
|
|
35
|
+
<p><a href="https://github.com/caioribeiroclw-pixel/pluribus">GitHub repo</a> · <a href="https://www.npmjs.com/package/pluribus-context">npm package</a></p>
|
|
36
|
+
</main>
|
|
37
|
+
</body>
|
|
38
|
+
</html>
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>Pluribus Receipt Playground</title>
|
|
7
|
+
<style>
|
|
8
|
+
:root { color-scheme: dark light; --bg:#0b1020; --card:#121a33; --text:#e8ecf8; --muted:#aab4cf; --accent:#8ee6c4; --bad:#ff8f9c; --warn:#ffd166; --ok:#8ee6c4; --border:#283454; }
|
|
9
|
+
* { box-sizing:border-box; }
|
|
10
|
+
body { margin:0; font:15px/1.5 system-ui,-apple-system,Segoe UI,sans-serif; background:linear-gradient(180deg,#0b1020,#10182e); color:var(--text); }
|
|
11
|
+
main { max-width:1120px; margin:0 auto; padding:34px 18px 48px; }
|
|
12
|
+
h1 { font-size:clamp(2rem,4vw,3.4rem); line-height:1.05; margin:.2rem 0 1rem; letter-spacing:-.04em; }
|
|
13
|
+
h2 { margin-top:0; }
|
|
14
|
+
p, li { color:var(--muted); }
|
|
15
|
+
a { color:var(--accent); }
|
|
16
|
+
.grid { display:grid; grid-template-columns:1fr; gap:16px; }
|
|
17
|
+
@media (min-width:900px) { .grid { grid-template-columns:1.1fr .9fr; } }
|
|
18
|
+
.card { background:rgba(18,26,51,.92); border:1px solid var(--border); border-radius:18px; padding:18px; box-shadow:0 20px 80px rgba(0,0,0,.24); }
|
|
19
|
+
textarea { width:100%; min-height:560px; resize:vertical; border:1px solid var(--border); border-radius:14px; padding:14px; background:#060a15; color:#e8ecf8; font:13px/1.45 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; }
|
|
20
|
+
button, select { border:1px solid var(--border); border-radius:999px; background:#182344; color:var(--text); padding:10px 14px; cursor:pointer; }
|
|
21
|
+
button:hover, select:hover { border-color:var(--accent); }
|
|
22
|
+
.controls { display:flex; flex-wrap:wrap; gap:10px; align-items:center; margin:0 0 12px; }
|
|
23
|
+
.result { white-space:pre-wrap; overflow:auto; border-radius:14px; padding:14px; background:#060a15; border:1px solid var(--border); min-height:210px; font:13px/1.45 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; }
|
|
24
|
+
.ok { color:var(--ok); }
|
|
25
|
+
.bad { color:var(--bad); }
|
|
26
|
+
.warn { color:var(--warn); }
|
|
27
|
+
.pill { display:inline-block; border:1px solid var(--border); border-radius:999px; padding:.2rem .55rem; color:var(--muted); margin:.1rem .2rem .1rem 0; }
|
|
28
|
+
code { background:#060a15; padding:.12rem .32rem; border-radius:6px; color:#d7e2ff; }
|
|
29
|
+
</style>
|
|
30
|
+
</head>
|
|
31
|
+
<body>
|
|
32
|
+
<main>
|
|
33
|
+
<p><a href="index.html">← Pluribus</a></p>
|
|
34
|
+
<h1>Receipt playground</h1>
|
|
35
|
+
<p>Paste a Pluribus receipt and validate the boundary evidence locally in your browser. No network calls, no raw prompts/results required.</p>
|
|
36
|
+
<div class="grid">
|
|
37
|
+
<section class="card">
|
|
38
|
+
<div class="controls">
|
|
39
|
+
<select id="sample">
|
|
40
|
+
<option value="toolSurface">Sample: MCP tool-surface diff</option>
|
|
41
|
+
<option value="attentionPass">Sample: context attention pass</option>
|
|
42
|
+
<option value="attentionFail">Sample: context attention fail</option>
|
|
43
|
+
<option value="ruleAttention">Sample: CLAUDE.md rule attention drift</option>
|
|
44
|
+
<option value="skillInstall">Sample: Agent Skill install provenance</option>
|
|
45
|
+
</select>
|
|
46
|
+
<button id="load">Load sample</button>
|
|
47
|
+
<button id="validate">Validate</button>
|
|
48
|
+
</div>
|
|
49
|
+
<textarea id="receipt" spellcheck="false"></textarea>
|
|
50
|
+
</section>
|
|
51
|
+
<aside class="card">
|
|
52
|
+
<h2>Validation result</h2>
|
|
53
|
+
<div id="result" class="result">Click Validate.</div>
|
|
54
|
+
<h2>What this checks</h2>
|
|
55
|
+
<p><span class="pill">tool-surface diff</span> proves runtime discovery changes without logging raw schemas/prompts/results.</p>
|
|
56
|
+
<p><span class="pill">context attention</span> proves required retrieved context was delivered, acknowledged, and cited before edits.</p>
|
|
57
|
+
<p><span class="pill">rule attention</span> shows whether project rules were re-read, cited in the pre-edit plan, and checked before changes.</p>
|
|
58
|
+
<p><span class="pill">skill install provenance</span> shows which <code>SKILL.md</code> source path won, which mirrors were ignored, and whether install metadata stayed content-safe.</p>
|
|
59
|
+
<h2>CLI equivalent</h2>
|
|
60
|
+
<p><code>npx --yes pluribus-context@latest demo tool-surface-diff --json</code></p>
|
|
61
|
+
</aside>
|
|
62
|
+
</div>
|
|
63
|
+
</main>
|
|
64
|
+
<script>
|
|
65
|
+
const samples = {
|
|
66
|
+
toolSurface: {
|
|
67
|
+
schema: 'pluribus.mcp_tool_surface_diff_receipt.v1',
|
|
68
|
+
run_id: 'tool-surface-diff-demo',
|
|
69
|
+
generated_at: '2026-06-09T13:00:00Z',
|
|
70
|
+
platform: { name: 'enterprise-mcp-dynamic-discovery', audit_sink: 'admin-center-or-siem' },
|
|
71
|
+
catalog: { server_id: 'mcp://sales-ops-gateway', previous_hash: 'sha256:previous-catalog-redacted', current_hash: 'sha256:current-catalog-redacted' },
|
|
72
|
+
runtime_discovery: { enabled: true, trigger: 'runtime_tool_catalog_diff' },
|
|
73
|
+
privacy_boundary: { raw_schemas: 'omitted_hash_only', raw_prompts: 'omitted', raw_results: 'omitted' },
|
|
74
|
+
tools: [
|
|
75
|
+
{ tool_id: 'tool:crm.search_accounts', name_hash: 'sha256:0cc2...', schema_hash: 'sha256:6f4f...', status: 'activated', validation_outcome: 'accepted', diff_summary: { added_fields: 1, removed_fields: 0, changed_fields: 0 } },
|
|
76
|
+
{ tool_id: 'tool:crm.export_contacts', name_hash: 'sha256:f38f...', schema_hash: 'sha256:95dd...', status: 'blocked', validation_outcome: 'blocked_by_rai', diff_summary: { added_fields: 4, removed_fields: 0, changed_fields: 2 } },
|
|
77
|
+
{ tool_id: 'tool:billing.refund_invoice', name_hash: 'sha256:abfd...', schema_hash: 'sha256:3b4f...', status: 'withheld', validation_outcome: 'entitlement_filtered', diff_summary: { added_fields: 0, removed_fields: 0, changed_fields: 0 } }
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
attentionPass: {
|
|
81
|
+
schema: 'pluribus.context_attention_receipt.v1', receipt_id: 'attn_demo_pass', task_id: 'claude-code-refactor-184', agent_surface: 'claude_code', retrieval_system: 'graph_memory_mcp',
|
|
82
|
+
required_context: [{ id: 'ctx:architecture:tenant-routing' }, { id: 'ctx:decision:readonly-audit-first' }],
|
|
83
|
+
delivery: { surface: 'mcp_tool_response', delivered_context_ids: ['ctx:architecture:tenant-routing', 'ctx:decision:readonly-audit-first'], raw_context_omitted: true, evidence_path: '.pluribus/receipts/context-attention.ndjson' },
|
|
84
|
+
attention: { acknowledged_before_plan: ['ctx:architecture:tenant-routing', 'ctx:decision:readonly-audit-first'], cited_in_plan: ['ctx:architecture:tenant-routing', 'ctx:decision:readonly-audit-first'], missing_context_stop: false },
|
|
85
|
+
privacy: { raw_prompts_omitted: true, raw_documents_omitted: true, source_code_omitted: true, tool_outputs_omitted: true, tokens_omitted: true, customer_data_omitted: true },
|
|
86
|
+
result: { status: 'safe_to_continue', next_safe_action: 'continue with dry-run refactor plan' }
|
|
87
|
+
},
|
|
88
|
+
attentionFail: {
|
|
89
|
+
schema: 'pluribus.context_attention_receipt.v1', receipt_id: 'attn_demo_fail', task_id: 'claude-code-refactor-185', agent_surface: 'claude_code', retrieval_system: 'graph_memory_mcp',
|
|
90
|
+
required_context: [{ id: 'ctx:architecture:tenant-routing' }, { id: 'ctx:decision:readonly-audit-first' }],
|
|
91
|
+
delivery: { surface: 'mcp_tool_response', delivered_context_ids: ['ctx:architecture:tenant-routing', 'ctx:decision:readonly-audit-first'], raw_context_omitted: true, evidence_path: '.pluribus/receipts/context-attention.ndjson' },
|
|
92
|
+
attention: { acknowledged_before_plan: ['ctx:architecture:tenant-routing'], cited_in_plan: [], missing_context_stop: false },
|
|
93
|
+
privacy: { raw_prompts_omitted: true, raw_documents_omitted: true, source_code_omitted: true, tool_outputs_omitted: true, tokens_omitted: true, customer_data_omitted: true },
|
|
94
|
+
result: { status: 'unsafe_to_continue', next_safe_action: 'stop and re-deliver required context before editing' }
|
|
95
|
+
},
|
|
96
|
+
ruleAttention: {
|
|
97
|
+
schema: 'pluribus.claude_code_rule_attention_receipt.v1',
|
|
98
|
+
receipt_id: 'rule_attn_demo_62087',
|
|
99
|
+
task_id: 'claude-code-long-session-62087',
|
|
100
|
+
agent_surface: 'claude_code',
|
|
101
|
+
context_boundary: { session_phase: 'post-compaction-long-session', before_first_edit: true },
|
|
102
|
+
rules: [
|
|
103
|
+
{ rule_id: 'CLAUDE.md:test-after-plan', source: 'CLAUDE.md#workflow', last_loaded_at: '2026-06-09T22:41:00Z', last_referenced_at: null, cited_in_pre_edit_plan: false, edit_check: 'missing', violation_category: 'loaded_but_not_referenced' },
|
|
104
|
+
{ rule_id: 'CLAUDE.md:no-skip-steps', source: 'CLAUDE.md#workflow', last_loaded_at: '2026-06-09T22:41:00Z', last_referenced_at: '2026-06-09T22:58:00Z', cited_in_pre_edit_plan: true, edit_check: 'pass', violation_category: null }
|
|
105
|
+
],
|
|
106
|
+
privacy: { raw_prompts_omitted: true, raw_claude_md_omitted: true, source_code_omitted: true, tool_outputs_omitted: true, tokens_omitted: true, customer_data_omitted: true },
|
|
107
|
+
result: { status: 'unsafe_to_edit', next_safe_action: 'stop, re-read missing rule ids, and restate the pre-edit plan with citations' }
|
|
108
|
+
},
|
|
109
|
+
skillInstall: {
|
|
110
|
+
schema: 'pluribus.agent_skill_install_provenance_receipt.v1',
|
|
111
|
+
receipt_id: 'skill_install_openskills_demo',
|
|
112
|
+
installer: { name: 'agent-skill-package-manager', mode: 'universal', target_agent_dir: '.agent/skills' },
|
|
113
|
+
source: { kind: 'github_repo', repo: 'caioribeiroclw-pixel/pluribus', requested_ref: 'v0.3.40', resolved_sha: 'sha256:resolved-commit-redacted' },
|
|
114
|
+
discovery: {
|
|
115
|
+
requested_skill_names: ['context-receipts', 'skill-policy-receipts'],
|
|
116
|
+
discovered_source_paths: [
|
|
117
|
+
'skills/context-receipts/SKILL.md',
|
|
118
|
+
'examples/agent-skills/context-receipts/SKILL.md',
|
|
119
|
+
'docs/.well-known/agent-skills/context-receipts/SKILL.md',
|
|
120
|
+
'skills/skill-policy-receipts/SKILL.md',
|
|
121
|
+
'examples/agent-skills/skill-policy-receipts/SKILL.md',
|
|
122
|
+
'docs/.well-known/agent-skills/skill-policy-receipts/SKILL.md'
|
|
123
|
+
],
|
|
124
|
+
duplicate_resolution: 'prefer_top_level_skills_dir'
|
|
125
|
+
},
|
|
126
|
+
selected_skills: [
|
|
127
|
+
{ name: 'context-receipts', selected_source_path: 'skills/context-receipts/SKILL.md', target_path: '.agent/skills/context-receipts/SKILL.md', operation: 'install', lockfile_entry_written: true },
|
|
128
|
+
{ name: 'skill-policy-receipts', selected_source_path: 'skills/skill-policy-receipts/SKILL.md', target_path: '.agent/skills/skill-policy-receipts/SKILL.md', operation: 'install', lockfile_entry_written: true }
|
|
129
|
+
],
|
|
130
|
+
ignored_duplicates: [
|
|
131
|
+
{ name: 'context-receipts', ignored_source_path: 'examples/agent-skills/context-receipts/SKILL.md', reason: 'duplicate_mirror_not_canonical' },
|
|
132
|
+
{ name: 'context-receipts', ignored_source_path: 'docs/.well-known/agent-skills/context-receipts/SKILL.md', reason: 'duplicate_mirror_not_canonical' },
|
|
133
|
+
{ name: 'skill-policy-receipts', ignored_source_path: 'examples/agent-skills/skill-policy-receipts/SKILL.md', reason: 'duplicate_mirror_not_canonical' },
|
|
134
|
+
{ name: 'skill-policy-receipts', ignored_source_path: 'docs/.well-known/agent-skills/skill-policy-receipts/SKILL.md', reason: 'duplicate_mirror_not_canonical' }
|
|
135
|
+
],
|
|
136
|
+
safety: { content_sanitizers: ['frontmatter-parse', 'markdown-only'], raw_secret_or_env_values_copied: false, scripts_or_hooks_installed: false, network_capability_added: false, manual_review_required: true },
|
|
137
|
+
privacy: { raw_skill_body_omitted: true, raw_env_values_omitted: true, auth_headers_omitted: true, customer_data_omitted: true },
|
|
138
|
+
result: { status: 'safe_to_install_after_review', installed_count: 2, ignored_duplicate_count: 4 }
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const receiptEl = document.querySelector('#receipt')
|
|
143
|
+
const resultEl = document.querySelector('#result')
|
|
144
|
+
document.querySelector('#load').addEventListener('click', loadSample)
|
|
145
|
+
document.querySelector('#validate').addEventListener('click', validate)
|
|
146
|
+
document.querySelector('#sample').addEventListener('change', loadSample)
|
|
147
|
+
loadSample()
|
|
148
|
+
|
|
149
|
+
function loadSample() {
|
|
150
|
+
const key = document.querySelector('#sample').value
|
|
151
|
+
receiptEl.value = JSON.stringify(samples[key], null, 2)
|
|
152
|
+
validate()
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function validate() {
|
|
156
|
+
let receipt
|
|
157
|
+
try { receipt = JSON.parse(receiptEl.value) }
|
|
158
|
+
catch (error) { return render({ ok:false, errors:[`invalid JSON: ${error.message}`], warnings:[] }) }
|
|
159
|
+
if (receipt.schema === 'pluribus.mcp_tool_surface_diff_receipt.v1') return render(validateToolSurface(receipt))
|
|
160
|
+
if (receipt.schema === 'pluribus.context_attention_receipt.v1') return render(validateAttention(receipt))
|
|
161
|
+
if (receipt.schema === 'pluribus.claude_code_rule_attention_receipt.v1') return render(validateRuleAttention(receipt))
|
|
162
|
+
if (receipt.schema === 'pluribus.agent_skill_install_provenance_receipt.v1') return render(validateSkillInstall(receipt))
|
|
163
|
+
render({ ok:false, errors:[`unsupported schema: ${receipt.schema || '(missing)'}`], warnings:[] })
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function validateToolSurface(r) {
|
|
167
|
+
const errors = [], warnings = []
|
|
168
|
+
const privacy = r.privacy_boundary || {}
|
|
169
|
+
if (!r.catalog?.current_hash) errors.push('catalog.current_hash is required')
|
|
170
|
+
if (!Array.isArray(r.tools) || r.tools.length === 0) errors.push('tools must include at least one discovered/activated/withheld/blocked tool')
|
|
171
|
+
for (const field of ['raw_schemas','raw_prompts','raw_results']) if (!String(privacy[field] || '').startsWith('omitted')) errors.push(`privacy_boundary.${field} must be omitted`)
|
|
172
|
+
const counts = countBy(r.tools || [], 'status')
|
|
173
|
+
if (!counts.activated && !counts.withheld && !counts.blocked) warnings.push('receipt has no activated/withheld/blocked status counts')
|
|
174
|
+
return { ok: errors.length === 0, schema:r.schema, summary:counts, errors, warnings }
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function validateAttention(r) {
|
|
178
|
+
const errors = [], warnings = []
|
|
179
|
+
const required = ids((r.required_context || []).map(x => x.id))
|
|
180
|
+
const delivered = ids(r.delivery?.delivered_context_ids)
|
|
181
|
+
const ack = ids(r.attention?.acknowledged_before_plan)
|
|
182
|
+
const cited = ids(r.attention?.cited_in_plan)
|
|
183
|
+
if (!required.length) errors.push('required_context must name at least one id')
|
|
184
|
+
for (const id of required) {
|
|
185
|
+
if (!delivered.includes(id)) errors.push(`required context not delivered: ${id}`)
|
|
186
|
+
if (!ack.includes(id)) errors.push(`required context not acknowledged before plan: ${id}`)
|
|
187
|
+
if (!cited.includes(id)) errors.push(`required context not cited in plan: ${id}`)
|
|
188
|
+
}
|
|
189
|
+
if (r.delivery?.raw_context_omitted !== true) errors.push('delivery.raw_context_omitted must be true')
|
|
190
|
+
for (const field of ['raw_prompts_omitted','raw_documents_omitted','source_code_omitted','tool_outputs_omitted','tokens_omitted','customer_data_omitted']) if (r.privacy?.[field] !== true) errors.push(`privacy.${field} must be true`)
|
|
191
|
+
if (errors.length && r.attention?.missing_context_stop !== true) errors.push('missing_context_stop must be true when required attention evidence is incomplete')
|
|
192
|
+
if (!r.delivery?.evidence_path) warnings.push('delivery.evidence_path is missing')
|
|
193
|
+
return { ok: errors.length === 0, schema:r.schema, required_count:required.length, delivered_count:delivered.length, acknowledged_count:ack.length, cited_count:cited.length, errors, warnings }
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function validateRuleAttention(r) {
|
|
197
|
+
const errors = [], warnings = []
|
|
198
|
+
const rules = Array.isArray(r.rules) ? r.rules : []
|
|
199
|
+
if (!rules.length) errors.push('rules must include at least one project rule')
|
|
200
|
+
for (const rule of rules) {
|
|
201
|
+
if (!rule.rule_id) errors.push('each rule must include rule_id')
|
|
202
|
+
if (!rule.source) errors.push(`${rule.rule_id || 'rule'} must include source`)
|
|
203
|
+
if (!rule.last_loaded_at) errors.push(`${rule.rule_id || 'rule'} must include last_loaded_at`)
|
|
204
|
+
if (rule.cited_in_pre_edit_plan !== true) warnings.push(`${rule.rule_id || 'rule'} was not cited in the pre-edit plan`)
|
|
205
|
+
if (!['pass','fail','missing'].includes(rule.edit_check)) errors.push(`${rule.rule_id || 'rule'} edit_check must be pass, fail, or missing`)
|
|
206
|
+
}
|
|
207
|
+
for (const field of ['raw_prompts_omitted','raw_claude_md_omitted','source_code_omitted','tool_outputs_omitted','tokens_omitted','customer_data_omitted']) if (r.privacy?.[field] !== true) errors.push(`privacy.${field} must be true`)
|
|
208
|
+
const missing = rules.filter(rule => rule.cited_in_pre_edit_plan !== true || rule.edit_check !== 'pass')
|
|
209
|
+
if (missing.length && r.result?.status === 'safe_to_edit') errors.push('result.status cannot be safe_to_edit while a required rule is uncited or failing')
|
|
210
|
+
return { ok: errors.length === 0 && missing.length === 0, schema:r.schema, rules_count:rules.length, uncited_or_failing_rules:missing.map(rule => rule.rule_id), errors, warnings }
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function validateSkillInstall(r) {
|
|
214
|
+
const errors = [], warnings = []
|
|
215
|
+
const selected = Array.isArray(r.selected_skills) ? r.selected_skills : []
|
|
216
|
+
const ignored = Array.isArray(r.ignored_duplicates) ? r.ignored_duplicates : []
|
|
217
|
+
const discovered = Array.isArray(r.discovery?.discovered_source_paths) ? r.discovery.discovered_source_paths : []
|
|
218
|
+
if (!r.source?.repo) errors.push('source.repo is required')
|
|
219
|
+
if (!r.source?.resolved_sha) errors.push('source.resolved_sha is required')
|
|
220
|
+
if (!r.installer?.target_agent_dir) errors.push('installer.target_agent_dir is required')
|
|
221
|
+
if (!selected.length) errors.push('selected_skills must include at least one installed skill')
|
|
222
|
+
for (const skill of selected) {
|
|
223
|
+
if (!skill.name) errors.push('each selected skill must include name')
|
|
224
|
+
if (!skill.selected_source_path) errors.push(`${skill.name || 'skill'} must include selected_source_path`)
|
|
225
|
+
if (!skill.target_path) errors.push(`${skill.name || 'skill'} must include target_path`)
|
|
226
|
+
if (skill.lockfile_entry_written !== true) warnings.push(`${skill.name || 'skill'} did not write lockfile metadata`)
|
|
227
|
+
}
|
|
228
|
+
const selectedNames = selected.map(skill => skill.name).filter(Boolean)
|
|
229
|
+
for (const name of selectedNames) {
|
|
230
|
+
const discoveredForName = discovered.filter(path => path.includes(`/${name}/`) || path.includes(`${name}/SKILL.md`)).length
|
|
231
|
+
const ignoredForName = ignored.filter(item => item.name === name).length
|
|
232
|
+
if (discoveredForName > 1 && ignoredForName === 0) errors.push(`${name} has multiple discovered paths but no ignored_duplicates evidence`)
|
|
233
|
+
}
|
|
234
|
+
if (r.safety?.raw_secret_or_env_values_copied !== false) errors.push('safety.raw_secret_or_env_values_copied must be false')
|
|
235
|
+
if (r.safety?.scripts_or_hooks_installed !== false) errors.push('safety.scripts_or_hooks_installed must be false for a low-authority skill receipt')
|
|
236
|
+
if (r.safety?.network_capability_added !== false) errors.push('safety.network_capability_added must be false for a skill-only install')
|
|
237
|
+
for (const field of ['raw_skill_body_omitted','raw_env_values_omitted','auth_headers_omitted','customer_data_omitted']) if (r.privacy?.[field] !== true) errors.push(`privacy.${field} must be true`)
|
|
238
|
+
if (selected.length !== new Set(selectedNames).size) errors.push('selected_skills contains duplicate names after resolution')
|
|
239
|
+
return { ok: errors.length === 0, schema:r.schema, selected_count:selected.length, ignored_duplicate_count:ignored.length, discovered_source_count:discovered.length, selected_source_paths:selected.map(skill => skill.selected_source_path), errors, warnings }
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function countBy(items, key) { return items.reduce((acc, item) => (acc[item[key] || 'unknown'] = (acc[item[key] || 'unknown'] || 0) + 1, acc), {}) }
|
|
243
|
+
function ids(v) { return Array.isArray(v) ? v.filter(x => typeof x === 'string' && x) : [] }
|
|
244
|
+
function render(obj) {
|
|
245
|
+
resultEl.className = 'result ' + (obj.ok ? 'ok' : 'bad')
|
|
246
|
+
resultEl.textContent = JSON.stringify(obj, null, 2)
|
|
247
|
+
}
|
|
248
|
+
</script>
|
|
249
|
+
</body>
|
|
250
|
+
</html>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Context attention receipts
|
|
2
|
+
|
|
3
|
+
This example is for the `r/ClaudeCode` / GraphRAG failure mode: a graph, memory, RAG, or MCP retrieval system finds the right context, but the coding agent behaves as if it never saw it.
|
|
4
|
+
|
|
5
|
+
Pluribus should not replace graph memory, RAG, or MCP search. The useful boundary is smaller: emit a privacy-safe receipt proving whether selected context actually crossed the agent boundary and was treated as required before planning or editing.
|
|
6
|
+
|
|
7
|
+
## What the receipt proves
|
|
8
|
+
|
|
9
|
+
`pluribus.context_attention_receipt.v1` records low-cardinality evidence only:
|
|
10
|
+
|
|
11
|
+
- which retrieval/memory/tool context IDs were required for the task;
|
|
12
|
+
- which surface delivered them (`mcp_tool_response`, `claude_hook`, `CLAUDE.md`, `AGENTS.md`, etc.);
|
|
13
|
+
- whether the agent acknowledged those IDs before plan/edit;
|
|
14
|
+
- whether the final plan cites the IDs it depended on;
|
|
15
|
+
- whether missing context forced a stop instead of a best-effort edit;
|
|
16
|
+
- whether raw documents, prompts, source code, transcripts, tokens, or customer data were omitted.
|
|
17
|
+
|
|
18
|
+
It intentionally does **not** store the retrieved chunks themselves. Use stable IDs, hashes, coarse labels, and evidence paths instead.
|
|
19
|
+
|
|
20
|
+
## Smoke test
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
node examples/context-attention-receipts/check-attention-receipt.mjs \
|
|
24
|
+
examples/context-attention-receipts/attention-receipt-pass.json
|
|
25
|
+
|
|
26
|
+
node examples/context-attention-receipts/check-attention-receipt.mjs \
|
|
27
|
+
examples/context-attention-receipts/attention-receipt-fail.json
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The first command should pass. The second should fail because the graph/memory result was retrieved but not acknowledged or cited before editing.
|
|
31
|
+
|
|
32
|
+
## Why this exists
|
|
33
|
+
|
|
34
|
+
A high-quality retrieval layer is still weak if the next agent turn can ignore it. The receipt makes that failure visible:
|
|
35
|
+
|
|
36
|
+
- retrieval succeeded;
|
|
37
|
+
- required context was or was not delivered to the agent surface;
|
|
38
|
+
- the agent did or did not acknowledge it before changing files;
|
|
39
|
+
- the wrapper/hook did or did not stop the run when required context was missing.
|
|
40
|
+
|
|
41
|
+
That is the narrow Pluribus angle: not more memory, not a new graph database, and not another router — evidence that the context boundary was actually crossed.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": "pluribus.context_attention_receipt.v1",
|
|
3
|
+
"receipt_id": "attn_2026_06_09_demo_fail",
|
|
4
|
+
"task_id": "claude-code-refactor-185",
|
|
5
|
+
"agent_surface": "claude_code",
|
|
6
|
+
"retrieval_system": "graph_memory_mcp",
|
|
7
|
+
"required_context": [
|
|
8
|
+
{
|
|
9
|
+
"id": "ctx:architecture:tenant-routing",
|
|
10
|
+
"source_type": "knowledge_graph",
|
|
11
|
+
"source_hash": "sha256:7bf3e0c1-redacted",
|
|
12
|
+
"why_required": "routes tenant-scoped writes through the policy gateway"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"id": "ctx:decision:readonly-audit-first",
|
|
16
|
+
"source_type": "decision_log",
|
|
17
|
+
"source_hash": "sha256:11ab91d4-redacted",
|
|
18
|
+
"why_required": "requires dry-run/audit before writes"
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"delivery": {
|
|
22
|
+
"surface": "mcp_tool_response",
|
|
23
|
+
"delivered_context_ids": [
|
|
24
|
+
"ctx:architecture:tenant-routing",
|
|
25
|
+
"ctx:decision:readonly-audit-first"
|
|
26
|
+
],
|
|
27
|
+
"raw_context_omitted": true,
|
|
28
|
+
"evidence_path": ".pluribus/receipts/context-attention.ndjson"
|
|
29
|
+
},
|
|
30
|
+
"attention": {
|
|
31
|
+
"acknowledged_before_plan": [
|
|
32
|
+
"ctx:architecture:tenant-routing"
|
|
33
|
+
],
|
|
34
|
+
"cited_in_plan": [],
|
|
35
|
+
"missing_context_stop": false
|
|
36
|
+
},
|
|
37
|
+
"privacy": {
|
|
38
|
+
"raw_prompts_omitted": true,
|
|
39
|
+
"raw_documents_omitted": true,
|
|
40
|
+
"source_code_omitted": true,
|
|
41
|
+
"tool_outputs_omitted": true,
|
|
42
|
+
"tokens_omitted": true,
|
|
43
|
+
"customer_data_omitted": true
|
|
44
|
+
},
|
|
45
|
+
"result": {
|
|
46
|
+
"status": "unsafe_to_continue",
|
|
47
|
+
"next_safe_action": "stop and ask the retrieval wrapper to re-deliver required context before editing"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": "pluribus.context_attention_receipt.v1",
|
|
3
|
+
"receipt_id": "attn_2026_06_09_demo_pass",
|
|
4
|
+
"task_id": "claude-code-refactor-184",
|
|
5
|
+
"agent_surface": "claude_code",
|
|
6
|
+
"retrieval_system": "graph_memory_mcp",
|
|
7
|
+
"required_context": [
|
|
8
|
+
{
|
|
9
|
+
"id": "ctx:architecture:tenant-routing",
|
|
10
|
+
"source_type": "knowledge_graph",
|
|
11
|
+
"source_hash": "sha256:7bf3e0c1-redacted",
|
|
12
|
+
"why_required": "routes tenant-scoped writes through the policy gateway"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"id": "ctx:decision:readonly-audit-first",
|
|
16
|
+
"source_type": "decision_log",
|
|
17
|
+
"source_hash": "sha256:11ab91d4-redacted",
|
|
18
|
+
"why_required": "requires dry-run/audit before writes"
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"delivery": {
|
|
22
|
+
"surface": "mcp_tool_response",
|
|
23
|
+
"delivered_context_ids": [
|
|
24
|
+
"ctx:architecture:tenant-routing",
|
|
25
|
+
"ctx:decision:readonly-audit-first"
|
|
26
|
+
],
|
|
27
|
+
"raw_context_omitted": true,
|
|
28
|
+
"evidence_path": ".pluribus/receipts/context-attention.ndjson"
|
|
29
|
+
},
|
|
30
|
+
"attention": {
|
|
31
|
+
"acknowledged_before_plan": [
|
|
32
|
+
"ctx:architecture:tenant-routing",
|
|
33
|
+
"ctx:decision:readonly-audit-first"
|
|
34
|
+
],
|
|
35
|
+
"cited_in_plan": [
|
|
36
|
+
"ctx:architecture:tenant-routing",
|
|
37
|
+
"ctx:decision:readonly-audit-first"
|
|
38
|
+
],
|
|
39
|
+
"missing_context_stop": false
|
|
40
|
+
},
|
|
41
|
+
"privacy": {
|
|
42
|
+
"raw_prompts_omitted": true,
|
|
43
|
+
"raw_documents_omitted": true,
|
|
44
|
+
"source_code_omitted": true,
|
|
45
|
+
"tool_outputs_omitted": true,
|
|
46
|
+
"tokens_omitted": true,
|
|
47
|
+
"customer_data_omitted": true
|
|
48
|
+
},
|
|
49
|
+
"result": {
|
|
50
|
+
"status": "safe_to_continue",
|
|
51
|
+
"next_safe_action": "continue with dry-run refactor plan"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from 'node:fs'
|
|
3
|
+
import { resolve } from 'node:path'
|
|
4
|
+
|
|
5
|
+
const [receiptPathArg] = process.argv.slice(2)
|
|
6
|
+
|
|
7
|
+
if (!receiptPathArg) {
|
|
8
|
+
fail(['usage: node check-attention-receipt.mjs <receipt.json>'], 2)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const receiptPath = resolve(process.cwd(), receiptPathArg)
|
|
12
|
+
let receipt
|
|
13
|
+
try {
|
|
14
|
+
receipt = JSON.parse(readFileSync(receiptPath, 'utf8'))
|
|
15
|
+
} catch (error) {
|
|
16
|
+
fail([`could not read receipt JSON: ${error.message}`], 2)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const errors = []
|
|
20
|
+
const warnings = []
|
|
21
|
+
|
|
22
|
+
if (receipt.schema !== 'pluribus.context_attention_receipt.v1') {
|
|
23
|
+
errors.push('schema must be pluribus.context_attention_receipt.v1')
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const requiredIds = ids(receipt.required_context?.map((item) => item.id))
|
|
27
|
+
const deliveredIds = ids(receipt.delivery?.delivered_context_ids)
|
|
28
|
+
const acknowledgedIds = ids(receipt.attention?.acknowledged_before_plan)
|
|
29
|
+
const citedIds = ids(receipt.attention?.cited_in_plan)
|
|
30
|
+
|
|
31
|
+
if (requiredIds.length === 0) errors.push('required_context must name at least one context id')
|
|
32
|
+
|
|
33
|
+
for (const id of requiredIds) {
|
|
34
|
+
if (!deliveredIds.includes(id)) errors.push(`required context not delivered: ${id}`)
|
|
35
|
+
if (!acknowledgedIds.includes(id)) errors.push(`required context not acknowledged before plan: ${id}`)
|
|
36
|
+
if (!citedIds.includes(id)) errors.push(`required context not cited in plan: ${id}`)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (receipt.delivery?.raw_context_omitted !== true) {
|
|
40
|
+
errors.push('delivery.raw_context_omitted must be true')
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const privacy = receipt.privacy || {}
|
|
44
|
+
for (const field of [
|
|
45
|
+
'raw_prompts_omitted',
|
|
46
|
+
'raw_documents_omitted',
|
|
47
|
+
'source_code_omitted',
|
|
48
|
+
'tool_outputs_omitted',
|
|
49
|
+
'tokens_omitted',
|
|
50
|
+
'customer_data_omitted'
|
|
51
|
+
]) {
|
|
52
|
+
if (privacy[field] !== true) errors.push(`privacy.${field} must be true`)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (errors.length > 0 && receipt.attention?.missing_context_stop !== true) {
|
|
56
|
+
errors.push('missing_context_stop must be true when required context attention evidence is incomplete')
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (receipt.result?.status === 'safe_to_continue' && errors.length > 0) {
|
|
60
|
+
errors.push('result.status cannot be safe_to_continue when required evidence is incomplete')
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (!receipt.delivery?.evidence_path) {
|
|
64
|
+
warnings.push('delivery.evidence_path is missing; reviewers need a pointer to the audit trail')
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const output = {
|
|
68
|
+
ok: errors.length === 0,
|
|
69
|
+
receipt_id: receipt.receipt_id || null,
|
|
70
|
+
task_id: receipt.task_id || null,
|
|
71
|
+
agent_surface: receipt.agent_surface || null,
|
|
72
|
+
required_count: requiredIds.length,
|
|
73
|
+
delivered_count: deliveredIds.length,
|
|
74
|
+
acknowledged_count: acknowledgedIds.length,
|
|
75
|
+
cited_count: citedIds.length,
|
|
76
|
+
status: receipt.result?.status || null,
|
|
77
|
+
next_safe_action: receipt.result?.next_safe_action || null,
|
|
78
|
+
errors,
|
|
79
|
+
warnings
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (output.ok) {
|
|
83
|
+
console.log(JSON.stringify(output, null, 2))
|
|
84
|
+
process.exit(0)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
console.error(JSON.stringify(output, null, 2))
|
|
88
|
+
process.exit(1)
|
|
89
|
+
|
|
90
|
+
function ids(value) {
|
|
91
|
+
return Array.isArray(value) ? value.filter((id) => typeof id === 'string' && id.length > 0) : []
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function fail(errors, code) {
|
|
95
|
+
console.error(JSON.stringify({ ok: false, errors }, null, 2))
|
|
96
|
+
process.exit(code)
|
|
97
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pluribus-context",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.41",
|
|
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",
|
|
@@ -89,7 +89,10 @@
|
|
|
89
89
|
"agent-context-audit",
|
|
90
90
|
"agent-memory",
|
|
91
91
|
"bob",
|
|
92
|
-
"bob-rules"
|
|
92
|
+
"bob-rules",
|
|
93
|
+
"agent-skill",
|
|
94
|
+
"skillpm",
|
|
95
|
+
"agent-skills-registry"
|
|
93
96
|
],
|
|
94
97
|
"author": "Caio Ribeiro",
|
|
95
98
|
"license": "MIT",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Context receipts Agent Skill recipe
|
|
2
2
|
|
|
3
|
-
This is a small, copyable Agent Skill recipe for context-engineering users who are adopting Tool Search, lazy MCP loading, skills, memory, compaction, or subagents and need to verify what actually crossed the context boundary.
|
|
3
|
+
This is a small, copyable Agent Skill recipe for context-engineering users who are adopting Tool Search, lazy MCP loading, dynamic tool discovery, skills, memory, compaction, GraphRAG/code search, transcript review, or subagents and need to verify what actually crossed the context boundary.
|
|
4
4
|
|
|
5
5
|
It is intentionally markdown-only so it can be copied into a local skills directory such as:
|
|
6
6
|
|
|
@@ -8,6 +8,11 @@ It is intentionally markdown-only so it can be copied into a local skills direct
|
|
|
8
8
|
- `.opencode/skills/context-receipts/SKILL.md`
|
|
9
9
|
- `.agents/skills/context-receipts/SKILL.md`
|
|
10
10
|
|
|
11
|
+
The two newest smoke paths are:
|
|
12
|
+
|
|
13
|
+
- **Runtime tool-surface diff:** prove which MCP tools were discovered, activated, withheld, or blocked without copying raw schemas/prompts/results.
|
|
14
|
+
- **Context attention:** prove that retrieved/baseline context was delivered, acknowledged before planning, and cited before edits/tool calls.
|
|
15
|
+
|
|
11
16
|
## Quick smoke
|
|
12
17
|
|
|
13
18
|
Ask an agent or harness using the skill to emit a receipt for one workflow and verify these constraints:
|
|
@@ -19,9 +24,15 @@ grep -E 'raw_(schema|query|args|result|output|transcript|text)_copied":false|raw
|
|
|
19
24
|
|
|
20
25
|
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
26
|
|
|
22
|
-
For executable fixture examples, see
|
|
27
|
+
For executable fixture examples, see:
|
|
28
|
+
|
|
29
|
+
- [`../../examples/tool-surface-diff-receipts/`](../../examples/tool-surface-diff-receipts/) for runtime MCP tool-surface diff receipts.
|
|
30
|
+
- [`../../examples/context-attention-receipts/`](../../examples/context-attention-receipts/) for retrieved-context attention receipts.
|
|
31
|
+
- [`../../examples/context-input-evidence/`](../../examples/context-input-evidence/) for ToolSearch propagation, pruning, and compaction transaction smokes.
|
|
23
32
|
|
|
24
33
|
```bash
|
|
34
|
+
node ../../examples/context-attention-receipts/check-attention-receipt.mjs \
|
|
35
|
+
../../examples/context-attention-receipts/attention-receipt-pass.json
|
|
25
36
|
node ../../examples/context-input-evidence/convert-subagent-toolsearch-propagation-log.mjs
|
|
26
37
|
node ../../examples/context-input-evidence/convert-pruning-log.mjs
|
|
27
38
|
node ../../examples/context-input-evidence/convert-compaction-transaction-log.mjs
|
|
@@ -45,6 +45,71 @@ Minimal JSONL event names:
|
|
|
45
45
|
{"event":"mcp.tool_call.completed","tool_id":"github.search_code","args_hash":"sha256:...","result_token_bucket":"2k_4k","raw_args_copied":false,"raw_result_copied":false,"status":"ok"}
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
+
## Runtime tool-surface diff smoke
|
|
49
|
+
|
|
50
|
+
For MCP dynamic discovery, gateways, admin/Purview-style audit trails, or runtime tool catalogs, separate discovery from activation:
|
|
51
|
+
|
|
52
|
+
- which platform/gateway/audit sink observed the runtime catalog change;
|
|
53
|
+
- which catalog/version/hash was active before and after discovery;
|
|
54
|
+
- which tools were discovered, activated, withheld, or blocked;
|
|
55
|
+
- which validation outcome applied, such as `accepted`, `blocked_by_rai`, `blocked_by_xpia`, `schema_invalid`, or `entitlement_filtered`;
|
|
56
|
+
- whether only low-cardinality ids, hashes, counts, and outcome codes entered the receipt;
|
|
57
|
+
- the audit gap, such as not proving the tool was semantically right for the user task.
|
|
58
|
+
|
|
59
|
+
Minimal JSON shape:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"receipt_type": "pluribus.mcp_tool_surface_diff_receipt.v1",
|
|
64
|
+
"runtime_discovery": {
|
|
65
|
+
"trigger": "turn_start|admin_refresh|tool_search|manual_refresh",
|
|
66
|
+
"before_catalog_hash": "sha256:...",
|
|
67
|
+
"after_catalog_hash": "sha256:..."
|
|
68
|
+
},
|
|
69
|
+
"summary": {
|
|
70
|
+
"discovered_count": 3,
|
|
71
|
+
"activated_count": 1,
|
|
72
|
+
"withheld_count": 1,
|
|
73
|
+
"blocked_count": 1
|
|
74
|
+
},
|
|
75
|
+
"privacy": {
|
|
76
|
+
"raw_schemas_copied": false,
|
|
77
|
+
"raw_prompts_copied": false,
|
|
78
|
+
"raw_results_copied": false
|
|
79
|
+
},
|
|
80
|
+
"audit_gap": "proves tool-surface boundary, not semantic usefulness"
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Context attention smoke
|
|
85
|
+
|
|
86
|
+
For GraphRAG, memory, code search, transcript review, or baseline-first workflows, separate retrieval from attention:
|
|
87
|
+
|
|
88
|
+
- which required context ids were selected or retrieved;
|
|
89
|
+
- where they were delivered, such as prompt, tool result, memory result, subagent packet, or file read;
|
|
90
|
+
- which ids were acknowledged before planning;
|
|
91
|
+
- which ids were cited before edits/tool calls;
|
|
92
|
+
- what the agent must stop on if a required id is missing;
|
|
93
|
+
- whether raw docs, prompts, results, paths, customer text, and full transcript snippets stayed out of the receipt.
|
|
94
|
+
|
|
95
|
+
Minimal JSON shape:
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"receipt_type": "pluribus.context_attention_receipt.v1",
|
|
100
|
+
"required_context_ids": ["ctx:auth-boundary", "ctx:migration-plan"],
|
|
101
|
+
"delivered_context_ids": ["ctx:auth-boundary", "ctx:migration-plan"],
|
|
102
|
+
"acknowledged_before_plan_ids": ["ctx:auth-boundary", "ctx:migration-plan"],
|
|
103
|
+
"cited_before_edit_ids": ["ctx:auth-boundary"],
|
|
104
|
+
"missing_context_stop": "stop_before_edit",
|
|
105
|
+
"privacy": {
|
|
106
|
+
"raw_context_copied": false,
|
|
107
|
+
"raw_transcript_copied": false
|
|
108
|
+
},
|
|
109
|
+
"audit_gap": "proves required context was acknowledged/cited, not that the edit is correct"
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
48
113
|
## Skill / prompt context smoke
|
|
49
114
|
|
|
50
115
|
For skills, rules, AGENTS.md overlays, or instruction files, answer:
|
package/src/utils/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.3.
|
|
1
|
+
export const VERSION = '0.3.41'
|