Bento docs
Operate

Testing

The primary v1 path is a modular monolith. Go and Nest are checked with unit, contract, browser, acceptance, load and recovery tests; optional split-deployment experiments remain available for products that need them.

backend/scripts · frontend/e2e · infra/testing · .github/workflowsChecked against the files 16 October 2026

Layers

LayerToolRuns in CIProves
UnitGo testing, VitestYesDomain rules, handlers and adapters in isolation.
ArchitectureGo architecture test, dependency-cruiserYesNo cross-module imports; layers point inward; SQL names only its own schema.
ContractRedocly, oasdiff, parity scriptsYesThe API spec is valid and not broken; both backends ship the same migrations and catalogs.
SecurityRole acceptance, security matrices, ZAPSelected / manualRole boundaries, denials, authenticated API responses and configured scan coverage.
End-to-endPlaywright, backend scripts, curl, jqSelected in CICore user journeys run through both frontends and both backends. Main/dev, scheduled and opted-in runs execute the wider browser and backend matrix; most PRs use faster gates.
Loadk6Manual / selectedAccount, Files, Billing, Chat, Webhook, identity and AI workloads have bounded smoke/load profiles. Results qualify tested runs, not production capacity.
ResilienceToxiproxy, disposable services, recovery harnessesManual / selectedRecovery scenarios cover PostgreSQL, NATS, AI providers, Files/S3, Chat, Billing, Webhooks and notifications. Offline orchestration checks run separately from live drills.

Unit and integration tests

Go

Go

Standard testing with no assertion library, next to the code they test. Root CI runs go test -race -p 4 ./..., retaining every package while bounding package concurrency. Database- and Redis-backed suites need their matching test URLs.

Nest

NestJS

Vitest, type/build and architecture checks, plus an in-process HTTP end-to-end spec. PostgreSQL-backed cases run when configured by the test workflow.

Every domain

All fifteen Go/Nest modules have tests in their owning packages. Shared HTTP, event, capability and fixture contracts make the infrastructure suites reusable across backend implementations. The commands below are selected database recovery or boundary suites; the coverage column also includes unit, contract and acceptance checks. Each live suite needs its documented disposable dependencies.

DomainCoverageSelected live suite
IdentitySessions, MFA/passkeys, OAuth, security changes and identity lifecyclemake test-identity-recovery BACKEND=go
AccountMembership, ownership, lifecycle, receipts and concurrent writesmake test-account-recovery BACKEND=go
AuthorizationPermission projections, revocation, replay and provider failuresmake test-authorization-recovery BACKEND=go
AuditHash chains, append/export/prune, event replay and recoverymake test-audit-recovery BACKEND=go
BillingCheckout, subscription and invoice lifecycle, ownership and reconciliationmake test-billing-recovery BACKEND=go
ChatMessage order, receipts, attachments, membership, erasure and purgemake test-chat-recovery BACKEND=go
EntitlementsPlan projections, grants, revocation and event replaymake test-entitlements-recovery BACKEND=go
UsageReservations, settlement, storage gauges and month boundariesmake test-usage-boundaries BACKEND=go
AIWorker leases, quota races, cancellation, documents and tool approvalsmake test-ai-recovery BACKEND=go
IntegrationsAPI keys, signed webhooks, delivery leases, MCP and outbound target checksmake test-webhook-recovery BACKEND=go
NotificationsInbox/preferences, source events, email, retention and privacymake test-notification-delivery BACKEND=go
FilesUploads, scanner/copy failures, quota, receipts, erasure and purgemake test-files-recovery BACKEND=go
PrivacyExports, erasure fences, retention and restore-ledger replaymake test-privacy-export-recovery BACKEND=go
RealtimeBroadcast recovery, authorization, subscriptions and presencemake test-realtime-recovery BACKEND=go
OperationsStaff authorization, maintenance, account freezes and recoverymake test-operations-recovery BACKEND=go

Use BACKEND=nest for the matching Nest execution. Python, Rust, .NET, Java and Zig require their own adapters and live qualification; shared contracts alone do not establish parity.

Verified checkpoints

The 16 October 2026 core recovery closeout passed all 65 default root CI gates in one execution: 136 Go race-test packages, 1,861 Nest cases and 15,289 Python cases. Nest retained 324 skips and Python 532; skipped database/live tests are not counted as live evidence. Infrastructure checks included 991 resilience helpers, 116 acceptance helpers, 109 schema regressions and six alert harness cases.

The checkpoint fixed PDF.js input-buffer ownership in Nest so scanned PDFs retain their bytes for OCR fallback. Two worker-transfer regressions and a native PDF.js probe verify the fix. Source snapshots, ordered gate results, failures from superseded attempts and cleanup records are retained privately; the public progress record is infra/testing/completion.md.

Native k6 fixture checks and paired live fault runs are recorded separately. Recovery hardening uses one allowance through restoration, retry/replay, durable state, event delivery and final public/liveness checks. A late successful response cannot satisfy the recovery budget. Remaining capacity, production restore and operational work is tracked separately from this checkpoint.

The finite closeout passes 117 new regressions, 316 native fixture cases and all twelve live runs: PostgreSQL read/write completion loss, lock cancellation, transaction crash, migration rollback/retry and remote Authorization recovery on both Go and Nest. Complete recovery takes 0–13 integer seconds within the original 90-second database or 30-second provider allowance. Thirty-six independent resource queries verify cleanup. See infra/testing/resilience/core-dependency-closeout.md.

Where testing stopped

The Go/Nest core dependency recovery tranche is complete at candidate 20261016T111155Z: 65/65 default root CI gates and twelve paired live recovery runs passed. The repository handoff at infra/testing/HANDOFF.md records the evidence, source boundary and remaining work. Later source changes require their own checks.

Representative capacity, wider fault and security coverage, production operations and additional backend qualification remain separately scoped in infra/testing/roadmap.md. The next planned phase is a compliance-readiness assessment, beginning with control-to-evidence mapping and gaps for the selected deployment. That phase has not started; the testing checkpoint is technical evidence and does not establish SOC 2 attestation.

Contract checks

  • OpenAPI lint with Redocly.
  • Breaking changes: oasdiff against the merge base on main, failing on errors unless the break is listed in breaking-changes-approved.txt.
  • Realtime contract: a Python check of the WebSocket protocol and its client library.
  • Migration parity: the Go and Nest migration folders must be identical.
  • Catalog parity: entitlements, usage meters, notifications and AI catalogs must match across v1 implementations and their contracts.
  • Route parity, in optional split-deployment checks: each service's internal route inventory must match the OpenAPI spec.
  • Property-based API checks: Schemathesis exercises selected authenticated operations against the generated OpenAPI contract.

End-to-end suites

The scripts in backend/scripts exercise HTTP contracts and domain journeys. The browser suite infrontend/e2e runs each web frontend against each v1 backend: Next→Go, Next→Nest, Svelte→Go and Svelte→Nest. Isolated API instances can use alternate ports; see frontend/e2e/README.md.

SuiteCovers
identity-e2e.shSign-up, verification, sign-in and sign-out, sessions, password reset.
accounts-e2e.shWorkspaces, roles, invitations, ownership transfer.
entitlements-e2e.shBilling events through Entitlements to Files limits.
lifecycle-e2e.shSession lifecycle, workspace close and reopen, deletion, CORS.
trust-e2e.shTerms, step-up, password and email change, TOTP MFA.
privacy-e2e.shExports and the operator commands.
audit-e2e.shThe audit log API and chain verification.
usage-e2e.shThe usage view.
ai-e2e.shAI tasks and credit metering against a fake model.
billing-e2e.shTrials, checkout, signed webhooks, subscriptions, invoices and usage reconciliation.
integrations-e2e.shAPI keys, signed webhooks, MCP connection lifecycle and protected calls.
notifications-e2e.shInbox/preferences and durable email delivery behavior.
chat-e2e.shConversations, ordered messages, attachments, read cursors, erasure and account lifecycle.
staff-e2e.sh · impersonation-e2e.shStaff role/MFA gates, support access, approvals and audited impersonation lifecycle.
frontend/e2eBrowser journeys for auth, MFA/passkeys, billing, files, chat, integrations, MCP consent/OAuth and AI flows across all four web/backend pairings.
files-e2e.shFolders, trash, quota, upload CORS.
receipts-e2e.shRetry-safe writes: replay after a lost response or a stale If-Match, key reuse, and the receipt lookup.
realtime-e2e.shThe WebSocket protocol.
cache-e2e.shTwo instances sharing Redis, and one with Redis unreachable.

Optional split-deployment run

split-e2e.sh starts, for each backend, a core service, an Account and Files service, an edge in front of both, and a Realtime-only service behind its own edge, with fresh Ed25519 keys and NATS. It runs every suite except the cache suite, checks that edges return 404 for /internal/* and 401 for a client-supplied assertion, and checks route parity.

Load tests with k6

infra/testing provides typed k6 workloads, disposable dependency stacks, tenant fixtures, privacy-checked reports and bounded traffic profiles. Workloads cover Account, Files, Billing, Chat, Webhooks, identity and AI. A manual smoke workflow offers selected Go/Nest workloads; broader profiles run locally or through selected workflows. These checks target disposable infrastructure, not a production service.

WorkloadDoes
account/readReads the fixture workspace.
account/createCreates a workspace, replays the same idempotency key, reads it back.
account/mixedFour reads per create. The default.
account/list, account/manage, account/fairnessPagination, role-aware updates/invitations and a busy tenant's effect on control traffic.
identity/readAuthenticated session and profile reads across fixture owners.
files/lifecycle, files/mixed, files/purgeUpload/download, tenant access, exact bytes and cleanup.
billing/read, billing/invoicesPlan/subscription reads and exact invoice pagination.
chat/mixed, chat/replicasMultiple writers, ordered messages, retries and contention across processes.
webhooks/dispatch, webhooks/source, webhooks/source-recoverySigned delivery, source events and recovery with tenant-owned endpoints.
ai/run, ai/concurrency, ai/quota-raceRun lifecycle, same-key contention and concurrent quota admission.
account/rename-race, health/liveVersion conflicts and independent public health observations.
ProfileTraffic
smoke1 workflow/s for 15 s
load5 workflows/s for 60 s
spikeRamp to 5× the configured rate, hold for 60 s, then recover
stressStaged 2×/5× traffic, sustained hold and recovery
breakpointDoubling steps through 8× by default; bounded configuration up to 16×
soak5 workflows/s for 30 min by default; maximum 6 hours

These are the standard shared-profile defaults. Workloads can use dedicated contention scenarios; overrides, effective options and requested versus achieved traffic are recorded in their reports. A workflow can make several HTTP requests.

A run passes only if every check passes, fewer than 1% of requests fail, p95 latency stays under one second overall and per operation, and no iteration is dropped. Reports go to infra/testing/reports/<run>/.

make test-setup
make test-smoke BACKEND=go WORKLOAD=account/read
make test-load  BACKEND=nest PROFILE=spike WORKLOAD=account/mixed

Resilience with Toxiproxy

Recovery scenarios inject dependency faults or process failures, then verify durable state, retries, replay, public behavior, event drain and cleanup. NATS recovery is one case; PostgreSQL response/commit faults, AI provider failure, Files storage, Chat, Billing, Webhooks and notification delivery have dedicated scenarios. For example, make test-resilience BACKEND=go SCENARIO=event-recovery:

  1. BaselineCapture existing state and health.
  2. FaultInject a bounded network, dependency or process fault while the workload runs.
  3. EvidenceCheck persisted rows, events, receipts, privacy boundaries and user-visible outcomes.
  4. RecoveryRestore the dependency/process and require replay or retry within a bounded deadline.
  5. CleanupProve exact final state, healthy control work and independently verified cleanup.

Run-specific evidence and limits are recorded in infra/testing/completion.md and the scenario guides.

CI

Local make ci runs 65 default gates for Go, Nest, Python, Next, Svelte, mobile, CLI, contracts, infrastructure and dependency audits. Native k6 fixture checks, database-backed suites and live fault drills are separate selections. Rust, .NET and Python-live are opt-in; Java and Zig have separate build paths. The hosted workflows below have their own triggers and do not imply a hosted run occurred with each local checkpoint.

Workflow · jobRuns
backend · goFormatting, the architecture test, vet, build, go test -race, govulncheck.
backend · nestPrettier, dependency-cruiser, Oxlint, type-check, build, Vitest, npm audit.
backend · contractOpenAPI lint, oasdiff, realtime contract, migration and catalog parity.
backend · secretsgitleaks over the full history.
backend · e2eMain/dev, scheduled, manual or opted-in PR runs: local dependencies, Go/Nest builds, browser journeys, monolith and optional split suites, plus a Redis-cache leg.
frontend · mobile, next, svelteType/static checks and tests for mobile and both web apps; see Frontends.
recovery-drills · testing-smokeManual workflows for selected bounded Go/Nest recovery and smoke scenarios; they are not part of every pull request.

Dependabot opens weekly updates for both backends and GitHub Actions.

Gaps and roadmap

Gaps
  • Manual load and recovery evidence qualifies only the scenarios and source revision recorded in each report; it is not a production SLO or a blanket guarantee.
  • Hosted AI/MCP outcomes depend on provider/model availability and quality; fake-provider coverage does not validate those external behaviors.
  • Go and Nest are the v1 backends. Python is progressing toward parity; Rust, .NET, Java and Zig remain separate builds and are not the supported v1 starter path.
  • Split-service deployment checks exist but are optional for the current modular-monolith-first project path.
Later
  • Production backup and restore qualification against the selected hosting and storage providers.
  • Production deployment manifests, release ownership and operations integrations for a chosen hosting target.
  • Provider-specific AI quality, cost and operational limits for the models each product selects.

Current scope and qualification boundaries

AreaAvailable nowProject-specific follow-up
Contracts and authorizationOpenAPI/Schemathesis selections, role-specific acceptance and security suites, migration/catalog parity.Add the operations, roles and product-specific constraints required by each generated app.
OperationsLocal observability, alert rules, manual k6 profiles and recovery drills with status-only reports.Set service objectives, alert destinations, capacity budgets and backup policies for the chosen deployment.
ProvidersFake adapters and local fixtures support deterministic checks; selected hosted checks exist for AI, billing and email behavior.Supply product credentials and verify the provider, model, plan, region and cost behavior being deployed.

Details: infra/testing/README.md and infra/testing/roadmap.md.