- conforms_to::[[Observation Form Contract]]
- has_epistemic_status::[[Empirical Observation]]
- in_practice_domain::[[eOS Continuum]]
- authored_by::[[Christopher Allen]]
- has_lifecycle::[[Seed Stage]]↗
- has_curation::[[Working Draft]]↗
Two Agents Contending for a Bounded Resource: Exactly One Claim Commits
Claim
In the eOS-Harness MVA running against DGD 1.7.9 plus the eOS-kernellib chat-app write-coherence branch, when two users contend for the single open slot in a capacity-bounded chat room, the runtime serializes the two claim operations so that exactly one commits and the other reads the committed state and is refused -- with no lock, no retry loop, and no coordination protocol. The mechanism: obj/room.c carries a capacity and a claim_slot(user) that re-reads the room's CURRENT member list (query_members()) at write time and refuses (returns 0) when sizeof(current) >= capacity. The phase sets a room's capacity to 1, then has two users (frank, grace) both call claim_slot. Each call runs as its own atomic DGD task, so DGD's single-threaded scheduling runs them one after another: the first reads zero members, takes the slot, and commits; the second reads the post-commit membership (one member, at capacity) and is refused. The driver asserts exactly one claim returned 1, the room holds exactly the winner, and the loser is not a member (sentinel COHERENCE-SERIALIZE OK). The losing writer never executes a lock acquisition or a compare-and-swap retry -- its plain read of current state at write time already reflects the winner's commit, which is the coherent-state primitive providing the serialization for free.
Grounds
This is an Empirical Observation. The grounds are a captured three-boot smoke run 2026-05-30 against the live MVA demonstration instance with examples/chat-app/ overlaid into the isolated runtime staging tree.
Setup (verifiable from repo state):
- Driver: DGD 1.7.9 built from
dworkin/dgd; binary symlinked into the runtime staging tree. - Kernel layer: eOSContinuum/eOS-kernellib's chat-app write-coherence branch at HEAD
2bb1596. - Application layer:
examples/chat-app/, deployed with the Chat domain overlay. - Runtime config: the instance config; the isolated runtime staging tree layout; the chat-app smoke script runs the three-boot regression and counts
OKsentinels (expected 13).
Load-bearing source (examples/chat-app/obj/room.c and a phase of examples/chat-app/sys/test.c):
/* room.c: the serialized slot claim */
int claim_slot(object user)
{
object *current;
int cap;
cap = query_capacity();
current = query_members(); /* current state, read at write time */
if (cap > 0 && sizeof(current) >= cap) {
return 0; /* room full -- the loser sees the update */
}
if (!member(user, current)) {
set_property("chat-room.member-list", current + ({ user }));
}
return 1;
}
/* test.c: two users contend for the one slot */
room_c->set_capacity(1);
frank_won = room_c->claim_slot(frank); /* commits, room now full */
grace_won = room_c->claim_slot(grace); /* reads the full room, refused */
/* asserts: frank_won + grace_won == 1; sizeof(members) == 1; loser not a member */
Smoke transcript (the load-bearing portion of the result log after boot 1):
ChatApp:test: EVENT-ROLLBACK OK
ChatApp:test: COHERENCE-SERIALIZE OK
ChatApp:test: LOST-UPDATE OK
COHERENCE-SERIALIZE OK writes only when exactly one of the two claims returned 1, the room holds exactly one member, and the losing user is not a member. The assertion is inside catch{}; both-or-neither winning, a wrong member count, or the loser still joined each log a distinct FAIL.
What the evidence establishes:
- Two concurrent mutations of the same bounded resource serialize at the atomic-task boundary: exactly one commits, the other is a clean refusal, with no observable interleaving.
- The loser observes the winner's committed state: its plain read at write time reflects the post-commit membership, so it yields without any lock, version check, or retry.
- The serialization is the runtime's, not the application's:
claim_slotcarries no coordination code -- it reads current state and writes, and the single-threaded atomic-task model supplies the ordering.
What the evidence does not establish:
- Agent-identity-mediated conflict. The contenders here are chat users driven by the boot-time test driver; an agent-identity wrapper associating each contender with a runtime user-object and surfacing the post-conflict state through an inter-agent protocol is a downstream concern for future agent-identity work. This phase demonstrates the runtime serialization that such a wrapper exposes.
- Cross-instance contention. The demonstration is single-coherence-domain; contention crossing a process or machine boundary is outside the platform's primitive and not exercised.
- Preemptive interleaving. DGD tasks run to completion atomically; the demonstration does not (and on this platform cannot) show a partially-applied claim interrupted mid-write, because that partial-state window is exactly what the atomic-task model removes.
What Would Revise It
- A demonstration that both contenders committed (the room exceeding capacity, or both users joined) would falsify the exactly-one-commits claim; the current evidence shows exactly one winner and the room at capacity.
- A case where the loser observed stale (pre-commit) state at write time would contradict the coherent-read claim; the current evidence shows the loser refused because its read reflected the winner's commit.
- A DGD or eOS-kernellib change to atomic-task scheduling or property-write commit semantics would invalidate the snapshot; the claim rests on DGD 1.7.9 plus the cited eOS-kernellib HEAD.
Sources
examples/chat-app/obj/room.c(eOS-kernellib) --set_capacity/query_capacity/claim_slot(the serialized current-read-at-write-time path) /claim_slot_stale(the contrast).examples/chat-app/sys/test.c(eOS-kernellib) -- the coherence-serialize phase: two users contend for a capacity-1 room.docs/chat-applications.md(eOS-kernellib) -- the "Multi-agent coherence" walkthrough; the coherence-serialize phase.- The result log written into the runtime staging tree's
usr/Chat/data/path -- carriesCOHERENCE-SERIALIZE OKafter a clean boot. - The chat-app smoke script and the instance config -- the three-boot regression harness and runtime config.
Relations
-
conforms_to::[[Observation Form Contract]]
- Carries
has_epistemic_status::[[Empirical Observation]], names the measurement (one three-boot smoke run; the coherence-serialize phase assertion), states the limits (runtime serialization, not agent-identity-mediated; single-coherence-domain; no preemptive interleaving on this platform), and lists concrete revision conditions.
- Carries
-
informs_downstream::[[Multiple Agents See Coherent State Without User-Land Coordination]]
- The Conviction holds that when two agents both read a value and both try to mutate it, the runtime serializes so exactly one succeeds and the other sees the post-update state and decides what to do next -- no eventual consistency, no leader election, no lock dance. This Observation is the positive evidence for the write-coherence half: two contending claims serialize, exactly one commits, and the loser yields on a plain read of the committed state.
-
composes_with::[[Agent Operations Commit Wholly or Roll Back Wholly]]
- The serialization happens at the atomic-operation boundary: each
claim_slotis an atomic envelope, and the runtime orders the envelopes so exactly one of the conflicting set commits. The atomic primitive is what makes "the winner committed; the loser now sees the post-winner state" a clean before-and-after pair with no observable middle.
- The serialization happens at the atomic-operation boundary: each
-
contrasts_with::[[A Lost Update Appears Only Without the Runtime's Serialization of Concurrent Writes]]
- The negative-case peer. This case shows that re-reading current state at write time (the
claim_slotpath) serializes the contenders; the negative shows that writing from a snapshot captured before the other's commit (theclaim_slot_stalepath) produces the lost update the coherent-state read removes. The two together bound the mechanism: coherence is the runtime's standing condition for reads at write time, and the lost update appears only when an application deliberately acts on state read before a concurrent commit.
- The negative-case peer. This case shows that re-reading current state at write time (the