G A-25: the first chunk of a put session carries the put's description

Builds: design 47 G A-25, §518
Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
2026-11-11 21:55:33 +01:00
parent 3aec0b1335
commit 54c0c3bf22
4 changed files with 14 additions and 6 deletions
+3 -1
View File
@@ -105,7 +105,7 @@ const ChunkBytes = 512 << 10
// ObjectsPutChunkRequest is one chunk of a put session (design 47 G §518, A-21): the object `name` in the store `objects`,
// `call` the bundle's id for this put, `seq` from 1 and one more each chunk, `last` true on the last chunk alone, and the
// chunk's bytes.
// chunk's bytes; the first chunk also carries the put's `description` (A-25).
type ObjectsPutChunkRequest struct {
Objects string `json:"objects"`
Name string `json:"name"`
@@ -113,6 +113,8 @@ type ObjectsPutChunkRequest struct {
Seq uint32 `json:"seq"`
Last bool `json:"last,omitempty"`
Data []byte `json:"data"`
// Description is the put's, carried on the first chunk alone (design 47 G A-25).
Description string `json:"description,omitempty"`
}
// ObjectsChunkTaken is the answer to a chunk that is not the last: the sequence taken, or the reason it was not.
+1 -1
View File
@@ -36,7 +36,7 @@ func call[T any](method string, params any) (T, error) {
// object, never split over several.
func (o Objects) Put(name string, data []byte, description string) (buscalls.ObjectInfo, error) {
if len(data) > buscalls.ChunkBytes {
return o.putSession(name, data)
return o.putSession(name, data, description)
}
return call[buscalls.ObjectInfo](buscalls.ObjectsPut, buscalls.ObjectsPutRequest{Objects: o.local, Name: name,
Data: data, Description: description})
+6 -3
View File
@@ -25,7 +25,7 @@ func callID() string {
// put sends data as a put session: chunks of buscalls.ChunkBytes in order, each answered before the next is sent, the
// answer to the last being the put's.
func (o Objects) putSession(name string, data []byte) (buscalls.ObjectInfo, error) {
func (o Objects) putSession(name string, data []byte, description string) (buscalls.ObjectInfo, error) {
if err := stdio.RequireCapability(stdio.CapPutSessions); err != nil {
return buscalls.ObjectInfo{}, fmt.Errorf("putting %s, larger than one call carries: %w", name, err)
}
@@ -33,8 +33,11 @@ func (o Objects) putSession(name string, data []byte) (buscalls.ObjectInfo, erro
for seq, at := uint32(1), 0; ; seq++ {
end := min(at+buscalls.ChunkBytes, len(data))
last := end == len(data)
raw, err := stdio.BusState(buscalls.ObjectsPutChunk, buscalls.ObjectsPutChunkRequest{Objects: o.local, Name: name, Call: id,
Seq: seq, Last: last, Data: data[at:end]})
req := buscalls.ObjectsPutChunkRequest{Objects: o.local, Name: name, Call: id, Seq: seq, Last: last, Data: data[at:end]}
if seq == 1 {
req.Description = description // the first chunk carries it (design 47 G A-25)
}
raw, err := stdio.BusState(buscalls.ObjectsPutChunk, req)
if err != nil {
return buscalls.ObjectInfo{}, fmt.Errorf("putting %s, chunk %d: %w", name, seq, err)
}
+4 -1
View File
@@ -74,7 +74,7 @@ func TestAValueLargerThanOneChunkIsPutAndGotBySession(t *testing.T) {
var tampered bool
serveRuntime(t, func() {
o := ObjectsOf("incoming")
_, putErr = o.Put("big", value, "")
_, putErr = o.Put("big", value, "a big one")
d, err := o.Get("big")
gotValue, getErr = d.Data, err
tampered = true
@@ -91,6 +91,9 @@ func TestAValueLargerThanOneChunkIsPutAndGotBySession(t *testing.T) {
raw, _ := json.Marshal(p["data"])
var b []byte
_ = json.Unmarshal(raw, &b)
if (p["description"] == "a big one") != (p["seq"].(float64) == 1) {
t.Errorf("chunk %v carries the description %v: the first chunk alone does", p["seq"], p["description"])
}
stored = append(stored, b...)
seqs = append(seqs, uint32(p["seq"].(float64)))
if p["last"] == true {