Skip to content

feat(acceptance): nightly full suite in 8 groups and its regressions (#2221) - #2235

Merged
cjimti merged 1 commit into
mainfrom
feat/2221-full-acceptance-suite
Oct 20, 2026
Merged

cjimti merged 1 commit into
mainfrom
feat/2221-full-acceptance-suite

Conversation

@cjimti

@cjimti cjimti commented Oct 20, 2026

Copy link
Copy Markdown
Member

Description

Changes platform_info (pkg/platform/info_tool.go), the memory and call index vector writes, save_asset, the index job claim (pkg/indexjobs), the catalog scan loop, the upstream OAuth token lifetime (internal/upstreamauth, new internal/upstreamauth/tokenexpiry, new key oauth_token_lifetime), the tile worker's own-file reads, .github/workflows/e2e-nightly.yml, the Makefile and scripts/acceptance-env.py; four tickets, the whole of epic #2221, and eleven product defects the full acceptance runs found:

  1. platform_info fails the output schema clients cached before v1.146 #2216 platform_info: features reports query_enrichment and storage_enrichment again, always false. Releases up to v1.145.0 advertised both as required in the output schema, and a client holding that cached schema refused every platform_info result. test/acceptance/testdata/issue_2216_platform_info_v1.145.0.json is the v1.145.0 schema, and the criterion validates a live result against it.
  2. Embedding a memory record restarts its archive retention #2217 memory retention: embedding a memory record (internal/platform/memoryindex, and internal/platform/callindex for call records) and the recall check (pkg/toolkits/memory/recall_settle.go, through the new RecordUpdate.KeepUpdatedAt) no longer set updated_at, so neither restarts an archived record's retention clock.
  3. Run the full acceptance suite nightly and before tags; fix 17 stale criteria #2218 the full suite on a schedule:
    • E2E Nightly: the full acceptance suite runs in eight parallel jobs, each its own dev stack, split by ticket number (ACCEPTANCE_SHARD=i/N, scripts/acceptance-env.py flags dev --shard i/N), plus the worker-off and clickstack environments. Each job has a 100-minute limit and a 75-minute suite timeout; the browser suite runs in group 1 only. TestEveryAcceptanceEnvironmentRunsNightly and TestAcceptanceShardsCoverEveryTicketOnce (test/gates/acceptance_env_test.go) hold the workflow to the ticket list: every dev group 1/N..N/N present, every ticket in exactly one group.
    • make verify-release is verify codeql mutate acceptance-release-check: it requires a recorded passing run for each ticket changed since the last tag, and no longer runs the whole suite. TestVerifyReleaseRunsInOneInvocation pins that. ACCEPTANCE_TIMEOUT is 240m for a full local run and 40m with ISSUE.
    • Stale criteria: 17 criteria whose product had moved on are brought up to date, among 34 acceptance files changed in all; the full list is in the diff under test/acceptance/.
  4. Acceptance criteria that cannot run on the make dev stack run nowhere #2219 criteria needing another stack: criteria that need services make dev does not start are listed in test/acceptance/environments.txt with their environment, skipped by the dev run, and run in their own nightly jobs (scripts/acceptance-services.sh, ACCEPTANCE_ENV in scripts/release-acceptance.sh). Dev Keycloak is 26.7.5 (dev/docker-compose.yml), which feat(upstream auth): first-class Google service account credentials (accept the JSON key file, put scopes in the assertion, optional sub) #2061's jwt_bearer criteria need. Those criteria, the UI mock and its tests use neutral Google service-account names (sheets, drive, bigquery); GoogleServiceAccountFields.tsx's scope example is spreadsheets.readonly.

Defects the full runs found, fixed here

  1. save_asset recorded an asset's references after its first version (pkg/toolkits/portal/toolkit.go). The version is what makes the asset owed a tile, so the tile worker could draw the page before its referenced fonts and images were granted, and the tile was drawn with them missing. References are now recorded between the asset insert and the first version. TestSaveRecordsReferencesBeforeTheFirstVersion fails without the change. The same race on manage_asset update and patch cannot be fixed by reordering; it is fix(portal): a tile can be drawn before an update's new references are granted #2234.
  2. The index queue served one kind's backlog before every other kind (pkg/indexjobs/store_postgres.go). A backlog of 6,143 unembedded call records held a changed dataset description out of search for minutes. Writes and operator retries still go ahead of reconciler jobs; within each, a claimer now takes the next kind after the one it last claimed (ORDER BY (trigger_kind = 'reconciler'), (source_kind <= $last), source_kind, next_run_at, id). TestClaim_RealDB_KindsTakeTurns and TestClaim_RealDB_AHeldCandidateIsSkipped cover it. The search criterion went from timing out at 3 minutes to passing in 10 seconds.
  3. A catalog "Scan now" made while another replica was scanning waited for the next one-minute poll (internal/platform/catalogscan/loop.go). The replica holding the lock now checks for requests again before releasing it and serves any made during its scan. TestLockedScanServesARequestMadeDuringTheScan and TestLockedScanReportsALaterPassFailing cover it.
  4. A token response with no expires_in was reused for a fixed 15 minutes. The new connection key oauth_token_lifetime (a duration string or seconds; 15m by default; negative refused) sets that window per api and graphql connection, and both kinds carry it through their own OAuth2Config copies (TestParseConfig_OAuthTokenLifetimeRoundTrips). The bounding moved to internal/upstreamauth/tokenexpiry to keep internal/upstreamauth within its size budget. This makes the window an operator setting, which fix(upstream auth): client_credentials token with no expires_in is reused forever #1737 had decided against. fix(upstream auth): client_credentials token with no expires_in is reused forever #1737's refetch criterion now waits 38 seconds instead of 15 minutes and sends the key in both forms.
  5. A referenced file the platform was too slow to serve was stored on the tile as missing. An in-process read that runs out of time now answers 503 (internal/inproc), the renderer counts it as the page's own failure when subresources are required (internal/headless/intercept.go), and the tile worker retries the tile. It is 503 rather than 504 because the CDN-status gate refuses 502 and 504.
  6. Provenance missed a cited call another replica had not yet flushed. resolveCited reads again before recording the capture without it (internal/platform/provenance).
  7. The api gateway's call timeout ignored the request context and is now derived from req.Context().
  8. The maps index read its settings once. It re-reads them and retries per claim (internal/maps).
  9. A Trino connection saved on one replica was unknown to the other until its reload notice arrived. The Trino kind now reads the connection store for a connection it has not heard of (pkg/toolkits/trino/catchup.go, internal/platform/trinowiring).
  10. indexjob_jobs_total series appeared only after their first job and now start at zero for every registered kind, trigger and outcome.
  11. Admin Get Persona answered from the replica's registry, which can trail a save made through another replica. It now reads the store first (pkg/admin/persona_handler.go). A script test also replays the register check its run recorded (internal/platform/scriptrun/host.go).

Also:

  • dev/seed.sql points acme-warehouse at the local mock. The old host did not resolve, so the Trino driver retried for two minutes on every catalog scan.
  • The import ratchet gains internal/upstreamauth -> internal/upstreamauth/tokenexpiry.
  • Docs: docs/server/data-retention.md, configuration.md, asset-references.md, api-gateway.md (oauth_token_lifetime), admin-api.md, observability.md, the other pages in the diff, README.md, CLAUDE.md, llms.txt and llms-full.txt.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Test improvement (new or updated tests)
  • Documentation update
  • Stability/performance improvement

Related Issues

Closes #2216
Closes #2217
Closes #2218
Closes #2219
Closes #2221

Filed from this work: #2232 (real-clock waits left in the suite), #2233 (run criteria in parallel), #2234 (the tile race on manage_asset update/patch), #2224, #2230, #2231.

Readers of this state

  • GET /api/v1/admin/personas/{name} returns the same shape, read from the store first. The portal persona editor reads it unchanged.
  • Connection config gains oauth_token_lifetime on api and graphql connections. GET /api/v1/admin/connection-instances/{kind}/{name} returns it as stored. The connection forms do not show it yet; it is set through the admin API.
  • platform_info's features gains query_enrichment and storage_enrichment, always false. Read by clients holding the v1.145.0 output schema and by the platform_info fails the output schema clients cached before v1.146 #2216 criterion.
  • internal/apidocs/swagger.json and the ui/src types are unchanged. The only ui/src changes are the neutral names in the Google service-account mock, tests and scope example.

Testing

  • Acceptance through the real surface on the local dev stack (two replicas behind the proxy), run per ticket after the last change to each. Every criterion passed: 1625 (3/3), 1737 (4/4), 1918 (5/5), 1919 (2/2), 2062 (2/2, three runs in a row), 2111 (7/7), 2216 (1/1), 2218 (2/2). Transcripts and records are in build/<n>/acceptance.md and acceptance.jsonl. make acceptance-check confirms every changed acceptance file's criteria passed in their recorded run.

  • Full-suite runs of all 296 tickets on this branch found the defects above.

  • Real-Postgres: the kind rotation and held-candidate claims, the memory recall check keeping updated_at, and the SQL statement gate.

  • The eight-group nightly is checked by the gate tests above but has not yet run on GitHub's runners; its first run is the next scheduled or dispatched E2E Nightly.

  • make verify passed: the full Go race and coverage run (total 93.9%, patch 98.8%), the schedule lane, the real-database lane, the full vitest suite (3,231) and Playwright (296).

  • Ran make test locally

  • Tested manually

  • Added new tests for changes (if applicable)

Checklist

  • My code follows the project's style guidelines (make lint)
  • I have read CONTRIBUTING.md
  • I have updated documentation if needed
  • This PR is focused and does not include unrelated changes

…2221)

