// inject(boundary[0]) → observe(boundary[1..n]) → verdict: pass | break_at(k)

Daisy Chains

Declarative flow specs that agents can test — borrowed from hardware, built for event-driven systems
Lenora AI workflows · march 2026
1

The Testing Gap

Five approaches to testing flows — none of them let you say "here is the flow, test it"
5
existing approaches
unit · integration · E2E · sagas · tracing
0
that declare expected flows
and detect breaks passively
Unit tests verify isolated services. Integration tests check pairs. E2E tests drive a browser and pray. Sagas add an orchestrator that every participant implicitly depends on — and it on them. Distributed traces instrument every service to emit spans after the fact. None of these let you declare a flow and test it as one thing.
  • Unit tests say nothing about whether services are wired together correctly
  • Integration tests only cover the pairs you thought to test
  • E2E tests are slow, brittle, and their timeouts tell you nothing about where the break is
  • Sagas introduce load-bearing infrastructure that must itself be tested
  • Traces are diagnostic, not declarative — they tell you what happened, not what should have happened
Insight: Contract tests (Pact) verify pairs of services, not flows. They test individual connections — the equivalent of testing each solder joint with a multimeter. Thorough but unscalable (Lehvä et al. 2019).
References
  • Paper Lehvä, J. et al. (2019)"Consumer-Driven Contract Tests for Microservices: A Case Study" Springer. Scholar
  • Paper Megargel, A. & Poskitt, C.M. (2021)"Microservices Orchestration vs. Choreography: A Decision Framework" IEEE ICCCN. Scholar
  • Paper Daraghmi, E. et al. (2022)"Enhancing Saga Pattern for Distributed Transactions" Applied Sciences, MDPI. Scholar
2

The Hardware Precedent

IEEE 1149.1 solved this in 1990 — inject at one boundary, observe at every other
1990
IEEE 1149.1 ratified
0
internal probes required
All
chips tested in one serial chain — no per-chip probe
JTAG boundary scan doesn't test the internals of each chip. It injects a known pattern at the boundary of one chip, observes what arrives at the boundary of the next, and checks if the chain is intact. The chips are black boxes. The connections are the test surface. Scan chains daisy-chain boundary scan cells across multiple chips — distributed verification with no per-chip instrumentation.
Insight: Boundary scan defect coverage depends on the fault model, not the chip internals. The test surface is the interconnection, not the implementation. This principle translates directly to bounded contexts (Parker 2003).
References
  • Std IEEE (1990)"IEEE Std 1149.1-1990: Standard Test Access Port and Boundary-Scan Architecture" Scholar
  • Paper Wagner, P.T. (1987)"Interconnect Testing with Boundary Scan" IEEE International Test Conference. Scholar
  • Paper Parker, K.P. (2003)"Defect Coverage of Boundary-Scan Tests" International Test Conference, IEEE. Scholar
  • Paper Cheng, K.T. & Krstic, A. (1999)"Current Directions in Automatic Test-Pattern Generation" IEEE Computer. Scholar
3

The Daisy Chain Spec Proposal

A declared description of an expected flow across bounded contexts

Transport-Agnostic

The chain definition names boundaries and signals — not protocols. HTTP, NATS, SMTP are adapters. The chain is the port.

chain: place-order
links:
  - boundary: storefront-ui
    signal:   POST /api/orders
    transport: http
  - boundary: order-service
    signal:   order.validated
    transport: nats

Timing Contracts

Each link declares a time window. The chain doesn't prescribe how — it asserts when. Miss the window, and the observer knows exactly which link broke.

- boundary: inventory-service
  signal:   inventory.reserved
  expect_within: 500ms

- boundary: payment-service
  signal:   payment.charged
  expect_within: 2000ms

Boundary Promise

Every link makes one promise: "If I receive X at my boundary, I will produce Y at my boundary within T." No upstream knowledge. No downstream coupling.

// each link is a contract:
receive(X)produce(Y) ≤ T

// chained:
A→B→C→D→E
// one artifact, three functions:
// spec · test · monitor
Insight: Schema-guided testing of message-oriented systems shows that matching temporal specifications to message schemas enables fault detection at the boundary level, not inside the service (Santos et al. 2022).
References
  • Paper Santos, A. et al. (2022)"Schema-Guided Testing of Message-Oriented Systems" INESTEC. Scholar
  • Paper Wu, C.F. et al. (2022)"Testing for Event-Driven Microservices Based on Consumer-Driven Contracts and State Models" APSEC, IEEE. Scholar
  • Paper Hatcliff, J. et al. (2012)"Behavioral Interface Specification Languages" ACM Computing Surveys. Scholar
4

Chains vs. Sagas vs. Traces

Three different tools solving three different problems — but only one is passive
Pattern A

Sagas

Run the flow — orchestrate and compensate
  • Orchestrator is inside the flow
  • Every participant implicitly depends on it, and it on them
  • Can't test the flow without running the saga
  • Failure = compensating transactions + new failure modes
"Step 1, do this. Step 2, do that. Step 3 failed — compensate."
Pattern B

Distributed Traces

Describe what happened — after the fact
  • Bottom-up: each service emits spans
  • Requires instrumentation inside every service
  • Descriptive, not prescriptive
  • Helps debug after failure, not detect during
