Skip to content

Commit aa41eef

Browse files
wow-mileyMiley Chandonnetclaude
authored
AMPR-176/#505: ProvenanceCommitted design placeholder (#513)
Forward-looking design placeholder for the future `MemoryEvent.ProvenanceCommitted` event, per the Wave 3 audit (AMPR-168) Gap-5 finding. No new event type, no publish site, no tests — just the design doc and a TODO marker so the work is tracked when AMPERE is ready to grow the provenance-chain surface. - `docs/design/provenance-event.md` — sketches event shape, hash and signature working assumption (Ed25519 over a parent-hash chain), three publish-site patterns with a checkpoint-only recommendation, the OpenAI grant "verifier first vs event first" open question, and explicit promotion criteria for when this becomes an implementation ticket. - `MemoryEvent.kt` — `TODO(AMPR-176)` marker inside `sealed interface MemoryEvent`, pointing at the design doc. Closes #505 Co-authored-by: Miley Chandonnet <miley@Mileys-Mac-mini.local> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 074bbc7 commit aa41eef

2 files changed

Lines changed: 138 additions & 0 deletions

File tree

ampere-core/src/commonMain/kotlin/link/socket/ampere/agents/domain/event/MemoryEvent.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ data class RetrievedKnowledgeSummary(
3535
*/
3636
sealed interface MemoryEvent : Event {
3737

38+
// TODO(AMPR-176): Add `ProvenanceCommitted` here when the provenance-chain
39+
// surface is promoted from design placeholder to implementation. Design
40+
// sketch in docs/design/provenance-event.md covers event shape
41+
// (entryId / parentHash / contentHash / signer), hash/signature scheme,
42+
// publish-site choice, and the relationship to the OpenAI grant's
43+
// formal-verification workstream. Do not implement here without first
44+
// satisfying one of the promotion criteria in that doc.
45+
3846
/**
3947
* Event emitted when a Knowledge entry is successfully stored.
4048
*

docs/design/provenance-event.md

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# `MemoryEvent.ProvenanceCommitted` — Design Placeholder
2+
3+
**Issue:** [AMPR-176](https://linear.app/miley/issue/AMPR-176) (forward-looking design placeholder)
4+
**Status:** Not implemented. Design sketch only — promote to an implementation ticket when one of the trigger conditions in [Promotion criteria](#promotion-criteria) fires.
5+
**Related work:** [AMPR-168](https://linear.app/miley/issue/AMPR-168) (Wave 3 cognitive event audit, Gap-5), [AMPR-175](https://linear.app/miley/issue/AMPR-175) (`MemoryEvent.MilestoneReached`), [AMPR-169](https://linear.app/miley/issue/AMPR-169) (Phosphor / Lumos bridge).
6+
**Last verified:** 2026-05-30
7+
8+
---
9+
10+
## Context
11+
12+
The Wave 3 cognitive event audit (AMPR-168) flagged that the original Wave 3 plan referenced "blockchain provenance entries" without confirming whether such an event existed. It does not. `MemoryEvent` today carries only `KnowledgeStored` and `KnowledgeRecalled` (see `ampere-core/src/commonMain/kotlin/link/socket/ampere/agents/domain/event/MemoryEvent.kt`). The `OutcomeRecorded` event referenced in `docs/concepts/memory-provenance.md` is itself aspirational.
13+
14+
The Wave 3 Lumos bridge ships without provenance-chain semantics. Routine milestones — the STAR glyph signal — are covered by `MemoryEvent.MilestoneReached` (AMPR-175). Provenance is a *separate* axis: a verifiable cross-history chain for every memory write, hash-linked back to its parent, optionally signed.
15+
16+
This document captures the design space so the work is not re-derived from scratch when AMPERE grows that surface.
17+
18+
---
19+
20+
## Suggested event shape
21+
22+
```kotlin
23+
@Serializable
24+
data class ProvenanceCommitted(
25+
override val eventId: EventId,
26+
override val timestamp: Instant,
27+
override val eventSource: EventSource,
28+
override val urgency: Urgency = Urgency.LOW,
29+
30+
// Identity of the committed memory entry.
31+
val entryId: String, // KnowledgeId or OutcomeId — depends on publish-site choice.
32+
val entryKind: ProvenanceEntryKind, // KNOWLEDGE | OUTCOME | CHECKPOINT
33+
val knowledgeId: String? = null, // present when entryKind == KNOWLEDGE
34+
val taskId: String? = null, // optional — present when the commit was task-scoped
35+
36+
// Chain linkage.
37+
val parentHash: String?, // null only for genesis; otherwise the prior entry's contentHash
38+
val contentHash: String, // canonical hash of (entryId, payload, parentHash, timestamp)
39+
val signer: SignerId, // who signed; opaque ID (agent / device / key)
40+
val signature: ByteArray? = null, // optional in early designs; required once signing is live
41+
42+
val runId: String? = null, // preserves ArcTraceProjection wiring
43+
) : MemoryEvent
44+
```
45+
46+
`ProvenanceEntryKind` is a sealed enum (`KNOWLEDGE`, `OUTCOME`, `CHECKPOINT`) so consumers can filter without inspecting payload shape. `SignerId` is intentionally opaque — leave the key-material story to the implementation ticket.
47+
48+
The exact field set is **not load-bearing** at this stage. The point of fixing a sketch now is so future code-review on the implementation ticket has a fixed reference to argue against, not so this becomes the schema.
49+
50+
---
51+
52+
## Hash / signature scheme
53+
54+
**Working assumption:** Ed25519 signatures over a Merkle-DAG-style parent-hash chain (each entry references one parent by `contentHash`; checkpoint entries may reference multiple parents, forming a DAG rather than a strict list).
55+
56+
**Why Ed25519:** small keys, small signatures, fast verification, well-supported in KMP targets via `kotlin-crypto` or platform-actual wrappers. No hard requirement — Schnorr or post-quantum schemes are equally compatible with the chain shape.
57+
58+
**Why a parent-hash chain, not a Merkle tree:** the agent writes entries serially. There is no batch-verification motivation today. A simple `parentHash` link gives append-only tamper detection at minimal complexity; the DAG generalisation is reserved for checkpoint entries that summarise N predecessors.
59+
60+
**Explicitly out of scope at this stage:**
61+
- Choice of hash function (BLAKE3, SHA-256, both — open).
62+
- Key custody / rotation story.
63+
- Off-chain anchoring (timestamp-server, public-ledger anchoring) — none of which is in scope unless a consumer pulls.
64+
65+
---
66+
67+
## Publish site
68+
69+
Three plausible patterns. The implementation ticket picks one.
70+
71+
**A. Co-located with every memory write.** Every `KnowledgeRepository.storeKnowledge` and every `OutcomeMemoryRepository.recordOutcome` emits one `ProvenanceCommitted`. Highest fidelity, highest event volume.
72+
73+
**B. Checkpoint-only.** Provenance entries are emitted only at *checkpoints* — e.g., end-of-phase, end-of-run, or explicit `flushProvenance()` calls. Lower volume; each checkpoint hash covers a batch of writes via DAG fan-in. Aligns better with the OpenAI grant's formal verification cadence (one proof obligation per checkpoint, not per write).
74+
75+
**C. Hybrid.** Per-write commit for `Knowledge`; checkpoint-only for `ExecutionOutcome` (which can be high-frequency). Operationally cheap, semantically awkward — two chains to reason about.
76+
77+
**Recommendation for the implementation ticket:** start with **B (checkpoint-only)**. Per-write provenance can be added incrementally without breaking the chain shape; checkpoint-only is the cheaper default and matches the verification workstream's natural granularity.
78+
79+
---
80+
81+
## Relationship to OpenAI grant — formal verification workstream
82+
83+
Open question for the implementation ticket: **does AMPERE need `ProvenanceCommitted` before formal verification work begins, or does the event shape *emerge from* that work?**
84+
85+
Two paths:
86+
87+
1. **Event first.** Ship `ProvenanceCommitted` with a conservative shape; let the verification workstream consume it. Risk: the verifier needs a field we did not include, and we churn the event shape early in its life.
88+
2. **Verifier first.** Let the formal verification workstream define what it needs to prove (chain integrity, signer attribution, replay determinism); derive `ProvenanceCommitted` from those proof obligations. Risk: the verification workstream blocks on event design that nobody else is paid to do.
89+
90+
Path 2 is preferred *unless* a non-verification consumer (see below) creates pull first. The event exists to be verified; designing it without the verifier's input is speculative.
91+
92+
---
93+
94+
## Promotion criteria
95+
96+
This ticket may be promoted from "design placeholder" to "implementation" when **any one** of these fires:
97+
98+
- **Act 5 closes** and the next phase (Act 6?) opens its scope discussion — provenance is a natural Act 6 candidate.
99+
- **OpenAI grant work begins concretely** and provenance becomes a deliverable in workstream-1 (formal verification).
100+
- **Consumer pull arrives** — most likely Socket's "time-travel debugging" feature, which already reads `ArcTraceProjection` and would benefit from a tamper-evident chain. CHI / interpretability is a secondary consumer.
101+
102+
Until one of these fires, the cost of speculative implementation (event shape churn, premature commitment to a signature scheme, write-amplification on the memory path) exceeds the value.
103+
104+
---
105+
106+
## What this design does *not* lock in
107+
108+
- The exact event payload — fields above are a sketch, not a contract.
109+
- The hash function or signature scheme.
110+
- Whether `ProvenanceCommitted` extends `MemoryEvent` or becomes its own sealed family. The current proposal keeps it under `MemoryEvent` because the publish site is the memory layer; a `ProvenanceEvent` family is reasonable if non-memory commits (config, plan, identity) join the chain.
111+
- Batching, retention, and pruning behaviour.
112+
- The wire format used by any future Lumos / Phosphor bridge — Wave 3's STAR glyph signal is `MilestoneReached`, not `ProvenanceCommitted`.
113+
114+
---
115+
116+
## Implementation ticket — checklist seed
117+
118+
When the implementation ticket is filed, it should at minimum:
119+
120+
1. Pick one of the three publish-site patterns and justify the choice against the then-current consumer set.
121+
2. Pick a hash function and signature scheme (or explicitly defer signing to a follow-up).
122+
3. Define `ProvenanceEntryKind` and the genesis-entry convention.
123+
4. Add `provenance_store.sq` (SQLDelight schema) carrying `entry_id`, `parent_hash`, `content_hash`, `signer`, `signature`, `run_id`, `timestamp`.
124+
5. Update `docs/concepts/memory-provenance.md` to make the chain an invariant rather than an aspiration.
125+
6. Add `ArcTraceProjection` support so a time-travelled run includes its provenance entries.
126+
7. Remove the `TODO(AMPR-176)` marker in `MemoryEvent.kt`.
127+
128+
---
129+
130+
*Design placeholder filed for AMPR-176. No code changes accompany this document beyond the TODO marker in `MemoryEvent.kt`.*

0 commit comments

Comments
 (0)