v0.19.0 — Public display-read seams for ecosystem companions
Public display-read seams for ecosystem companions. Adds separate, additive, read-only contracts so a companion (starting with laravel-swarm-filament) can DISPLAY durable-run branch/child/hierarchical-node data and audit-outbox health through supported public seams that honor swarm.persistence.decrypt_failure_policy — without binding to the @internal cipher or the strict-operational resume reads. Operational strict/consuming methods are untouched; the display and operational paths stay separate by construction.
Added
InspectsDurableRuns— public read-only durable inspection contract. The supported, container-bound seam for companion packages and external readers to DISPLAY a durable run's assembled state (find(),inspect(),inspectByLabels()), returning a display-decryptedDurableRunDetail. It is the read-only counterpart toSwarmOperator(control): resolve it withapp(InspectsDurableRuns::class)instead of binding the@internalDurableSwarmManager/DurableRunInspectoror the@internalSwarmPersistenceCipher. Every sealed field is opened through the evidence path that honorsswarm.persistence.decrypt_failure_policyand degrades per row — an undecryptable value becomesnullwith an explicit*_available: falseflag rather than throwing or leakingsw0:ciphertext, so one poison row never aborts the batch or 500s a display surface. The operational resume reads onDurableRunStoreare untouched and still decrypt strictly (fail loud on a rotatedAPP_KEY).ReadableRunHistoryStore— public read-only run-history display contract. The display twin ofRunHistoryStore::find(), which is a SHARED read that also feeds operational consumers (guardrail parent lookups, hierarchical execution, durable recording) and must fail loud under thethrowpolicy.findForDisplay()returns the same record shape but degrades the run context input, run output, and every step's input/output per field (*_availableflags) so a run + step detail surface never throws and never renderssw0:ciphertext;query()is the decryption-free run-list projection. The sharedfind()/SwarmHistory/swarm:historypaths are unchanged. Bound to the same instance asRunHistoryStore.ReadableAuditOutbox— public read-only audit-outbox health contract. The non-mutating counterpart toAuditOutbox::drain()(which reserves and consumes rows):pending(),deadLettered(),record(),healthSummary(), andisAvailable()for outbox-health surfaces. Every read is a pure SELECT that never writesreserved_atand never deletes, so it coexists with a concurrentswarm:relay --type=auditdrainer instead of stealing its rows. Sealedpayload/last_errorare display-decrypted with the same per-row degrade. To minimize decrypted-evidence exposure, the list reads (pending()/deadLettered()) return metadata +last_erroronly; the full evidence payload is fetched on demand per row viarecord()(mirroring howswarm:tracegates payloads behind--include-payloads). Bound to the database outbox when the persistence driver supports it and a no-op (reporting an empty, unavailable outbox) otherwise.DurableRunDetail::hierarchicalNodeOutputs. The assembled durable read model now includes hierarchical node outputs (display-decrypted, per-rowoutput_availableflag), completing cross-topology parity with parallel branches and child runs on the inspection surface.
Changed
DurableRunInspectornow implements the publicInspectsDurableRunscontract (the class stays@internal; consumers bind the contract). Its branch, child-run, and hierarchical-node-output display reads now degrade per row via a newSwarmPersistenceCipher::openForDisplay()helper rather than surfacing raw ciphertext under thelegacypolicy or throwing under thethrowpolicy.