"Here's the assembled trace — does it look right to you?"
Daisy Chains: Top-down. Declare what the flow should look like. Observe passively. If reality diverges from the spec, the divergence is the finding. Zero coupling to any participant's internals. The chain is outside the flow.
References
  • Paper Kløvedal, V.S. et al. (2026)"Accompanist: A Runtime for Resilient Choreographic Programming" arXiv:2603.20942. PDF
  • Paper Li, B. et al. (2022)"Enjoy Your Observability: An Industrial Survey of Microservice Tracing" Empirical SE, Springer. Scholar
  • Paper Hierons, R.M. (2011)"Oracles for Distributed Testing" IEEE TSE. Scholar
5

Passive Observation as Runtime Verification

Declare expected behavior → observe at boundaries → alert on divergence
Runtime verification is the formal method that most closely matches daisy chain observation. You write a specification of expected behavior. A monitor watches system execution. When the observed trace violates the spec, the monitor reports. The key difference: traditional RV instruments each component. Daisy chains observe only at boundaries — the scan chain controller watches I/O pins, not internal registers.
Spec
declare expected signals
at each boundary
Observe
multi-transport listener
NATS · HTTP · SMTP
Insight: Decentralized runtime verification distributes monitors across system nodes. Daisy chains take this further: monitors sit at boundaries only, reducing coupling from O(services) to O(boundaries) (Francalanza et al. 2018; Mostafa & Bonakdarpour 2015).
References
  • Paper Francalanza, A. et al. (2018)"Runtime Verification for Decentralised and Distributed Systems" Lectures on RV, Springer. Scholar
  • Paper Mostafa, M. & Bonakdarpour, B. (2015)"Decentralized Runtime Verification of LTL Specifications in Distributed Systems" IEEE TPDS. Scholar
  • Paper Karimi, M. et al. (2026)"Sharing the Secret: Distributed Privacy-Preserving Monitoring" arXiv:2603.20107. PDF
  • Paper Lima, B. et al. (2020)"Local Observability and Controllability in Distributed Testing with Time Constraints" IEEE Access. Scholar
6

Agentic Chain Testing

Machine-readable specs + autonomous agents = continuous boundary scan
A daisy chain is a machine-readable spec. An agent — not a human — picks it up and operates autonomously: inject test vectors, observe boundaries, detect breaks, run continuously against production, and eventually generate new chain specs from observed traffic.
phase 1: functional
> playwright → POST /api/orders > chain observer: passive > ✓ order.validated 87ms > ✓ inventory.reserved 234ms > ✓ payment.charged 1102ms > ✓ confirmation.sent 2340ms
phase 2: boundary scan
> inject → order-service boundary > no browser, no UI > ✓ inventory.reserved 198ms > ✗ payment.charged TIMEOUT > - confirmation.sent SKIPPED > BREAK: inventory → payment
phase 3: ATPG
> observing production traffic... > pattern detected: 14,291× > inferred chain: refund-flow > 4 links · 3 transports > → proposing for review > coverage: +1 chain auto-gen
Insight: Multi-agent feedback-driven loops can evolve software testing into autonomous, continuously learning quality assurance ecosystems. Daisy chains give these agents a declarative surface to operate on — not code, not logs, but specs (Nagvi et al. 2026).
References
  • Paper Nagvi, S. et al. (2026)"The Rise of Agentic Testing: Multi-Agent Systems for Robust Software QA" arXiv:2601.02454. PDF
  • Paper Martin, G. & Olszewska, J. (2025)"Automation Testing Framework for Reliable Autonomous Agentic AI" IEEE. Scholar
  • Paper Cheng, K.T. & Krstic, A. (1999)"Current Directions in Automatic Test-Pattern Generation" IEEE Computer — ATPG foundations. Scholar
7

Start Small

Five steps from YAML to continuous boundary scan
01
Declare one chain. Pick your most critical flow. Write boundaries, signals, timing as YAML. Don't build anything yet — the act of declaring it will surface ambiguities your team has been living with.
02
Add a passive observer. Subscribe to NATS subjects, HTTP endpoints, whatever your chain crosses. Log whether the expected signals appear in order. No enforcement — just visibility.
03
Add timing assertions. Turn the observer into a test. Run it in CI. When a signal doesn't appear within its window, fail the build. You now have a chain runner.
04
Add an agent. Let it inject test vectors, run chains on a schedule, report breaks. Now you have continuous boundary scan — the software equivalent of JTAG running at board power-on.
05
Let the agent generate chains. Observe production traffic, infer chain specs, propose for human review. Your test coverage grows from observation, not from writing tests. This is ATPG for event-driven systems.
Insight: Model-based testing shows that dynamic oracles checking global properties outperform static test suites for distributed systems. A chain spec is exactly such an oracle — it defines the expected global property of a flow (Sünyd et al. 2014; Hierons 2011).
References
  • Paper Sünyd, G. et al. (2014)"Model-Based Testing of Global Properties on Large-Scale Distributed Systems" Information & Software Tech., Elsevier. Scholar
  • Paper Hierons, R.M. (2011)"Oracles for Distributed Testing" IEEE TSE — oracle checks observed trace against specification. Scholar
  • Paper Ferme, V. & Pautasso, C. (2018)"A Declarative Approach for Performance Tests in Continuous Software Development" ACM/SPEC. Scholar
The Takeaway

Declare the chain.
The spec is the test.
The test is the monitor.

Stop testing internals — test interconnections. Stop orchestrating flows — declare them. Stop instrumenting services — observe boundaries. Hardware solved this in 1990. It's time software caught up.
View Testing Landscape Comparison →
RFC — Request for Comments
This is a spec proposal, not written in stone.
We want your feedback — corrections, concerns, alternatives, endorsements. Everything is open for discussion.