Free a slot only on explicit release — never by inference #37

Closed
opened 2026-09-03 18:25:13 +00:00 by larandar · 0 comments
Owner

Proposal

The pool's core invariant, in the only form that needs no mechanism: a slot is freed by an explicit release and by nothing else.

Delivery class

agent-unit — the release path and the refusal of every other path, with capture doubles.

Design

A slot is available when something explicitly released it. Every other condition holds it: no timeout frees a slot, no staleness backstop frees a slot, no unreachable or silent runtime frees a slot, and no absence of evidence frees a slot.

This is the whole behaviour, not a fallback branch. Per the freeholder direction on Ting/Ting#2 Q2 (2026-09-04), the liveness mechanism stays undefined until there is operational evidence to design it against. Rather than leave that as a gap, the record takes the conservative shape: nothing infers liveness at all. There is no mechanism to get wrong because there is no inference.

Directory state was never a candidate anyway. It records attribution — holder, checkout time, generation — all written by the checkout now in doubt. A record of who took a slot is not evidence they still hold it.

The failure this chooses

A drone that dies without releasing holds its slot indefinitely. Ten such deaths exhaust the pool: allocation refuses, and the swarm cannot start.

That is the intended failure, and choosing it is the point. It is loud, bounded, non-destructive, and recoverable by an explicit release. The alternative — an automatic release built on a mechanism nobody has validated — fails silently, and its failure is two live drones sharing one identity: unbounded, and found late.

Held slots are drift this service observes and cannot resolve, so they are raised under the #11 mandate rather than left to accumulate quietly. The pool says it is filling before it is full.

What is deferred

The eventual liveness source. It returns as an amendment when held-slot incidents show what evidence was actually available at the time — grounded rather than assumed. Nothing in this record needs revisiting to add it: an inference path would be a new way to release, not a change to the rule that only a release frees a slot.

Tasks

  • Implement explicit release as the only path that frees a slot.
  • Refuse reissue on every other condition: unknown, unreachable, timed out, or positively live.
  • Prove no elapsed time, however long, frees a slot.
  • Prove a liveness or transport failure holds the slot and reports rather than freeing.
  • Raise a held-slot alert when a slot outlives a plausible session, without freeing it.
  • Prove pool exhaustion refuses allocation cleanly rather than degrading into reuse.

Specification Delta

Requirement: only an explicit release frees a slot

Scenario: a holder disappears without releasing

  • GIVEN a slot whose holder has stopped without an explicit release
  • WHEN allocation is attempted, at any later time
  • THEN the slot is not reissued

Scenario: the pool is exhausted

  • GIVEN every slot held
  • WHEN allocation is attempted
  • THEN allocation refuses and reports exhaustion
  • AND no held slot is reclaimed to satisfy the request

Requirement: a failed check never reads as availability

Scenario: a liveness or transport failure

  • GIVEN any check that times out or cannot reach its source
  • WHEN allocation is attempted
  • THEN the slot is not reissued
  • AND the failure is reported rather than treated as absence

OpenSpec

OpenSpec 30

Structural parent

Vedanta#31

## Proposal The pool's core invariant, in the only form that needs no mechanism: a slot is freed by an **explicit release** and by nothing else. ## Delivery class `agent-unit` — the release path and the refusal of every other path, with capture doubles. ## Design A slot is available when something explicitly released it. Every other condition holds it: no timeout frees a slot, no staleness backstop frees a slot, no unreachable or silent runtime frees a slot, and no absence of evidence frees a slot. **This is the whole behaviour, not a fallback branch.** Per the freeholder direction on [Ting/Ting#2](https://jo.et0.pw/Ting/Ting/issues/2#issuecomment-15474) Q2 (2026-09-04), the liveness mechanism stays undefined until there is operational evidence to design it against. Rather than leave that as a gap, the record takes the conservative shape: nothing infers liveness at all. There is no mechanism to get wrong because there is no inference. Directory state was never a candidate anyway. It records attribution — holder, checkout time, generation — all written by the checkout now in doubt. A record of who took a slot is not evidence they still hold it. ### The failure this chooses A drone that dies without releasing holds its slot indefinitely. Ten such deaths exhaust the pool: allocation refuses, and the swarm cannot start. That is the **intended** failure, and choosing it is the point. It is loud, bounded, non-destructive, and recoverable by an explicit release. The alternative — an automatic release built on a mechanism nobody has validated — fails silently, and its failure is two live drones sharing one identity: unbounded, and found late. Held slots are drift this service observes and cannot resolve, so they are raised under the [#11](https://jo.et0.pw/Ting/Vedanta/issues/11) mandate rather than left to accumulate quietly. The pool says it is filling before it is full. ### What is deferred The eventual liveness source. It returns as an amendment when held-slot incidents show what evidence was actually available at the time — grounded rather than assumed. Nothing in this record needs revisiting to add it: an inference path would be a new way to release, not a change to the rule that only a release frees a slot. ## Tasks - [ ] Implement explicit release as the only path that frees a slot. - [ ] Refuse reissue on every other condition: unknown, unreachable, timed out, or positively live. - [ ] Prove no elapsed time, however long, frees a slot. - [ ] Prove a liveness or transport failure holds the slot and reports rather than freeing. - [ ] Raise a held-slot alert when a slot outlives a plausible session, without freeing it. - [ ] Prove pool exhaustion refuses allocation cleanly rather than degrading into reuse. ## Specification Delta ### Requirement: only an explicit release frees a slot #### Scenario: a holder disappears without releasing - **GIVEN** a slot whose holder has stopped without an explicit release - **WHEN** allocation is attempted, at any later time - **THEN** the slot is not reissued #### Scenario: the pool is exhausted - **GIVEN** every slot held - **WHEN** allocation is attempted - **THEN** allocation refuses and reports exhaustion - **AND** no held slot is reclaimed to satisfy the request ### Requirement: a failed check never reads as availability #### Scenario: a liveness or transport failure - **GIVEN** any check that times out or cannot reach its source - **WHEN** allocation is attempted - **THEN** the slot is not reissued - **AND** the failure is reported rather than treated as absence ## OpenSpec [OpenSpec 30](https://jo.et0.pw/Ting/Vedanta/wiki/OpenSpec-30-agent-identity-pool-lifecycle) ## Structural parent [Vedanta#31](https://jo.et0.pw/Ting/Vedanta/issues/31)
larandar changed title from Refuse reissue until the previous holder is shown gone to Free a slot only on explicit release — never by inference 2026-09-03 22:13:30 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
Ting/Vedanta#37
No description provided.