pluribus-context 0.3.34 → 0.3.35
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 +15 -0
- package/README.md +2 -1
- package/docs/ai-pr-review-receipts.md +153 -0
- package/docs/canonical-output-receipts.md +107 -0
- package/docs/dynamic-workflow-run-receipts.md +158 -0
- package/docs/install-plan-receipts.md +77 -0
- package/docs/mcp-tool-visibility-receipts.md +67 -0
- package/docs/review-primitive-gate.md +107 -0
- package/docs/skill-policy-receipts.md +87 -0
- package/docs/subagent-role-receipts.md +95 -0
- package/docs/temporal-context-receipts.md +123 -0
- package/examples/agent-skills/skill-policy-receipts/README.md +22 -0
- package/examples/agent-skills/skill-policy-receipts/SKILL.md +77 -0
- package/examples/ai-pr-review-receipts/.github/pull_request_template.md +31 -0
- package/examples/ai-pr-review-receipts/README.md +5 -0
- package/examples/canonical-output-receipts/canonical-output-receipt.json +55 -0
- package/examples/claude-code-review-hook/README.md +74 -0
- package/examples/claude-code-review-hook/check-review-receipt-hook.mjs +80 -0
- package/examples/claude-code-review-hook/sample-task-completed-event.json +6 -0
- package/examples/dynamic-workflow-run-receipts/README.md +18 -0
- package/examples/dynamic-workflow-run-receipts/workflow-run-receipt.json +112 -0
- package/examples/install-plan-receipts/README.md +34 -0
- package/examples/install-plan-receipts/agent-install-plan-receipt.json +56 -0
- package/examples/review-primitive-gate/README.md +19 -0
- package/examples/review-primitive-gate/check-review-receipt.mjs +100 -0
- package/examples/review-primitive-gate/fail-review-receipt.json +42 -0
- package/examples/review-primitive-gate/pass-review-receipt.json +54 -0
- package/examples/subagent-role-receipts/README.md +15 -0
- package/examples/subagent-role-receipts/agents.toml +36 -0
- package/examples/temporal-context-receipts/CURRENT_STATE.md +13 -0
- package/examples/temporal-context-receipts/specs/2025-checkout-rewrite.md +10 -0
- package/examples/temporal-context-receipts/specs/2026-checkout-risk-notes.md +10 -0
- package/examples/temporal-context-receipts/temporal-authority-receipt.json +27 -0
- package/package.json +1 -1
- package/src/utils/version.js +1 -1
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from 'node:fs'
|
|
3
|
+
import { spawnSync } from 'node:child_process'
|
|
4
|
+
import { dirname, resolve } from 'node:path'
|
|
5
|
+
import { fileURLToPath } from 'node:url'
|
|
6
|
+
|
|
7
|
+
const [receiptPathArg] = process.argv.slice(2)
|
|
8
|
+
|
|
9
|
+
if (!receiptPathArg) {
|
|
10
|
+
console.error(JSON.stringify({ ok: false, errors: ['usage: node check-review-receipt-hook.mjs <receipt.json>'] }, null, 2))
|
|
11
|
+
process.exit(2)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const stdin = readFileSync(0, 'utf8').trim()
|
|
15
|
+
let hookInput = {}
|
|
16
|
+
if (stdin) {
|
|
17
|
+
try {
|
|
18
|
+
hookInput = JSON.parse(stdin)
|
|
19
|
+
} catch (error) {
|
|
20
|
+
console.error(JSON.stringify({ ok: false, errors: [`invalid hook JSON on stdin: ${error.message}`] }, null, 2))
|
|
21
|
+
process.exit(2)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const here = dirname(fileURLToPath(import.meta.url))
|
|
26
|
+
const localGate = resolve(here, '../review-primitive-gate/check-review-receipt.mjs')
|
|
27
|
+
const copiedGate = resolve(here, 'check-review-receipt.mjs')
|
|
28
|
+
const gatePath = process.env.PLURIBUS_REVIEW_GATE || (exists(copiedGate) ? copiedGate : localGate)
|
|
29
|
+
const receiptPath = resolve(process.cwd(), receiptPathArg)
|
|
30
|
+
|
|
31
|
+
const result = spawnSync(process.execPath, [gatePath, receiptPath], {
|
|
32
|
+
encoding: 'utf8',
|
|
33
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
let gateResult = null
|
|
37
|
+
try {
|
|
38
|
+
gateResult = JSON.parse(result.stdout || '{}')
|
|
39
|
+
} catch {
|
|
40
|
+
gateResult = { ok: false, errors: ['review gate did not return JSON'], raw_stdout: result.stdout.trim() }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const hookEventName = hookInput.hook_event_name || hookInput.hookEventName || hookInput.event || 'unknown'
|
|
44
|
+
const output = {
|
|
45
|
+
ok: result.status === 0 && gateResult.ok === true,
|
|
46
|
+
hook_event_name: hookEventName,
|
|
47
|
+
receipt_path: receiptPathArg,
|
|
48
|
+
resume_state: gateResult.resume_state,
|
|
49
|
+
assignment_id: gateResult.assignment_id,
|
|
50
|
+
run_id: gateResult.run_id,
|
|
51
|
+
next_safe_action: readNextSafeAction(receiptPath),
|
|
52
|
+
errors: gateResult.errors || [],
|
|
53
|
+
warnings: gateResult.warnings || []
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (output.ok) {
|
|
57
|
+
console.log(JSON.stringify(output, null, 2))
|
|
58
|
+
process.exit(0)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
console.error(JSON.stringify(output, null, 2))
|
|
62
|
+
process.exit(result.status || 1)
|
|
63
|
+
|
|
64
|
+
function exists(path) {
|
|
65
|
+
try {
|
|
66
|
+
readFileSync(path)
|
|
67
|
+
return true
|
|
68
|
+
} catch {
|
|
69
|
+
return false
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function readNextSafeAction(path) {
|
|
74
|
+
try {
|
|
75
|
+
const receipt = JSON.parse(readFileSync(path, 'utf8'))
|
|
76
|
+
return receipt?.handoff?.next_safe_action || null
|
|
77
|
+
} catch {
|
|
78
|
+
return null
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Dynamic workflow run receipt example
|
|
2
|
+
|
|
3
|
+
This example is a copyable privacy-safe receipt for Claude Code-style dynamic workflows, ultracode runs, local LLM gateway orchestration, or any script that spawns several subagents to audit, migrate, research, or verify a codebase.
|
|
4
|
+
|
|
5
|
+
Use it when the parent session only sees the final report, but reviewers still need to understand:
|
|
6
|
+
|
|
7
|
+
- which phases ran;
|
|
8
|
+
- how many agents were spawned;
|
|
9
|
+
- which role/model/provider each agent actually used;
|
|
10
|
+
- which context was loaded, skipped, or suppressed;
|
|
11
|
+
- which tools/capabilities were granted and used;
|
|
12
|
+
- how token spend was bucketed;
|
|
13
|
+
- where each agent stopped;
|
|
14
|
+
- which gaps remain before mutation or merge.
|
|
15
|
+
|
|
16
|
+
The example intentionally uses coarse labels, buckets, and hashes instead of raw prompts, source code, exact paths, transcripts, tool output, secrets, or customer data.
|
|
17
|
+
|
|
18
|
+
See [`docs/dynamic-workflow-run-receipts.md`](../../docs/dynamic-workflow-run-receipts.md) for the checklist and field rationale.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "dynamic.workflow.run_receipt.v1",
|
|
3
|
+
"workflow": {
|
|
4
|
+
"workflow_id": "wf_checkout_auth_audit_2026_05_30",
|
|
5
|
+
"runner": "claude-code-dynamic-workflow",
|
|
6
|
+
"script_source": "generated-then-reviewed-command",
|
|
7
|
+
"script_hash": "sha256:example-only",
|
|
8
|
+
"task_kind": "codebase_auth_audit",
|
|
9
|
+
"plan_approved_before_run": true,
|
|
10
|
+
"resumable": true,
|
|
11
|
+
"max_wall_clock_bucket": "under_15m",
|
|
12
|
+
"kill_switch_available": true,
|
|
13
|
+
"started_at": "2026-05-30T15:20:00Z",
|
|
14
|
+
"completed_at": "2026-05-30T15:31:42Z"
|
|
15
|
+
},
|
|
16
|
+
"permissions": {
|
|
17
|
+
"tool_allowlist_inherited": true,
|
|
18
|
+
"writes_allowed": false,
|
|
19
|
+
"network_allowed": false,
|
|
20
|
+
"external_commands_allowed": ["grep", "test --dry-run"],
|
|
21
|
+
"permission_profile": "review-only"
|
|
22
|
+
},
|
|
23
|
+
"phases": [
|
|
24
|
+
{
|
|
25
|
+
"phase_id": "route-inventory",
|
|
26
|
+
"purpose": "find candidate auth-sensitive routes",
|
|
27
|
+
"agent_count": 3,
|
|
28
|
+
"token_spend_bucket": "under_50k",
|
|
29
|
+
"elapsed_ms_bucket": "under_2m",
|
|
30
|
+
"result": "completed"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"phase_id": "adversarial-review",
|
|
34
|
+
"purpose": "cross-check candidate misses",
|
|
35
|
+
"agent_count": 2,
|
|
36
|
+
"token_spend_bucket": "under_25k",
|
|
37
|
+
"elapsed_ms_bucket": "under_2m",
|
|
38
|
+
"result": "completed_with_gaps"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"agents": [
|
|
42
|
+
{
|
|
43
|
+
"agent_id": "agent-route-auditor-1",
|
|
44
|
+
"phase_id": "route-inventory",
|
|
45
|
+
"role": "route-auth-auditor",
|
|
46
|
+
"model": "claude-sonnet",
|
|
47
|
+
"provider": "anthropic",
|
|
48
|
+
"context_loaded": ["repo-policy", "auth-boundary-rules", "route-index-summary"],
|
|
49
|
+
"context_skipped_or_suppressed": [
|
|
50
|
+
{
|
|
51
|
+
"source": "customer-fixture-dump",
|
|
52
|
+
"reason": "contains raw customer data; summary hash only"
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
"tools_granted": ["read", "grep"],
|
|
56
|
+
"tools_used": ["grep"],
|
|
57
|
+
"feature_areas_checked": ["checkout routes", "admin routes"],
|
|
58
|
+
"token_budget_bucket": "under_25k",
|
|
59
|
+
"token_spend_bucket": "under_10k",
|
|
60
|
+
"max_iterations": 8,
|
|
61
|
+
"iterations_used": 3,
|
|
62
|
+
"heartbeat_seen_at": "2026-05-30T15:25:00Z",
|
|
63
|
+
"partial_progress_reported": true,
|
|
64
|
+
"fuse_triggered": false,
|
|
65
|
+
"stop_reason": "completed_assigned_partition",
|
|
66
|
+
"confidence": "medium",
|
|
67
|
+
"known_gaps": ["did not execute integration tests"],
|
|
68
|
+
"raw_prompt_logged": false,
|
|
69
|
+
"raw_tool_output_logged": false,
|
|
70
|
+
"raw_paths_logged": false
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"agent_id": "agent-reviewer-1",
|
|
74
|
+
"phase_id": "adversarial-review",
|
|
75
|
+
"role": "adversarial-auth-reviewer",
|
|
76
|
+
"model": "local-codex-compatible",
|
|
77
|
+
"provider": "local-llm-gateway",
|
|
78
|
+
"context_loaded": ["candidate-findings-summary", "public-api-contract-summary"],
|
|
79
|
+
"context_skipped_or_suppressed": [],
|
|
80
|
+
"tools_granted": ["read"],
|
|
81
|
+
"tools_used": ["read"],
|
|
82
|
+
"feature_areas_checked": ["route findings cross-check"],
|
|
83
|
+
"token_budget_bucket": "under_10k",
|
|
84
|
+
"token_spend_bucket": "under_10k",
|
|
85
|
+
"max_iterations": 5,
|
|
86
|
+
"iterations_used": 5,
|
|
87
|
+
"heartbeat_seen_at": "2026-05-30T15:30:00Z",
|
|
88
|
+
"partial_progress_reported": true,
|
|
89
|
+
"fuse_triggered": true,
|
|
90
|
+
"stop_reason": "iteration_budget_reached_before_claim_verified",
|
|
91
|
+
"confidence": "low",
|
|
92
|
+
"known_gaps": ["one route requires owner confirmation before merge"],
|
|
93
|
+
"raw_prompt_logged": false,
|
|
94
|
+
"raw_tool_output_logged": false,
|
|
95
|
+
"raw_paths_logged": false
|
|
96
|
+
}
|
|
97
|
+
],
|
|
98
|
+
"handoff": {
|
|
99
|
+
"final_result_kind": "workflow_review_receipt",
|
|
100
|
+
"claims_rejected_or_deferred": 1,
|
|
101
|
+
"next_safe_action": "ask route owner to confirm checkout callback auth before writing fix",
|
|
102
|
+
"where_it_stopped": "ambiguous auth boundary before mutation"
|
|
103
|
+
},
|
|
104
|
+
"privacy": {
|
|
105
|
+
"raw_prompts_logged": false,
|
|
106
|
+
"raw_source_logged": false,
|
|
107
|
+
"raw_tool_output_logged": false,
|
|
108
|
+
"transcripts_logged": false,
|
|
109
|
+
"secrets_logged": false,
|
|
110
|
+
"customer_data_logged": false
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Install-plan receipt example
|
|
2
|
+
|
|
3
|
+
This example is for one-command agent setup tools that configure MCP, Skills, instruction files, hooks, or plugins across multiple AI coding tools.
|
|
4
|
+
|
|
5
|
+
Use it when you want a setup script to prove what it will write before it writes anything.
|
|
6
|
+
|
|
7
|
+
## Copyable preflight checklist
|
|
8
|
+
|
|
9
|
+
Before applying installer changes, ask the agent or setup script to emit an `agent.install.plan.v1` receipt with:
|
|
10
|
+
|
|
11
|
+
- `agents_detected`
|
|
12
|
+
- `agents_selected`
|
|
13
|
+
- `planned_writes[]` with `kind`, `target`, `operation`, and `backup_planned`
|
|
14
|
+
- `external_commands_planned[]`
|
|
15
|
+
- `network_after_install`
|
|
16
|
+
- `writes_started=false`
|
|
17
|
+
- `next_safe_command`
|
|
18
|
+
|
|
19
|
+
Review the receipt, then run the apply command only if the planned writes match your intent.
|
|
20
|
+
|
|
21
|
+
## Smoke test
|
|
22
|
+
|
|
23
|
+
The sample receipt is intentionally static JSON so it can be inspected without running an installer:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
cat examples/install-plan-receipts/agent-install-plan-receipt.json
|
|
27
|
+
node -e "const r=require('./examples/install-plan-receipts/agent-install-plan-receipt.json'); if (r.writes_started !== false) process.exit(1); console.log(r.receipt_type, r.planned_writes.length)"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Expected output:
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
agent.install.plan.v1 3
|
|
34
|
+
```
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"receipt_type": "agent.install.plan.v1",
|
|
3
|
+
"run_id": "demo-install-2026-05-29T16:00Z",
|
|
4
|
+
"installer": "example-agent-setup",
|
|
5
|
+
"mode_requested": "plan",
|
|
6
|
+
"mode_effective": "plan",
|
|
7
|
+
"agents_detected": [
|
|
8
|
+
"claude-code",
|
|
9
|
+
"cursor",
|
|
10
|
+
"codex",
|
|
11
|
+
"openclaw"
|
|
12
|
+
],
|
|
13
|
+
"agents_selected": [
|
|
14
|
+
"claude-code",
|
|
15
|
+
"openclaw"
|
|
16
|
+
],
|
|
17
|
+
"planned_writes": [
|
|
18
|
+
{
|
|
19
|
+
"kind": "mcp_config",
|
|
20
|
+
"target": "claude-code project config",
|
|
21
|
+
"operation": "add_local_mcp_server",
|
|
22
|
+
"backup_planned": true
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"kind": "instruction_file",
|
|
26
|
+
"target": "AGENTS.md",
|
|
27
|
+
"operation": "append_usage_notes",
|
|
28
|
+
"backup_planned": true
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"kind": "hook",
|
|
32
|
+
"target": "pre-tool hook config",
|
|
33
|
+
"operation": "register_receipt_guard",
|
|
34
|
+
"backup_planned": true
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"external_commands_planned": [
|
|
38
|
+
{
|
|
39
|
+
"phase": "apply",
|
|
40
|
+
"command_class": "package_manager_install"
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
"network_after_install": "local_mcp_server_only",
|
|
44
|
+
"writes_started": false,
|
|
45
|
+
"next_safe_command": "example-agent-setup apply --from-plan install-plan.json",
|
|
46
|
+
"privacy_exclusions": [
|
|
47
|
+
"raw_source",
|
|
48
|
+
"secrets",
|
|
49
|
+
"env_dump",
|
|
50
|
+
"raw_prompt",
|
|
51
|
+
"transcript",
|
|
52
|
+
"raw_tool_output",
|
|
53
|
+
"customer_data",
|
|
54
|
+
"private_absolute_path"
|
|
55
|
+
]
|
|
56
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Review primitive gate example
|
|
2
|
+
|
|
3
|
+
This example validates a privacy-safe agent handoff receipt as a reviewer/CI primitive.
|
|
4
|
+
|
|
5
|
+
Run the passing fixture:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
node examples/review-primitive-gate/check-review-receipt.mjs \
|
|
9
|
+
examples/review-primitive-gate/pass-review-receipt.json
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Run the failing fixture:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
node examples/review-primitive-gate/check-review-receipt.mjs \
|
|
16
|
+
examples/review-primitive-gate/fail-review-receipt.json
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The script exits non-zero if the run is partial/unsafe, if a required check failed or was skipped, or if the agent changed scope/access without approval.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from 'node:fs'
|
|
3
|
+
|
|
4
|
+
const [file] = process.argv.slice(2)
|
|
5
|
+
|
|
6
|
+
if (!file) {
|
|
7
|
+
console.error('Usage: node check-review-receipt.mjs <receipt.json>')
|
|
8
|
+
process.exit(2)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let receipt
|
|
12
|
+
try {
|
|
13
|
+
receipt = JSON.parse(readFileSync(file, 'utf8'))
|
|
14
|
+
} catch (error) {
|
|
15
|
+
console.error(JSON.stringify({ ok: false, file, errors: [`invalid JSON: ${error.message}`] }, null, 2))
|
|
16
|
+
process.exit(2)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const errors = []
|
|
20
|
+
const warnings = []
|
|
21
|
+
|
|
22
|
+
if (receipt.type !== 'agent.review_primitive_receipt.v1') {
|
|
23
|
+
errors.push('type must be agent.review_primitive_receipt.v1')
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
for (const key of ['assignment_id', 'run_id']) {
|
|
27
|
+
if (!receipt[key] || typeof receipt[key] !== 'string') {
|
|
28
|
+
errors.push(`${key} is required`)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const boundaries = receipt.approved_boundaries || {}
|
|
33
|
+
if (!Array.isArray(boundaries.read) || boundaries.read.length === 0) {
|
|
34
|
+
errors.push('approved_boundaries.read must name at least one coarse read boundary')
|
|
35
|
+
}
|
|
36
|
+
if (!Array.isArray(boundaries.write)) {
|
|
37
|
+
errors.push('approved_boundaries.write must be an array, even for read-only runs')
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const scopeChanges = receipt.scope_access_changes || []
|
|
41
|
+
if (!Array.isArray(scopeChanges)) {
|
|
42
|
+
errors.push('scope_access_changes must be an array')
|
|
43
|
+
} else {
|
|
44
|
+
for (const [index, change] of scopeChanges.entries()) {
|
|
45
|
+
if (change?.approved !== true) {
|
|
46
|
+
errors.push(`scope_access_changes[${index}] is not explicitly approved`)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const checks = receipt.commands_and_checks || []
|
|
52
|
+
if (!Array.isArray(checks) || checks.length === 0) {
|
|
53
|
+
errors.push('commands_and_checks must include at least one required check/test')
|
|
54
|
+
} else {
|
|
55
|
+
for (const [index, check] of checks.entries()) {
|
|
56
|
+
if (!String(check?.kind || '').startsWith('required_')) continue
|
|
57
|
+
if (check.status !== 'passed') {
|
|
58
|
+
errors.push(`commands_and_checks[${index}] required check did not pass: ${check.status || 'missing status'}`)
|
|
59
|
+
}
|
|
60
|
+
if (!check.evidence || check.evidence === 'not-run') {
|
|
61
|
+
errors.push(`commands_and_checks[${index}] required check is missing evidence`)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const allowedResumeStates = new Set(['complete', 'partial', 'unsafe-to-resume'])
|
|
67
|
+
if (!allowedResumeStates.has(receipt.resume_state)) {
|
|
68
|
+
errors.push('resume_state must be complete, partial, or unsafe-to-resume')
|
|
69
|
+
}
|
|
70
|
+
if (receipt.resume_state !== 'complete') {
|
|
71
|
+
errors.push(`resume_state is ${receipt.resume_state}; reviewer must inspect before merge/continuation`)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const handoff = receipt.handoff || {}
|
|
75
|
+
if (!handoff.next_safe_action || typeof handoff.next_safe_action !== 'string') {
|
|
76
|
+
errors.push('handoff.next_safe_action is required')
|
|
77
|
+
}
|
|
78
|
+
if (!handoff.evidence_path || typeof handoff.evidence_path !== 'string') {
|
|
79
|
+
warnings.push('handoff.evidence_path is recommended for review traceability')
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const privacy = receipt.privacy || {}
|
|
83
|
+
for (const key of ['raw_prompts_logged', 'raw_tool_output_logged', 'source_code_logged', 'secrets_logged']) {
|
|
84
|
+
if (privacy[key] !== false) {
|
|
85
|
+
errors.push(`privacy.${key} must be false for this gate`)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const result = {
|
|
90
|
+
ok: errors.length === 0,
|
|
91
|
+
file,
|
|
92
|
+
assignment_id: receipt.assignment_id,
|
|
93
|
+
run_id: receipt.run_id,
|
|
94
|
+
resume_state: receipt.resume_state,
|
|
95
|
+
errors,
|
|
96
|
+
warnings
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
console.log(JSON.stringify(result, null, 2))
|
|
100
|
+
process.exit(result.ok ? 0 : 1)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "agent.review_primitive_receipt.v1",
|
|
3
|
+
"assignment_id": "agent-auth-audit-43",
|
|
4
|
+
"run_id": "run-2026-05-31T17-05Z",
|
|
5
|
+
"agent": {
|
|
6
|
+
"tool": "claude-code",
|
|
7
|
+
"role": "auth-reviewer"
|
|
8
|
+
},
|
|
9
|
+
"approved_boundaries": {
|
|
10
|
+
"read": ["src/auth/**", "tests/auth/**"],
|
|
11
|
+
"write": ["tests/auth/**"],
|
|
12
|
+
"network": false
|
|
13
|
+
},
|
|
14
|
+
"scope_access_changes": [
|
|
15
|
+
{
|
|
16
|
+
"change": "write src/auth/session.ts",
|
|
17
|
+
"reason": "agent decided implementation change was easier than fixture-only test",
|
|
18
|
+
"approved": false
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"commands_and_checks": [
|
|
22
|
+
{
|
|
23
|
+
"name": "npm test -- tests/auth",
|
|
24
|
+
"kind": "required_test",
|
|
25
|
+
"status": "skipped",
|
|
26
|
+
"evidence": "not-run"
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
"refused_operations": [],
|
|
30
|
+
"handoff": {
|
|
31
|
+
"changed_files_bucket": "under_5",
|
|
32
|
+
"evidence_path": "artifacts/agent-auth-audit-43.json",
|
|
33
|
+
"next_safe_action": "human must review scope change before any continuation"
|
|
34
|
+
},
|
|
35
|
+
"resume_state": "unsafe-to-resume",
|
|
36
|
+
"privacy": {
|
|
37
|
+
"raw_prompts_logged": false,
|
|
38
|
+
"raw_tool_output_logged": false,
|
|
39
|
+
"source_code_logged": false,
|
|
40
|
+
"secrets_logged": false
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "agent.review_primitive_receipt.v1",
|
|
3
|
+
"assignment_id": "agent-auth-audit-42",
|
|
4
|
+
"run_id": "run-2026-05-31T17-00Z",
|
|
5
|
+
"agent": {
|
|
6
|
+
"tool": "claude-code",
|
|
7
|
+
"role": "auth-reviewer"
|
|
8
|
+
},
|
|
9
|
+
"approved_boundaries": {
|
|
10
|
+
"read": ["src/auth/**", "tests/auth/**"],
|
|
11
|
+
"write": ["tests/auth/**"],
|
|
12
|
+
"network": false
|
|
13
|
+
},
|
|
14
|
+
"scope_access_changes": [
|
|
15
|
+
{
|
|
16
|
+
"change": "read docs/security/**",
|
|
17
|
+
"reason": "needed policy wording for test fixture",
|
|
18
|
+
"approved": true,
|
|
19
|
+
"approved_by": "human-reviewer"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"commands_and_checks": [
|
|
23
|
+
{
|
|
24
|
+
"name": "npm test -- tests/auth",
|
|
25
|
+
"kind": "required_test",
|
|
26
|
+
"status": "passed",
|
|
27
|
+
"evidence": "ci://job/123#auth-tests"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "npm run lint",
|
|
31
|
+
"kind": "required_check",
|
|
32
|
+
"status": "passed",
|
|
33
|
+
"evidence": "ci://job/123#lint"
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"refused_operations": [
|
|
37
|
+
{
|
|
38
|
+
"operation": "write src/auth/session.ts",
|
|
39
|
+
"reason": "outside approved write boundary"
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"handoff": {
|
|
43
|
+
"changed_files_bucket": "under_5",
|
|
44
|
+
"evidence_path": "artifacts/agent-auth-audit-42.json",
|
|
45
|
+
"next_safe_action": "review tests/auth/session.test.ts before merge"
|
|
46
|
+
},
|
|
47
|
+
"resume_state": "complete",
|
|
48
|
+
"privacy": {
|
|
49
|
+
"raw_prompts_logged": false,
|
|
50
|
+
"raw_tool_output_logged": false,
|
|
51
|
+
"source_code_logged": false,
|
|
52
|
+
"secrets_logged": false
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Subagent role receipts example
|
|
2
|
+
|
|
3
|
+
This directory contains a small `agents.toml` example for teams experimenting with project-local subagent roles.
|
|
4
|
+
|
|
5
|
+
The important artifact is not the exact TOML dialect. The important artifact is the receipt that proves the role boundary:
|
|
6
|
+
|
|
7
|
+
- requested role vs effective role;
|
|
8
|
+
- role source and coarse hash/version;
|
|
9
|
+
- whether role instructions loaded;
|
|
10
|
+
- allowed/refused write and tool capabilities;
|
|
11
|
+
- boundary decisions made by the role;
|
|
12
|
+
- where the role stopped and the next safe action;
|
|
13
|
+
- privacy flags excluding raw prompts, code, transcripts, secrets, customer data, and raw tool output.
|
|
14
|
+
|
|
15
|
+
See [`../../docs/subagent-role-receipts.md`](../../docs/subagent-role-receipts.md) for the full recipe.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Example only: adapt field names and location to the subagent runner you use.
|
|
2
|
+
# The stable idea is the receipt, not this exact TOML dialect.
|
|
3
|
+
|
|
4
|
+
[[agents]]
|
|
5
|
+
name = "blast-radius-reviewer"
|
|
6
|
+
description = "Reviews AI-generated PRs by operational blast radius before merge."
|
|
7
|
+
model = "default"
|
|
8
|
+
tools = ["read", "grep", "test-summary"]
|
|
9
|
+
writes_allowed = false
|
|
10
|
+
instructions = """
|
|
11
|
+
Review by blast radius, not diff size.
|
|
12
|
+
|
|
13
|
+
Require explicit evidence for:
|
|
14
|
+
- schema or persisted data contracts;
|
|
15
|
+
- live reader/writer compatibility;
|
|
16
|
+
- async jobs, queues, cron, webhooks, and retries;
|
|
17
|
+
- rollout gates, feature flags, or kill switches;
|
|
18
|
+
- external side effects such as email, payments, auth, billing, analytics, or third-party APIs;
|
|
19
|
+
- generated files, public APIs, plugin manifests, MCP/Skill/hook configuration.
|
|
20
|
+
|
|
21
|
+
Do not approve merge when any high-risk boundary is ambiguous. Emit a privacy-safe review.blast_radius.v1 or subagent.role_boundary.v1 receipt instead of logging raw source, prompts, transcripts, or tool output.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
[[agents]]
|
|
25
|
+
name = "temporal-authority-checker"
|
|
26
|
+
description = "Checks whether matched docs/specs are current authority or historical citations before edits."
|
|
27
|
+
model = "default"
|
|
28
|
+
tools = ["read", "grep"]
|
|
29
|
+
writes_allowed = false
|
|
30
|
+
instructions = """
|
|
31
|
+
Before code changes, identify the current authority source and any historical/superseded specs.
|
|
32
|
+
|
|
33
|
+
Refuse writes when two sources conflict and neither one declares status, date, scope, or superseded_by metadata. Emit a privacy-safe context.temporal_authority.v1 or subagent.role_boundary.v1 receipt with coarse document names, status, decision, stopped_at, and next_safe_action.
|
|
34
|
+
|
|
35
|
+
Do not log raw prompts, source code, private paths, transcripts, secrets, or customer data.
|
|
36
|
+
"""
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Current state
|
|
2
|
+
|
|
3
|
+
## checkout-flow
|
|
4
|
+
|
|
5
|
+
- status: current
|
|
6
|
+
- as_of: 2026-05-28
|
|
7
|
+
- current authority: this section
|
|
8
|
+
- scope: checkout-flow
|
|
9
|
+
- related historical specs:
|
|
10
|
+
- `specs/2025-checkout-rewrite.md` — superseded; rationale only
|
|
11
|
+
- `specs/2026-checkout-risk-notes.md` — current supporting context
|
|
12
|
+
|
|
13
|
+
Agents may cite superseded specs for rationale, but must not implement from them unless this file explicitly reactivates that behavior.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"receipt_type": "context.temporal_authority.v1",
|
|
3
|
+
"request_id": "local-run-2026-05-28T16:00Z",
|
|
4
|
+
"current_authority": {
|
|
5
|
+
"file": "CURRENT_STATE.md",
|
|
6
|
+
"status": "current",
|
|
7
|
+
"as_of": "2026-05-28",
|
|
8
|
+
"scope": "checkout-flow"
|
|
9
|
+
},
|
|
10
|
+
"sources_considered": [
|
|
11
|
+
{
|
|
12
|
+
"file": "specs/2025-checkout-rewrite.md",
|
|
13
|
+
"status": "superseded",
|
|
14
|
+
"superseded_by": "CURRENT_STATE.md#checkout-flow",
|
|
15
|
+
"decision": "historical_citation_only"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"file": "specs/2026-checkout-risk-notes.md",
|
|
19
|
+
"status": "current",
|
|
20
|
+
"scope": "checkout-flow",
|
|
21
|
+
"decision": "allowed_as_supporting_context"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"ambiguous_sources": [],
|
|
25
|
+
"write_started": true,
|
|
26
|
+
"stopped_at": "temporal_authority_resolved"
|
|
27
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pluribus-context",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.35",
|
|
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.35'
|