Status: accepted
Last reviewed: 2026-07-22
The verification cadence below is normative. The production verification log is append-oriented historical evidence and may mention earlier migration heads, test counts, readiness behavior, or deployed revisions. Use Current implementation state for present behavior.
Development should keep the main implementation flow moving and use concentrated verification instead of rerunning the complete test suite after every edit.
- During a feature slice, run only checks needed to resolve a concrete risk or failure.
- Run the relevant focused checks when a contract, migration, security boundary, or streaming behavior changes.
- Run the complete backend and frontend quality checks once at a meaningful commit, merge, milestone, or release boundary.
- Record manual integration or recovery verification in the owning roadmap or operations page when it establishes an exit criterion.
- CI remains the independent full-suite gate for every push and pull request.
This cadence changes when tests run, not the quality bar. A feature slice is not complete while a known failure remains or its critical path has not been exercised.
- Added
docker-compose.soak.ymlandscripts/run-compose-soak.sh. They use the isolatednorthgate-soakCompose project, private network, database volume, and host port, and remove all of those resources on exit. - Ran two five-iteration phases. Every iteration included a non-streaming call, a complete SSE call, a two-request tool execution loop, and a stream closed by the client after its first event.
- Configured the primary mock provider to return
503every fourth call and kept a healthy fallback. The attempt ledger recorded 12 fallback attempts. - Force-recreated only the isolated Northgate container between phases and waited for readiness before resuming traffic.
- The final direct storage checks found zero request records in
startedand zero active Redis concurrency leases. The harness exited successfully and removed its containers, network, and database volume. - Ran the new application-side readiness probe from the existing
dayboard-api-1container tohttp://northgate:8080/health/ready; it returned the expected ready response without changing or recreating production containers.
Run the same deterministic local acceptance with:
./scripts/run-compose-soak.sh- Applied migrations
0012and0013and enabled the outbox only in the real-storage streaming integration test. Three sequential SSE requests each produced a completed durable event, terminal request and attempt records, and zero active concurrency leases. - Injected a Redis policy-settlement failure after PostgreSQL terminal updates. The event retained its database progress, retried idempotently, released the lease, and settled five tokens without double counting.
- Verified an outbox enqueue failure falls back to inline request/attempt
settlement and increments the bounded
outbox_enqueuefailure metric. - Ran the real PostgreSQL/Redis tests with
PYTHONWARNINGS=error; all three passed without leaked SQLAlchemy connections. The complete backend suite passed 78 tests, both Compose configurations validated, and Alembic reported0013as the single head. - Ran
northgate-worker --onceagainst the migrated local PostgreSQL and Redis; it drained available work and exited successfully. - Verified one request can own independent
attempt:{attempt_id}andterminalevents. Retryable status, timeout, transport error, cache hit, route-health failure, and attempt-ledger failure exits all use the guarded durable handoff. - Extended the isolated soak with worker heartbeat/readiness and failure recovery.
The current harness expects degraded readiness after stopping the worker and
reserves
503for an overdue recoverable backlog. Stopping Redis after an active lease produced a retry event; Redis, Northgate, and the worker were restored, and final reconciliation reportedstarted=0,leases=0,pending=0,failed=0, with 12 fallback attempts. Dedicated Compose resources were removed. - Added worker-aware Compose upgrade validation: when outbox is enabled, the supported upgrade builds, stops, and starts Northgate and the settlement worker together and rejects a merged configuration without the worker service.
- Fixed the exhausted-retry regression: a final retryable provider
5xxis drained and settled before Northgate returnsPROVIDER_UNAVAILABLE. The concurrency-limit-one regression sends two requests through two502attempts each and proves the second request is admitted immediately in inline and first-process-failure outbox modes. Provider-native final429remains intact. - Made the application-container readiness probe mandatory in the supported Compose upgrade command. A missing probe container now stops the command before build, backup, migration, or service replacement.
- Added
northgate-worker --healthcheckand attached it to the Compose worker service. It checks the Redis heartbeat used by data-plane readiness, while the topology preflight now rejects an outbox worker without a healthcheck. - Instrumented SQLAlchemy pool invalidation events with bounded cancellation, error, and unspecified reasons, and added an alert for explicit cancelled database connections.
- Extracted provider request construction and streaming transport execution into
attempt_execution.py. Focused tests cover successful response handoff and timeout, connection, and ambiguous transport failures without changing retry or settlement ownership. - Moved retryable-response consumption behind the same attempt boundary. Focused
contracts verify intermediate provider
429is consumed for retry, final429is passed through unchanged, and an exhausted final502is drained with usage before request settlement. - Extracted stream byte relay and its shielded finalizer handoff into
stream_relay.py. Focused tests prove SSE[DONE]prevents reads past the terminal event and interrupted upstream reads report a transport failure before settlement finalization. - Extracted shared request/attempt settlement helpers into
proxy_settlement.pyand moved streamed cache, route-health, ledger, outbox, and policy finalization intostream_finalization.py. The endpoint module now orchestrates those stages without implementing the stream lifecycle itself. - Added migration
0014and trusted application-key route metadata. Existing keys are backfilled to explicit legacy mode for staged replacement; new trusted keys use only server identity and fixed operator values, with negative tests against caller tenant spoofing. - Added migration
0015and per-key request metadata trust classes. Usage records retain server, fixed, untrusted, and legacy provenance; tenant aggregation only consumes trusted fixed or future signed values. - Began the request-pipeline decomposition by extracting bounded request input,
metadata/model parsing, token estimation, and allowed forwarded headers into
immutable
ProxyRequestInput; the existing proxy behavior suite remained green. - Extracted application-key route resolution, metadata candidate selection, and
primary adapter validation into
route_planning.py. Fallback validation and provider HTTP execution deliberately remain together for the next executor slice.
- Built the Dayboard API/worker image from clean commit
b6c0f58; uncommitted workspace changes were excluded from the image. - Deployed the image to API and worker while leaving the web service and the original provider connection unchanged.
- Enabled Northgate only for the newer of two production tenants. Each tenant had one member at the time of deployment, so the allowlist represented one user.
- Confirmed both containers were healthy, could resolve
northgateon the sharedplatform-infranetwork, and received HTTP 200 from Northgate readiness. - Exercised Dayboard's deployed selection logic without another model request: the canary tenant selected the Northgate connection and trusted metadata, while the control tenant selected the original connection without Northgate metadata.
- Confirmed the Northgate and Dayboard startup logs contained no errors after the deployment.
The pre-canary Dayboard environment backup is stored at
/var/backups/dayboard/config/dayboard-env-pre-canary-20260717T151852Z.env with a
root-only checksum. Rollback restores that file and recreates only the Dayboard API
and worker containers. Provider and application secrets are stored separately as
root-only files and are intentionally not recorded here.
- Observed the single-tenant deployment for 11 hours. Northgate, Dayboard API, and Dayboard worker remained healthy, and the previous Northgate documentation CI run completed successfully.
- No organic canary traffic arrived during that window, so ran one minimal Dayboard agent smoke through the deployed factory, Northgate, and the real provider without writing Dayboard business data or printing model content.
- The smoke completed with HTTP 200 and outcome
succeeded: one provider attempt, no retry or fallback, 1,169 ms total latency, 1,164 ms first-token latency, and complete tenant, user, and run attribution. - Added the remaining production tenant to the allowlist. Production contained two tenants with one member each at rollout time; both now select Northgate and trusted metadata through Dayboard's deployed configuration.
- Recreated only the API and worker containers, confirmed both healthy, confirmed HTTP 200 from Northgate readiness, and found no startup or proxy errors.
- Kept Dayboard's original provider connection in the environment for rollback.
The pre-full-rollout environment backup is stored at
/var/backups/dayboard/config/dayboard-env-pre-full-northgate-20260718T023133Z.env
with a verified root-only checksum. Restoring it and recreating only API and worker
returns Dayboard to the single-tenant canary.
- Added operator-only tenant aggregates and the React console tenant table in
commit
7fc90cb. - Ran Ruff lint and format checks for the affected backend files and the focused tenant analytics test; the test passed, including operator authorization and omission of user/run metadata.
- Ran the console TypeScript check and production build successfully. No browser screenshots were created.
- Executed the SQLAlchemy tenant aggregation against the production PostgreSQL schema before deployment; all 19 historical records were classified as succeeded with no in-flight or error records.
- Rebuilt and replaced only the Northgate application container. The deployed endpoint rejected an unauthenticated request with HTTP 401 and returned, for its default 24-hour range, six successful requests across three groups, including two attributed tenant groups, with no errors or in-flight records.
- Confirmed the console returned HTTP 200, its bundle contained the tenant view, and Dayboard still received HTTP 200 from Northgate readiness over the shared platform network.
- Added append-only model price list/create control APIs and a React console price
form in commit
d8427b1. The form accepts dollars per one million tokens and the API stores integer micro-USD with a timezone-qualified effective timestamp. - Ran Ruff lint and format checks, the focused control-price and integer-cost tests, the console TypeScript check, and the console production build successfully.
- Rebuilt and replaced only the Northgate application container. The deployed list
endpoint rejected an unauthenticated request with HTTP 401 and returned the one
existing
gpt-testrecord to an operator with all price fields present. - Confirmed a validation-only create request without a timezone returned HTTP 422 and left the production table at one record.
- Confirmed the console and its pricing bundle were available, Dayboard still received HTTP 200 from Northgate readiness, and Northgate logged no deployment errors.
- Did not add a price for Dayboard's
gpt-5.4-mini: its five recorded requests have no matched price, and an authoritative exact price could not be retrieved during this deployment. Operators must record the supplier or contract price before treating cost analytics as complete or enabling spend limits.
- Replaced the single-page dashboard composition with a React Router management shell and route-level lazy loading for Overview, Requests, Usage, and Pricing.
- Added TanStack Query server-state handling, Zod response validation, Ant Design management controls, and React Hook Form forms while retaining Recharts for the bounded traffic and token chart.
- Added a bounded newest-first mode to
GET /api/v1/usage/requests, includinghas_moreand known request cost, while retaining paired metadata correlation and redaction of metadata values and request content. - Added request detail pages over the shared diagnostics API with findings, provider attempts, and redacted settlement progress. FastAPI now serves the SPA index for nested Console URLs.
- Ran the focused analytics and application tests, Ruff checks, Console TypeScript check, and production build. The Ant Design shared chunk remains larger than the default Vite warning threshold; business pages are separately lazy-loaded.
- Added a Gateway workspace over the existing Operator control APIs with project/Gateway selection, Gateway creation, provider-credential-aware Route listing and creation, and explicit Route priority, weight, and enabled updates.
- Route creation exposes retry, circuit-breaker, and trusted metadata match fields without accepting credential secrets in the browser response.
- Added complete Gateway Policy replacement for request, concurrency, token, spend, and exact-cache limits. Blank fields deliberately map to disabled limits.
- Ran the Console TypeScript check and production build, then exercised the Web page against the real read-only production control responses. Both configured Gateways loaded with no browser or schema errors; no production mutation was performed.
- Added authenticated diagnostics capabilities and bounded time-range usage APIs with optional metadata grouping, trust classes, explicit truncation, cache lower-bound semantics, retry/fallback counts, and joined request findings.
- Added
northgate-inspect usage,recent, anddoctor, including explicit IANA timezone handling and application name/ID resolution without product coupling. - Added MCP usage-range and recent-correlation tools over the same Operator API, plus protected client provisioning from a retained raw operator key.
- Verified focused REST/CLI/MCP tests and the real PostgreSQL/Redis diagnostics integration path.
- Deployed commits
3352c5aand5ab23bdthrough verified backups, Alembic head checks, readiness, and the Dayboard connectivity probe. Productiondoctorconfirmed schema version 1 through the protected file credential. - The two-hour
dayboard-canaryproduction sample returned 11 requests across 4run_idgroups, 34,638 total tokens, 10,496 confirmed cached prompt tokens, five requests without cache detail, explicit lower-bound labelling, no truncation, and no warning/error findings. - A real stdio MCP subprocess discovered all seven tools and returned the same
11-request/4-group aggregate. The first exercise exposed
httpxINFO URL logs; commit5ab23bdsuppresses those dependency logs so metadata query values are not emitted by default.
- Replaced raw whole-body byte estimation with model-visible prompt estimation.
Exact tokenizer registry matches are preferred; current OpenAI
gpt-4o,gpt-5,o1,o3, ando4family suffixes useo200k_base, while unrelated unknown models retain the explicit UTF-8 byte fallback. - Split and persisted prompt estimate, output reserve, attempt multiplier, margin, total reserve, estimator, and output source. Diagnostics, analytics, CLI, MCP, Prometheus, and Console expose terminal actual, released tokens, and estimate/actual ratio without returning request content.
- Added request, route, model, and global output-limit precedence. Production had 38 complete Dayboard requests with completion tokens from 7 through 94; the Dayboard primary route was set to 512 tokens, retaining more than five times the observed maximum while explicit request limits can still override it.
- The original 11-request incident sample reserved 165,200 tokens for 34,638 actual tokens, a 4.77x aggregate ratio. A post-deployment Chinese, eight-tool production probe reported 691 prompt and 7 completion tokens. Northgate estimated 639 prompt tokens and 735 including the per-attempt safety margin. With the route default and two-attempt plan it reserved 2,494 tokens (3.57x); the former algorithm on the identical body would reserve 10,128 (14.51x), so the controlled reservation fell 75.4%.
- The release boundary passed Ruff and format checks, 112 non-integration tests,
9 required PostgreSQL/Redis integration tests, Console TypeScript and production
builds, Compose validation, and Alembic single-head verification. Production
upgraded to
0017from verified backupbackups/northgate-20260723T030211Z.dump; readiness, the Dayboard application probe, diagnostics doctor, and post-deployment ledger inspection passed.
- Added Applications management for organizations, projects, application-key issuance, caller/fixed metadata classes, trusted/legacy routing mode, one-time secret display, copy, and revocation.
- Added Provider Credentials management for project-scoped encrypted credential creation, OpenAI-compatible/Azure adapter configuration, redacted route references, and write-only secret rotation. Production read responses were checked to contain neither plaintext nor encrypted secret fields.
- Added a read-only Operations workspace over readiness and stale diagnostics. It shows settlement backlog, recoverable versus unprotected ledgers, attempt state, outbox events, and active/expired concurrency leases, with request-detail navigation. Reconciliation mutations remain CLI-only.
- Ran Console TypeScript validation and production build, Ruff and format checks,
112 non-integration tests, Compose validation, and production read-only API
contract checks. CI run
29977269636passed quality, integration, and Console jobs. - Deployed commit
64552ccfrom checksum-verified backupbackups/northgate-20260723T033335Z.dump. Alembic remained at0017; readiness, the Dayboard application probe,/console/applications,/console/providers,/console/operations, and the referenced JavaScript bundle all returned HTTP 200. No screenshot, mobile, or visual review was performed by request.