Skip to main content

The inbound queue

Everything inbound passes through one queue on the box, and almost every question people ask about it — is something listening? what if my agent is down? do I have to reconnect? — has the same answer, which is that there is no connection to lose.

The box never dials home. Home dials out.

The shape to carry: home pulls, writes, and only then permits a delete.

Nothing is connected, in the literal sense​

There is no session, no registration, no socket held open in the other direction, and nothing on the box that knows whether you exist right now. Authorisation is a bearer key in a file — ~/.mecha/factory/drain.key, mode 0600, minted once when you paired the machine.

So:

  • Killing an agent breaks nothing. There is no subscription to lapse.
  • Restarting does not require reconnecting. The drain loop starts, reads its key off disk, and long-polls again.
  • "Instant" is a property of who waits, not of who calls. --wait 25 holds a request open on the box, so a booking becomes a calendar event seconds after the click — with the connection still initiated from home every time.

What happens when no machine of yours is running​

The queue grows. That is the whole answer, and two design choices guarantee it:

GET /v1/queue is a pure read. Records are not marked, leased, or consumed by being fetched. A response that never arrives costs nothing but a repeat — and repeating is correct, because the alternative is a stranger's request disappearing into a dropped connection.

Deleting is a separate, explicit act. POST /v1/queue/ack names every sequence number it removes. It is deliberately not a watermark: a watermark deletes rows nobody named, and that failure is silent.

Home writes the bytes to disk before acknowledging. A crash between the two means the record arrives again on the next drain; a crash the other way round would lose a real person's request with no trace on either machine. Only one of those is recoverable, so the ordering is not negotiable.

At-least-once, and where the duplicate is absorbed

Because a fetch is not a consume, delivery is at-least-once and de-duplication happens at home. It happens by filename: a record lands as 0000000008-book.json, keyed on the box's sequence number, so a re-delivered record overwrites itself instead of becoming a second row. Note the boundary of that guarantee — a filesystem. It works perfectly within one machine and not at all across two.

Two smaller properties worth knowing:

  • since stays 0. The endpoint takes a cursor and home deliberately does not use one, because a cursor would let home's idea of what it holds drift ahead of what it actually wrote. Asking for everything and writing what is new is self-healing.
  • A record that fails validation at home is still written, with valid: false and a reason. The box validated it on the way in and home validates again — neither trusts the other — but a mismatch is a bug in us, and losing somebody's request over it is the one outcome worth avoiding.

The one way data leaves without being drained​

A request type may declare retain_days in its manifest. That stamps a retain_until on the row, and a sweep on the box (factory sweep, on a timer) removes what has passed it, files included. A type that declares nothing keeps its records until they are drained and acked.

So an unattended queue is bounded by your own retention policy and by nothing else. If you want a request type to survive a long absence, leave retain_days unset.

More than one drainer​

This is the one place the design has a sharp edge, and it follows directly from "a fetch is not a consume".

The queue belongs to an account, not to a machine. Every machine you pair holds its own drain.key, but they all drain the same rows.

Since there is no lease, two machines polling at once both receive the record, both write it, and both run it through the front door — producing two drafted replies in two outboxes, neither aware of the other. The ack race itself is harmless (whoever acks first deletes; the second ack deletes nothing). The duplicated work is not.

Run exactly one draining machine per account. If a second machine needs to publish, it should hold publish.key without drain.key — the scopes are separate for exactly this reason. Pairing installs both, so pair it and then revoke that machine's drain key from the Machines table on your account page (each key is listed with its scope and label); a revoked key drains nothing even if the file stays on disk.

Several drainers on one machine are fine, and normal​

Within a single machine the seq-keyed filename absorbs everything, which is why the shipped arrangement has three drainers running happily side by side:

WhatCadenceWhy
mecha-drain.servicecontinuous long pollLatency. A confirmed booking reaches the calendar in seconds.
mecha-slots.timerevery few minutesBackstop. A wedged loop degrades to this instead of to silence.
frontdoor.shhourlyDrains before extraction, so the token-free leg runs even when the model server is down.

That last row is the ordering rule generalised: drain is the zero-token leg, so it runs first and unconditionally. A dead model server must never stop requests from coming home.

What the box will not tell you​

There is no "your agent is connected" indicator, because there is nothing connected to indicate. What the box does keep is close to it:

  • Each key's last use. The Machines table on your account page lists every key with its scope, label, when it was minted and when it was last used — and every authenticated call stamps that, so a drain key's "last used" is when that machine last asked for the queue.
  • Your queue depth. GET /v1/health answers anyone with a bare "up", and adds your account's queued count, handle and status for a caller holding any live key of yours.

Neither says the rest of the path worked: a drain key used seconds ago says the drain is running, not that anything at home extracted or answered what it fetched. If you want certainty that the path is working end to end, the honest check is at home — look for records arriving in ~/.mecha/requests/, or run mecha doctor, which reports requests that have been waiting on you past a threshold.

Next​

  • The front door — what happens to a drained request: the quarantined extraction, triage, and the draft you review.
  • Onboarding — pairing a machine, and which keys land on it.
  • What the factory is — the boundary in both directions.