Aller au contenu principal

Existing substrate — what App Works builds on, and what is missing

Status: Reference · Created: 2026-09-17 · Verified against: develop @ 873274c9f (2026-09-17; previously e5f43f44d, before that ee45946e5) Audience: anyone sizing or implementing an App Works epic

Re-verification 2026-09-17 (a655b53ca → ee45946e5). Every repository path cited as existing across the program was checked by script against develop @ ee45946e5, along with the symbols cited next to those paths and the line numbers in the plans. Nothing the program relies on was removed or renamed. develop gained AW-23 (Agent identity and brake) and AW-24 P1 (safety rails). The agent git tool defects APW-08 P0 fixes are still there unchanged; the AGENT_GIT_FACADE provider only moved to ~lines 597–749 of apps/api/src/agents/agents.module.ts. Five things are new, and the affected plans now say so. (1) Every Agent run passes a run admission chain: global stop flag → Agent brake → Work → organization → credits (APW-04, APW-08). (2) Every tool call passes a safety gate, and commitToRepo / openPullRequest / deploy count as publish.external, with default rung ask (APW-04, APW-08). (3) Approval proposals fold in the trust-ladder rung, and approveAll counts irreversible types as excluded (APW-09). (4) AuthenticatedUser.authMethod already exists as 'session' | 'api-key', so APW-12 appends a value and does not add the field (APW-11, APW-12). (5) The newest migration is 1791240000000-AddSafetyRailsCore.ts, still below every 1792… block. Citations fixed in this pass (all wrong or vague when authored, not moved by develop): a ... placeholder path, two shorthand filenames, paths for three evidence entries that named only a class, K8sApiService → KubernetesApiService (APW-07), the EVER_WORKS_DOMAIN source (APW-11) and evaluateAndRun's file (APW-08). APW-10 now has a naming note that separates its quarantine from the platform stop flag and the AW-23/AW-24 pauses. Re-checked on e5f43f44d (AW-22 workspace backup, a schedules flat-list fix and a job-runtime audit fix): no cited path moved and no cited symbol was removed, the newest migration is still 1791240000000-AddSafetyRailsCore.ts, APW-02's dispatcher arity now starts from 14 instead of 13, and every table an epic adds must now be classified for the workspace backup (Resolution R-25; row in §1).

Re-verification 2026-09-17 (e5f43f44d → 873274c9f, 21 commits). Re-checked every path and symbol the program relies on that these commits touch. Nothing the program relies on was removed or renamed, and the newest migration is still 1791240000000-AddSafetyRailsCore.ts, so the 1792… block is intact. Three things changed and the affected rows below now say so. (1) Fleet runs report the containment they actually got. A run's node-side record is normalised by normalizeFleetAgentTaskContainment (packages/contracts/src/fleet/fleet-jobs.types.ts:1301, shape at :1245, downgrade list at :1224) and read by apps/api/src/fleet/fleet-agent-task-reconciler.service.ts; the operator's home directory is denied to the model step through apps/node/src/core/model-execution/isolated-home.ts. A run can therefore be less contained than the design intends, and the record says so — APW-04 and APW-08 admission must read it rather than assume containment (see the row in §3 and Resolution R-33). (2) Clone URLs are validated before git sees them. isRemoteCloneUrl (packages/contracts/src/fleet/fleet-task-workspace.types.ts:239) allow-lists token-free https, http and ssh remotes and refuses option-shaped and transport-helper URLs; both workspace plugins call it (packages/plugins/local-workspace/src/local-workspace.plugin.ts, packages/plugins/sandbox-workspace/src/sandbox-workspace.plugin.ts). Plain http/https stay allowed, so the PR lane's fake GitHub on a loopback address still mounts. (3) Two acceptance-checks additions (apps/node/src/core/executors/acceptance-checks.ts) and a runtime change (apps/node/src/core/runtime.ts) — neither moves a path this program cites.

Standing rule (inherited from Agent Workspace). A "we don't have this" claim decays; a "we already have this" claim does not. Before building anything listed as missing below, search for it first. Every row names the file it rests on; line numbers are indicative and drift.

The headline: roughly half of the owner's loop already ships. The fork API call, server-side Kubernetes apply, a user-supplied kubeconfig, managed subdomains, custom domains, a per-Work Postgres provisioner, the Task → isolated workspace → checks → PR → merge-policy loop, the Fleet, the chat tool registry and the runtime-loaded Blueprint catalog are all real. What is missing is concentrated in: creating a Work from an arbitrary URL, understanding how to run arbitrary software, building it, running more than one stateless container, schema-driven env and dependencies, following upstream, and a hosting tier that is safe for user-controlled code.


