Skip to content

fix(#856): the analytics family of draw sites - #1288

Merged
scttfrdmn merged 2 commits into
mainfrom
ids-tier5-analytics
Sep 26, 2026
Merged

scttfrdmn merged 2 commits into
mainfrom
ids-tier5-analytics

Conversation

@scttfrdmn

Copy link
Copy Markdown
Owner

Tier 5 of #856: Athena, Redshift Data, Glue, Timestream, OpenSearch and QuickSight.

Seven generators move onto IDMint — an Athena query execution ID, a Redshift Data statement ID, a
Glue job-run ID, a Timestream QueryId, an OpenSearch document _id and _scroll_id, and a
QuickSight ingestion ID and response RequestId. Every rendering is byte-for-byte the one
crypto/rand produced, so an identifier a previous substrate recorded is still the shape this one
mints.

What this family adds is the shape of the call the identifier gates. An analytics identifier
names a submission rather than a resource, so unlike a bucket or a Glue job there is no
caller-chosen name to fall back on: GetQueryExecution, GetQueryResults and StopQueryExecution
all key on the one ID StartQueryExecution returned, and a re-minted one answered every recorded
poll with InvalidRequestException against a query the recording had just created. Redshift Data
breaks the same way with ResourceNotFoundException, Glue with EntityNotFoundException, an
OpenSearch document read with a 404 and a scroll continuation with
search_context_missing_exception. Timestream is the exception and is in the stream for the other
half of the property: its QueryId reaches no later call, so a fresh draw there costs a body
difference rather than a refusal.

Non-vacuity. Reverting the Athena minter alone produces 38 differences and two refused reads out
of the 19-request stream, which is the check tier 4 ran with generateVersionID.

IDMint.Base64URL is new, for the one identifier that travels in a URL path: an OpenSearch
document ID is the path of every later GET, PUT and DELETE of that document, so its alphabet is
- and _ rather than + and /. Neither the document nor the scroll shape is published by AWS —
they are the domain's own REST API, not the es control plane — so substrate's sixteen characters
are a convention it keeps rather than a constraint it meets.

A second cross-service borrow, fixed. CreateDataSet drew its SPICE ingestion ID from the
generator that mints the RequestId every QuickSight response carries. An ingestion ID is a handle a
recorded DescribeIngestion URL contains, where a request ID is observed once and never sent back,
so one function serving both meant a change to how a request ID renders would have moved the
identifier a recorded path depends on. Same split #856 made between ACM and API Gateway's API keys.

#671 applied five more times. A Timestream QueryId is hex where a Redshift Data statement ID is
a dashed UUID, and the difference is the published model: API_query_Query constrains QueryId to
[a-zA-Z0-9]+, which excludes the hyphen, while API_ExecuteStatement documents Id as a UUID and
publishes the dashed pattern. Neither constrains a position, so both are indifferent to the RFC 4122
version and variant bits. Athena's QueryExecutionId publishes \S+, which decides nothing, and
Glue's JobRunId admits nearly any text, so the jr_ prefix stays as the service's own convention.

11 draw sites remain on crypto/rand.

Verification

make lint (0 issues), make test (race, full suite green), and
make docs-reference-check docs-versions version-check discarded-unmarshal-check wire-bookkeeping-check with the ratchet still at 330. Patch coverage is 20/20 changed statements,
intersected against git diff -U0 main.

Refs #856.

Seven generators across six services move onto IDMint: an Athena query execution
ID, a Redshift Data statement ID, a Glue job-run ID, a Timestream QueryId, an
OpenSearch document _id and _scroll_id, and a QuickSight ingestion ID and
response RequestId. Every rendering is byte-for-byte what crypto/rand produced.

What this family adds is the shape of the call the identifier gates. An analytics
identifier names a submission rather than a resource, so there is no
caller-chosen name to fall back on: GetQueryExecution, GetQueryResults and
StopQueryExecution all key on the one ID StartQueryExecution returned, and a
re-minted one answered every recorded poll with InvalidRequestException against a
query the recording had just created. Redshift Data breaks the same way with
ResourceNotFoundException, Glue with EntityNotFoundException, an OpenSearch
document read with a 404 and a scroll continuation with
search_context_missing_exception. Reverting the Athena minter alone to confirm
the replay assertion is not vacuous produces 38 differences and two refused reads
out of a 19-request stream.

Timestream is the exception and is in the stream for the other half of the
property: its QueryId reaches no later call, so a fresh draw there costs a body
difference rather than a refusal.

IDMint.Base64URL is new, for the one identifier that travels in a URL path: an
OpenSearch document id is the path of every later GET, PUT and DELETE of that
document, so its alphabet is - and _ rather than + and /.

A QuickSight ingestion ID was drawn from the generator that mints the RequestId
every response carries - the second instance of the cross-service borrow the
ACM/API Gateway split fixed. An ingestion ID is a handle a recorded
DescribeIngestion URL contains where a request ID is never sent back, so one
function serving both meant a change to how a request ID renders would have moved
the identifier a recorded path depends on.

A Timestream QueryId is hex where a Redshift Data statement ID is a dashed UUID,
and the difference is the published model rather than a preference:
API_query_Query constrains QueryId to [a-zA-Z0-9]+, which excludes the hyphen.
Neither pattern constrains a position, so both are indifferent to the RFC 4122
version and variant bits, which is why deriving them preserved each rendering
instead of quietly setting two nibbles (#671).

11 draw sites remain on crypto/rand.
The scroll refusal is search_context_missing_exception rather than an empty
page, and "the same sixteen derived bytes" read as if Timestream and Redshift
Data rendered one value two ways rather than each rendering its own.
@codecov

codecov Bot commented Sep 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@scttfrdmn
scttfrdmn merged commit 282f5fd into main Sep 26, 2026
18 checks passed
@scttfrdmn
scttfrdmn deleted the ids-tier5-analytics branch September 26, 2026 14:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant