strata-agent-memory 0.2.4__tar.gz → 0.2.6__tar.gz
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.
- {strata_agent_memory-0.2.4/strata_agent_memory.egg-info → strata_agent_memory-0.2.6}/PKG-INFO +8 -4
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/README.md +7 -3
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/__init__.py +1 -1
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/audit.py +87 -6
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/cli.py +385 -50
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/compact.py +2 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/compiler.py +6 -1
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/contracts.py +53 -15
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/evidence.py +951 -76
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/hooks.py +12 -9
- strata_agent_memory-0.2.6/agent_memory/lane.py +932 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/ledger.py +74 -7
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/mcp_server.py +50 -12
- strata_agent_memory-0.2.6/agent_memory/measure.py +692 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/pathmap.py +36 -5
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/recheck.py +54 -18
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/records.py +142 -2
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/relay/adapters.py +5 -3
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/relay/cli.py +31 -9
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/relay/client.py +329 -25
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/relay/core.py +115 -11
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/reliability.py +107 -21
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/remote.py +16 -4
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/serve.py +130 -7
- strata_agent_memory-0.2.6/agent_memory/supersession.py +143 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/trust.py +45 -14
- strata_agent_memory-0.2.6/agent_memory/wake.py +296 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/mac/README.md +16 -3
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/mac/agent-session.sh +9 -3
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/mac/relay-agent.sh +34 -12
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/plugins/README.md +39 -3
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/plugins/claude-code/.claude-plugin/plugin.json +2 -2
- strata_agent_memory-0.2.6/deploy/plugins/claude-code/bin/agent-memory-wake +36 -0
- strata_agent_memory-0.2.6/deploy/plugins/claude-code/monitors/monitors.json +7 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/plugins/claude-code/skills/approvals/SKILL.md +2 -2
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/plugins/claude-code/skills/approve/SKILL.md +2 -2
- strata_agent_memory-0.2.6/deploy/plugins/claude-code/skills/inbox/SKILL.md +27 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/plugins/claude-code/skills/reject/SKILL.md +2 -2
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/relay/install-relay-mac.sh +46 -15
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/relay/install-relay.sh +17 -10
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/relay/macos/com.strata.agent-memory.relay.plist.template +4 -3
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/pyproject.toml +2 -1
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6/strata_agent_memory.egg-info}/PKG-INFO +8 -4
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/strata_agent_memory.egg-info/SOURCES.txt +31 -1
- strata_agent_memory-0.2.6/tests/test_assessment_67b26eae.py +266 -0
- strata_agent_memory-0.2.6/tests/test_audit_lane_numbers_ea89ba26.py +289 -0
- strata_agent_memory-0.2.6/tests/test_audit_measurement_13190a20.py +441 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_backlog_check.py +3 -2
- strata_agent_memory-0.2.6/tests/test_changelog_guard_shallow_57a2f78e.py +168 -0
- strata_agent_memory-0.2.6/tests/test_ci_docs_only_353ce010.py +134 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_contracts.py +3 -1
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_deploy_mac.py +4 -2
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_deploy_relay.py +2 -2
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_evidence.py +4 -3
- strata_agent_memory-0.2.6/tests/test_find_root_b4b5019b.py +216 -0
- strata_agent_memory-0.2.6/tests/test_lane_63b7cf8b.py +762 -0
- strata_agent_memory-0.2.6/tests/test_lane_priority_779d51ba.py +328 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_ledger.py +6 -2
- strata_agent_memory-0.2.6/tests/test_live_wake_c217c336.py +921 -0
- strata_agent_memory-0.2.6/tests/test_local_lanes_sibling_1411a2b2.py +275 -0
- strata_agent_memory-0.2.6/tests/test_outcome_commit_binding_b1de564d.py +527 -0
- strata_agent_memory-0.2.6/tests/test_outcome_needs_evidence_b1de564d.py +130 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_plugins.py +4 -4
- strata_agent_memory-0.2.6/tests/test_receipt_reports_274e6199.py +432 -0
- strata_agent_memory-0.2.6/tests/test_recheck_remote_8185d2d3.py +317 -0
- strata_agent_memory-0.2.6/tests/test_recheck_sandbox_543e48a7.py +615 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_relay_client.py +7 -2
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_relay_core.py +3 -3
- strata_agent_memory-0.2.6/tests/test_relay_instance_2a2e3887.py +120 -0
- strata_agent_memory-0.2.6/tests/test_relay_release_526f5261.py +128 -0
- strata_agent_memory-0.2.6/tests/test_relay_release_gate_b3b3e487.py +383 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_remote.py +4 -2
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_serve.py +42 -5
- strata_agent_memory-0.2.6/tests/test_sit_fleet_1b24b0b1.py +86 -0
- strata_agent_memory-0.2.6/tests/test_sit_fleet_ci_0d9b76a2.py +30 -0
- strata_agent_memory-0.2.6/tests/test_sit_var_bindings_e802ca84.py +288 -0
- strata_agent_memory-0.2.6/tests/test_supersedes_61416280.py +433 -0
- strata_agent_memory-0.2.6/tests/test_uv_lock_env_274e6199.py +245 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/LICENSE +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/__main__.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/approvals.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/export.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/identity.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/instances.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/kit.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/memorizer.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/relay/__init__.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/render.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/roster.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/signing.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/agent_memory/stats.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/mac/agent-keys.sh +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/mac/backup-tokens.sh +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/mac/install-hooks-mac.sh +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/mac/install-relay-driver.sh +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/mac/install-replica-driver.sh +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/mac/install-runner-driver.sh +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/mac/instances.example.json +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/mac/onboard-agent.sh +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/mac/seed-board.sh +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/mac/seed-mail-context.sh +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/mac/seed-topics.sh +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/mac/upgrade-driver.sh +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/plugins/.claude-plugin/marketplace.json +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/plugins/claude-code/bin/agent-memory-approvals +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/plugins/claude-code/hooks/hooks.json +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/plugins/claude-code/rules/approvals.md +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/plugins/codex/skills/agent-memory-answer/SKILL.md +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/plugins/codex/skills/agent-memory-answer/agents/openai.yaml +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/plugins/codex/skills/agent-memory-approvals/SKILL.md +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/plugins/codex/skills/agent-memory-approvals/agents/openai.yaml +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/plugins/codex/skills/agent-memory-approvals/rules/approvals.md +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/plugins/codex/skills/agent-memory-approvals/scripts/agent-memory-approvals +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/relay/README.md +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/relay/agent-memory-relay@.service +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/deploy/relay/relay-launch.sh +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/setup.cfg +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/strata_agent_memory.egg-info/dependency_links.txt +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/strata_agent_memory.egg-info/entry_points.txt +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/strata_agent_memory.egg-info/requires.txt +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/strata_agent_memory.egg-info/top_level.txt +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_audit.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_changelog_fragments.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_cli.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_compact.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_compiler.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_compiler_render.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_config.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_deploy_replica.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_deploy_tokens.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_hooks.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_identity.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_issue_bridge.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_ledger_index.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_memorizer.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_packaging.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_pathmap.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_phase2.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_recheck.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_records.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_redaction.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_relay_adapters.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_relay_codex.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_reliability.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_remote_signing.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_review2_fixes.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_review3_fixes.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_review_fixes.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_scale.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_signing.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_stats.py +0 -0
- {strata_agent_memory-0.2.4 → strata_agent_memory-0.2.6}/tests/test_trust.py +0 -0
{strata_agent_memory-0.2.4/strata_agent_memory.egg-info → strata_agent_memory-0.2.6}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: strata-agent-memory
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.6
|
|
4
4
|
Summary: Portable, auditable, cross-vendor memory for LLM agents: evidence-bound claims, trust tiers, and compiled context views.
|
|
5
5
|
Author: Strata Intelligence
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -75,7 +75,7 @@ pip install strata-agent-memory # the CLI is `agent-memory`; or, from a chec
|
|
|
75
75
|
cd your-project && agent-memory init
|
|
76
76
|
|
|
77
77
|
agent-memory run -- pytest -q # -> {"id": "ev_…", "kind": "test", "passed": 42, ...}
|
|
78
|
-
agent-memory claim outcome "auth tests pass" -e ev_…
|
|
78
|
+
agent-memory claim outcome "auth tests pass" -e ev_… # inside a git checkout it binds HEAD too
|
|
79
79
|
agent-memory claim outcome "deployed" # -> rejected: outcome claims require at least one receipt
|
|
80
80
|
|
|
81
81
|
agent-memory claim fact "sessions renew via renewSession()" --source src/auth.py
|
|
@@ -91,6 +91,7 @@ agent-memory claim fact "w3lib.get_meta_refresh takes baseurl" --source w3lib/ht
|
|
|
91
91
|
agent-memory compile --role worker --task "extend auth" # a fork-mode brief; reports what memory holds nothing on
|
|
92
92
|
agent-memory compile --role verifier --contract ctr_… --round 2 --lens security # isolated review brief with a lens
|
|
93
93
|
agent-memory audit # tiers, static-only outcomes, taint chains, verifier lineage matrix
|
|
94
|
+
agent-memory audit --since 2026-09-21 --until 2026-09-28 # and the measurement section for that week (default: the last seven days)
|
|
94
95
|
agent-memory reliability # how often claims like these were refuted, with n and an interval; fitted staleness
|
|
95
96
|
AGENT_MEMORY_HARNESS=ollama agent-memory recheck --map /Users/craig/src=/home/chris/src # the nightly lane, from another machine
|
|
96
97
|
agent-memory serve # HTTP API, SSE and remote MCP on loopback; add --tokens FILE
|
|
@@ -150,8 +151,11 @@ disposable replica: a SQLite index rebuilt from the shards, bearer-token
|
|
|
150
151
|
identity, an HTTP API, server-sent events, a remote MCP endpoint
|
|
151
152
|
(Streamable HTTP, revisions 2025-03-26, 2025-06-18 and the stateless
|
|
152
153
|
2026-07-28, chosen per request) so cloud agents
|
|
153
|
-
reach the ledger without a clone (Claude Code on the web
|
|
154
|
-
organization-managed
|
|
154
|
+
reach the ledger without a clone (Claude Code on the web through the repo's
|
|
155
|
+
`.mcp.json` in single-repo sessions, organization-managed connectors, beta
|
|
156
|
+
static-header connectors or self-hosted environments
|
|
157
|
+
( https://code.claude.com/docs/en/claude-code-on-the-web ); Codex cloud
|
|
158
|
+
unverified), and scheduled
|
|
155
159
|
recheck and git-sync lanes. Losing the service never loses state
|
|
156
160
|
(docs/BETA-SPEC.md section 4, `examples/remote/`).
|
|
157
161
|
|
|
@@ -51,7 +51,7 @@ pip install strata-agent-memory # the CLI is `agent-memory`; or, from a chec
|
|
|
51
51
|
cd your-project && agent-memory init
|
|
52
52
|
|
|
53
53
|
agent-memory run -- pytest -q # -> {"id": "ev_…", "kind": "test", "passed": 42, ...}
|
|
54
|
-
agent-memory claim outcome "auth tests pass" -e ev_…
|
|
54
|
+
agent-memory claim outcome "auth tests pass" -e ev_… # inside a git checkout it binds HEAD too
|
|
55
55
|
agent-memory claim outcome "deployed" # -> rejected: outcome claims require at least one receipt
|
|
56
56
|
|
|
57
57
|
agent-memory claim fact "sessions renew via renewSession()" --source src/auth.py
|
|
@@ -67,6 +67,7 @@ agent-memory claim fact "w3lib.get_meta_refresh takes baseurl" --source w3lib/ht
|
|
|
67
67
|
agent-memory compile --role worker --task "extend auth" # a fork-mode brief; reports what memory holds nothing on
|
|
68
68
|
agent-memory compile --role verifier --contract ctr_… --round 2 --lens security # isolated review brief with a lens
|
|
69
69
|
agent-memory audit # tiers, static-only outcomes, taint chains, verifier lineage matrix
|
|
70
|
+
agent-memory audit --since 2026-09-21 --until 2026-09-28 # and the measurement section for that week (default: the last seven days)
|
|
70
71
|
agent-memory reliability # how often claims like these were refuted, with n and an interval; fitted staleness
|
|
71
72
|
AGENT_MEMORY_HARNESS=ollama agent-memory recheck --map /Users/craig/src=/home/chris/src # the nightly lane, from another machine
|
|
72
73
|
agent-memory serve # HTTP API, SSE and remote MCP on loopback; add --tokens FILE
|
|
@@ -126,8 +127,11 @@ disposable replica: a SQLite index rebuilt from the shards, bearer-token
|
|
|
126
127
|
identity, an HTTP API, server-sent events, a remote MCP endpoint
|
|
127
128
|
(Streamable HTTP, revisions 2025-03-26, 2025-06-18 and the stateless
|
|
128
129
|
2026-07-28, chosen per request) so cloud agents
|
|
129
|
-
reach the ledger without a clone (Claude Code on the web
|
|
130
|
-
organization-managed
|
|
130
|
+
reach the ledger without a clone (Claude Code on the web through the repo's
|
|
131
|
+
`.mcp.json` in single-repo sessions, organization-managed connectors, beta
|
|
132
|
+
static-header connectors or self-hosted environments
|
|
133
|
+
( https://code.claude.com/docs/en/claude-code-on-the-web ); Codex cloud
|
|
134
|
+
unverified), and scheduled
|
|
131
135
|
recheck and git-sync lanes. Losing the service never loses state
|
|
132
136
|
(docs/BETA-SPEC.md section 4, `examples/remote/`).
|
|
133
137
|
|
|
@@ -27,12 +27,14 @@ from collections import Counter, defaultdict
|
|
|
27
27
|
from typing import Dict, List, Optional
|
|
28
28
|
|
|
29
29
|
from . import evidence as ev
|
|
30
|
+
from . import measure as measure_mod
|
|
30
31
|
from . import reliability as rel
|
|
32
|
+
from . import supersession as supersession_mod
|
|
31
33
|
from . import roster as roster_mod
|
|
32
34
|
from . import signing
|
|
33
35
|
from .contracts import status_of
|
|
34
36
|
from .ledger import UNTRUSTED_POLICY
|
|
35
|
-
from .records import is_redacted, receipt_visible_to
|
|
37
|
+
from .records import is_assessment, is_redacted, receipt_visible_to
|
|
36
38
|
from .trust import TIERS, assess, lineage_differs, summarize
|
|
37
39
|
|
|
38
40
|
# Anything a compiled view would have to render on its own line. The renderer collapses
|
|
@@ -189,12 +191,15 @@ def _roster_sections(ledger, rep: Dict, by_id: Dict[str, dict], reader_user: Opt
|
|
|
189
191
|
|
|
190
192
|
|
|
191
193
|
def report(ledger, recheck: bool = False, cwd: Optional[str] = None, timeout: Optional[float] = 300,
|
|
192
|
-
path_map=None, reader_user: Optional[str] = None
|
|
194
|
+
path_map=None, reader_user: Optional[str] = None, since: Optional[str] = None,
|
|
195
|
+
until: Optional[str] = None) -> dict:
|
|
193
196
|
"""The audit, for one reader. ``reader_user`` is who is asking: a user-scoped claim is
|
|
194
197
|
one person's private memory and is listed for its owner and for nobody else, the same
|
|
195
198
|
rule ``receipt_visible_to`` applies everywhere a record is shown (verification review
|
|
196
199
|
F1: the audit listed every user's private statements to any token). A local audit
|
|
197
|
-
with no reader named sees everything, as the local ledger's owner does.
|
|
200
|
+
with no reader named sees everything, as the local ledger's owner does. ``since`` and
|
|
201
|
+
``until`` are the measurement section's window (measure.window; ValueError when it is
|
|
202
|
+
empty or a bound does not parse)."""
|
|
198
203
|
assessment = assess(ledger)
|
|
199
204
|
claims = ledger.claims()
|
|
200
205
|
if reader_user is not None:
|
|
@@ -213,10 +218,14 @@ def report(ledger, recheck: bool = False, cwd: Optional[str] = None, timeout: Op
|
|
|
213
218
|
"unrechecked_outcomes": [],
|
|
214
219
|
"failing_receipt_outcomes": [],
|
|
215
220
|
"static_only_outcomes": [],
|
|
221
|
+
"dirty_bound_outcomes": [],
|
|
216
222
|
"assurance_overridden": [],
|
|
217
223
|
"same_vendor_only": [],
|
|
218
224
|
"self_verified_by_author": [],
|
|
219
225
|
"same_session_different_harness": [],
|
|
226
|
+
# D6 (ctr_67b26eae6bff4b63): another identity's reading of a claim, asked for; listed
|
|
227
|
+
# here and nowhere a verdict is counted
|
|
228
|
+
"assessments": [],
|
|
220
229
|
"formatted_statements": [],
|
|
221
230
|
"redactions": {"count": 0, "ids": []},
|
|
222
231
|
# absent and empty mean different things (an absent key is the starter default
|
|
@@ -227,6 +236,11 @@ def report(ledger, recheck: bool = False, cwd: Optional[str] = None, timeout: Op
|
|
|
227
236
|
"same_lineage_refutation_rate": None,
|
|
228
237
|
"cross_lineage_refutation_rate": None,
|
|
229
238
|
"refuted": [],
|
|
239
|
+
# ctr_614162800937e387: outcomes replaced by a later one, records withdrawn as
|
|
240
|
+
# artefacts, and the old wrong retractions a PM may want to call artefacts
|
|
241
|
+
"superseded": [],
|
|
242
|
+
"withdrawn": [],
|
|
243
|
+
"artefact_candidates": [],
|
|
230
244
|
"taint_chains": [],
|
|
231
245
|
"stale": [],
|
|
232
246
|
"asserted_facts": [],
|
|
@@ -241,6 +255,23 @@ def report(ledger, recheck: bool = False, cwd: Optional[str] = None, timeout: Op
|
|
|
241
255
|
"verifications_outside_project_roster": {},
|
|
242
256
|
"recheck": [],
|
|
243
257
|
}
|
|
258
|
+
# retractions filed as wrong -- every one before kinds -- whose reason names the claim
|
|
259
|
+
# that replaced it or reads like a stray test record: the PM may file an artefact
|
|
260
|
+
# retraction beside each, which then decides the claim's kind, never editing the old
|
|
261
|
+
# record (ctr_614162800937e387)
|
|
262
|
+
for r in sorted(ledger.by_kind("retraction"), key=lambda rec: rec["ts"]):
|
|
263
|
+
body = r.get("body") if isinstance(r.get("body"), dict) else {}
|
|
264
|
+
claim_id = body.get("claim")
|
|
265
|
+
if claim_id not in by_id or supersession_mod.retraction_kind(r) != "wrong":
|
|
266
|
+
continue
|
|
267
|
+
if supersession_mod.operative_kind(ledger.retractions_for(claim_id)) != "wrong":
|
|
268
|
+
continue # already answered by an artefact retraction beside it
|
|
269
|
+
reason = str(body.get("reason") or "")
|
|
270
|
+
why = ("names the claim that replaced it" if supersession_mod.REPLACEMENT.search(reason)
|
|
271
|
+
else "reads like a stray test record" if supersession_mod.TEST_LEAK.search(reason) else None)
|
|
272
|
+
if why:
|
|
273
|
+
rep["artefact_candidates"].append({"retraction": r["id"], "claim": claim_id,
|
|
274
|
+
"reason": reason[:160], "why": why})
|
|
244
275
|
# measured history, computed from the ledger alone: counts, intervals, and the word
|
|
245
276
|
# "insufficient history" wherever there are too few of them
|
|
246
277
|
measured = rel.report(ledger, assessment)
|
|
@@ -275,6 +306,12 @@ def report(ledger, recheck: bool = False, cwd: Optional[str] = None, timeout: Op
|
|
|
275
306
|
if backed in ("static", "attested"):
|
|
276
307
|
# a clean static gate is not evidence that the thing runs
|
|
277
308
|
rep["static_only_outcomes"].append({**entry, "assurance": backed})
|
|
309
|
+
# the writer's own word that its receipts ran on a tree no sha reproduces: no
|
|
310
|
+
# lane checks those out, so a practice of it is a PM's question per author (S3)
|
|
311
|
+
heads = [item.get("sha") for item in b.get("evidence") or []
|
|
312
|
+
if isinstance(item, dict) and item.get("kind") == "commit" and item.get("dirty")]
|
|
313
|
+
if heads:
|
|
314
|
+
rep["dirty_bound_outcomes"].append({**entry, "user": a.get("user"), "head": heads[0]})
|
|
278
315
|
# a measure, not a tier: every claim whose only verifiers are agents of its own
|
|
279
316
|
# vendor, whether the ledger's policy lets that reach `verified` or not
|
|
280
317
|
if info["verified_by"] and not info.get("cross_vendor") and not info.get("self_verified_by_author") \
|
|
@@ -287,10 +324,15 @@ def report(ledger, recheck: bool = False, cwd: Optional[str] = None, timeout: Op
|
|
|
287
324
|
# byte for byte is not the audit this ledger promises
|
|
288
325
|
deps = sorted(d for d in ledger.dependents_of(c["id"], through_kinds=("claim",)) if d in by_id)
|
|
289
326
|
rep["refuted"].append({**entry, "reasons": info["reasons"], "dependents": len(deps)})
|
|
290
|
-
|
|
327
|
+
# the rule trust applies: a superseded claim taints nothing unless it was retracted as wrong
|
|
328
|
+
if deps and not supersession_mod.taint_skipped(info.get("superseded_by"), ledger.retractions_for(c["id"])):
|
|
291
329
|
rep["taint_chains"].append({"root": c["id"], "tainted": [{"id": d, "statement": by_id[d]["body"]["statement"][:120]} for d in deps]})
|
|
292
330
|
if info["tier"] == "stale":
|
|
293
331
|
rep["stale"].append({**entry, "reasons": info["reasons"]})
|
|
332
|
+
if info.get("superseded_by"):
|
|
333
|
+
rep["superseded"].append({**entry, "superseded_by": info["superseded_by"], "tier": info["tier"]})
|
|
334
|
+
if info["tier"] == "withdrawn":
|
|
335
|
+
rep["withdrawn"].append({**entry, "reasons": info["reasons"]})
|
|
294
336
|
if info["tier"] == "asserted" and b["type"] == "fact":
|
|
295
337
|
rep["asserted_facts"].append(entry)
|
|
296
338
|
for field in _FORMATTED_FIELDS:
|
|
@@ -323,6 +365,17 @@ def report(ledger, recheck: bool = False, cwd: Optional[str] = None, timeout: Op
|
|
|
323
365
|
claim = by_id.get(v["body"].get("claim"))
|
|
324
366
|
if claim is None:
|
|
325
367
|
continue
|
|
368
|
+
if is_assessment(v): # a reading, not a verdict: its own column, never the matrix
|
|
369
|
+
rep["assessments"].append({
|
|
370
|
+
"id": v["id"], "claim": claim["id"], "verdict": v["body"]["verdict"],
|
|
371
|
+
"by": v["author"].get("harness"), "vendor": v["author"].get("vendor"),
|
|
372
|
+
"user": v["author"].get("user"), "ts": v["ts"],
|
|
373
|
+
"lineage": ("another lineage" if lineage_differs(claim["author"], v["author"])
|
|
374
|
+
else "same lineage: never counted"),
|
|
375
|
+
"note": str(v["body"].get("note") or "")[:160], "cited": list(v["body"].get("cited") or []),
|
|
376
|
+
"statement": claim["body"]["statement"][:120],
|
|
377
|
+
})
|
|
378
|
+
continue
|
|
326
379
|
verdict = v["body"]["verdict"]
|
|
327
380
|
key = f"{claim['author'].get('vendor')}->{v['author'].get('vendor')}"
|
|
328
381
|
cell = rep["lineage_matrix"].setdefault(key, {"verified": 0, "refuted": 0, "inconclusive": 0})
|
|
@@ -421,8 +474,8 @@ def report(ledger, recheck: bool = False, cwd: Optional[str] = None, timeout: Op
|
|
|
421
474
|
if recheck:
|
|
422
475
|
for c in claims:
|
|
423
476
|
info = assessment[c["id"]]
|
|
424
|
-
if info["tier"] in ("refuted", "tainted"):
|
|
425
|
-
continue
|
|
477
|
+
if info["tier"] in ("refuted", "withdrawn", "tainted") or info.get("superseded_by"):
|
|
478
|
+
continue # settled, a stray, or a replaced head: re-running says nothing
|
|
426
479
|
unmet = set(ev.unmet_expectations(ledger, c))
|
|
427
480
|
for r in ev.recheck_claim(ledger, c, cwd=cwd, timeout=timeout, path_map=path_map):
|
|
428
481
|
if r["outcome"] == "skipped":
|
|
@@ -433,6 +486,13 @@ def report(ledger, recheck: bool = False, cwd: Optional[str] = None, timeout: Op
|
|
|
433
486
|
if r["outcome"] == "match" and r["evidence"] in unmet:
|
|
434
487
|
entry["note"] = ev.FAILING_RECEIPT_NOTE # reproducing a failure verifies nothing
|
|
435
488
|
rep["recheck"].append(entry)
|
|
489
|
+
# what the reliability measurements leave out, and why (the PE's ruling, item 4)
|
|
490
|
+
rep["not_measured"] = {"superseded": len(rep["superseded"]), "artefact": len(rep["withdrawn"])}
|
|
491
|
+
# the vision's numbers for a window, recomputable by anyone with the shards
|
|
492
|
+
# (ctr_13190a200fbbd682; docs/BENCHMARK-PLAN.md section 3)
|
|
493
|
+
rep["measurement"] = measure_mod.measurement(
|
|
494
|
+
ledger, since, until, sees=lambda rec: _reader_sees(ledger, rec, by_id, reader_user),
|
|
495
|
+
assessment=assessment)
|
|
436
496
|
return rep
|
|
437
497
|
|
|
438
498
|
|
|
@@ -486,6 +546,9 @@ def format_report(rep: dict) -> str:
|
|
|
486
546
|
lambda r: f"{r['id']} [{r['by']}] {r['statement']} -- receipts: {', '.join(r['receipts'])}")
|
|
487
547
|
section("Outcome claims backed only by static evidence (static-pass/dynamic-fail risk)",
|
|
488
548
|
rep["static_only_outcomes"], lambda r: f"{r['id']} [{r['by']}, {r['assurance']}] {r['statement']}")
|
|
549
|
+
section("Outcome claims bound to a dirty tree (their commit is not what ran; no lane re-runs them at it)",
|
|
550
|
+
rep.get("dirty_bound_outcomes", []),
|
|
551
|
+
lambda r: f"{r['id']} [{r['by']}, {r['user']}] at {str(r['head'])[:12]} {r['statement']}")
|
|
489
552
|
section("Receipts whose assurance was declared above the computed default", rep["assurance_overridden"],
|
|
490
553
|
lambda r: f"{r['id']} [{r['by']}] declared {r['declared']}, computed {r['computed']}: {r['what']}"
|
|
491
554
|
+ (f" (cited by {', '.join(r['claims'])})" if r["claims"] else " (cited by no claim)"))
|
|
@@ -497,11 +560,22 @@ def format_report(rep: dict) -> str:
|
|
|
497
560
|
rep.get("same_session_different_harness", []),
|
|
498
561
|
lambda r: f"{r['id']} [{r['by']} -> {r['verified_by']}, {r['user']} session {r['session']}] "
|
|
499
562
|
f"{r['statement']}")
|
|
563
|
+
section("Assessments (a reading on request, never a check: they move no tier)", rep.get("assessments", []),
|
|
564
|
+
lambda r: f"{r['id']} on {r['claim']} [{r['verdict']} by {r['by']}, {r['vendor']}, {r['user']}; "
|
|
565
|
+
f"{r['lineage']}] {r['note']}" + (f" (cites {', '.join(r['cited'])})" if r["cited"] else ""))
|
|
500
566
|
section("Statements shaped like a document (injection risk)", rep.get("formatted_statements", []),
|
|
501
567
|
lambda r: f"{r['id']} [{r['by']}] {r['field']} starts a line with: {r['line']}")
|
|
502
568
|
section("Refuted", rep["refuted"], lambda r: f"{r['id']} {r['statement']} -- {'; '.join(r['reasons'])} (dependents: {r['dependents']})")
|
|
503
569
|
section("Taint chains", rep["taint_chains"], lambda r: f"{r['root']} -> " + ", ".join(t['id'] for t in r['tainted']))
|
|
504
570
|
section("Stale", rep["stale"], lambda r: f"{r['id']} {r['statement']} -- {'; '.join(r['reasons'])}")
|
|
571
|
+
section("Superseded outcomes (replaced by a later outcome of their contract; they count nowhere and block nothing)",
|
|
572
|
+
rep.get("superseded", []),
|
|
573
|
+
lambda r: f"{r['id']} {r['statement']} -- superseded by {', '.join(r['superseded_by'])} (was {r['tier']})")
|
|
574
|
+
section("Withdrawn as artefacts (stray or test records; they count nowhere and taint nothing)",
|
|
575
|
+
rep.get("withdrawn", []), lambda r: f"{r['id']} {r['statement']} -- {'; '.join(r['reasons'])}")
|
|
576
|
+
section("Retractions filed as wrong that read like an artefact (a PM may file an artefact retraction beside each)",
|
|
577
|
+
rep.get("artefact_candidates", []),
|
|
578
|
+
lambda r: f"{r['claim']} (retraction {r['retraction']}): {r['why']} -- {r['reason']}")
|
|
505
579
|
section("Facts with no evidence (asserted)", rep["asserted_facts"], lambda r: f"{r['id']} [{r['by']}] {r['statement']}")
|
|
506
580
|
section("Pinned sections over config.compile_pinned_chars",
|
|
507
581
|
rep.get("pinned_over_cap", []),
|
|
@@ -571,10 +645,17 @@ def format_report(rep: dict) -> str:
|
|
|
571
645
|
f"cross-lineage refutation rate: {_rate(rep['cross_lineage_refutation_rate'])}")
|
|
572
646
|
if "reliability" in rep:
|
|
573
647
|
lines.append("")
|
|
648
|
+
if rep.get("not_measured"):
|
|
649
|
+
nm = rep["not_measured"]
|
|
650
|
+
lines.append(f"Not measured below: {nm['superseded']} superseded outcome(s) and {nm['artefact']} "
|
|
651
|
+
f"artefact retraction(s); refuted counts verification mismatches and wrong retractions only")
|
|
574
652
|
lines.append(rel.format_report({"table": rep["reliability"],
|
|
575
653
|
"same_lineage_agreement": rep["same_lineage_agreement"],
|
|
576
654
|
"staleness": rep["staleness"],
|
|
577
655
|
"judgment_calibration": rep["judgment_calibration"]}).rstrip("\n"))
|
|
656
|
+
if rep.get("measurement"): # a replica older than this section sends none
|
|
657
|
+
lines.extend(measure_mod.format_noise(rep["measurement"]))
|
|
658
|
+
lines.extend(measure_mod.format_measurement(rep["measurement"]))
|
|
578
659
|
if rep["recheck"]:
|
|
579
660
|
section("Evidence re-check", rep["recheck"],
|
|
580
661
|
lambda r: f"{r['claim']} {r['evidence']}: {r['outcome']} -- {r['detail']}"
|