D51 settled a question that had circled three different tasks under three different names -- T221's "are Workspace conditions persisted items," July's Insight analysis, T126's own build request -- and the answer to all three turned out to be the same absent write, seen from three angles.
Conditions stay projections. They own no state, and nothing is created for one -- not in the detected provenance (an invalidated RelationEdge), not in asserted (a contradicts edge), not in scheduled (the item itself). A condition's identity is just its own qualified subject, (subject_type, subject_id), and that turned out to be enough for every real use an identity has to serve -- stable rendering, model linkage, addressing, dedup, history -- even for the one provenance with no obvious durable object to point at.
What *is* persisted is the finding a detector produces about a subject. D51 named it Finding -- not Insight, which the July analysis and T126 both used, and which is already spoken for as a Cloud capability -- and gave it a shape D46 had already mostly decided a month earlier: thin, and with no write surface at all. acknowledged, dismissed, accepted-as-is -- the human-resolution vocabulary the original design sketched -- are exactly what D46 rules a finding cannot carry. A finding resolves when its own detector stops firing for the same subject, not by someone clicking a button. Building a create_finding/update_finding pair would have been building the invitation to do the thing the design explicitly forbids.
What shipped
smeldr.dev/core v1.90.0 adds Finding and FindingStore:
app.Findings(smeldr.NewFindingStore(db))
// App.SweepStructural now records a Finding for each newly-flagged
// stale relation edge, in addition to its existing AfterRelationCascade
// signal -- no FindingStore configured means no behaviour change.
Identity is (Detector, SubjectType, SubjectID). Record upserts: a repeat finding for a subject already on file updates LastSeenAt and Message only, never creating a duplicate row -- the dedup-across-sweeps requirement D51's own derivation named directly.
smeldr.dev/mcp v1.37.0 adds the one tool D51 allows: list_findings (Author role, optional detector filter). No sibling create_*/ update_* tools exist, and won't -- that's not an oversight to fix later, it's the point.
Only the structural detector is wired in this release, through RelationStore.SweepStructural's own existing onStale callback -- the hook was already there, built for the AfterRelationCascade signal, and extending it needed no new plumbing. DrainEvalQueue's own scheduled provenance is real under D51 too, but it has no equivalent "just flagged this" callback yet to hang a Finding off of. That's separate, follow-up work, not a gap in this release's own scope.
What's next
A Finding is addressable now, which is what D51's own "model linkage" use case was for -- a Decision can suppress one, a Task can investigates one, once something actually does. Nothing in this release wires that linkage yet; it's the next real use of the identity this release makes durable.