Skip to content

RFC-0001: v0.1 implementation plan

Status: Accepted Author: Alex Nodeland Created: 2026-09-30 Discussion: derived from stackr RFC-0002, accepted on 2026-09-29 with its decisions D1 to D7 Siblings:

Summary

relayr is the bridge that stackr RFC-0002 designs between artifactr and reflexr: an inbound adapter that turns selected artifactr events into reflexr events, an outbound adapter that lets reflexr runs act back in artifactr, mostly as proposals and notices, and a ledger of its own. This RFC is relayr's plan for v0.1: RFC-0002's seven phases, after a foundation, with the packages each phase adds, where its work lands, and what it waits on. The design itself is RFC-0002's and is not repeated here.

Motivation

RFC-0002 is stackr's document, and its phases span three repositories: relayr, stackr's template, and the product repository generated from it. relayr needs a plan in its own repository that its pull requests reference and tick, that says which work is relayr's, and that records what has changed in the libraries since the design was accepted.

Design

Packages

Package Holds Phase Extra
relayr.events The bridged event types, under a base declared with event_namespace="artifactr", and the projections applications register for their app_events and artifact kinds 1
relayr.ledger The ledger port and its in-memory adapter, with one contract test for every adapter 1
relayr.sql The ledger's SQL adapter: SQLAlchemy, Alembic migrations and relayr_-prefixed tables in the application's schema 1 sql, sqlite, postgres
relayr.inbound One follower per workspace, with its lease, cursor and dead letters 1
relayr.outbound The pydantic-ai capability and the helpers for function actions, allowlists, derived ids, keyed patches, and chain continuation 2
relayr.telemetry Span links, the thread:, chain: and rule: tags, and the Langfuse user 4 otel, once needed
relayr.rules The rule artifact type, its validation and replay preview, the install rule, and provenance 5
relayr.evals Proposal outcomes as feedback on the runs that proposed, and the measures 6

Each package uses only the libraries' public APIs, as RFC-0002's table lists them. A package's name may change when it is built; the architecture's status table shows what exists.

Since RFC-0002

The libraries have moved since RFC-0002 was written, and three changes bear on this plan:

  • Messages are idempotent by id in artifactr. artifactr ADR-0045 (from #61) refuses a used message id in a workspace, durably. A notice or message posted with an id derived from the run is posted once however often the run retries, so phase 2 derives message ids as it derives the others, and needs none of the ledger's read-back that RFC-0002 designed for the gap.
  • Log consumers have durable cursors. artifactr's Workspace.cursor and save_cursor (#67, artifactr ADR-0046) keep a named consumer's position in the library's own storage, and only move forward. Phase 1 decides, in an ADR, whether the follower's cursor lives there or in the ledger, and how its lease is held.
  • Rule names are qualified, as event types are (reflexr #83), so a rule's actor is reflexr:<namespace>:<name>.

Prerequisites

As of 2026-09-30:

Prerequisite Library Issue Needed by State
Namespaced event types reflexr #45 phase 1 Done: reflexr ADR-0039, implemented in reflexr #83
Durable message idempotency artifactr #61 phase 2 Done: artifactr ADR-0045
Notices that don't start or steer a turn, marked as notices artifactr #63 phase 2 Open
Workspace discovery: list a tenant's workspaces artifactr #62 phase 3 Open
Telemetry that composes across both libraries, untraced polling, mirror cursors reflexr, artifactr reflexr #62, artifactr #50 phase 4 Done
traceparent on artifactr envelopes artifactr #60 phase 4 Done
Runtime rule management reflexr #21, reflexr RFC-0003 phase 5 Phases 1 to 4 merged; phase 5, docs and oncall, open
Reserved publishers reflexr #72 phase 5 Open

Phases

Phase Deliverable Lands in Waits on Exit criteria
0. Foundation Packaging, tooling, CI, the documentation site and brand, ADRs for D1 to D7, and this plan relayr Nothing CI green at 100% coverage, and the site builds in strict mode
1. Inbound adapter relayr.events, relayr.ledger, relayr.sql and relayr.inbound: the bridged types, the follower with its lease, cursor and dead letters, and the ledger with both adapters relayr Nothing: reflexr #45 is done An artifactr message fires a reflexr rule exactly once, across a restart and a redelivery, on memory, SQLite and PostgreSQL
2. Outbound adapter and loop control relayr.outbound: the capability and helpers, allowlists, derived ids, keyed patches, and chain continuation relayr artifactr #63 Under forced retries, a rule's proposal and notice each appear once. Two rules that answer each other stop at the depth limit
3. Template option, example and smoke test The bridge question, the incident timeline example, and make smoke-app extended stackr's template artifactr #62 A generated application passes its CI, and the smoke test sees an event cross each way
4. Telemetry links and tags relayr.telemetry: span links, the tags, and the Langfuse user relayr Nothing: its prerequisites are done In Tempo, a turn started by a run links to the run's span. In Langfuse, each session carries the other's tag
5. Rules from chat relayr.rules: the rule artifact type, validation, preview, the install rule, and provenance relayr reflexr RFC-0003's last phase, and reflexr #72 A rule drafted in a thread goes live only after a person accepts it, and a forged artifactr:proposal_resolved installs nothing
6. Evaluation relayr.evals: proposal-outcome feedback and the measures; the combined experiment in the template's evals/ relayr and stackr's template Phases 2 and 5 The example's experiment reports acceptance, rewrite rate and time to resolution
7. Docs, ADRs and the product repository relayr's guides and ADRs, stackr's docs, and the product repository generated from the template relayr, stackr and the product repository Phases 1 to 6 The product repository passes its CI on the stack

Each phase is a series of small pull requests to main, and a phase that lands in relayr brings its guides, reference pages, architecture and ADRs with it.

Drawbacks

  • It waits on the libraries. Phases 2, 3 and 5 can't finish until their prerequisites land, and relayr moves only as its pins do (ADR-0012).
  • Half the plan lands elsewhere. Phases 3, 6 and 7 are largely stackr's and the product repository's, so this checklist tracks work its own pull requests don't contain.

Alternatives

RFC-0002 weighs where the bridge lives, and the alternatives to a bridge at all, in its Alternatives and decision D1 (ADR-0001). For the plan itself, tracking relayr's work in RFC-0002's checklist would keep one list, but in another repository, which relayr's pull requests couldn't tick.

Unresolved questions

RFC-0002's own open questions stand: who may accept a rule, how far a chat rule reaches, a combined session measure in evalr, whether thread_created belongs in the default set, how clients show a notice, and bridging across deployments. Two more are phase 1's to settle:

  • Where the follower's cursor lives: in artifactr's consumer cursors, or in the ledger.
  • How a follower holds its lease: through a mechanism the libraries' public APIs offer, or in the ledger.

Tracking

  • Phase 0: foundation
  • Phase 1: inbound adapter
  • Phase 2: outbound adapter and loop control (waits on artifactr #63)
  • Phase 3: template option, example and smoke test (waits on artifactr #62)
  • Phase 4: telemetry links and tags
  • Phase 5: rules from chat (waits on reflexr RFC-0003's last phase, and reflexr #72)
  • Phase 6: evaluation
  • Phase 7: docs, ADRs and the product repository (ADR-0001 to ADR-0007 recorded in phase 0)