1. Works, kinds and creation​

CapabilityState on developEvidence
Work kinds + capability matrixShips. USER_SELECTABLE_WORK_KINDS (website, landing-page, blog, directory, awesome-repo, repo), WORK_KINDS adds company, campaign, default. work.kind is varchar(32) modelled as an open string union so a new kind can ship server-first. Capabilities are a per-kind hide-list consumed by API, agent and web (tabs, metrics).packages/contracts/src/domain/work-kind.ts, packages/contracts/src/domain/work-capabilities.ts, docs/features/work-kinds.md
Repository Work (repo, EW-766)Ships — and is the closest precedent. GitHub-only URL parser; verifies the caller's own access (hasRepositoryAccess) before any side effect; 409 if another account already wraps the repository; persists sourceRepository.relatedRepositories.data, syncIntervalMinutes: 0; skips template, deploy quota, managed-git provisioning. One shared guard refuses every generator/deploy/write path. No fork, no build, no deploy — by design.packages/agent/src/works/repository-work-source.ts, packages/agent/src/works/repository-work-guard.ts, packages/agent/src/services/work-lifecycle.service.ts (createWork repo branch, resolveRepositoryWorkSource), docs/internal/feat-repo-work-kind-notes.md
Kind-aware create UIShips. Kind chips on /new and /works/new; RepositoryWorkForm (URL → derived name/slug); the Repository chip routes the composer text to /works/new?mode=manual&kind=repo&prompt=…. The createWork server action requires a connected personal git provider for repo.apps/web/src/components/works/RepositoryWorkForm.tsx, apps/web/src/components/new/NewPageClient.tsx, apps/web/src/app/[locale]/(dashboard)/works/new/new-work-client.tsx, apps/web/src/app/actions/dashboard/works.ts
Company / Campaign kindsShips. Minted by dedicated flows with deployProvider: null — the precedent for "a kind with no deploy by default".WorkLifecycleService.createCompanyWork
Work ImportShips. Arbitrary GitHub/GitLab/Bitbucket URL; modes data_repo, awesome_readme, link_existing. Directory-generation shaped; link_existing needs write access to that exact repository; no fork step.docs/features/work-import.md, SourceRepoAnalyzerService (packages/agent/src/import/source-repo-analyzer.service.ts), WorkImportService (packages/agent/src/services/work-import.service.ts), packages/contracts/src/api/work/import-source.dto.ts
.works/works.yml v2 kind specsShips. spec is discriminated by kind in KIND_SPEC_SCHEMAS; repo has source.{repo,branch}, tasks.{base_branch,checks} (checks bounded, documented as a trust boundary). Unknown kinds pass with a warning. tasks.checks IS read and executed today — repository-declared commands: readFleetRepoDeclaredCommands (task-workspace.service.ts:543) → parseRepoDeclaredCommands(spec) (:618) → admitRepoDeclaredCommands (:619), gated on the Work's repoDeclaredCommands.mode === 'allowlist' (:556, default 'off'), merged into the Fleet run plan at fleet-agent-task-planner.service.ts:589-590. Only tasks.base_branch is unread. Treat the block as a live trust boundary — its own module docblock is a "WHAT THE ALLOW-LIST DOES NOT BOUND" warning.packages/agent/src/works-config/schema/works-config.schema.ts, docs/agent-services/works-yml-schema.md, docs/features/works-config.md
Repositories registryShips. Account-level repo_connections, credential pointers, seed .env files, Agent attachments. Attachment is advisory for the sandbox/local workspace providers (no executor checks an attached repository out yet).packages/agent/src/services/repo-registry.service.ts, docs/features/repositories.md, docs/internal/feat-repo-registry-notes.md
Workspace backup (AW-22)Ships (added after authoring). Owner-only dated .zip of one workspace in 15 sections plus a manifest (/api/account/backups, migration 1791220000000-CreateWorkspaceBackups.ts). Coverage is one table, BACKUP_DOMAIN_SPECS; BACKUP_DROPPED_ENTITIES and the { wasSet } maps decide what never leaves. A secret-shaped column with no rule fails a test, but a table in no section is silently absent — hence R-25.packages/agent/src/account-transfer/backup/collectors/domain-specs.ts, collectors.spec.ts, packages/agent/src/account-transfer/backup/redaction.ts, apps/api/src/account/workspace-backup.controller.ts, docs/features/workspace-backup.md

