0.29.0
Wave G of docs/plan/store-waves-f-g-h.md: the plan's own store is a provider. The markdown documents are an entity-store provider held to the runtime's own suite, MarkdownBackend is the one adapter over it, history and audit come from the event log, and validate reports an edit made in an editor or an rm. Deviations D-P2, D-P3 and D-P4 close. Four stories, accepted, implemented and moved to implemented on recorded evidence the same day.
Added
-
The plan's documents are an
entity-storeprovider.aep_backend_markdown::provider::MarkdownProviderimplementsStateProvider,EventProviderandStoreover.engineering/planning/: a document's frontmatter is the instance's fields,statusits state,revisionits revision, the body abodyfield;journal.jsonlis the event log, one event per line beside the entries already there. It passesentity-runtime's own provider suite — nine cases written by somebody who has never seen a planning document — and the suite is shown to catch a deliberately wrong copy of it. A refused commit changes neither file; a document a person wrote by hand loads with an empty log; every one of this repository's own documents round-trips byte for byte. -
History and audit are answered from the event log (D-P3 closed in full).
history()andaudit()on everyEntityBackendread the provider's events — a second process answers exactly what the first wrote — and the in-memory records are a cache of the log, not its source. For a plan, the accepted commands another process ran arrive inaudit()with their command ids and the revision they produced; a document with no events yet answers what it answered before. -
protocol artifact validatereports drift and deletion (D-P2 and D-P4 closed by detection). A document whose frontmatter disagrees with the fold of its events is drift, per document, naming the fields and the event; a document the log has events for and the store no longer holds is deleted, naming the last event; both exit 1. A document with no events at all predates the log and is counted (N document(s) predate the event log;pre_providerin JSON), not blamed. Prevention — a hook, a lock — was considered and refused on the record: a check in the gate cannot be routed around.
Changed
-
MarkdownBackendis the adapter over that provider. It isaep_backend_entity::EntityBackend<MarkdownProvider, MarkdownProjection>behind the sameopen; its hand-writtenpersist, latch andjournal::appendare gone —backend.rswent from 883 lines to 196, and what left is not kept beside the new path. What stays is the plan's shape, inprojection.rs: the prose preserved, relations added into frontmatter and never removed, the ladder consulted on a status that arrives on a plain update, and the journal's own vocabulary noted on every event. Nobody can tell: a fixture recorded with 0.28.0 pins thatnew,relate,body,moveandevidenceleave byte-identical documents and thatlist,board,graph,validate,lifecycleandhistoryprint the same bytes.journal::readanswers the same entries for a line written before the provider and one written after it. -
The adapter has a projection seam.
EntityBackend<S, P = Identity>:Identityis the shape a SQLite plan takes — every record under its own type, hydrated on open; a plan-shaped projection lives beside the plan's provider. Nothing changes forSqliteBackend. -
The pin moved to
entity-runtime0.11.0; every event the adapter writes carriesargs— the command's payload, which is what the operation was decided on.