You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: doc/rfc/stovepipe/request-history-api.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
3
3
## Summary
4
4
5
-
Stovepipe exposes retained request history through queue-scoped point lookups by request ID and exact URI. Both selectors return the same ordered, cursor-paginated history.
5
+
Stovepipe exposes retained request history through queue-scoped point lookups by request ID and exact URI. URI lookup resolves the newest authoritative request for that commit. Both selectors return the same ordered, cursor-paginated history.
6
6
7
7
The API reads the append-only model defined by [Stovepipe Request Event History](request-event-history.md) directly. It does not replay history into current state or introduce a second persisted history projection. Current commit status remains a separate read concern derived from operational entities rather than request history.
8
8
@@ -15,7 +15,7 @@ The API supports the same selectors as [SubmitQueue Gateway Request History APIs
15
15
16
16
Both methods require a queue because Stovepipe storage and authorization are queue-scoped. A selector belonging to another queue is not found rather than resolved across shards.
17
17
18
-
SubmitQueue's URI method returns several histories because the same change may be submitted repeatedly. Stovepipe ingest permanently deduplicates `(queue, URI)` to one request, so its URI method returns exactly one history. Relaxing that invariant later would require a new plural method rather than changing this method's cardinality in place.
18
+
SubmitQueue's URI method returns several histories because the same change may be submitted repeatedly. Stovepipe's URI method instead returns exactly one history: the request selected by the queue's durable authoritative mapping for that URI. The current insert-once mapping selects the only request; future revalidation advances the mapping to the newest accepted request without changing this API's cardinality. Older attempts remain addressable by request ID, and discovering every attempt can be added later as a separate list API.
19
19
20
20
## Representative Contract
21
21
@@ -83,9 +83,9 @@ Entry IDs and page tokens are opaque. Clients may compare entry IDs and pass pag
83
83
84
84
Request-ID lookup validates the queue, ID, page size, and optional token; loads the queue's `Request` to validate the selector and supply immutable wrapper context; and lists one bounded page of its `RequestHistoryStore` entries.
85
85
86
-
URI lookup resolves the existing `RequestURIStore` primary key and delegates to the same paginated request-ID path. It does not scan history by an entry's `URI` field and requires no new storage index. A missing mapping is not found; a mapping whose Request is missing is an internal consistency error.
86
+
URI lookup resolves the authoritative request ID from the existing `RequestURIStore` primary key and delegates to the same paginated request-ID path. Authority is explicit stored state rather than a timestamp comparison. The current mapping is insert-once; supporting revalidation later requires a versioned conditional update that advances it only after the newer Request is durable. It does not scan history by an entry's `URI` field and requires no new storage index. A missing mapping is not found; a mapping whose Request is missing is an internal consistency error.
87
87
88
-
The request-URI mapping must be repaired and retained with its Request and history. Otherwise URI lookup could lose coverage while request-ID lookup still succeeds. The loaded Request supplies URI, build strategy, and base URI once on the `RequestHistory` wrapper; these immutable values are not duplicated on every entry.
88
+
The request-URI mapping must be repaired and retained with its Request and history. Otherwise URI lookup could lose coverage while request-ID lookup still succeeds. Once a newer request becomes authoritative, a later failure does not fall back to an older successful attempt. The loaded Request supplies URI, build strategy, and base URI once on the `RequestHistory` wrapper; these immutable values are not duplicated on every entry.
89
89
90
90
## Public Projection
91
91
@@ -133,7 +133,7 @@ Request-ID and URI lookup return the same stored entries, ordering, and paginati
133
133
134
134
The public shape follows SubmitQueue's queue `List` convention: an empty token selects the first page, zero page size selects the server default, and the response returns an opaque `next_page_token` that is empty on the last page. The initial default is 50 entries and the maximum is 200. The controller requests one more entry than the effective page size, returns only the requested page, and issues a token only when the extra entry proves that another page exists.
135
135
136
-
Pagination uses the immutable keyset `(timestamp_ms ASC, entry_id ASC)`. The versioned token represents the last returned ordering tuple and is bound to the original selector kind and value, queue, and resolved request ID. The binding does not prescribe whether those values are embedded or fingerprinted in the token. Reusing a token with another method, queue, request ID, or URI is invalid. Page size is not bound into the token, so a caller may change it between pages within the server maximum. The controller decodes the public token into the storage contract's typed exclusive cursor; storage implementations never parse wire tokens.
136
+
Pagination uses the immutable keyset `(timestamp_ms ASC, entry_id ASC)`. The versioned token represents the last returned ordering tuple and is bound to the original selector kind and value, queue, and resolved request ID. Binding URI pagination to the resolved request ID keeps an in-progress traversal on the same history if a newer request becomes authoritative between pages. The binding does not prescribe whether those values are embedded or fingerprinted in the token. Reusing a token with another method, queue, request ID, or URI is invalid. Page size is not bound into the token, so a caller may change it between pages within the server maximum. The controller decodes the public token into the storage contract's typed exclusive cursor; storage implementations never parse wire tokens.
137
137
138
138
Tokens are traversal cursors rather than snapshot handles. A new occurrence ordered after the cursor can appear on a later page. A repair that inserts an older occurrence at or before an already-consumed cursor may be observed only by starting a fresh traversal. This is the paginated form of the API's existing eventual-consistency guarantee: a token prevents duplicates from stable retained entries but does not freeze history while pipeline writers and repair are active.
139
139
@@ -177,7 +177,7 @@ Rejected because it would add query-by-attribute capability to `RequestHistorySt
177
177
178
178
### Return several histories by URI
179
179
180
-
Rejected while ingest enforces one request per `(queue, URI)`. A repeated field would imply cardinality the domain does not permit and make a future deduplication change silently alter existing responses.
180
+
Rejected because URI lookup answers which request is authoritative for the commit. Returning every attempt would mix audit discovery with one request's independently paginated history. A future attempt-listing API can return request IDs without changing this point lookup.
0 commit comments