2. Templates, Blueprints and catalogs​

CapabilityState on developEvidence
Work Blueprints catalogShips. manifest.json in the public ever-works/works repo, tokenless raw read with authenticated fallback, 1 h cache (30 s on failure), sanitized rows, public GET /api/work-templates?chipType=…, degrades to a built-in list. Template repos must match ^ever-works/[a-z0-9-]+$ (SSRF containment). The pattern to copy for the Apps catalog.apps/api/src/works/works-template-catalog.service.ts, apps/api/src/works/work-templates.controller.ts, docs/features/work-blueprints.md
Work Templates (fork-first)Ships. Fork a starter repository into the user's account/org with an owner picker; POST /api/templates/fork, POST /api/templates/custom accepts any GitHub URL as a catalog row. Forking is gated to sourceType === 'built_in'.packages/agent/src/template-catalog/template-catalog.service.ts (forkTemplateForUser), apps/web/src/components/templates/CreateCustomTemplateDialog.tsx, docs/features/work-templates.md
Runtime catalogs (ADR-014)Ships. ever-works/works, agents, orgs, skills, missions (+ placeholders tasks, ideas). Catalog content never lives in platform code.GitHub org ever-works; docs/features/agents-catalog.md, docs/features/skills-catalog.md, docs/features/mission-templates.md

3. Git provider, forks and pull requests​

CapabilityState on developEvidence
Fork a repositoryShips, narrowly used. forkRepository?(owner, repo, {name, organization, defaultBranchOnly}) → POST /forks, then polls repos.get 24×5 s (blocking ~2 min), null on timeout. Looks for an existing fork only when name is passed. hasForkRelationship compares parent only.packages/plugin/src/contracts/capabilities/git-provider.interface.ts, packages/plugins/github/src/github-api.service.ts
Repository metadataShips. getRepository returns isFork, parent, permissions — not source (root), allow_forking, archived.same
Sync a fork with upstreamMissing. No merge-upstream call. WebsiteUpdateService.updateFork returns true without syncing (dead path); template "sync" is clone → swap remote → push.packages/agent/src/generators/website-generator/website-update.service.ts
Ahead/behind divergenceMissing (compare-by-basehead exists as getCompareDiff, unused for this).github-api.service.ts
Cross-repository pull requestsMissing. createPullRequest passes head through but maps the result to head: data.head.ref, dropping the head owner; no head_repo / maintainer_can_modify.github-api.service.ts
Webhook installationMissing. Inbound GitHub events (pull_request, push, check_run/suite, workflow_run, installation) are handled at POST /api/ingest/github/events, but nothing installs a webhook on a user repository.apps/api/src/ingest/github/github-events.controller.ts, github-check-intake.service.ts
Actions secrets / workflowsShips. Set secrets/variables, list/enable/disable workflows, dispatchWorkflow.packages/plugins/github/src/github-actions.service.ts
OAuth scopesShips. Plugin OAuth requests repo, workflow, read:org, write:repo_hook, delete_repo, project, user scopes; the facade only asserts repo.packages/plugin/src/common/github.scopes.ts, packages/plugins/github/src/github.connection-scopes.ts, packages/agent/src/facades/git.facade.ts
Token resolutionShips. Explicit token → platform customer-org PAT when storage is managed → GitHub App installation token (sourceRepository.auth.mode) → user's OAuth account → plugin-settings PAT.git.facade.ts (resolvePluginAndToken)
Local checkouts (isomorphic-git)Ships, with two hazards. (1) Checkout directory is tmpdir/ever-works-repos/<slug(owner-repo)> — lower-cased with the separator lost, so a-b/c and a/b-c collide. (2) A NotFound/"empty" clone silently falls back to git init + remote — dangerous right after an asynchronous fork. No depth, no LFS; runs on the event loop.packages/plugin/src/git/git-operations.ts
Task workspaces (shell git)Ships. Sandbox and local worktree providers use shell git with --depth 1 default and per-operation credential injection.packages/plugins/sandbox-workspace/src/sandbox-workspace.plugin.ts, packages/plugins/local-workspace/src/local-workspace.plugin.ts
Agent git toolsAppear broken on develop (to verify with a failing test first). commitToRepo passes providerId: '' (the ?? fallback keeps '', then "providerId is required"), ignores branch; openPullRequest passes owner: '', repo: ''. Both hard-code github. Re-verified unchanged on ee45946e5; since AW-24 both tools are classified publish.external and pass the safety gate in AgentRunService.invokeTool before the adapter runs.apps/api/src/agents/agents.module.ts (AGENT_GIT_FACADE provider ~597–749), packages/agent/src/safety/action-category.ts
Fleet push credentialShips. GitHub App installation token narrowed to repository ids with contents: write only — cannot change workflow files or open PRs by itself.apps/api/src/fleet/fleet-push-credential.service.ts
Fleet run containment (added 2026-09-17)Ships, and is narrower than it sounds. A run reports what containment it actually got: FleetAgentTaskContainment (fleet-jobs.types.ts:1245), its bounded downgrade list (:1224), FLEET_AGENT_TASK_EXECUTION_PATHS = ['hardened','ordinary'] (:1207), coerced by normalizeFleetAgentTaskContainment (:1301) and normalised into the run by apps/api/src/fleet/fleet-agent-task-reconciler.service.ts:959. The isolated home (apps/node/src/core/model-execution/isolated-home.ts) is environment construction only — no filesystem boundary and no egress control — and the ordinary runner keeps or back-fills HOME/USERPROFILE/APPDATA, so Fleet setup steps and App checks run with the machine's real home directory and toolchain. App Work run admission must read this record (Resolution R-33) rather than assume containment.packages/contracts/src/fleet/fleet-jobs.types.ts, apps/api/src/fleet/fleet-agent-task-reconciler.service.ts, apps/node/src/core/model-execution/isolated-home.ts
Workspace clone-URL guards (added 2026-09-17)Ships. Both workspace plugins refuse a non-remote clone URL: isRemoteCloneUrl (packages/contracts/src/fleet/fleet-task-workspace.types.ts:239) allows token-free http, https and ssh (including the user@host: scp form) and rejects option-shaped (-…), transport-helper (helper::) and control-character forms; assertRemoteCloneUrl enforces it in local-workspace.plugin.ts and sandbox-workspace.plugin.ts. Plain http/https stay allowed, so the PR lane's fake GitHub on a loopback address still mounts.packages/contracts/src/fleet/fleet-task-workspace.types.ts, packages/plugins/local-workspace/src/local-workspace.plugin.ts, packages/plugins/sandbox-workspace/src/sandbox-workspace.plugin.ts

