# Refuse lineup links whose origin or landing is gone \(\#209\) · dara/icarus

[View on GitCafe](https://git.cafe/dara/icarus/commit/9b0c60afaa94fae9783d687a1e92657c8bbd0206)

Repository: [dara/icarus](https://git.cafe/dara/icarus)

Visibility: public

Requested revision: 9b0c60afaa94fae9783d687a1e92657c8bbd0206

Requested commit: 9b0c60afaa94fae9783d687a1e92657c8bbd0206

Commit: 9b0c60afaa94fae9783d687a1e92657c8bbd0206

Tree: a97e9e81aa670fce13b001c3a0289559d26e1401

Author: Dara Adedeji

Committer: GitHub

## Message

```
Refuse lineup links whose origin or landing is gone (#209)

* Refuse lineup links whose origin or landing is gone

A link placed from an origin a teammate had just deleted was accepted by
the server and then silently dropped on the next load, since hydration
cannot draw a link without both ends.

- Server: lineup link adds and patches fail with LINEUP_LINK_END_MISSING
  unless both ends are live rows on the link's page. A batch applies its
  origin and landing ops before its link ops (results keep sent order), so
  an outbox reloaded in key order (links before origins) still lands.
- Client: the queue claims lineup ends before links, so a batch cut never
  sends a link ahead of its ends; a link the user is placing or editing
  re-adds an end a teammate deleted after the canvas drew it; the failure
  lands in attention with a plain explanation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Check link ends only for clients that send ends first

Review follow-ups:
- applyBatch takes an optional checkLineupLinkEnds flag; only clients that
  send it get LINEUP_LINK_END_MISSING. Older clients can split a link from
  its origin across batches after a restart, so they keep today's
  behavior. The server no longer reorders batches.
- The outbox holds a link back while an origin or landing it names is
  still queued outside the batch (key order after restart, batch cap,
  another client id), and picks the batch's client from a record that can
  be sent, so a waiting link never stalls the queue.
- Keep mine re-sends a link refused for a missing end as it was (fresh
  op id, same add or patch and revision) instead of skipping a new link
  or turning a tombstone restore into a patch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Keep links waiting on an end out of the background drain

A link waiting for an origin or landing that is backing off (or
uncertain) looked due to the background drain, which picked its strategy,
claimed nothing and rescheduled at once, starving other strategies. The
drain now uses the same waiting rule as the batch claim, so it schedules
against the end's own retry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
```

## Parents

- [ff825f2d5f0ddf8c96c0b5810aaed498323929f4](https://git.cafe/dara/icarus/commit/ff825f2d5f0ddf8c96c0b5810aaed498323929f4?format=markdown)

[Source at this commit](https://git.cafe/dara/icarus/tree/9b0c60afaa94fae9783d687a1e92657c8bbd0206?format=markdown)
