Skip to content

v0.19.0 — Public display-read seams for ecosystem companions

Choose a tag to compare

@dberry37388 dberry37388 released this 08 Jul 15:17
5c1df15

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-decrypted DurableRunDetail. It is the read-only counterpart to SwarmOperator (control): resolve it with app(InspectsDurableRuns::class) instead of binding the @internal DurableSwarmManager/DurableRunInspector or the @internal SwarmPersistenceCipher. Every sealed field is opened through the evidence path that honors swarm.persistence.decrypt_failure_policy and degrades per row — an undecryptable value becomes null with an explicit *_available: false flag rather than throwing or leaking sw0: ciphertext, so one poison row never aborts the batch or 500s a display surface. The operational resume reads on DurableRunStore are untouched and still decrypt strictly (fail loud on a rotated APP_KEY).
  • ReadableRunHistoryStore — public read-only run-history display contract. The display twin of RunHistoryStore::find(), which is a SHARED read that also feeds operational consumers (guardrail parent lookups, hierarchical execution, durable recording) and must fail loud under the throw policy. findForDisplay() returns the same record shape but degrades the run context input, run output, and every step's input/output per field (*_available flags) so a run + step detail surface never throws and never renders sw0: ciphertext; query() is the decryption-free run-list projection. The shared find() / SwarmHistory / swarm:history paths are unchanged. Bound to the same instance as RunHistoryStore.
  • ReadableAuditOutbox — public read-only audit-outbox health contract. The non-mutating counterpart to AuditOutbox::drain() (which reserves and consumes rows): pending(), deadLettered(), record(), healthSummary(), and isAvailable() for outbox-health surfaces. Every read is a pure SELECT that never writes reserved_at and never deletes, so it coexists with a concurrent swarm:relay --type=audit drainer instead of stealing its rows. Sealed payload/last_error are display-decrypted with the same per-row degrade. To minimize decrypted-evidence exposure, the list reads (pending()/deadLettered()) return metadata + last_error only; the full evidence payload is fetched on demand per row via record() (mirroring how swarm:trace gates 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-row output_available flag), completing cross-topology parity with parallel branches and child runs on the inspection surface.

Changed

  • DurableRunInspector now implements the public InspectsDurableRuns contract (the class stays @internal; consumers bind the contract). Its branch, child-run, and hierarchical-node-output display reads now degrade per row via a new SwarmPersistenceCipher::openForDisplay() helper rather than surfacing raw ciphertext under the legacy policy or throwing under the throw policy.