4. Build, deploy, hosting​

CapabilityState on developEvidence
Deployment pluginsShips. vercel and k8s implement IDeploymentPlugin; DeployFacadeService resolves plugin + token + settings per Work; DeployService.deploy orchestrates.packages/plugins/k8s/src/k8s.plugin.ts, packages/plugins/vercel/src/vercel.plugin.ts, apps/api/src/plugins-capabilities/deploy/deploy.service.ts
Two deploy pathsShips. (a) Workflow dispatch: secrets pushed to the Work's website repository, which builds its own image in GitHub Actions and deploys. (b) Server-side: for platform-managed clusters the API calls KubernetesPlugin.deploy() directly, because CI runners cannot reach those clusters.deploy.service.ts (deployServerSideManaged, workflow dispatch helpers)
Manifest renderingShips, single-container. Deployment + Service + Ingress + pull Secret for an image assumed to exist; per-tier memory floors; env from a <slug>-runtime-env Secret. No Jobs, CronJobs, multi-component, probes-from-spec, volumes or dependencies; not designed for untrusted code.packages/plugins/k8s/src/manifest.renderer.ts
Generic build of arbitrary reposMissing. No Dockerfile detection/generation, buildpacks, compose parsing. Today's builds exist only because the platform owns each template's Dockerfile and build workflow.repository-wide search
Cluster-source matrix / BYO kubeconfigShips. k8s-works-shared (default), k8s-works (admin-only), custom-kubeconfig (user-supplied, encrypted x-secret), validated server-side.apps/api/src/plugins-capabilities/deploy/cluster-source-matrix.ts, docs/specs/features/k8s-cluster-source-matrix/spec.md, packages/agent/src/facades/deployment-context.resolver.ts
Managed subdomainsShips. SubdomainAllocator + cloudflare-dns plugin; managed hosting env-gated with a per-user cap of 3 Works.packages/agent/src/ever-works-providers/subdomain-allocator.service.ts, docs/features/managed-hosting.md, EverWorksDeployQuotaService (packages/agent/src/ever-works-providers/ever-works-deploy-quota.service.ts)
Custom domainsShips. Add/verify/remove; verification checks the record resolves to the cluster's ingress; hosts merged into the Ingress.docs/features/custom-domains.md, deploy.service.ts (mergeCustomDomainHosts), packages/plugins/k8s/src/domain.handler.ts
Per-Work PostgresShips. One database + one role per Work, idempotent DDL, on a shared server or a user-supplied server. No Redis, no object storage. Built for platform-generated Works — must not be reused for untrusted apps as-is (README D8).packages/agent/src/ever-works-providers/ever-works-db-provision.service.ts
Runtime env for deployed sitesShips, allow-listed. WORK_RUNTIME_ENV_ALLOWED_KEYS is a fixed Stripe-shaped list; anything else is 400. Platform-minted keys assembled per deploy.packages/agent/src/services/work-runtime-env.constants.ts, deploy.service.ts (collectServerSideRuntimeEnv), docs/runbooks/WORK_RUNTIME_ENV.md
Deployment verificationShips. DeploymentVerifierService polls status and surfaces it on the Deploy tab and in Activity. DeploymentEnvironment is production / preview only.apps/api/src/plugins-capabilities/deploy/tasks/deployment-verifier.service.ts, packages/agent/src/entities/work-deployment.entity.ts
"Environments" featureShips — but it is agent sandbox runtime recipes, not dev/stage/prod deploy environments. Do not reuse the word.docs/features/environments.md