Changes platform_info (pkg/platform info_tool.go), the memory and call index vector writes, save_asset, the index job claim (pkg/indexjobs), the catalog scan loop, the upstream OAuth token lifetime (internal/upstreamauth, new tokenexpiry package, oauth_token_lifetime key), the tile worker's own-file reads, .github/workflows/e2e-nightly.yml, the Makefile and scripts/acceptance-env.py; four tickets, the whole of epic #2221:

1. #2216 platform_info: features reports query_enrichment and storage_enrichment again (always false), so a client holding the output schema releases up to v1.145.0 advertised accepts the result; the past output schemas test data holds it.
2. #2217 memory retention: embedding a memory record, and the recall check, no longer set updated_at (RecordUpdate.KeepUpdatedAt), so neither restarts an archived record's retention.
3. #2218 the full acceptance suite runs in the E2E Nightly in eight groups by ticket number (ACCEPTANCE_SHARD=i/N, scripts/acceptance-env.py --shard), plus the worker-off and clickstack environments; make verify-release no longer runs the suite and keeps acceptance-release-check. 17 stale criteria were brought up to date, and the full runs found these product defects, fixed here:
   - save_asset recorded references after the first version, so the tile worker could draw the page before its referenced files were granted;
   - the index queue served one kind's backlog before every other kind's jobs; kinds now take turns per claimer;
   - a catalog "Scan now" made during another replica's scan waited for the next poll; the scan holding the lock serves it before releasing;
   - a token response without expires_in was reused for a fixed 15 minutes; oauth_token_lifetime sets it per api and graphql connection;
   - an own file the platform was slow to serve was recorded as missing on the tile; it now answers 503 and the tile is retried;
   - also: provenance re-reads a cited call another replica had not yet flushed; the api gateway's timeout derives from the request context; the maps index retries and re-reads its settings per claim; the Trino kind reads the connection store for a connection another replica saved; indexjob_jobs_total series start at zero; a script test replays the register check its run recorded; admin Get Persona reads the store first.
