Skip to content

Commit b98fbe9

Browse files
committed
docs(stovepipe): clarify validation lookup storage
1 parent 6ee4425 commit b98fbe9

1 file changed

Lines changed: 19 additions & 5 deletions

File tree

doc/rfc/stovepipe/get-validation-api.md

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,11 @@ The existing degree scale answers “how broken is this scope”: `0.0` is fully
6969

7070
## Selection and Projection
7171

72-
`queue` and `change_uri` identify one request through the existing request-URI mapping. Permanent ingest deduplication makes this cardinality one request per `(queue, change_uri)`. The controller loads that request, its project manifest, and its whole-repository fact.
72+
`queue` and `change_uri` identify one request through the existing request-URI mapping. Permanent ingest deduplication makes this cardinality one request per `(queue, change_uri)`. The controller binds storage to the queue, reads `request_uri` by its `(queue, URI)` primary key, then reads `request` by its `(queue, request ID)` primary key. It does not scan or query the Request table by an attribute.
73+
74+
The controller verifies that the loaded Request has the requested queue and URI before loading its project manifest and whole-repository fact. Request URI is immutable once the request and mapping are created; storage updates must not permit the two records to diverge.
75+
76+
Ingest claims `request_uri` before creating the Request so concurrent ingests converge without a cross-record transaction. A lookup racing that sequence can therefore observe a mapping whose Request is not present yet. `GetValidation` treats that condition as unavailable and retryable rather than not found or immediate corruption. Repeated occurrences are surfaced through consistency metrics and require repair; a mapping to a Request with a different queue or URI is an internal consistency error.
7377

7478
Lifecycle is a coarse, stable API projection rather than a duplicate of every internal request state:
7579

@@ -90,7 +94,9 @@ The whole-repository fact is independent of project facts. The controller does n
9094

9195
## Project Manifest and Completion
9296

93-
Project analysis creates one immutable, request-owned manifest containing unique project IDs in ascending bytewise order. It persists the manifest before recording project facts. The manifest is fetched by request ID, so it remains a get-by-key contract and serves as the index for exact `ValidationFactStore.Get(changeURI, project)` reads; `ValidationFactStore` does not gain `ListByURI` or another secondary-index query.
97+
Project analysis creates one immutable, request-owned logical manifest containing unique project IDs in ascending bytewise order. It persists the manifest before recording project facts. The manifest is addressed by request ID and serves as the index for exact `ValidationFactStore.Get(changeURI, project)` reads; `ValidationFactStore` does not gain `ListByURI` or another secondary-index query.
98+
99+
The storage representation does not require the entire list to fit in one row. A backend may keep a root record keyed by request ID that names immutable deterministic chunks and their ordered boundaries. This preserves exact get-by-key operations while allowing page reads to avoid loading a service list that was already too large for an event payload.
94100

95101
The project list used to execute validation is the list returned by this API. No separate response-only service list is maintained. A retry that proposes a different list for the same request is an invariant violation rather than an in-place replacement.
96102

@@ -102,16 +108,24 @@ Request terminal state and result completion are intentionally distinct. The cur
102108

103109
Pagination follows the same public convention as Stovepipe request history and SubmitQueue queue listing: an empty token selects the first page, zero page size selects the server default, and `next_page_token` is empty on the final page. The initial default is 50 projects and the maximum is 200.
104110

105-
The controller slices the immutable manifest in `project ASC` order and inspects one project beyond the effective page size before issuing a continuation token. The opaque, versioned token carries the last returned project ID and is bound to the queue, change URI, resolved request ID, and all-project selector mode. Decoding produces a typed exclusive project cursor; neither the manifest store nor the fact store parses public tokens. Page size is not bound, so callers may change it between pages. A malformed token, unsupported version, or token reused for another query is invalid.
111+
The controller reads the immutable manifest in `project ASC` order and inspects one project beyond the effective page size before issuing a continuation token. The opaque, versioned token represents the exclusive position after the last returned project and is bound to the queue, change URI, resolved request ID, and all-project selector mode. Decoding produces a typed manifest cursor; neither the manifest store nor the fact store parses public tokens. The cursor may include a deterministic chunk position in addition to the last project ID without exposing either representation to clients. Page size is not bound, so callers may change it between pages. A malformed token, unsupported version, or token reused for another query is invalid.
112+
113+
After reading one manifest page, the controller loads its project facts through bounded parallel exact reads. The caller owns that concurrency; the fact-store contract remains a portable single-key `Get` rather than requiring SQL `IN`, batch atomicity, or a secondary index.
106114

107115
The manifest is immutable, so pages neither skip nor duplicate project identities. Facts are create-only and may appear between reads: an incomplete traversal can observe more results on later pages, while a new traversal reflects all facts available at its start. `project_results_complete` is the durable signal that no planned result remains absent; it is not computed by counting the current page.
108116

117+
## Storage Identity and Evolution
118+
119+
URI, request ID, queue, and project identity use byte-exact comparison. MySQL schemas declare an explicit binary collation for these key columns rather than inherit the server's case- or accent-insensitive default. API validation and storage schemas use the same explicit length limits, so an oversized selector is rejected before lookup rather than failing or truncating inside a backend.
120+
121+
The insert-once request-URI mapping intentionally selects only one request today. Supporting revalidation of the same URI requires a separate design that widens validation-fact identity and changes the mapping into an explicitly versioned authoritative-attempt pointer. It must not silently turn this method into an ambiguous multi-request lookup.
122+
109123
## Errors and Authorization
110124

111125
- Empty queue or change URI is invalid.
112126
- An empty explicit project, invalid page size, page fields used with a project selector, or invalid token is invalid.
113127
- An unknown queue-scoped change URI or a project absent from its manifest is not found.
114-
- A dangling URI mapping, missing manifest for a request that should have been planned, a completion marker with any missing fact, or a fact attributed to another request is an internal consistency error.
128+
- A URI mapping whose Request is not yet visible is unavailable and retryable; a mismatched Request, missing manifest for a request that should have been planned, a completion marker with any missing fact, or a fact attributed to another request is an internal consistency error.
115129
- Retryable storage failures are unavailable; context cancellation and deadline errors retain their canonical codes.
116130

117131
Authorization follows the queue policy used by other Stovepipe reads. Both the request-URI mapping and every loaded entity remain scoped to the supplied queue.
@@ -120,4 +134,4 @@ Authorization follows the queue policy used by other Stovepipe reads. Both the r
120134

121135
The endpoint is enabled only after project-manifest persistence, project-fact recording, the completion marker, and `end_validation` publish ordering are deployed. This avoids exposing a nominal all-project response that silently omits the service list.
122136

123-
Contract and controller tests cover lifecycle projection, result presence at degree zero, whole-repository and project independence, exact project selection, incomplete and complete manifests, empty manifests, first/middle/final pages, token query binding, stable ordering, cross-queue isolation, dangling records, and publish-after-completion ordering.
137+
Contract and controller tests cover lifecycle projection, result presence at degree zero, whole-repository and project independence, exact project selection, incomplete and complete manifests, empty and chunked manifests, first/middle/final pages, token query binding, stable ordering, cross-queue isolation, mapping-before-Request retries, mismatched identities, byte-distinct keys, storage limits, and publish-after-completion ordering.

0 commit comments

Comments
 (0)