5. Agents, chat and the evolve loop​

CapabilityState on developEvidence
Platform chat toolsShips. ~400 tools (generated + hand-written) incl. create Work, create/run Task, Missions; destructive tools require confirmation.apps/web/src/lib/ai/tools/index.ts, work.tools.ts, missions.tools.ts, docs/features/platform-chat.md
Task → Run → PRShips, kind-agnostic. Run resolves an Agent; worktree-per-Task via the workspace capability; pipeline plugins (claude-code, codex, opencode, claude-managed-agent, gemini, agent-pipeline); finalize pushes, simulates the merge, opens a same-repository PR. taskIsolationTargetRepo is declared but not consumed — the triple work-output/data/provider exists on the entity (work.entity.ts:426) and is sanitised on import (account-import.service.ts:752,842), but nothing resolves it: task-workspace.service.ts:219-220 hard-codes work.getRepoOwner()/work.getDataRepo(), and the web write path accepts a different pair (z.enum(['work-output','linked']), apps/web/src/app/actions/dashboard/works.ts:1515). Repo targeting is therefore not configurable today — do not build on it.packages/agent/src/tasks-domain/task-workspace.service.ts, packages/agent/src/facades/workspace.facade.ts, docs/features/task-isolation.md, docs/features/tasks.md
Quality gatesShips. Per-Task or Work checkDefaults; red required checks send the agent back up to maxGateAttempts (1–5).docs/features/quality-gates.md
Merge policyShips. Five knobs resolved platform → tenant → org → Work → Agent; default allowAgentMerge: false; stable refusal codes.docs/features/merge-policy.md, git.facade.ts (mergePullRequest)
FleetShips. model-cli mode runs a local coding CLI in an isolated worktree, grades checks, pushes; multi-repo mounts (≤ 8); ask-human pause via .ever-works/QUESTION.md; browser-check job kind. Env grants are exact-name; prompt injection via a dependency README is a documented risk.docs/features/fleet.md, docs/internal/feat-fleet-*-notes.md
Job runtimesPartial. Trigger.dev is the registered runtime; other runtime plugins exist but the selector does not yet move the queue dispatchers (except the Fleet Agent-run path).docs/features/job-runtimes.md, packages/tasks/src/trigger/trigger.module.ts
MissionsShips. Typed Mission↔Work relations (created/improves/operates/markets/researches/retires); Missions are Idea → Work factories, not Task factories on an existing Work.docs/features/missions.md
GoalsShips. An iteration is a Task routed to a pinned/round-robin Agent; concurrency 1 by default. A Goal has no workId.packages/agent/src/entities/goal.entity.ts, packages/agent/src/goals/goal-orchestrator.service.ts, docs/features/goals.md
SchedulesShips. Task scheduled/recurring (RRULE/cron), Mission cron ticks, Goal check frequency.docs/features/tasks.md, docs/scheduled-work-system.md
Agent & Skill templatesShips — but read this before designing around it. The shipped agent templates are an in-code catalog (packages/agent/src/agents/agent-templates.ts:7,62, read by agent-templates.service.ts:56, written out as SOUL.md), and the ever-works/agents reader fetches manifest.json only (apps/api/src/agent-template-catalog.service.ts:50-51,191-212) — it does not read SOUL.md, .works/agent.yml or skills.yml (skills.yml has 0 references in any .ts; agent.yml exists only as one of five DB-inline file names, agent-file.service.ts:25). The Skills half is as described: SKILL.md from ever-works/skills (everworks-skills.plugin.ts:20, packages/agent-plugins/src/skills.ts:38). Loading agent templates from the catalog repo's files is new work (APW-04 plan:607 calls it "(new, additive)").apps/api/src/agents/agent-template-catalog.service.ts, packages/agent/src/agents/agent-templates.ts, docs/features/agents-catalog.md, docs/features/skills-catalog.md
Activity logShips.docs/activity-log-spec.md, docs/features/activity.md, apps/api/src/activity-log
Run admission, Agent brake, safety rails (AW-23 / AW-24, added after authoring)Ships (AW-24 P1 only). Every Agent run passes DEFAULT_RUN_ADMISSION_CHAIN: global stop flag (parks kill-switch) → Agent brake (parks agent-paused while the Agent is paused or archived) → Work valve → organization valve → credits. Every tool call passes SAFETY_GATE (platform stop, workspace pause, caps, trust ladder, …); commitToRepo, openPullRequest and facade:deploy are publish.external (default rung ask, shown but not enforced until an explicit rung is set or SHIPPED_DEFAULT_RUNG_POLICY becomes enforce in AW-24 P2). Approval proposals fold the rung in (stricter wins) via PROPOSAL_ACTION_CATEGORY. Task finalize pushes and pull requests are not gated by the ladder yet.packages/agent/src/agents/run-admission-chain.ts, run-dispatch-gate.service.ts, agent-brake.service.ts, agent-halt.service.ts, packages/agent/src/safety/action-category.ts, safety-gate.port.ts, guardrail-interop.ts, packages/contracts/src/safety/action-category.types.ts, docs/specs/features/agent-workspace/AW-24-safety-rails/