4. #2219 criteria that need a stack make dev does not make are listed in test/acceptance/environments.txt and run in their own nightly jobs (scripts/acceptance-services.sh, ACCEPTANCE_ENV); dev Keycloak is 26.7.5 for #2061, and the Google service-account criteria use neutral names.

Also: dev/seed.sql points acme-warehouse at the local mock; the import ratchet gains internal/upstreamauth -> internal/upstreamauth/tokenexpiry; docs/server data-retention, configuration, asset-references, api-gateway, admin-api, observability and the other pages listed in the diff, README.md, CLAUDE.md, llms.txt and llms-full.txt.

Closes #2216
Closes #2217
Closes #2218
Closes #2219
Closes #2221
@codecov

codecov Bot commented Oct 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.59813% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.79%. Comparing base (1760c1a) to head (63f2f6c).

Files with missing lines Patch % Lines
internal/maps/service.go 85.71% 1 Missing ⚠️
internal/maps/source.go 96.29% 1 Missing ⚠️
pkg/platform/platform.go 83.33% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##             main    #2235    +/-   ##
========================================
  Coverage   94.78%   94.79%            
========================================
  Files        1374     1376     +2     
  Lines      111373   111500   +127     
========================================
+ Hits       105567   105698   +131     
+ Misses       5788     5785     -3     
+ Partials       18       17     -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cjimti
cjimti merged commit 7790188 into main Oct 20, 2026
12 checks passed
@cjimti
cjimti deleted the feat/2221-full-acceptance-suite branch October 20, 2026 20:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant