wave-1 D3: stamp a per-assignment claim at pool-slot allocation #9

Closed
opened 2026-08-14 23:21:56 +00:00 by agent.odin · 2 comments
Owner

Campaign: Ting/Ting#18 (closed campaign; plan: Ting/Ting#18 (comment)) — item D3. Ruling R4 ratified 2026-08-15: scope per assignment.

Because drones are pool slots (Ting/Ting#2 invariant) reassigned across containers, and flake-ops#96's ACL paths key on sub (the SA UUID), a reassigned slot would inherit the previous occupant's drones/<sub>/* and reports/<sub>/* data. R4 rules: add a per-assignment claim segment at allocation time.

Work

Stamp the per-assignment claim in Vedanta's pool-checkout path (builds on the token-minting plumbing from wave-1 B5, and on the pool-manager work as it lands).

Acceptance

  • New claim present on reissue
  • flake-ops#96's path-inheritance risk closed (path shape coordinated with flake-ops wave-1 B3)

Depends on: wave-1 B5/D1.

Campaign: Ting/Ting#18 (closed campaign; plan: https://jo.et0.pw/Ting/Ting/issues/18#issuecomment-5392) — item D3. **Ruling R4 ratified** 2026-08-15: scope per assignment. Because drones are pool slots (Ting/Ting#2 invariant) reassigned across containers, and flake-ops#96's ACL paths key on `sub` (the SA UUID), a reassigned slot would inherit the previous occupant's `drones/<sub>/*` and `reports/<sub>/*` data. R4 rules: add a per-assignment claim segment at allocation time. ## Work Stamp the per-assignment claim in Vedanta's pool-checkout path (builds on the token-minting plumbing from wave-1 B5, and on the pool-manager work as it lands). ## Acceptance - [ ] New claim present on reissue - [ ] flake-ops#96's path-inheritance risk closed (path shape coordinated with flake-ops wave-1 B3) Depends on: wave-1 B5/D1.
Owner

Grooming state: Premise investigated, consumer built, producer confirmed as this repository's and unbuilt.
Evidence: R4 ratified per-assignment isolation, and flake-ops#96 comment 3012 plus flake-ops#178 name this issue as the claim producer.

The consumer now exists

flake-ops#471 builds the swarm secret space, and R4's segment is in the path from the first write rather than retrofitted after a leak: swarm/data/<swarm>/drones/<slot>/<assignment>/*, with reports carrying the same shape under a create-and-update-never-read boundary. The question this record asked — retire R4, or rebuild it — is answered by construction. Neither: it is honoured where the path is written, and what remains here is the producer that fills the segment.

F1 — assignment cannot be a claim, so it is not one

A kanidm claim map is valuesByGroup, so a claim carries only what the directory asserts about an account. Which occupancy of a pool slot is calling changes per allocation, and the only way to express that as a group is one group per assignment — the pool's churn leaking into the directory. The segment therefore reads custom_metadata on the slot's OpenBao entity alias, written out of band, which a login does not overwrite (metadata is claim-populated and rewritten on every login; custom_metadata is not).

So this record's own title is now slightly wrong: what Vedanta stamps is not a claim. It is alias custom metadata. The mechanism changed; the obligation did not.

F2 — the producer is Vedanta's, and this record is right about that

Recorded because a grooming pass got it wrong today and the next one should not. Ting/Ting#2 describes the pool manager as "a new, 100%-code service, parallel to the steward … explicitly NOT queen's responsibility and NOT Jostoph's either". That reads like a fourth party and is not: the ticket was written 2026-08-09, before the service had a name, and flake-ops#96 comment 3012 records both the naming and the division of labour in one breath — "Ting/Vedanta (the estate's minting service — I had been calling it 'Sevanta', which was my invention)" and "Vedanta mints and allocates; Jostoph rotates and disables." Allocation is checkout.

src/main.rs excluding worker- slots from the mint CLI is a scoping of the one-shot mint against Vedanta's own checkout/reissue path — not a handoff. That path is unbuilt, which is why the producer does not exist yet.

A trap worth recording separately

The delivered private contract already has an assignment_idQueenAuthorityRef in src/private_api.rs — meaning the queen's tenure assignment that authorized a request. One value, shared by every drone under a queen, so it cannot separate two occupants of one slot, which is this segment's entire job. Same word, different thing; a path built on it looks isolated and is not.

Frontier

Q1 — R4 delivery. Restated with the premise settled. R4 is not retired and needs no rebuilding as a contract: the consumer is written and reviewed. What this record now owns is one bounded act — write the assignment onto the slot's OpenBao entity alias at checkout — which sits inside Vedanta's unbuilt pool checkout/reissue path. Does #9 stay a Deliverable gated on that path, or does it fold into the checkout Session as one of its requirements?

➡️ Fold it in. The stamp is not separately deliverable: it has no caller until checkout exists, and a producer specified apart from the allocation that invokes it would be specified against a shape that does not exist yet. Carry it as a named requirement of the checkout work, with the path shape flake-ops#471 fixed as its acceptance.

Refinement, whichever way it goes, must restate this record around custom_metadata rather than a claim, and drop the stale "wave-1 D3 / B5" framing.

Evidence bound: declared trees at nixops4-providers@b9c119d, flake-ops@e4290ac, Ting/Vedanta@f09b6d2. No live OpenBao inspected; that custom_metadata survives a login writing metadata is the documented split and unverified against a running store.

<!-- larandar:groom:v1 --> **Grooming state:** Premise investigated, consumer built, producer confirmed as this repository's and unbuilt. **Evidence:** [R4](https://jo.et0.pw/Ting/Ting/issues/18#issuecomment-5392) ratified per-assignment isolation, and [flake-ops#96 comment 3012](https://jo.et0.pw/lar.ad/flake-ops/issues/96#issuecomment-3012) plus [flake-ops#178](https://jo.et0.pw/lar.ad/flake-ops/issues/178) name this issue as the claim producer. ### The consumer now exists [flake-ops#471](https://jo.et0.pw/lar.ad/flake-ops/pulls/471) builds the swarm secret space, and R4's segment is in the path from the first write rather than retrofitted after a leak: `swarm/data/<swarm>/drones/<slot>/<assignment>/*`, with reports carrying the same shape under a create-and-update-never-read boundary. The question this record asked — retire R4, or rebuild it — is answered by construction. Neither: it is honoured where the path is written, and what remains here is the producer that fills the segment. ### F1 — `assignment` cannot be a claim, so it is not one A kanidm claim map is `valuesByGroup`, so a claim carries only what the directory asserts about an account. Which occupancy of a pool slot is calling changes per allocation, and the only way to express that as a group is one group per assignment — the pool's churn leaking into the directory. The segment therefore reads **`custom_metadata`** on the slot's OpenBao entity alias, written out of band, which a login does not overwrite (`metadata` is claim-populated and rewritten on every login; `custom_metadata` is not). **So this record's own title is now slightly wrong**: what Vedanta stamps is not a *claim*. It is alias custom metadata. The mechanism changed; the obligation did not. ### F2 — the producer is Vedanta's, and this record is right about that Recorded because a grooming pass got it wrong today and the next one should not. [Ting/Ting#2](https://jo.et0.pw/Ting/Ting/issues/2) describes the pool manager as "a new, 100%-code service, parallel to the steward … explicitly NOT queen's responsibility and NOT Jostoph's either". That reads like a fourth party and is not: the ticket was written 2026-08-09, before the service had a name, and [flake-ops#96 comment 3012](https://jo.et0.pw/lar.ad/flake-ops/issues/96#issuecomment-3012) records both the naming and the division of labour in one breath — *"Ting/Vedanta (the estate's minting service — I had been calling it 'Sevanta', which was my invention)"* and *"Vedanta mints and allocates; Jostoph rotates and disables."* **Allocation is checkout.** `src/main.rs` excluding `worker-` slots from the mint CLI is a scoping of the one-shot mint against Vedanta's own checkout/reissue path — not a handoff. That path is unbuilt, which is why the producer does not exist yet. ### A trap worth recording separately The delivered private contract already has an `assignment_id` — `QueenAuthorityRef` in `src/private_api.rs` — meaning the **queen's tenure assignment** that authorized a request. One value, shared by every drone under a queen, so it cannot separate two occupants of one slot, which is this segment's entire job. Same word, different thing; a path built on it looks isolated and is not. ### Frontier **Q1 — R4 delivery. Restated with the premise settled.** R4 is not retired and needs no rebuilding as a contract: the consumer is written and reviewed. What this record now owns is one bounded act — **write the assignment onto the slot's OpenBao entity alias at checkout** — which sits inside Vedanta's unbuilt pool checkout/reissue path. Does #9 stay a Deliverable gated on that path, or does it fold into the checkout Session as one of its requirements? ➡️ Fold it in. The stamp is not separately deliverable: it has no caller until checkout exists, and a producer specified apart from the allocation that invokes it would be specified against a shape that does not exist yet. Carry it as a named requirement of the checkout work, with the path shape flake-ops#471 fixed as its acceptance. Refinement, whichever way it goes, must restate this record around `custom_metadata` rather than a claim, and drop the stale "wave-1 D3 / B5" framing. **Evidence bound:** declared trees at `nixops4-providers@b9c119d`, `flake-ops@e4290ac`, `Ting/Vedanta@f09b6d2`. No live OpenBao inspected; that `custom_metadata` survives a login writing `metadata` is the documented split and unverified against a running store.
Owner

Q1 has a concrete target now — 2026-09-03

The frontier entry above recommended folding this record into the checkout work. That work now exists: #31, the steady-state Session under OpenSpec 30, created after the freeholder ratified the two-Session split on Ting/Ting#2 Q3.

#31 carries R4 as a named requirement, listed under its Absorbs section, with the occupancy stamp as a task and flake-ops#471's path shape as its acceptance. Its Specification Delta states the obligation directly — "occupancy is what isolates, not the slot" — so R4 survives as a testable requirement rather than as a cross-reference.

Both corrections this record surfaced are carried there and in the package, so closing this loses neither: the value is alias custom_metadata rather than a claim, and the contract's existing assignment_id is the queen's tenure and cannot substitute.

Q1 is therefore ready to answer as a simple disposition: close this record as absorbed by #31, or keep it open as a pointer. ➡️ Close it — the requirement is now specified where it will be built, and a record whose whole content lives in another record's acceptance is one more thing to keep in step.

<!-- larandar:groom:v1 --> ## Q1 has a concrete target now — 2026-09-03 The frontier entry above recommended folding this record into the checkout work. That work now exists: [#31](https://jo.et0.pw/Ting/Vedanta/issues/31), the steady-state Session under [OpenSpec 30](https://jo.et0.pw/Ting/Vedanta/wiki/OpenSpec-30-agent-identity-pool-lifecycle), created after the freeholder ratified the two-Session split on [Ting/Ting#2](https://jo.et0.pw/Ting/Ting/issues/2#issuecomment-15365) Q3. **#31 carries R4 as a named requirement**, listed under its *Absorbs* section, with the occupancy stamp as a task and [flake-ops#471](https://jo.et0.pw/lar.ad/flake-ops/pulls/471)'s path shape as its acceptance. Its Specification Delta states the obligation directly — *"occupancy is what isolates, not the slot"* — so R4 survives as a testable requirement rather than as a cross-reference. Both corrections this record surfaced are carried there and in the package, so closing this loses neither: the value is alias `custom_metadata` rather than a claim, and the contract's existing `assignment_id` is the queen's tenure and cannot substitute. **Q1 is therefore ready to answer as a simple disposition:** close this record as absorbed by #31, or keep it open as a pointer. ➡️ Close it — the requirement is now specified where it will be built, and a record whose whole content lives in another record's acceptance is one more thing to keep in step.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
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#9
No description provided.