6. Identity and cross-platform navigation​

CapabilityState on developEvidence
Sign-inShips. Better Auth behind an abstraction; bearer() plugin; hashed random session tokens (older docs still say "JWT"); email/password, magic link, anonymous, GitHub/Google/Facebook/LinkedIn. Not an OpenID Connect provider (no JWKS, no authorization server).apps/api/src/auth/providers/auth-provider.abstract.ts, apps/api/src/auth/providers/auth-runtime.instance.ts
Credential path on the request (AW-24, added after authoring)Ships. AuthenticatedUser.authMethod?: 'session' | 'api-key', stamped by AuthSessionGuard on both branches (fleet-run ew_run_ tokens stamp 'api-key'). @HumanOnly() + HumanActorGuard refuse anything but 'session', fail closed on a missing stamp. APW-12 extends this union; it does not add the field.apps/api/src/auth/types/auth.types.ts, apps/api/src/auth/guards/auth-session.guard.ts, apps/api/src/safety/guards/human-actor.guard.ts
Token hand-off to local clientsShips — do not extend. /api/auth/authorize + addSessionTokenToUrl put the session token into a query string for allow-listed local hosts (CLI, node). Not a pattern for cross-site SSO.apps/web/src/app/api/auth/authorize/route.ts, apps/web/src/lib/utils/url.ts
API keysShips. ew_live_ keys, ≤ 10 per user, full user powers, no scopes.docs/features/api-keys.md
In-product switchersShips. Organization switcher (WorkspaceSwitcher), Work switcher (WorkSwitcher), command palette. No cross-platform launcher.apps/web/src/components/layout/WorkspaceSwitcher.tsx, apps/web/src/components/dashboard/WorkSwitcher.tsx
Live URLs a launcher can listShips. WorkDeployment, WorkCustomDomain, deployProvider, observe URLs on the Work.packages/agent/src/entities/work.entity.ts

7. Launch-parity backlog items this program closes or touches​

docs/internal/launch-parity-backlog.md: G-24 ungate managed hosting (APW-06/10), G-22 vertical presets, gallery and remix = fork into your account (APW-01/03), G-09 enterprise identity — "no page may claim SSO" until it ships (APW-12 must respect this in every doc and UI string until Ever ID is live).