Skip to content

Validate writer-exclusivity for link_from at config time #89

@lxsaah

Description

@lxsaah

Context

The runtime treats .source(), .transform(), and .link_from() as
interchangeable record producers — all three ultimately call
TypedRecord::produce() and push into the same buffer. There is already
mutual-exclusion at config time between .source() and .transform():

.link_from() is the gap. A node can declare .link_from() alongside
.source() or .transform() on the same key and the runtime will accept
it. Both writers race into Buffer::push and the latest_snapshot becomes
last-writer-wins with no panic, no log, no diagnostic. This is the actual
"two writers per record" misconfiguration — the one worth catching.

Proposal

Extend the existing config-time mutual-exclusion pattern to cover inbound
connectors:

  1. In InboundConnectorBuilder::finish
    (aimdb-core/src/typed_api.rs:908):
    panic if has_transform() or has_producer_service() is already true.
  2. In set_producer_service and set_transform: panic if
    inbound_connectors() is non-empty.

All three predicates already exist — purely additive, no API change, same
panic-at-config-time semantics as the existing checks.

Scope / decisions

  • Multiple link_from on the same key: keep allowed. add_inbound_connector
    pushes onto a Vec, and multiple inbound feeds (redundant brokers, fan-in) is
    a legitimate pattern. Only forbid mixing inbound with local producers.
  • Where to enforce: existing mutual-exclusion lives on TypedRecord
    (set_producer_service, set_transform). Following that convention argues
    for adding the check to add_inbound_connector too, and letting the builder
    finish() rely on it. The builder-level check gives a better error message
    (includes the URL); the record-level check is harder to bypass. Probably do
    both — the record-level as the source of truth, the builder-level as a
    pre-check that fires earlier with more context.
  • Out of scope: detecting two different nodes both declaring link_to
    on the same key (cross-node writer conflict). That needs network-level
    awareness, not local config validation.

Background

Surfaced while reviewing the record-ownership blog draft. The blog originally
framed link_to + link_from on the same key as the misconfiguration to
watch for; the actual writer-conflict case is link_from + a local source.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions