Repository navigation
feat(backend)!: remove phone-home from the backend and the CLI - #70
Conversation
Thinker is self-hosted only, so the inherited Manifest Cloud UI goes. The frontend leaves first so no screen breaks when #14/#15 drop the matching backend endpoints. - Billing/plans: delete PlanPicker, UpgradeSuccessModal, UsageLimitBanner, the /upgrade page, the Register ?step=plan picker, the plan stores, the plan-based range locks on the analytics pages, the plan-limit upgrade CTAs in the request views, the Account billing and usage-email sections, and the @better-auth/stripe client plugin and dependency. - API Bot: delete the banner, the sidebar card, the dithered ground, their stylesheet and the SVG asset. - GitHub stars: drop the header star button and its /api/v1/github call. - Free Models: delete the page, its route, its API client and the assets only it used. - Managed Gemini Free: drop the provider entry, icon alias, background /ensure provisioning call and the Calendly key URL. - Cloud branches: checkIsSelfHosted() is gone and every screen behaves as self-hosted (Local providers always listed, local logs copy, CLI login pinned to this host, discovery after signup and setup). Drop the Manifest Cloud origin mapping, the cloud email card, the VITE_MANIFEST_SELFHOSTED read and the Dockerfile ENV that set it. - Help: drop the Manifest Calendly booking link. - Remove the dead CSS for all of the above, update the tests and the inherited dev guide. Closes #12 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Billing, Stripe and the Free/Pro plans belong to the SaaS layer that Thinker drops (docs/decisoes-iniciais.md section 3). - Delete packages/backend/src/billing (PlanService, billing controller, billing emails, request quota window, subscription status) and drop BillingModule from the app, proxy and analytics modules. - Proxy: remove the per-request plan gate (assertWithinRequestLimit) and the PLAN_LIMIT_REQUESTS / M204 handling in the controller and the exception filter. The proxy no longer answers 402 on its own; a 402 follows the generic error path. - Auth: remove the @better-auth/stripe plugin; drop the stripe and @better-auth/stripe dependencies from the backend. - Recording retention: keep only the global path (365-day default or REQUEST_RECORDING_RETENTION_DAYS); per-plan retention is gone. - Tenant entity: drop limit_overrides and billing_email_preferences; delete the TenantRequestUsage entity. - Shared: delete plan-limits and its exports. - Remove the STRIPE_* / PLAN_LIMIT_* / PLAN_REQUEST_QUOTA_RESET_AT variables from .env.example. - New migration DropBillingSchema1803200000000 drops the quota trigger and function, requests.quota_counted, tenant_request_usage, billing_email_logs and the two tenant columns. The old AddTenantRequestUsage migration keeps only its self-hosted path (a no-op up) so it no longer imports deleted billing code. /api/v1/billing/* no longer exists, and the STRIPE_* and PLAN_LIMIT_* variables are ignored if set. Closes #14 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Thinker makes no outbound calls of its own, and Autofix depended on Manifest's hosted Phoenix service. The dashboard drops both before the backend modules go in #16 and #17. - Update check: VersionIndicator now only shows the build-time __MANIFEST_VERSION__ badge. It makes no request, shows no "new version" link to the manifest.build changelog and has no dismiss state. services/api/version.ts and its test are gone. - Discovery: delete the post-signup questionnaire (page, service, styles, route, tests) and the pending-discovery redirects in AuthGuard and GuestGuard. First-admin setup now lands on / (Overview), signup on /welcome, and social signup also goes to /welcome. A leftover manifest_discovery_pending_* key from an older build no longer redirects anyone. - Wingman: delete the dev drawer, wingman-dev-proxy.ts, the VITE_WINGMAN_* / __WINGMAN_URL__ / __DEV_MODE__ build constants, the App and Welcome mounts, the drawer CSS and the CONTRIBUTING section. - Autofix: delete AutofixKpiCards, SettingsAutofixSection, NotificationBell (it only nagged about inactive Autofix), the Autofix switch and Manifest Terms/Privacy line on harness creation (modal and Welcome), the autofix badges, trigger filter, Phoenix panels, sibling links and status labels in the Requests views, the "Autofixed attempts" connection card, the Doctor tooltip variant, the healed chart series, the autofix fields in services/api/*, the two public PNGs, and the dead CSS. - The generic reliability metrics that the backend still serves under the legacy /overview/autofix-* paths (success rate, fallback recoveries, request status over time, per harness/provider/model reliability) stay. They are now read through neutral clients (getReliabilityStats, getRequestStatusTimeseries, RELIABILITY_PATHS) and shown by ReliabilityKpiCards. "Self-healed" becomes "Recovered" and counts fallback recoveries only. - Update the tests, the design-system registry and the inherited dev guide. Closes #13 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review follow-up for #57. - A harness stored without autofix_enabled inherits the backend default. The backend turns Autofix ON when it detects no container (bare-metal npm start, dev runs), and the dashboard no longer has a switch to turn it off. Until #16 removes Autofix from the backend: - createAgent always sends autofix_enabled: false, which covers the Connect Harness modal, Welcome and ConnectProvider; - duplicateAgent follows the copy with PATCH /routing/:agent/autofix {enabled:false}, because the duplicate endpoint has no field for it. Both live in one commented block in services/api/agents.ts, with tests on the request payloads. - The request-status timeseries client folds a legacy `healed` key into `success`. The backend's success rate already counts those requests as successes, so the bars still sum to the request total, Success + Recovered + Error matches the Success rate card, and Recovered stays fallback-only, like its KPI. - The Requests page rewrites a stale ?trigger= value (for example ?trigger=autofix) on load to the filter it actually applies. - Add AuthGuard tests for /cli/auth, with and without a session. - Correct the dev guide: the self-hosted default is OFF only in a container or with MANIFEST_MODE=selfhosted. Document AUTOFIX_GLOBAL_ENABLED=false as the operator workaround for existing harnesses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tHub stars and error pages Remove the Manifest Cloud and marketing surfaces from the backend: - waitlist/ (pivot and Autofix claims) and its open-CORS pivot route (applyPivotClaimCors, PIVOT_CLAIM_PATH, PIVOT_CLAIM_CLOUD_ORIGIN). - crm-metrics/ and CRM_METRICS_SECRET. - The managed Gemini Free provider: routing/managed-free-provider/, common/constants/managed-free-providers.ts, the CREDITS_* variables, and its entries in provider-endpoints, provider-client, provider.service, provider-model-fetcher and routing.module. No other provider's endpoint, prefix handling, fallback order or tier resolution changes. - free-models/ (sync from mnfst/awesome-free-llm-apis), github/ (stars from api.github.com) and error-pages/ (public and Peacock push routes, seeders, discovery), MANIFEST_PUBLIC_STATS and ERROR_PAGE_PUSH_SECRET. - gemini-free and the managedFree flag from manifest-shared, and the regenerated CLI provider catalog. - The plan_request_limit_exceeded error class left over from #14. DropSaasFeatureSchema1803300000000 sets a transaction-local lock_timeout, drops waitlist_claims, public_error_pages and the cloud-only IDX_requests_autofix_healed index, and deletes every gemini-free connection with its agent grants. Request history keeps its provider label, and routes that still name gemini-free resolve as unavailable and fall through to their fallbacks, as after a disconnect. down() restores the two tables as the self-hosted path created them. Closes #15 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Autofix sent failing requests to Manifest's hosted healer (autofix.manifest.build) and pinged it at every production boot. Thinker makes no such call (#16). The local self-heal of v0.6 will build on the fallback chain on its own terms. - Delete routing/autofix (AutofixService, healing clients, health probe, observation reporter, Phoenix types and vendored contract) and the contract:refresh script with its ajv/js-yaml devDependencies. - Proxy: drop the heal-once branch from the primary and fallback hops and the wire-body retry hook from ForwardResult. A failed request now goes straight to shouldTriggerFallback, exactly as for an agent that never opted in. The primary is always attempt 1, the x-manifest-provider / x-manifest-auth-type replay rewrite is gone, and the recorder writes no repair columns or auto_fixed rows. - Analytics: move the generic reliability metrics to /api/v1/overview/reliability/{stats,timeseries,per-agent,per-provider, per-model} without the Autofix fields; drop the healed disposition, the auto_fixed counter, the autofix trigger filter and the connection breakdown's Autofix attempts. - Remove /autofix/status, /autofix/enable-all, the per-harness /routing/:agent/autofix endpoints, the autofix_enabled create field, the MCP Autofix tools and the CLI `routing autofix` command and `--autofix`. - Schema: DropAutofixSchema1803400000000 drops the autofix columns, check constraint and indexes (lock_timeout, IF EXISTS, full revert). 1802200000000 now runs its self-hosted no-op path everywhere. - Shared: drop deriveAutofixStatus, AUTOFIX_STATUSES and auto_fixed. - Delete the unused doctor-release email. - Frontend: call the neutral reliability paths and drop the temporary autofix_enabled opt-out, the duplicate PATCH and the healed fold. - Docs: move the PoC spec to docs/referencia/, remove AUTOFIX_* from the guide, .env.example and the Docker README. BREAKING CHANGE: the Autofix API, analytics paths, MCP tools and CLI command are removed; the reliability analytics moved to /api/v1/overview/reliability/*. Closes #16 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Thinker makes no outbound call of its own. Remove every upstream phone-home from the backend and the CLI: - usage telemetry (telemetry/, InstallIdService, PayloadBuilderService, the InstallMetadata entity) and the CLI usage spool (packages/cli/src/telemetry.ts); - the daily update check (version/, GET /api/v1/version, the GitHub releases URL); - the discovery forwarding to blue.manifest.build (discovery/, POST /api/v1/discovery/complete); - Sentry (instrument.ts, sentry/, SentryModule/SentryGlobalFilter, the @sentry/nestjs dependency); - the hosted Wingman origin in CORS and CSP frame-src; frame-src is 'self' in every mode and WINGMAN_CORS_ORIGINS becomes THINKER_CORS_ORIGINS with the same meaning; - the modelparams.dev fetch on boot and hourly cron; parameter specs come only from the bundled modelparams package snapshot. DropInstallMetadata1803500000000 drops the install_metadata table (lock_timeout, IF EXISTS, revert recreates it empty). The removed variables leave docker-compose, the .env examples, the Docker README, the deploy templates and the developer guide. A new e2e guard fails if the backend, CLI or shared source names a removed destination again, or if a production-mode boot of the real server fetches or resolves anything outside the ADR 0003 catalogs. BREAKING CHANGE: GET /api/v1/version and POST /api/v1/discovery/complete are gone, the hosted Wingman origin is no longer allowed by CORS, and WINGMAN_CORS_ORIGINS is renamed THINKER_CORS_ORIGINS. Closes #17 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With no --url, MANIFEST_URL or stored login, the CLI targeted https://app.manifest.build, so a MANIFEST_API_KEY set without a host went to Manifest's cloud. DEFAULT_URL is now http://localhost:2099, the default Thinker port, and the invalid-URL hint and README follow. The backend's 404 hint for /chat/completions told callers to point their baseURL at https://app.manifest.build/v1; it now refers to this gateway. The egress guard now fails on app.manifest.build or gateway.manifest.build anywhere in the CLI or shared source (tests included), on a new backend production file naming them, on a CLI default that is not local, and on a boot request to either host. The three remaining backend files (Cloud trusted origins, the dashboard link fallback and the OG-tag placeholder) are pinned for #18, #22 and #25 and may only shrink. Refs #17 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Revisão do PR #70 (#17: remover phone-home do backend e da CLI)Diff revisado: Resumo: nada bloqueia. A remoção está completa. O guard de egresso é útil: confirmei por mutação que ele falha no código antigo. CORS e CSP ficaram mais restritos, não mais frouxos. A migration está correta. O PR é risco alto porque a migration apaga uma tabela e porque a CLI muda o destino padrão da chave de API. BloqueiosNenhum. Should-fixS1.
Nits
Verificações por foco
Outras observações
Risco altoCritérios que se aplicam:
CORS e CSP ficaram mais restritos e não entram como critério. Não há arquivo de governança no diff. O merge fica com o mantenedor. Antes dele, o S1 precisa estar corrigido no PR ou registrado em #22, com o link anotado no PR. Head revisado: d168f73 |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refs #67 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refs #67 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings in 498de23 (main plus #60) so #16 can merge into main after #60. Conflicts came from #57's interim dashboard handling of the legacy Autofix backend overlapping with this branch's backend removal: - frontend analytics client: RELIABILITY_PATHS points at the neutral /overview/reliability/* routes. foldLegacyRecoveredKey is dropped: the backend computes the request disposition from success/fallback only and DropAutofixSchema removes requests.autofix_status, so no row can come back as "healed", and the dashboard ships with its own backend. - frontend agents client: the auto-merged autofix_enabled opt-out on create and the PATCH /routing/:agent/autofix after duplicate are dropped (the field and the endpoint no longer exist; create rejects the field). - shared: keep the playground-headers exports, drop the autofix-status ones. - tests: keep this branch's versions (neutral paths, no opt-out, no fold). - e2e specs from main (local providers, reserved local runner aliases): stop sending autofix_enabled on agent create. - manifest guide: keep the "Autofix removed" section and neutral-path wording. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The DropAutofixSchema e2e spec opens its own DataSource with dropSchema, so it now takes its URL from resolveE2eDatabaseUrl() like the other migration specs instead of falling back to a default localhost database. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-phonehome-backend Brings in main (44f1689) through #66's final head so #70 merges cleanly after #66. Conflict resolutions: - packages/backend/package.json, package-lock.json: keep #70's removal of @sentry/nestjs and take better-auth 1.7.7 from #5. The lockfile was re-checked with npm install --package-lock-only and needed no change. - test/cors.e2e-spec.ts: keep #70's shared buildApp/buildDevApp/buildProdApp without the hosted Wingman origin; buildApp already serves on loopback (#77). - test/drop-autofix-schema-migration.e2e-spec.ts: keep both the DropInstallMetadata revert from #70 and resolveE2eDatabaseUrl from #66. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…se guard The DropInstallMetadata migration spec and the no-phone-home egress spec both open a dropSchema connection. Resolve their URL with resolveE2eDatabaseUrl() from test/e2e-db-guard instead of falling back to localhost:5432, so neither can wipe a database that is not an explicit, disposable test database (#67, #69). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
main's tree equals 5eef655, already merged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…le-selfhosted-mode Brings in main (#5, #63, #69, #100, #103, #104, #106, #107 and the SaaS, billing, Autofix and phone-home removals) through #66 and #70. Resolutions: - package-lock.json: keep undici 6.29.0 as a runtime dependency (no "dev": true), since ssrf-safe-fetch imports it; the version bump from #65 is kept. - src/mcp/mcp-discovery.spec.ts: keep the single-mode test (canonical resource and issuer whatever the Host header) and serve it on loopback like the rest of the spec (#77). - src/common/constants/local-servers.ts and its spec: import getContainerHostAlias from common/utils/container-host, since detect-self-hosted no longer exists. - design-system/registry: regenerate (npm run design:registry). The Playground header classes from #106 were missing from it, which the pre-commit check refuses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Re-revisão do PR #70 (#17: remover phone-home do backend e da CLI)Diff revisado: Resumo: nada bloqueia. O conteúdo é o mesmo que revisei em BloqueiosNenhum. Should-fixS1. CodeQL
Follow-up (fora do diff, pré-existente)F1. Sonda ao Ollama sem provedor configurado:
Verificações pedidas
Gates pendentes
Risco altoContinuam valendo os critérios da revisão anterior:
O diff não toca arquivo de governança, workflow nem release. O merge fica com o mantenedor. Head revisado: bfe9f1d |
CodeQL flagged js/incomplete-sanitization: only dots were escaped before building a RegExp from the host constants. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Re-revisão do PR #70: delta
|
| Check | Resultado |
|---|---|
| CodeQL (code scanning): "No new alerts in code changed by this pull request" | success |
| CodeQL (análise) | success |
| Lint | success |
| Unit backend (469 suítes), cli (13 suítes / 307 testes), shared (21 suítes / 525 testes), frontend | success |
Backend e2e (PostgreSQL 16): 68 suítes / 568 testes, no-phonehome-egress PASS |
success |
| Compose smoke test, install.sh end-to-end, dependency-review | success |
Achados
- Bloqueios: nenhum.
- Should-fix: nenhum em aberto. O S1 desta rodada (CodeQL) foi corrigido. O S1 da primeira revisão (logo dos e-mails) está na Rebranding do backend: textos, e-mails, MCP e atribuição de provedores #22.
- Follow-up: F1 (sonda ao Ollama em
/api/v1/setup/statussem provedor configurado, herdada do upstream) está na Setup: não sondar o Ollama local sem provedor configurado #109, com o link no PR. Os nits estão em Baseline do qa-docker: smoke e e2e da imagem v0.1 #34, CLI thinker #23, Release, Changesets 0.1.0 e publicação no Docker Hub #31 e Catálogos públicos: chave THINKER_CATALOG_SYNC e OpenCode Go só com provedor cadastrado #39.
Gates pendentes
- qa-docker: falta o resultado registrado para este head. O critério é de rede: um container limpo, sem variável de opt-out, não contata
modelparams.dev,telemetry.manifest.build,blue.manifest.build,api.github.comnem Sentry. A sonda ao Ollama é esperada até a Setup: não sondar o Ollama local sem provedor configurado #109 entrar e não reprova este PR.
Risco alto
- Migration que apaga dados:
DROP TABLE install_metadata(1803500000000-DropInstallMetadata.ts). Odown()recria a tabela vazia. - Manuseio de chave: o destino padrão da CLI para
MANIFEST_API_KEYmuda parahttp://localhost:2099(packages/cli/src/config.ts).
O diff não toca arquivo de governança, workflow nem release. O merge fica com o mantenedor.
Head revisado: 8aa729a
Veredito: risco alto (aguardar mantenedor)
QA (qa-docker) for #70Image/stack runs: head
Egress per side (DNS names from the pcap, default env)
Not contacted on either side: telemetry.manifest.build, *.up.railway.app, autofix.manifest.build, api.github.com, sentry, app.manifest.build. The PR no longer resolves modelparams.dev. After boot, the PR's only DNS lookups are Findings
Minor: on the first boot after the upgrade, Better Auth logged |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Closes #17
Summary
Thinker makes no outbound call of its own. This removes every upstream phone-home from the backend and the CLI.
telemetry.manifest.build/v1/reporttelemetry/(incl.InstallIdService,PayloadBuilderService),entities/install-metadata.entity.ts,MANIFEST_TELEMETRY_DISABLED,TELEMETRY_ENDPOINTtelemetry.manifest.build/v1/cli-reportpackages/cli/src/telemetry.ts(+ spec), the calls and USAGE notice inindex.ts, the README section,MANIFEST_CLI_TELEMETRY_ENDPOINTapi.github.com/repos/mnfst/llm-gateway/releasesversion/(module, controller,version-check.config.ts),GET /api/v1/version,MANIFEST_UPDATE_CHECK_*blue.manifest.build/v1/self-hosted/discoverydiscovery/,POST /api/v1/discovery/complete,DISCOVERY_ENDPOINT*.sentry.io(whenSENTRY_DSNset)instrument.ts,sentry/,SentryModule/SentryGlobalFilter,@sentry/nestjs(and its 17 transitive packages in the lockfile), the!instrument.tscoverage exclusion,SENTRY_*wingman.manifest.buildalways allowed by CORS (dev + prod) and CSPframe-src(dev)HOSTED_WINGMAN_ORIGIN,wingmanPort/WINGMAN_PORT, the Wingman dev origins,buildFrameSrc(frame-srcis now'self'in every mode)modelparams.dev/api/v1/models.jsonon boot +@Cron('34 * * * *')refreshCatalog,fetchAndSwapCatalog,scheduledRefresh,onModuleInit, ETag,MODELPARAMS_API_*;ProviderParamSpecServiceserves only the bundledmodelparamssnapshot (decided in ADR 0003 / #11)d168f73)app.manifest.buildwhenever no--url,MANIFEST_URLor stored login: aMANIFEST_API_KEYset without a host went to Manifest's cloudDEFAULT_URLis nowhttp://localhost:2099(the default Thinker port); the invalid-URL hint and the README follow. The config dir and the CLI rename stay in #23/chat/completions404 hintbaseURLtohttps://app.manifest.build/v1WINGMAN_CORS_ORIGINSis renamedTHINKER_CORS_ORIGINS, same meaning (extra browser origins allowed to call the gateway, exact match, trailing slash stripped). It now also applies in dev, on top ofCORS_ORIGIN. With it unset, production allows no cross-origin browser caller at all (security: no third-party origin by default).Schema: new migration
DropInstallMetadata1803500000000dropsinstall_metadata(SET LOCAL lock_timeout = '10s',DROP TABLE IF EXISTS).down()recreates the table as1775700000000created it, empty, so revertingDropAutofixSchema1803400000000next can restore its column. NoSET LOCALindown(), matching #16, becausemigration:revertruns with--transaction none.Not touched: the OpenRouter / models.dev / OpenCode Go catalog behaviour (#39), the frontend
ModelParamsAffordance.tsxreport link (#25).manifest.buildhosts in the CLI: besidesDEFAULT_URL, the only ones left are docs links: the README "CLI documentation" link andhomepageinpackage.json. Neither is an API endpoint; both are left to #23.skill/SKILL.mdand the generated skill content have none. Spec fixtures that usedapp.manifest.buildnow usegateway.example.com.Backend leftovers, out of scope here:
app.manifest.build/gateway.manifest.buildremain in three backend production files. None of them is a request destination:auth/auth.instance.ts: Cloud trusted origins and MCP resources (Modo único self-hosted: remover MANIFEST_MODE #18).common/utils/dashboard-url.ts: the dashboard link fallback used whenBETTER_AUTH_URLis unset (Rebranding do backend: textos, e-mails, MCP e atribuição de provedores #22).common/utils/og-rewrite.ts: the OG-tag placeholder, a literal in the frontend'sindex.html(Rebranding do dashboard #25).The guard pins this list so it can only shrink.
Docs and config
docs/dev/manifest-guide.md: overrides banner, intro, file tree, endpoint table, env vars (MANIFEST_TELEMETRY_*,MANIFEST_UPDATE_CHECK_*,DISCOVERY_ENDPOINT,WINGMAN_*,SENTRY_*,MODELPARAMS_API_*removed,THINKER_CORS_ORIGINSadded). The Telemetry and Sentry sections are replaced by a "No phone-home" section.docker/docker-compose.yml,docker/.env.example,packages/backend/.env.example: removed variables gone,THINKER_CORS_ORIGINSadded.docker/install.shhad none.docker/Dockerfile: drops the runtimeCOPY packages/manifest/package.json, which only the telemetry sender read. The frontend reads that file at build time, in the build stage, so the build is unaffected.docker/DOCKER_README.md,CONTRIBUTING.md,deploy/{easypanel,fly,apple-containers}: telemetry, update-check, Sentry and Wingman mentions removed. Only lines were deleted; the rest of these templates is left to Docker, Compose e instalador do Thinker #26 and Templates de deploy da comunidade #30.Guard against regressions
test/no-phonehome-egress.e2e-spec.ts:packages/{backend,cli,shared}/src(old migrations aside) mentiontelemetry.manifest.build,blue.manifest.build,api.github.com/repos/mnfst,modelparams.dev,wingman.manifest.build,sentry.ioor any of the removed services and variables, or if@sentry/*is a dependency again.src/main.ts, fullAppModule) in a child process withNODE_ENV=productionand no opt-out variable. A preload (test/support/egress-recorder.cjs) records everyfetchURL and every DNS lookup, sohttp/netegress that bypassesfetchis caught too, and keeps the process offline. The test asserts:/api/v1/versionand/api/v1/discovery/completeanswer 404.provider-param-spec.service.ts: the boot check failed with the recordedhttps://modelparams.dev/api/v1/models.jsonfetch.AppModuleinto jest because ts-jest reports akeyvduplicate-type error onapp.module.tsthattsc/nest builddo not. No e2e had importedAppModulebefore.test/cors.e2e-spec.tscovers:THINKER_CORS_ORIGINSopt-in gets the preflight, the POST, the PNA header and maxAge, with no credentials.test/csp.e2e-spec.tsassertsframe-src 'self'and no remote origin in the CSP.test/drop-install-metadata-migration.e2e-spec.tscovers:test/drop-autofix-schema-migration.e2e-spec.tsnow reverts this PR's drop first, in runner order, so the table its revert touches exists.provider-param-spec.service.spec.ts:parseModelParametersCatalog, now exported) is tested directly.Hosted gateway guard (in
no-phonehome-egress.e2e-spec.ts):app.manifest.buildorgateway.manifest.buildanywhere in the CLI or shared source, tests included;DEFAULT_URLis nothttp://localhost:2099;Mutation check: with the old
DEFAULT_URLrestored, both CLI checks fail.CLI
config.spec.tsasserts the local default, including that an env key with nothing configured resolves tohttp://localhost:2099.index.spec.tsasserts thatagent listwith onlyMANIFEST_API_KEYsends every request, carrying the key, tohttp://localhost:2099.CLI
index.spec.tschecks that a command sends only its own request, writes no telemetry files, and that USAGE has no telemetry notice. The test helper no longer sets an opt-out variable.Gates (local; CI only runs on PRs to
main)npm run lint(root: shared, backend, frontend, cli)build, backendtsc --noEmit+nest build, clitypecheck+buildTZ=UTC, disposablepostgres:16(removed after)migration:run→ table absent.migration:revert→ table recreated (5 columns). Secondrevert(#16) →autofix_consented_atrestored.migration:run→ table absent, noautofix*columnspackages/backend/src packages/cli/srcqa-docker
Required: runtime behaviour changed (no outbound calls, CORS/CSP, migration, Dockerfile). The issue's acceptance criterion is network-level: a fresh container with no opt-out variable makes no request to
modelparams.dev,telemetry.manifest.build,blue.manifest.build,api.github.comor Sentry (DNS/egress log, as in #34).Review follow-ups (bfe9f1d)
escapeRegExp./setup/statuswithout a configured provider, inherited): Setup: não sondar o Ollama local sem provedor configurado #109🤖 Generated with Claude Code