# Orbit 1.7.0 documentation # Settings and access Open Orbit → Settings as an agency owner or administrator. Settings are divided into focused sections: - **General:** enable Orbit, floating launcher, agency access and reviewed CRM changes. - **AI connections:** connect the account provider, choose its model and set daily reply limits. Personal ChatGPT access remains subject to configured registration and plan approval. - **GitHub & code:** connect GitHub, choose the CRM repository and review source-change permissions. - **Support:** configure the support agent, approved knowledge, permitted CRM tools and human handoff. - **Voice & screen:** configure calls and permitted in-app screen controls. - **Appearance:** choose the account theme and personal companion. - **Advanced:** allow specific extension endpoints. General, account-provider, appearance and extension changes use Save settings. Provider connections and GitHub connection actions happen immediately. Support and voice settings retain their own save controls. Switching sections does not discard the unsaved account settings form. ## Who sees what Agency owners and administrators have the full workspace, subject to native Orbit and settings permissions. Ordinary users see Support, their support conversations and My requests. They do not receive settings, guided-agent management or source-code controls. Their support tools remain limited by the configured support allowlist, native resource permissions and account boundaries. Connecting a CRM API key does not broaden those permissions. New ordinary-user conversations use support mode. Existing general conversations are retained, but ordinary users cannot continue their general-chat execution to bypass support policy. If support or Orbit is disabled, the user sees an unavailable state; enabling general Orbit does not silently enable support. ## Code changes in chat Admins can ask Orbit to draft a code request or use Code request in the composer. Review code request opens the source selector and full diff review inside the conversation. Back to chat restores the conversation and any unsent draft. The admin chooses existing files and prepares a proposal; the model does not get authority to choose and publish arbitrary files. Approval and the direct Open draft PR link work as in Code changes. See [Code review](CODE_CHANGES.md). --- # Reviewed application changes — local implementation Status: local implementation, not a published Orbit release. The portable module and isolated Seedly host are the scope of this change. No production deployment, real provider inference, GitHub branch, or PR was created during fixture validation. ## Included workflow An agency owner or administrator opens **Orbit → Code changes**, connects the private GitHub repository containing their CRM, chooses up to six existing UI, backend, shared-library, or test files, selects an existing OpenRouter, approved personal ChatGPT, or configured Local Codex connection, and describes a fix. Orbit reads the files at one immutable default-branch commit, together with bounded repository instructions, architecture context, and installed dependency manifests when available. The model returns replacement source as data. Orbit validates the proposed files and parses changed TypeScript in a module-owned Node action using TypeScript 5.9.3, then saves the original and proposed contents, and shows a diff plus the full files. It does not execute the generated code. After reviewing the exact proposal, the owner can explicitly create one new `orbit/fix-*` branch and a **draft** pull request. This action can trigger the repository's own automations; the confirmation states that before submission. Orbit never merges, updates the default branch, force-pushes, deploys, or sends CRM messages. The owner runs trusted checks and reviews the GitHub PR before merging through their usual workflow. ## Connections - GitHub uses a fine-grained token restricted to the selected private repository, with Contents and Pull requests read/write. Connect checks private-repository identity and source read access without writing a test branch. GitHub enforces write permissions during the explicitly approved publication; connecting does not certify those permissions. GitHub App sign-in and repository selection are also supported; see GITHUB_APP.md. - Tokens use the existing `ORBIT_KEY_ENCRYPTION_SECRET` AES-GCM storage with an additional module/agency/location/user binding. Public queries expose connection status, never credentials. A disconnect removes local ciphertext and invalidates pending proposals; revoke the token in GitHub to remove the remote grant as well. - OpenRouter reuses the existing location connection and selected model. There is no automatic fallback or automatic retry. - The personal ChatGPT path reuses the existing registered-client transport, per-user/location account, selected model, token-rotation fencing, and `ORBIT_CHATGPT_PLAN_ACCESS=approved` gate. It is not a Codex CLI login or a claim that a Codex subscription has been connected. - The Local Codex connector uses the signed-in CLI only for an explicitly bound operator on a trusted private CRM host. Do not copy Codex credentials into Orbit or share one operator’s login with unrelated users. A hosted multi-user ChatGPT integration remains separate and requires its applicable registration and plan access. See [LOCAL_CODEX.md](LOCAL_CODEX.md) and [CHATGPT.md](CHATGPT.md). ## Enforced boundaries - Native Orbit access, active tenant membership, agency owner/admin role and settings-update permission are rechecked on reads, generation, review, claim, and publication. An API key never grants the user more CRM authority. - Both new tables (`soCodeConnections`, `soCodeJobs`) are private and registered with the tenant-purge index. Connections and jobs are per user and location; another manager does not automatically inherit a user's token or source proposals. - Existing `.ts`, `.tsx`, and `.css` files below `apps/web/app`, `apps/web/components`, `apps/web/lib`, `apps/web/__tests__`, `convex`, and `packages/shared/src` or `packages/shared/__tests__` are eligible; backend files must be TypeScript. Layouts, auth/permissions, credentials, billing/payments, schema, migrations/seeding/purge/cron code, dependency/configuration files, CI, deployment, and Orbit’s own code-review engine are excluded. New files, deletion, renaming, symlinks, submodules, binary files, path traversal and unselected-file changes are refused. - File path filtering is a scope boundary, not a proof that arbitrary generated application code is safe. A human must inspect the full diff, including effects on network requests and data disclosure. No generated commands run in this implementation. - Individual source files are capped at 48 KB; selected source totals 160 KB; six files and five requests per user/location/UTC day. Limits bound requests, not dollar spend. Common embedded credential patterns cause refusal before source is sent to the provider. This heuristic is not a complete secret scanner; use a clean source repository. - Repository data and the user request are explicitly lower-priority task material. Knowledge and prompts do not grant tools, shell, network, or publishing authority to the model. Missing or out-of-scope context must produce no publishable edits. - Approval binds a SHA-256 digest to the full source snapshot, repository ID, base commit, selected files, proposal, static analysis report, required reviews, dependency context and policy version. It expires after 30 minutes. Changed source or connection/provider settings require a new proposal. - Publication is claimed once atomically. Every external write is preceded by a fresh authority check. Commit and branch recovery identity is stored before a visible branch is created. An interrupted/uncertain write stops the request without replaying it. Inspect GitHub manually before taking further action. Disconnect cannot recall an already in-flight request. - A draft PR and static validation are not passing tests. The UI and PR state that no build or tests ran on the proposed CRM fix; suggested checks are labeled unverified. No merge or deploy control is exposed. ## Hardening pass The second policy revision invalidates first-revision proposals; prepare a fresh request to use the stronger checks. Existing table additions are optional for schema compatibility. This is still a local implementation, not an expanded production release. - Provider connections are compared using a fingerprint of the encrypted connection and current configuration, not just a timestamp. Replacing an OpenRouter key in the same millisecond invalidates the old request. Personal ChatGPT token refresh preserves the connection revision rules. - The backend verifies a submitted snapshot's repository identity, selected paths, regular-file modes, byte limits and Git blob checksums again before saving it. Review hashes bind the complete snapshot and proposed edits. - At this earlier revision, new imports, remote URLs, network/storage/code-execution indicators, executable HTML, validation suppressions, and client/server boundary changes are refused. Changes are limited to 400 changed lines and 40 KB across the reviewed files; replacing most of a substantial file is refused. These are conservative static indicators, not semantic proof or a sandbox. Human source review and trusted checks remain required. - A missing-context response is saved with its explanation and no approval button. Expired generation requests cannot save a late result or hold up future work. - Each execution has an internal identity excluded from user-facing queries and model context. Publication records each request stage before the corresponding remote write and each confirmed receipt afterward. A stale execution cannot settle another attempt. An expired publication lease cannot grant permission for more writes. - Before creating a visible branch, Orbit verifies the actual commit's single parent and walks the old and new Git trees. Every unselected path and file mode must be unchanged; every selected new blob must match the reviewed content. Repository privacy/default branch and source freshness are checked again before visible writes. The returned PR must match the repository IDs, branch names, base and head commits, and review marker. - Confirmed receipts can be recorded after a caller loses their role, so a completed remote write is not lost from the audit trail. That recording grants no new access or publication authority. The revoked caller cannot read the result. - **Check GitHub status** is a read-only recovery action. It works without an inference provider and can use a reconnected token for the same repository. It verifies the stored commit and complete tree, current branch, and matching PR. A confirmed PR is adopted; a branch-only or missing result is explained without retrying a write. Retargeted branches, foreign PRs, ambiguous results and missing proof require manual inspection. - Cross-service checks are not a distributed transaction: a remote administrator can still change GitHub state between reads and writes. A branch or draft PR can trigger repository automations. Keep those workflows appropriately scoped and review the current PR before merging. ## Application-change expansion Policy `seedly-application-changes-3` supports bounded fixes to existing backend handlers and business logic, shared utilities, and regression tests alongside UI fixes. Examples include correcting a calculation, fixing a contact filter while preserving its account constraint, normalizing input within an authorized update, or repairing an existing regression test. New files, migrations, auth infrastructure and general shell execution remain outside this workflow. Older unsubmitted proposals must be regenerated; uncertain publications from older policies require manual GitHub inspection if their proof cannot be verified under the current policy. Changed TypeScript is parsed without executing it. The analyzer compares recognized authorization calls, their scopes/awaiting, account filters, ownership conditions/assignments, database targets and the relative order of existing authorization/database calls. New raw database writes require a matching existing create/update permission in their scope. New destructive operations, authority reassignment, disabled tests, and removal of existing tests/assertions are refused. New static imports must resolve to selected source, standard Convex helpers, or a dependency named in the captured manifests. This checks context availability, not package exports, resolution or type correctness. These are conservative source checks, not a security proof. Aliases, dynamic behavior, helper internals, indirect effects and the semantics of changed business logic still require full human review and trusted project checks. Source parsing cannot prove account isolation or compatibility. Repository text and generated code never run as a command, test runner, plugin or module during analysis. The module-owned parser dependency is pinned and installed with lifecycle scripts disabled. Backend changes require explicit acknowledgement of authorization, account isolation, side effects/deployment, and planned regression tests. Shared-library changes require compatibility and regression-test review. Changes to tests also require regression review. The server derives these requirements from the changed files, includes them in the immutable digest, and refuses publication if any required acknowledgement is missing. A checkbox confirms review; it does not certify that tests passed. The same report appears in the draft PR. No merge or deployment runs automatically. The original hardening checks below remain in force. Validation figures in the history below describe their respective earlier snapshots. ## Validation and remaining work The source policy suite checks restricted paths, credentials, file limits, tamper-bound review hashes and diffs. Installed-host tests use independent GitHub/model fixtures for encryption, tenant/role isolation, read-only generation, reviewed publication, stale branches, revoked access, scope escape, symlinks, cancellation and uncertain-write replay refusal. The initial November 5, 2026 implementation at `e0a820a` used module source snapshot `9aa84df1ea1631de61921745058088a380a7a841`, installed into a disposable clone of the private Orbit test host at `ca3031f3b213e6982f671d21ebf8882a363b4046` (Seedly 5.8.4). No deployment environment files were copied. Application API declarations were regenerated locally from the current modules using Convex's template while preserving the installed component declaration; authenticated component generation was not invoked because it pushes code to a backend. - `npm run orbit:test`: 42 passing source/installer/package tests. - Installed-host Convex tests for Orbit, ChatGPT, and code changes: 121 passing. - Installed-host browser component tests for exact-diff consent, consent invalidation, escaped source and expiry: 3 passing. - Existing host tenant-purge index and hardening checks: 15 passing. - Installed-host backend TypeScript check: passed. - Installed-host web TypeScript check: passed. - Production build and live provider/GitHub acceptance: not run for this local implementation. The hardening pass is based on `e0a820a` and uses the same isolated host. Its local suites pass 50 source/installer/package tests, 152 installed backend and tenant-cleanup tests, and 9 browser component tests (211 total). New cases cover complete-tree verification, wrong commit parents, same-timestamp key replacement, missing context, read-only recovery, changed branches and foreign PRs, late receipts after role revocation, execution identity fencing, expired leases, request deduplication, hidden credentials, and stale generation cleanup. Static checks also exercise unsafe capability additions, client/server boundaries, excessive diffs, Unicode controls and snapshot checksum tampering. Final hardening verification: - Backend and full web TypeScript checks passed. The web compiler's recorded source hashes were checked against the final coding-module files. - The full Next.js production build passed, including static-page generation. Next's existing configuration skips its embedded typecheck/lint, so the separate successful TypeScript checks above are authoritative. Sentry/OpenTelemetry and jose Edge-runtime dependency warnings remain; this change does not modify those dependencies. - The first build hit a temporary-filesystem quota while writing Webpack cache. Its output was preserved, and the successful retry used disk-backed local output with links to the same installed dependencies. No application source was changed for the retry. - Installer doctor confirms the host source, registered extension contributions and receipt match the module. - Active-request checks read only the bounded recent quota window, avoiding scans of dozens of full source snapshots. - No production environment files, live provider inference, real GitHub mutations, merges, deployment or asset uploads were used. Authenticated backend/component generation and live integration acceptance remain required before a release. When this becomes a release, deploy the new backend functions and private tables before the web update. Live provider execution, a real private test-repository PR, full backend/component generation, and deployment acceptance remain separate checks. Next milestones are repository browsing/context discovery, an approved commercial subscription execution adapter, GitHub App onboarding, and isolated trusted validation with no production credentials. Do not call this release production-certified before a real private test repository and provider run have been reviewed. ## Application expansion validation — November 5, 2026 The application expansion is based on hardened source `0e8aa74` and uses the same private Seedly 5.8.4 host described above. Module source and the installed host match byte for byte. - 52 module source, installer and package tests passed. - 169 backend tests passed: 32 code-workflow tests, 15 source-analysis cases, and 122 existing Orbit, ChatGPT and tenant-cleanup tests. - 10 web review tests passed, including required backend acknowledgements and reset after the reviewed digest changes. - The repository-wide installer regression suite passed 164 tests with 5 existing skips. - Full backend and web TypeScript checks passed. The web compiler's recorded hashes match the final source files. - Installer doctor passed; reinstall dry run reports zero source changes. - Full local Next.js production build passed, including page generation and build traces. Existing Sentry/OpenTelemetry and jose Edge-runtime dependency warnings remain. Separate type checks above cover the build configuration’s skipped embedded type validation. These tests validate the Orbit implementation using fixtures. They do not certify a customer's generated proposal, execute real model inference, or create a live GitHub PR. Trusted project tests and human review remain required for each proposed CRM change. ## Code requests inside chat An agency administrator can ask for a source change in chat or choose Request a code change below the composer. Orbit produces a request draft; it does not read GitHub or write a branch at that step. Review code request opens the source selector and full review inline. The administrator chooses the existing files, prepares the proposal, reviews the exact diff and acknowledges the required reviews before creating a draft PR. Requests are bound to the originating conversation. Archiving it or handing a support conversation to a person blocks further code publication from that conversation. GitHub can now use the registered-app browser flow described in [GitHub App setup](GITHUB_APP.md). User access tokens stay encrypted, rotate under a refresh lease and respect both user and app permissions. This does not add automatic customer-ticket-to-PR generation or automatic merging. ## Local Codex subscription The private/self-hosted connector can generate proposals through a Codex CLI signed into ChatGPT on the CRM host. It is restricted to one configured native user/account and keeps authentication local. It retains the same selected-source, validation and draft-PR review gates. See [Local Codex setup and limits](LOCAL_CODEX.md). This does not enable subscription access for unrelated users or replace the ordinary support/chat provider. --- # Connect GitHub with an app Orbit supports a browser sign-in and repository picker. Customers do not need to create personal access tokens when the installation has a configured GitHub App. The existing fine-grained-token option remains under Advanced. ## One-time setup for the installer Register a GitHub App owned by the organization that operates this Orbit installation. Configure: - Callback URL: `https://YOUR_CRM_HOST/api/orbit/github` (exact match; no query parameters). - Repository permissions: **Contents: Read and write**, **Pull requests: Read and write**. Metadata is read-only. Do not request Actions, Administration, Secrets or deployment permissions for this workflow. - Expiring user access tokens: enabled. Orbit also requests `offline_access` to require expiring credentials. - Webhooks: not needed by this implementation. Repository removal or revoked authorization is enforced by GitHub on the next API call. Set these server environment variables on the correct Convex deployment: | Variable | Value | | --- | --- | | `ORBIT_GITHUB_CLIENT_ID` | The app's client ID, not its numeric app ID | | `ORBIT_GITHUB_CLIENT_SECRET` | A client secret generated for the app | | `ORBIT_GITHUB_APP_SLUG` | Its URL slug, as shown at `github.com/apps/SLUG` | | `ORBIT_GITHUB_REDIRECT_URI` | The exact callback URL above | The web host's `SITE_URL` must match its real public origin so the callback and form-origin check use that origin. `ORBIT_KEY_ENCRYPTION_SECRET` remains required. No GitHub private key is required: this flow uses GitHub App **user access tokens**, so permissions are the intersection of the app installation and the signed-in GitHub user. Use your own CRM origin in the callback. Keep the client secret in deployment secret storage, never in Git, chat, screenshots or a browser environment variable. ## Customer flow 1. Open Orbit Settings → GitHub & code → Connect GitHub. 2. Authorize the app in GitHub. If it has not been installed on the CRM repository, use Manage repository access to install it with only that repository selected, then refresh the list. 3. Choose the active private CRM repository, confirm authority, and select Use repository. 4. Start a code request from chat or Code changes. Connecting GitHub does not grant automatic publication: review the selected files, proposed changes and required checks before creating each draft PR. The picker includes private, active repositories for which both the installation and the user have the required write permissions. It follows repository pages within a shared budget of 10 pages (up to 1,000 repository records) across at most 10 installations and labels truncation. For a large account, restrict the app installation to the intended CRM repository and refresh. ## Security and operational behavior The authorization transaction uses PKCE, a random state, an HttpOnly same-site browser cookie and a tenant/user-bound encrypted transaction. State is consumed once. Role, account and browser identity are rechecked on callback. Access and refresh tokens are encrypted with the existing Orbit encryption secret and excluded from all public status responses. Access tokens expire and are renewed under a single-use refresh lease. Interrupted or failed renewal requires reconnecting; it is not automatically replayed. Changing the GitHub account, app identity or repository invalidates pending code requests. Disconnect removes local credentials and stops new requests; remove the app's authorization/installation in GitHub to revoke the remote grant too. Already in-flight GitHub operations cannot be recalled. OAuth and repository access are covered by local fixtures. A real GitHub App must be registered and tested against a private repository before calling the one-click flow live-verified. The Connect GitHub button prepares its authorization transaction through a same-origin POST, receives the validated GitHub authorization URL as JSON, and then navigates the browser to GitHub. Keep the host's `form-action 'self'` security policy: redirecting a submitted form directly to GitHub is blocked by that policy in Chromium. The browser cookie, PKCE, state and native authorization checks still apply to the JSON handoff. References: [GitHub App user access tokens](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-user-access-token-for-a-github-app), [token renewal](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/refreshing-user-access-tokens). --- # Local Codex subscription connector Code requests can use the Codex CLI signed into ChatGPT on the same trusted machine that runs the CRM web server. This is a local, owner-bound connector for code discussions and proposals. It is separate from the registered-client ChatGPT text provider and from OpenRouter. The chat composer exposes Local Codex for code help and the account AI for CRM data/actions; ordinary user support keeps its configured provider. The connector is intended for a private local or self-hosted CRM. Do not enable one person's Codex login for customers or a public multi-user service. Each operator needs their own authorized local connection. The CLI must remain available and signed in; subscription limits still apply. There is no automatic fallback to API billing. ## Installer setup 1. Install a current Codex CLI on the CRM web host and run `codex login` using ChatGPT. This implementation is validated with CLI 0.164.0. `codex login status` must say `Logged in using ChatGPT`; API-key login is refused. 2. Set `ORBIT_CODEX_LOCAL_BINDING` in the CRM's Convex deployment to `:`. This restricts the connector to that exact account and user in addition to the existing administrator/settings permission checks. 3. Set `ORBIT_CODEX_LOCAL_MODEL` in Convex to a model available to that Codex subscription, using the model identifier available in your own Codex installation. 4. Set `ORBIT_CODEX_LOCAL_ENABLED=true` on the web host. Optionally set `ORBIT_CODEX_BIN` to the installed executable's absolute path and `ORBIT_CODEX_TMP_ROOT` to a private working directory outside the application source. 5. Deploy backend/schema first, then web code. Use Local Codex code help directly in chat, or open Code changes / Request a code change and choose Local Codex. Availability reflects installer configuration; a completed request verifies actual subscription access. No Codex token or auth file is copied into Convex, the browser, the repository, or a deployment bundle. The CLI reads its own existing local login. Its child environment excludes API keys and CRM credentials. ## Guardrails The web route requires a same-origin authenticated request. Convex rechecks the installer-bound user/account, native administrator permissions, selected private GitHub repository, source paths, quota and current connection. It pins the source on the server before starting the local process. Completing a request reads that stored source; callers cannot supply a replacement snapshot. The CLI runs in a fresh temporary directory, with a read-only sandbox, user configuration ignored, shell, app/MCP/plugin, browser, image, and multi-agent features disabled, and a strict JSON output schema. An observed tool call, failed turn, timeout or oversized output rejects the request. This connector asks Codex for a proposal; it does not let Codex edit the checkout, run project commands, create a branch, merge or deploy. Temporary files are removed after completion. The returned proposal goes through the existing source-boundary and TypeScript checks. The complete diff, immutable digest, required reviews, repository checks, explicit draft-PR approval and publication recovery remain unchanged. Revoking the local binding or changing its model invalidates pending proposals. References: [Codex authentication](https://learn.chatgpt.com/docs/auth), [non-interactive mode](https://learn.chatgpt.com/docs/non-interactive-mode). ## Code requests from ordinary chat For the bound administrator, Local Codex is selected by default in the chat composer. Natural-language code or design requests can return a code-request card and suggested paths from a bounded index of the connected repository. File contents are fetched only after the user reviews the selection and prepares the proposal. Clarifications can continue in the same conversation. The normal account AI remains selectable for live CRM data/actions, and support conversations cannot use this local owner login. Previous HTTP 402 replies expose Retry with Local Codex. The retry resubmits the original request through the local connector; it does not change or erase the old record. Local failures do not fall back to a paid API. Native run ownership, duplicate detection, limits, cancellation, encrypted execution tickets, and permission rechecks apply. --- # Managing voice and screen access Open **Orbit → Settings → Voice & screen controls**. Agency managers can enable calls, connect/replace/disconnect the account voice key, choose a voice and language, set call duration and daily limits, adjust metadata retention and optional cost estimates, and pause or resume voice across the agency. Connection and agency pause buttons act immediately; configuration fields use **Save voice & screen settings**. Choose a screen access level: navigation only; navigation and screen context; read/filter/open records; or those controls plus unsaved draft filling. Select which pages are allowed: Contacts, Tasks (including its list), Pipelines, Calendar, Conversations and Orbit. An empty selection disables all screen destinations. Turning screen access off leaves voice and reviewed CRM tools available. Existing settings without a level/page selection retain the previous full supported access; every caller must still opt in. **Apply to** selects this account or agency defaults. Locked agency defaults cannot be overridden. **Use agency defaults for voice and support** removes the entire account policy override, including support configuration. Saved policy changes invalidate active calls. **Allow CRM changes** in the main settings remains the prerequisite for draft filling and reviewed CRM writes; support calls also follow **Configure support agent → Diagnostics & actions**. Screen settings never grant native permissions or bypass review. Callers see the configured access level and pages before opting in. During calls they can mute, pause/resume screen controls, view activity, review proposals, or end the call. Escape and spoken pause requests stop screen work; only a user click resumes it. # Expanded native screen controls — October 14, 2026 With screen access enabled, Orbit can navigate Contacts, Tasks (dashboard and list), Pipelines, Calendar and Conversations; inspect their registered controls; filter supported lists; open loaded records; and fill contact, task, deal, appointment and message drafts. Available controls depend on the current view, loaded data and permissions. This is structured in-app control, not desktop or arbitrary browser takeover. No extension is needed. Inspect before each edit: commands bind to the exact screen revision and account. Human edits, changed routes, unmounted views and paused calls invalidate stale work. Each result waits for committed UI state. Pause screen control, press Escape, or ask Orbit to pause; resuming requires the user's button click. Voice can continue while controls are paused. End disconnects audio and cancels pending work. Draft filling does not save, book, send or approve anything. Users submit native forms themselves; direct CRM actions still use Orbit's review cards. Do not both fill a native form and create the same record through an API proposal. Consent shares supported visible record labels and draft fields with the voice model. UI content is untrusted data, never instructions. Native role checks, Orbit tool permissions, support allowlists and practice restrictions apply server-side. # In-app Orbit voice and Seedly actions October 14, 2026 update. **Call Orbit** is available in regular conversations as well as support. No browser extension or desktop companion is required. OpenAI Realtime handles speech; the existing Orbit worker handles permission-checked CRM reads and reviewed actions. ## Using the call 1. Open a conversation in Orbit or its floating launcher. Select **Allow Orbit to use Seedly screens** if you want spoken requests to open pages, then choose **Call Orbit** and grant microphone access. 2. The persistent voice panel stays mounted as you navigate within the account, including returning to Orbit. Mute and End are always accessible. Closing the voice panel, changing account, leaving the dashboard or refreshing ends the call. Hiding the conversation does not end it. 3. Ask for CRM work such as finding contacts or preparing a task. Open **Conversation & approvals** in the voice panel to inspect evidence and approve a change in the exact originating conversation. Ordinary chats use normal Orbit permissions; support calls additionally enforce the configured support tool allowlist. Voice never bypasses reviewed writes. 4. Ask to open Contacts, Tasks, Pipelines, Calendar, Conversations or Orbit. The backend checks the current account, native feature and resource permissions, and per-call consent. The browser independently checks the destination against fixed routes and reports success only after the router reaches it. Route acknowledgement does not certify data loading. No arbitrary URL, selector, generated script, screenshot access or other website control is exposed. ## Configuration In **Orbit → Settings → Voice & screen controls**, connect a direct OpenAI key and enable **Call Orbit**. Existing agency defaults, locked overrides, voice pause, call quotas, maximum duration, credential encryption and retention apply to both conversation types. Support itself can remain disabled while regular Orbit voice is enabled. Enable in-app screen controls in this section to let callers opt in per call. The text worker needs its configured provider or the user's enabled personal ChatGPT connection; voice always uses the separate OpenAI API credential. The voice panel lives in the existing dashboard floating integration, independently of the companion's hidden preference and normal floating-chat setting. It opens only after an explicit Call Orbit click and never resumes automatically after a refresh. A failed or completed call requires another explicit start. Current-context permissions are rechecked for every backend tool; cancellation discards late results and aborts pending navigation acknowledgement. Live audio acceptance still requires a funded direct OpenAI voice connection and actual microphone/playback testing. See VALIDATION.md. The historical 1.6 support-only implementation below documents the original candidate; its user-clicked page links and support-only entry point are superseded by the behavior above. --- # Live support — Orbit 1.6 Signed-in Seedly users can speak with an AI assistant from an Orbit support conversation. Browser audio uses OpenAI Realtime over WebRTC. The voice assistant delegates support questions and CRM work to Orbit’s existing support runtime, using the selected chat provider, approved knowledge, native resource permissions and support tool allowlist. CRM writes remain immutable proposals approved with the on-screen card. Spoken approval never executes a write. ## Agency and account setup 1. Install 1.6 and deploy the Convex schema/functions before deploying the web app. `soLiveSessions` must remain a private extension table with `by_subAccount` purge indexing. 2. Keep Orbit’s current chat provider connected. Voice and the support worker have separate provider usage; live speech does not replace the worker’s model. 3. Configure `ORBIT_KEY_ENCRYPTION_SECRET` using the existing installation instructions. Never put provider keys in `NEXT_PUBLIC_*`, source, chat, or screenshots. 4. As an agency manager with settings-update permission, open **Orbit → Support → Configure support → Live voice support**. Connect a direct OpenAI API key for this account. The key is encrypted with tenant-bound AES-GCM. Model lookup verifies access without a voice inference request; it does not prove sufficient credits or working audio. 5. Enable **Speak with AI**, select Marin/Cedar/Coral, and set 1–15 minutes per call and 1–50 reservations per user per UTC day. A failed connection consumes a reservation. Defaults are disabled, five minutes and ten calls. 6. The existing Apply to selector controls agency defaults or account overrides, including override locks. Credentials always belong to the current account. An installer can optionally configure server-only `ORBIT_REALTIME_API_KEY`; that is a deployment-wide fallback billed to its owner, not a per-agency credential. Removing a saved account key can reveal this fallback. 7. Save support settings, start a support conversation, then choose **Speak with AI**. Microphone access requires HTTPS or localhost and a supported WebRTC browser. The call identifies itself as AI. Customers can mute, interrupt speech, end the call, and read live captions. ## What the assistant can do - Explain approved product guidance and clarify an ambiguous problem. - Ask Orbit to inspect permitted CRM records or configuration and speak a short summary. Evidence and proposal cards remain in the conversation. - Navigate supported Seedly pages and inspect registered UI state after per-call consent and native permission checks. Controls can filter lists, open loaded records and fill supported unsaved native drafts. No screenshots, arbitrary selectors, generated code, external tabs, submit, send, delete or approval controls are exposed. - Direct the user to the existing **Talk to a person** flow. The requester still reviews the destination and summary before submission. ## Execution and security contract `liveProvider.start` accepts only a browser SDP offer, a requester-owned support thread, location and guidance preference. It creates a server-owned Realtime configuration and sends the SDP to `/v1/realtime/calls`; no standard or ephemeral provider key is returned to the browser. The browser forwards function calls to authenticated Convex actions. Browser/model arguments are untrusted: every request revalidates session ownership, location, support revision, enabled state, heartbeat and expiry. The server never trusts a client-supplied account override or tool-result assertion. Only `ask_orbit`, `show_page`, `prepare_handoff` and `end_call` are exposed. `end_call` terminates the current call when the user asks to stop; the End button is the deterministic stop control. `ask_orbit` delegates through the existing runtime and adds a session reference to the run. `show_page` resolves a server allowlist; no arbitrary URL, selector, JavaScript, shell or browser environment is accepted. All CRM resource authorization and API scope rules remain enforced. Existing record-scope restrictions remain unchanged. A call has at most 60 delegated tool calls, with atomic call-ID deduplication. Chat worker turns also consume existing daily turn limits. One active call per user/account is allowed, including calls spanning UTC midnight. Session minutes and call counts are not an exact dollar budget; configure provider spending limits separately. The browser sends heartbeats every ten seconds. Backend checks reject heartbeats older than 45 seconds. A scheduled watchdog runs at most every 30 seconds and schedules a provider hangup on expiry, stale heartbeat, changed support policy or handoff. Hangup failures retry four times and retain a diagnostic error; network/provider failure can delay termination and billing. Background-tab throttling may end a call. End closes browser tracks immediately and requests server cancellation. Running voice-worker replies and pending voice proposals are cancelled. Late results cannot append and stopped/expired sessions cannot approve proposals. An external write already approved and in flight cannot be undone by ending the call. Refreshing, switching conversation, or closing the floating panel ends the call. Reconnect starts a fresh voice session; there is no silent auto-retry of CRM writes. ## Storage and retention Orbit does not store raw call audio or the continuous voice transcript. Live captions are browser-local. Delegated questions, worker answers, evidence and approval records are stored as normal private Orbit conversation data. Session metadata records owner/account, times, status, bounded tool IDs and any hangup failure. Provider data handling follows the connected OpenAI account’s terms/configuration; not storing audio in Orbit does not imply zero provider retention. New call metadata and rehearsal results expire after the configured 7, 30, 90 or 365 days (default 30). The setting is snapshotted at creation; changing it does not retroactively delete old records. Earlier 1.6 candidate sessions without expiry remain until native account purge. Active calls or calls awaiting confirmed provider hangup retain their cleanup data and retry retention the next day. Chat messages, proposal audit records, native tickets and provider retention are separate and are not erased by this setting. Account deletion uses native private-table purge. ## Validation before rollout Use a synthetic account and a funded key. Check microphone denial, audio playback, greeting, interruptions, mute/unmute, a support question, an allowed read, forbidden operation, reviewed write, page guidance off/on, role revocation, policy/key changes, call expiry, network loss, tab close and human handoff. Verify actual CRM results and stored activity, not spoken claims alone. Test both agency and ordinary subaccount roles. Confirm provider hangup and usage after the test. Browser/provider audio certification is separate from mocked tool execution tests. ## Extending safely Add each guided page to the explicit server map with the correct native resource and feature. Expose no arbitrary paths or selectors. For richer same-page guidance, add typed host UI commands with bounded inputs and acknowledgement; never return model-generated code to the browser. CRM writes must continue through `propose` → human `approve`, including any future computer-use adapter. A separate computer-use browser requires its own isolated runtime, login/access lifecycle, audit trail and approval boundary; it is not part of 1.6. Official integration references: [Realtime](https://developers.openai.com/api/docs/guides/realtime), [WebRTC](https://developers.openai.com/api/docs/guides/realtime-webrtc), [Realtime calls](https://developers.openai.com/api/reference/resources/realtime/subresources/calls/methods/create). ## Support operations: setup, rehearse, improve Open **Support → Setup** for five steps: purpose/knowledge, permitted actions, native human routing, voice/data/billing, and a real practice call. Settings links open the existing editor. Save changes before rehearsing. The readiness view distinguishes a saved credential from proven audio and shows which account or installer pays for voice. The worker remains billed through its configured chat provider. Avoid deploying a generic agent with every tool enabled: begin with the most common support topics and explicitly select operations. **Support → Rehearsals** provides ten versioned scripts: greeting/microphone, knowledge, permitted lookup, correction, reviewed change, forbidden action, human handoff, interruption/stop, noise/silence, and network recovery. Each creates a requester-owned practice conversation. Practice mode blocks CRM execution and native handoff submission on the server; reads and AI calls are real and consume normal provider usage. Use synthetic accounts. Text scenarios can invoke the real support worker with one click. Audio scenarios must be spoken by an operator during a real call. No simulated audio, synthetic pass or automatic model-accuracy grading is claimed. Inspect the conversation, sources, execution receipts and proposed actions against the script. End the call and confirm audible playback in its optional feedback. Mark pass/fail with notes in Rehearsals. Passing an audio scenario requires an ended call with reported playback; a text scenario requires a successful worker run. These are operator-reviewed assessments, not objective proof that the model was correct. Configuration revision or worker-model changes invalidate prior results. Repeat tests under ordinary subaccount permissions as well as agency roles; managers conduct and record the built-in rehearsals. Keep failure notes and fix one behavior at a time. No production support enablement is silently changed by a rehearsal. Voice follows concise conversation rules for unclear speech, exact entities, corrections, short progress updates and explicit escalation. It can prepare an editable handoff review through `prepare_handoff`, but cannot send it. The draft separates the caller's problem, retrieved sources, actual proposal/action statuses and clearly labeled AI advice. It draws from at most 12 recent messages and 20 actions; it is not a complete transcript. The user can edit and must review the native destination before submitting. Explicit requests for a person are handled promptly; after two unsuccessful troubleshooting attempts the model is instructed to offer escalation. This remains model behavior rather than a guaranteed sentiment classifier. Published support hours and after-hours text are informational; there is no live staffing integration or automatic availability calculation. **Support → Quality** shows bounded, account-level aggregates to agency managers with settings-update permission. It never exposes another user's transcript. The sample covers up to the latest 500 call records and 1,000 worker runs within the displayed 30-day period; shorter retention and truncation are labeled. Practice calls are excluded. Resolved means the customer selected Yes; unrated or disconnected calls and submitted handoffs are never automatically resolved. Repeat issues and unsupported claims are customer reports, not verified findings. Native handoffs count unique conversations with accepted submissions, not live transfers. CRM failures and evidence warnings come from stored execution blocks; worker failures are separate. Latency percentiles measure browser-observed speech end to provider audio-buffer start, not actual speaker playback or audited provider timing. Interruptions are observed overlaps, not necessarily errors. Telemetry is best-effort, bounded, client-reported and may be missing if the browser closes or loses connectivity. The UI reports sample coverage. No continuous transcript or raw audio is stored. Review representative failed and flagged conversations with the requester; do not give managers blanket access to private chats. Optional USD estimates use configured voice cost per reserved minute and worker input/output cost per million tokens. Zero means unset. Reserved time includes connection time and may differ from provider-billed time; late provider hangup, cached token pricing, cancelled/missing worker usage, taxes and pricing tiers can change the invoice. Estimates are not spending caps. Set provider budgets separately and review usage during the pilot. **Pause agency voice** is independent of account overrides. It blocks new calls and backend voice actions immediately at the next permission check; browser subscriptions, heartbeats and the 30-second watchdog terminate current calls. It does not disable text support or undo already-approved external writes. Resume removes the pause but does not automatically start any call. Agency policies and the pause flag use the existing tenant-purge anchor account: export/re-establish the agency policy before deleting that anchor. ## Suggested pilot and operating routine 1. Choose a small group of accounts and 5–10 common support questions. Publish approved answers, owner/escalation instructions, support hours and the true request destination. 2. Run the scripts with representative permissions, noisy microphones, corrections and interrupted requests. Include forbidden cross-account/secret requests. Verify source receipts and CRM outcomes independently of spoken claims. 3. Start with reads and limited reviewed proposals. Confirm provider billing and native request delivery separately; a preview or mocked test is not a delivery test. 4. Review unresolved calls, failed tools, evidence warnings, reported unsupported claims and repeat issues. Compare customer-confirmed resolution with latency and cost; do not optimize for short calls or lack of escalation alone. 5. Rehearse again after knowledge, tool, prompt, model or policy changes. Pause agency voice if it misroutes work or makes unsafe claims, investigate, then explicitly resume. Keep the native support form available throughout. Design references: [OpenAI voice prompting](https://developers.openai.com/api/docs/guides/voice-prompting), [Google voice design](https://docs.cloud.google.com/dialogflow/cx/docs/concept/voice-agent-design), [Amazon Connect simulations](https://docs.aws.amazon.com/connect/latest/adminguide/testing-simulation.html), [Twilio voice measurements](https://www.twilio.com/docs/voice/voice-insights/conversation-relay-insights-dashboard). These inform the defaults, not a claim of certification or equivalent enterprise scale. ## Demo-day checks Open the sandbox in the browser you will actually present. Check chat first, then inspect Support → Setup and Rehearsals. A saved text rehearsal does not prove microphone or speaker playback. 1. Run Product guidance and inspect its recorded knowledge source. 2. Run Forbidden action and verify the reply refuses cross-account/secret access. A provider refusal must appear as a refusal; an empty response must never claim retrieved records. 3. Rehearse Reviewed change in a practice conversation. Inspect the proposal; practice mode blocks execution and support-request submission. 4. For voice, connect the direct OpenAI key, run Welcome & microphone, confirm audible playback, then test interruption, End, and network recovery in the presentation browser. 5. Keep text chat available as the recovery path. Failed setup times out after 45 seconds; ending or losing the call releases the microphone. Do not mark audio scenarios passed without an actual audible call. OpenRouter continues to power chat and delegated support work. OpenRouter documents separate speech-to-text and text-to-speech APIs, which could support an additional turn-based voice implementation. They are not wired into this release’s continuous WebRTC transport. Changing the worker provider or pasting an OpenRouter key into the OpenAI voice-key field does not enable that transport. --- # Upgrade to Orbit 1.7 Back up your CRM source, database and server configuration using your normal process. Commit or otherwise preserve local customizations before running the installer. This archive contains original Orbit add-on source only; it does not contain the separately licensed CRM, a preconfigured workspace, customer records or provider credentials. ## Install and validate 1. Extract the new archive and run `node bin/verify.mjs`. 2. Run `node bin/install.mjs --seedly /absolute/path/to/seedly` to preview changes. Inspect any customization conflict; the installer will not overwrite customer edits automatically. 3. Apply the reviewed installation with `--apply`, then run `node bin/doctor.mjs --seedly /absolute/path/to/seedly`. 4. Regenerate the combined Convex API, run the relevant host tests and type checks, and build the web app. 5. Deploy the backend and schema before the web app through your existing deployment process. 6. Verify ordinary-user Support and administrator Chat, Code changes and Settings separately. This release adds private code-connection, code-request and GitHub-account tables and the related authenticated routes. Existing conversations, support policies and provider settings are retained by the upgrade; no migration imports a demo account or configures an AI login. ## Connect your own services Code proposals require your private CRM repository and your own coding provider. [GitHub App setup](GITHUB_APP.md) explains the app registration, callback and permissions. For a trusted self-hosted CRM, [Local Codex](LOCAL_CODEX.md) explains the optional CLI sign-in and exact user/account binding. Do not share a personal Codex session with unrelated customer accounts. Hosted personal ChatGPT access remains a separate registered-client integration; installing this package does not activate it. Voice also retains its own provider setup. ## Review before release Start with a small change in a test repository. Inspect the selected files, complete diff and required review checkboxes. Orbit creates a draft PR only after explicit approval; run project tests and use your usual merge and deployment process. Source rollback should restore the prior committed module source using your normal release process. Do not delete the new private tables as a shortcut: they may contain review history. See [Installation](INSTALLATION.md) and [Validation](VALIDATION.md). --- # Upgrade to Orbit 1.6 Back up the current original module, host files and database. Preserve the verified 1.5 archive. Preview the installer changes and resolve customer modifications rather than overwriting them. The host reference remains Seedly 5.8.4; newer forks require their own compatibility checks. 1. Verify the archive’s SHA-256 and its bundled file manifest with `node bin/verify.mjs`. 2. Run `node bin/install.mjs --seedly /absolute/path/to/seedly` to preview, then repeat with `--apply`. Run `node bin/doctor.mjs --seedly /absolute/path/to/seedly`. 3. Generate fresh Convex APIs and check backend types. Deploy the schema/functions to the intended host deployment before publishing the frontend. Never copy a sandbox deployment configuration into production. 4. Verify native private-table/snapshot/purge guards include `soLiveSessions` and `soSupportRehearsals`. New operations settings, agency voice-pause flag, practice/draft thread fields, call feedback/measurements, support policy, credential, run and message fields are optional so existing 1.5 records remain valid. 5. Build/typecheck the web app and run Orbit host tests. Follow LIVE_SUPPORT.md for an actual audio/provider test on a synthetic account. 6. Voice is off by default. Existing chat keys, support settings, agents and approval policies remain intact. Configure a direct OpenAI voice key and enable voice only for selected accounts first. Rollback: disable live support and end calls before returning to older frontend code. Retain the expanded schema/private-table registry while 1.6 rows and optional fields exist; an older strict schema can reject these records. Do not purge stored conversations or keys merely to force rollback. Keep the original 1.5 customer downloads immutable as the prior-version fallback. Run real microphone/provider acceptance in your own test host before enabling voice for your users. ## Native screen controls The installer adds reversible hooks to supported Contacts, Tasks, Pipelines, Calendar and Conversations components. Modified host layouts fail preflight rather than being overwritten. Existing voice policies preserve their previous supported screen access; review the new access level and page allowlist under Settings → Voice & screen controls. Callers still opt in per call. New policy fields are optional. Backend/schema must deploy before the new web UI. --- # Upgrade to Orbit 1.5.0 Read AGENT_INSTALL.md and IMPLEMENTATION_CONTRACT.md first. Verified host: Seedly 5.8.4, extension API 1. Seedly 5.8.14 and modified forks require their own compatibility checks. ## Before installation - Back up the licensed host checkout, deployment configuration and database using your normal host workflow. Keep the previous Orbit archive and installer receipt. - Verify the new archive against its sidecar, extract to a separate directory, and run `node bin/verify.mjs` there. Never overwrite the only copy of the previous release. - Preview with `node bin/install.mjs --seedly /absolute/path/to/host`. Review the diff. Customer-modified owned files fail closed; reconcile those deliberately instead of overwriting them. ## Apply and release 1. Run `node bin/install.mjs --seedly /absolute/path/to/host --apply`, then `node bin/doctor.mjs --seedly /absolute/path/to/host`. 2. Confirm `soSupportPolicies` is registered as a private table with its native tenant-purge index. Existing chats, agents and provider settings remain in their existing tables. New thread/action/agent fields are optional; no backfill or new environment secret is required. 3. Generate fresh Convex API bindings. Run backend/frontend types, installed-host Orbit tests, native extension privacy/purge tests and a production web build. Never aim a clean validation checkout at a production backend. 4. Deploy backend/schema first, then the web app, following the host's deployment process. The module installer does not deploy either. 5. Test a regular chat, a saved agent and a synthetic reviewed proposal. Check permissions as both a manager and a restricted user. New event conditions require a new rehearsal before the edited agent can run. 6. Configure Support at the agency or account level. Support defaults to disabled, with no CRM tools allowed. Existing accounts are not silently enrolled. Add approved article text, select permitted tools, and test a greeting, product question, ambiguous problem and read-only CRM request. 7. Preview the human handoff and verify its native destination. Submit only to a designated test recipient when validating delivery: the native host may notify support members. Existing native feedback remains available. ## Rollback Disable Support and pause affected agents while investigating. Revert the web release first and preserve database backups and newly created support records. Do not remove new tables or optional fields merely to restore the old UI. Any backend rollback must retain schema compatibility with stored data and be validated in staging; do not blindly redeploy a 1.0 schema over 1.5 data. An additive forward fix is often safer. Preserve the failed deployment's logs and exact archive checksum. ## What changed - Natural support chat with agency/account configuration, approved knowledge, permitted diagnostics and reviewed actions. - Reviewed summaries handed to the native brand-admin request queue; AI pauses after handoff. This is request intake, not bidirectional human chat. - Conversational agent drafts, before/after previews on supported updates, and rechecks of known values before applying. - Event conditions for required/excluded tags and lifecycle stage, plus a personal agent inbox and optional success notifications. - Compact tool activity, better agent browsing and support intent guidance. Agency instructions supplement the built-in behavior. Read SUPPORT.md, AGENTS.md and VALIDATION.md for exact limits. AI usage, hosting and the Seedly license remain separate. --- # Orbit 1.7.0 — November 5, 2026 - Discuss CRM improvements in chat, select existing source files and review a proposed code change before opening a draft pull request. UI, supported backend code, shared libraries and tests can be reviewed. - Connect a customer-owned GitHub App through browser sign-in and select the private CRM repository. - Use an explicitly bound local Codex connection for code help on a trusted self-hosted CRM, or configure a supported provider. No account, login, token or subscription is included. - Cleaner chat composer, mobile conversation drawer, copy controls, inline rename and preserved drafts and reading position. - Review code in the conversation area, keep request setup collapsed while inspecting results, and open the existing draft PR directly from the review. - Administrator-only code controls retain source boundaries, exact-change consent and separate PR review. Ordinary users keep the configured support experience. Read [Upgrade to 1.7](UPGRADE_1_7.md) before updating an existing installation. # Orbit 1.6.0 — October 14, 2026 - Call Orbit from regular or support conversations with a persistent voice panel across same-account pages. - Navigate supported Seedly pages, inspect registered screen state, filter lists, open loaded records and fill unsaved contact, task, deal, appointment and message drafts. - Manage voice, credentials, language, call limits, screen access levels and allowed pages from Settings → Voice & screen controls. Agency defaults, locked overrides and agency-wide pause remain enforced. - Pause screen work by button, Escape or voice; resume by user click. Stale commands, account changes and revoked policies are rejected. - CRM actions still require review; native draft filling does not save, send or book. No extension, arbitrary website control or screenshot capture is included. - Includes the prior support setup, rehearsals, quality reporting and handoff improvements below. Requires a separately licensed Seedly 5.8.4 host and customer provider credentials. - Local build, permissions, installer and native-screen checks pass. Actual OpenAI microphone/provider acceptance remains unverified; see VALIDATION.md. Existing 1.5.0 archives remain immutable. # 1.6 support operations additions - Five-step setup with voice/worker readiness and billing ownership. - Concise voice rules for corrections, unclear audio and escalation; evidence-based editable handoff drafts. - Ten repeatable operator rehearsal scripts and one-click text scenarios. Server blocks practice CRM execution and support submission. Revision/model changes require retesting. - Optional call outcomes/playback confirmation and account quality aggregates: resolution, handoff, repeat issues, reported claims, recorded tool failures/warnings, timing, usage and configured estimates. - Agency-wide voice pause, optional language/after-hours settings and bounded metadata/rehearsal retention. - Raw audio and continuous transcripts remain unrecorded by Orbit. Real audio certification is separate. # 1.6.0 — Live support candidate - Optional OpenAI Realtime voice with captions, mute, end-call and bounded sessions. - Voice delegates to existing support knowledge, diagnostics and reviewed CRM tools. - Agency/account voice controls and an encrypted per-account OpenAI connection. - Opt-in permission-checked links to supported CRM pages. - Session ownership, revision checks, heartbeat expiry, duplicate-call protection and cancellation of unapproved voice work. - Original 1.5 downloads remain unchanged. Live audio verification is distinct from fixture validation. # Orbit 1.5.0 — September 30, 2026 ## Support inside the CRM Agency defaults and optional account overrides control identity, tone, instructions, curated knowledge, diagnostic access and permitted CRM actions. Support recognizes everyday requests, product questions and troubleshooting in context. CRM changes remain reviewed proposals. Users can preview and edit a summary before sending it to the native support request queue, then see its intake status in My requests. AI replies and approvals stop after handoff. ## Agents and workspace - Draft an agent through conversation, then review its setup and rehearse before enabling. - Filter supported CRM events by required/excluded contact tags and lifecycle stage. - Follow personal agent outcomes and approvals in Inbox; optionally surface successful runs. - Review before/after values for supported updates. Known values are rechecked before applying. - Quieter tool activity and a more compact agent workspace. See UPGRADE_1_5.md for installation and rollback considerations. See VALIDATION.md for the verified host and live/fixture coverage. Human handoff is native request intake, not live staff chat. Support articles are curated text, not automatically crawled websites. Source 1.0.0 and earlier archives remain unchanged. --- # Support mode Support mode helps signed-in Seedly CRM users ask questions, inspect permitted account data, review proposed CRM actions and submit a request to a person. It uses the account's existing Orbit AI connection and appearance. Ordinary users open this support-only workspace; the full general-chat, settings, guided-agent and source-code workspace belongs to agency owners and administrators. New ordinary-user conversations are support conversations, and server checks prevent legacy general-chat execution from bypassing support policy. It is not an anonymous website widget or an unattended support operator. ## Configure an agency or account 1. Open Orbit → Support → Configure support, or Orbit Settings → Configure support agent. 2. Choose Agency defaults to establish shared settings. Leave Allow account overrides on for account-specific configuration, or turn it off to enforce the agency configuration everywhere. Only a native agency owner/administrator with settings-update permission can save either scope. 3. Set the name, avatar symbol, welcome, tone and instructions. Enable support chat when ready. Instructions can specify escalation guidance but cannot grant tools or bypass permissions, approvals or handoff state. 4. Add approved knowledge articles. Built-in guidance covers Orbit provider setup, agent rehearsals, reviewed actions, inbox behavior and handoff. General Seedly documentation is not automatically ingested. Paste the approved text and optionally link its HTTPS source. Links are references, not a website crawler. Maximum 20 articles, 4,000 characters per article and 40,000 characters total. Never store credentials or private customer records as shared support knowledge. 5. Choose diagnostics and CRM tools. The default CRM tool list is empty. Enable only what this support agent needs, up to 30 eligible operations. Every call also checks the requester's native resource permissions, account-wide scope, enabled features, Orbit write policy and CRM API scopes. Administratively privileged and arbitrary extension endpoints are excluded from this initial support release. 6. Add published support hours and the handoff message. Hours are informational and do not control a staffing schedule, routing or response-time SLA. 7. Save and test as a representative user. Open support from the floating Orbit launcher if enabled; existing companion/hidden preferences and floating access still apply. Seedly's native request form remains available. Account overrides replace the complete configuration, rather than merging individual fields. Use agency defaults removes the local override. A locked agency configuration takes precedence over saved local overrides; unlocking restores those local configurations. Changes invalidate earlier support proposals, which must be requested again. Each account retains its own AI provider credentials and normal usage limits. ## Ask support Orbit interprets the current request in context rather than treating every message as a support issue. Greetings and writing/brainstorming requests get direct answers; product how-to questions use relevant knowledge; reported Orbit problems can use diagnostics; CRM reads and proposed changes use the configured tools. It asks one focused question when the request is ambiguous. A conversation can move between these topics without the user selecting a mode. Intent guides model behavior; it does not change permissions, tool availability or handoff state. These defaults live in `src/convex/seedlyOrbit/conversationGuidance.ts` and apply even to already-saved agency policies. Use the Instructions field for business-specific guidance, tone and escalation preferences, not a replacement for the base behavior. Ordinary Chat shares the conversational defaults but does not acquire Support's knowledge or diagnostics tools; it can suggest Support when those capabilities are needed. Scheduled agents keep their existing job instructions. When changing prompts or models, test greetings, a writing request, product how-to, a specific failure, an ambiguous "it's broken", a CRM read, an explicit human request, and a change of topic within one conversation. Check the actual recorded tool calls as well as the answer: a plausible reply alone is not proof that routing or evidence is correct. Model intent recognition is probabilistic. The server continues enforcing the configured tool list and approval rules regardless of the model's interpretation. The agent can search approved text and show retrieved sources under Activity & sources. Retrieval is bounded keyword ranking, not a claim that all relevant documentation was found. It can read verified Orbit configuration; permitted agency managers can inspect their own first 30 agents, including current status, rehearsal, schedule, conditions and trigger notes. It does not test external provider health or CRM connectivity merely by reading configuration, and it does not inspect another user's agents. Privileged diagnostic evidence marks the conversation as requiring agency-manager/settings-update access. Losing that access blocks later reads of its messages. Configured CRM reads likewise retain Orbit's existing operation-based history checks. A support chat remains owned by its requester; configuration management does not grant staff access to private chats. Allowed writes generate the existing immutable review card. Support cannot execute a CRM write without the requester's explicit approval. Before/after previews apply to supported update/get pairs, and approval rechecks the current support configuration revision. Do not automatically retry failed or ambiguous external writes. ## Talk to a person Talk to a person prepares an editable draft from up to 12 recent messages and 20 action records, separating source references, actual action status and clearly labeled AI advice. The user reviews the summary and the actual native destination before submitting. Only that summary, plus native requester and source-account details, is shared; raw tool results and the complete transcript are not silently attached. Common secret patterns are redacted before the final preview, but users must still inspect the text for sensitive information. The handoff calls Seedly's existing `pmSubmissions.createFeedback` in the same database transaction. Native routing sends the request to the source account's brand-admin subaccount when one exists, otherwise to the source account. Orbit does not accept arbitrary target account IDs or alternate notification recipients. The browser's native active subaccount must match the conversation's account; if it changed, select the correct account in the CRM switcher and review again. An inactive destination refuses submission. The existing native function resolves/creates the requester contact, creates the request, writes its audit entry and schedules notifications to the native support members. Orbit stores the returned submission reference. Repeated submission of the same conversation returns that same reference rather than creating duplicate requests. A changed destination requires a fresh review. Successful handoff cancels a running AI reply and rejects recent pending proposals. All further AI replies and approvals in that conversation are blocked on the server, including older proposals. An already-running CRM action must finish before handoff is allowed. Delayed provider replies cannot be appended after cancellation. The conversation stays available for the requester to read, subject to current permissions. ## My requests and human workflow My requests lists support conversations among the latest 200 conversations owned by the requester in the current account, with a truncation notice. It reads only the native intake status of the stored submission; it does not expose support staff notes or other submissions. - Awaiting support review: native status `pending`. - Accepted by support: native status `approved`; this is not proof of resolution. - Declined by support: native status `rejected`. - Request unavailable: the referenced native request is missing or no longer in its recorded destination. Staff handle these in Seedly's existing Tasks → Submissions workflow and follow up through their normal support process. Version 1.6 adds customer-reported call resolution/feedback and bounded quality aggregates, described in LIVE_SUPPORT.md. It does not add bidirectional human chat, staff assignment, internal notes or SLA automation. Those require a dedicated shared support conversation model and explicit support-role permissions. Do not reuse requester-owned Orbit threads to give support staff blanket CRM authority. ## Installation and upgrades for an AI agent 1. Read AGENT_INSTALL.md and IMPLEMENTATION_CONTRACT.md. Back up the existing installation and inspect module conflicts before applying changes. Do not copy licensed host source or credentials into a distributed package. 2. Install the original module with `node bin/install.mjs --seedly /absolute/path/to/seedly --apply`. Run doctor. 3. Confirm the new private `soSupportPolicies` table and its `by_subAccount` tenant index are in the schema/extension privacy registry. Agency configuration is unique by agency/scope; account configuration is unique by account/scope. Agency defaults are anchored to the account where they were first saved for native tenant-purge compatibility. Export/re-establish those defaults before deleting that anchor account; deleting it removes the default policy and inherited support fails closed to disabled. 4. Optional thread fields record support mode, handoff reference, destination, summary/time and restricted diagnostic evidence. Optional action revisions protect support approvals. Existing ordinary chats are unchanged. No backfill or new environment variable is required. 5. Generate fresh Convex bindings and run backend types, installed-host Orbit tests, extension privacy/purge checks, frontend types and build. Test the native feedback function contract in the actual licensed host. Current verified reference is 5.8.4; do not assert compatibility with an untested modified fork. 6. Deploy backend/schema before the UI. The native feedback route must remain authenticated and must resolve brand-admin routing server-side. Never bypass `getAuthContext`, `location`, `thread` or permission checks to make a handoff work. 7. Configure support and test documentation, forbidden tools, an allowed reviewed proposal and a handoff in synthetic accounts. Test both no-brand fallback and brand-admin routing, duplicate clicks, routing changes, revoked permissions and in-flight cancellation. Native notifications may trigger external delivery according to host configuration; use fixtures or explicitly approved recipients for delivery testing. 8. Verify account and agency overrides, disabled support, unavailable provider, closed-browser persistence and floating entry behavior. Keep a native request fallback available while testing. ## Adding support tools Use the existing catalog/permission/REST adapter for CRM operations and enforce the support allowlist in context, tool registration, proposal creation and approval. New diagnostic tools must return only necessary fields and register any extra history permission requirement before persisting privileged evidence. Keep actual receipts separate from model prose. Read source permissions on every call, including multi-round model loops. Curated content and CRM records are untrusted model inputs. Never turn article text into executable predicates, system access, URL fetches, recipient overrides or approval. Adding automatic URL ingestion requires a separate SSRF-safe fetcher, publication controls, content/version metadata and test coverage; it is not implemented by accepting a source link. Support state and configuration belong in original module files. If a newer host provides a true support-ticket/conversation API, write a tested adapter rather than inventing compatibility. Preserve native routing, idempotency, consent preview, principal checks and the AI-stop boundary. Share external messages only after the user submits the reviewed request. --- # Guided agents Available in Orbit 0.2.0-alpha.1. Open Orbit → Agents as an agency owner or administrator. Agents belong to their creator within one subaccount. They use that account’s configured AI provider and CRM key, bounded by the creator’s current native permissions. ## Start a job 1. Choose a briefing, contact review, follow-up template, or write your own job. 2. Specify the relevant records, exclusions and desired output. Choose only the necessary tools. Read tools retrieve data; change tools prepare proposals for approval. 3. Choose on-demand, daily, weekdays, weekly, monthly or a CRM event, with a local time and IANA timezone for schedules. Set records processed per run (1–100) and runs per UTC day (1–24). Rehearsals count toward usage. 4. Review the rules and select **Save & rehearse**. This performs real reads and consumes provider credits. Rehearsal proposals cannot be applied. 5. Inspect the sources, visuals and proposed actions. Save feedback. Use **Edit instructions** to turn feedback into a lasting rule; feedback never changes the rules automatically. 6. Accept a successful rehearsal of the current revision, then enable the agent. Enabled manual agents expose **Run now**. Scheduled agents show their next run and continue with the browser closed. Editing any configuration returns the agent to draft, cancels its schedule and requires a new accepted rehearsal. Pause stops future work; an already in-flight read may finish. Re-enabling a paused, previously reviewed revision resumes its schedule. ## Review and visibility Each run stores an immutable copy of its instructions, model, tool list and record limit. Inspect its conversation for sources and server-calculated visualizations. The agent detail displays the most recent 30 runs, status, feedback and token usage. Failed schedules pause with a visible explanation. **Pause my agents** affects only your agents in this subaccount. Live runs prepare changes for explicit approval in their run conversation. Agent proposals expire after the configured approval window (15 minutes to seven days; new agents default to one day, existing agents retain 15 minutes) and cannot be approved if the agent is paused, revised, or no longer allows the operation. Existing native permission and record-scope checks still apply. Rehearsals never offer executable approvals. ## Execution and limits - Convex durable scheduled functions power schedules; there is no browser timer or customer cron service to configure. - Daily and weekday schedules follow the specified timezone. A nonexistent daylight-saving wall time skips that date; repeated times run once. Missed jobs are not backfilled. - Each agent permits one active job. Duplicate schedule callbacks are ignored. Interrupted jobs expire after three minutes and are not automatically replayed. - Each run permits at most six model rounds, twelve tool calls and 2,500 output tokens per round, plus the account’s existing usage limits. Provider pricing varies; these are usage bounds, not a dollar budget. - The record limit bounds records processed and sent to the model. Some API endpoints may return larger pages before truncation. Results identify partial data; do not treat limited samples as complete account analytics. - Scheduled work re-resolves the creator’s current native authorization on every tool step. Deactivation, revoked membership, disabled Orbit, policy changes and tool restrictions block continued access. The saved principal is internal; no session token or user-selectable identity is used. - Changing the account AI provider requires editing and rehearsing the agent again. ## Installation and upgrade verification Follow INSTALLATION.md and AGENT_INSTALL.md. The installer adds private `soAgents` and `soAgentJobs` tables and an optional job link to Orbit threads, plus the native private-data registry contributions. Re-run the installer rather than manually replacing files. Run fresh Convex codegen, backend and frontend type checks, the supplied host test file and the frontend build before deploying. Deploy the backend before serving the new frontend. No new secret or external cron is required; existing provider encryption and CRM setup remain required. Start with a read-only contact review, confirm that enablement is blocked before accepting the rehearsal, inspect source records, then enable on-demand and run once. Test pause and changed permissions with synthetic data. Do not enable a recurring schedule merely to complete installation. ## Extending safely New tools must follow EXTENDING_API_WITH_AI.md and TOOL_RECIPES.md: native route authorization, validated arguments, catalog metadata, bounded result envelopes, private-table registration where applicable, and scoped tests. Agents select eligible catalog tools; arbitrary URLs and administrative/extension routes are excluded in this first release. Updating a tool must preserve its permission checks and read-versus-change classification. Never bypass the proposal/approval path to make a scheduled write automatic. This release supports guided setup, rehearsals, manual runs and daily/weekday/weekly/monthly schedules and native contact event triggers. Arbitrary cron expressions, automatic writes, cross-account jobs, email notifications, automatic learning and a dollar-spend budget are not implemented. ## Weekly and monthly timing Weekly jobs use the selected weekday. Monthly jobs use the selected day of month, clamped to the last day for shorter months (31 becomes February 28 or 29). Times follow the configured IANA timezone. A nonexistent daylight-saving time skips that occurrence. Editing the cadence or approval window changes the agent revision and requires a new rehearsal and acceptance before enabling. Approval duration is snapshotted when a job is queued. A longer window does not bypass permission, agent status, revision or operation checks when applying a proposal. Regular interactive chat proposals retain their 15-minute window. ## Event-triggered agents Choose Contact created, Contact updated or Tag added. Orbit receives these through the installed native workflow trigger bridge, even when no matching workflow exists. No public webhook URL or event secret is exposed. The triggering contact ID is included as context; the agent must read the current record through its allowed tools. Trigger text never replaces the job instructions. Activation still requires an accepted rehearsal. Saved owner permissions are rechecked before queuing and before tool calls. Each agent has one active run, a daily run cap, and a 5–1,440 minute cooldown (15 minutes by default). Events during a run or cooldown are coalesced, not queued for replay; the detail view reports this count. Duplicate event IDs are refused using stored job history; without an external ID, contact revision is used. Nested native trigger chains are skipped. Pausing stops new event jobs. CRM changes always require a person to approve them. Only the three listed native event types are supported in v1. Existing contacts do not automatically trigger a backfill. Use a manual rehearsal or scheduled job to review existing data. ## Review inbox and reusable jobs Agents shows your recent unexpired proposals with links to their original conversations. Approval still uses the existing immutable proposal and current permissions. Rehearsal proposals and paused or revised agent proposals are excluded. The inbox scans the latest 500 account proposals and displays up to 50 of yours; it discloses truncation. Duplicate copies a job into a draft owned by the same user. It carries no accepted rehearsal, active job or schedule. Search agents by name/instructions and filter by status. The tool picker is collapsed by default and searchable. ## Lifecycle report The Lifecycle report template uses `countContactsByLifecycle`. Grant the dedicated `orbit:contacts:read` scope to the configured CRM key. It counts stored lifecycle stages on active, non-deleted contacts; it does not infer stages from deals or invoices. This aggregate can scan more contacts than the agent's returned-record limit, because only six stage totals enter the AI context. The endpoint scans before applying its optional source filter. It processes at most 40 pages of 250 records and eight seconds between page requests. A budget-limited scan returns `hasMore: true` and no full total. Data can change during a multi-page scan; start and finish timestamps are returned. This is not an atomic analytics snapshot. Visualizations sum the count field automatically, rather than counting the stage rows. ## Design an agent in chat Choose New agent → Describe a job, or ask Orbit directly to build an agent. Explain the job, exclusions, desired trigger and timezone for timed schedules. Orbit can ask follow-up questions and return a draft card. Review agent setup transfers that draft into the existing editable rules and rehearsal flow. Nothing is saved, scheduled or enabled by the chat tool. The tool is restricted to agency managers, validates eligible tool IDs and bounded schedule/usage settings, and cannot be called by a running agent. Saving still enforces current permissions; enabling still requires an accepted rehearsal of the current revision. ## Review exact changes Contact, task and opportunity updates can display current and proposed values side by side. Current values come from a separate authenticated read, never model-generated prose. An agent must have the matching get operation in its approved tools and remaining record allowance; otherwise current values show as unavailable. Create proposals show the fields for a new record. Other operations retain exact API request details. Before applying a proposal with verified current fields, Orbit reads again. A changed value or failed verification prevents the write and requires a fresh proposal. This is not an atomic conditional update: a concurrent change can still occur between the verification and native REST write. Fields unavailable in the read are explicitly unverified. Approval, rejection and expiry remain immutable single-use actions. In ordinary chat, Request changes rejects the old proposal and prepares a follow-up message for your edits; it does not send it automatically. Agent-run proposals use the agent instructions/rehearsal workflow for lasting changes. ## Event conditions In agent rules, choose an event and expand Event conditions. Require all listed tags, exclude any listed tag, and choose any allowed lifecycle stage. Tags are exact, case-sensitive names; comma-separated entry supports up to 20 required and 20 excluded names, 80 characters each. A tag cannot be both required and excluded. Empty lists impose no restriction. Conditions combine with AND: all required tags, zero excluded tags, and any selected stage. The native event handler reads the active contact in the event's own subaccount, checks current owner/contact-read authority, and evaluates these rules before queuing or using AI credits. Nonmatches appear in Last trigger as skipped. Saved conditions are snapshotted on each queued job; editing conditions creates a new draft revision requiring rehearsal. These are conditions on the current record, not proof of which field or tag changed. Tag added means the native tag-added event occurred and the current contact matches; it does not claim the required tag was the one added. Changed-field filters need a verified host before/after event contract and are not supported. Conditions govern when the job runs, not the scope of every later tool read; describe the triggering-contact scope in the job instructions and choose appropriate tools. ## Agent notifications Orbit's Inbox is available to agency managers for their own runs in the current subaccount. Failed runs and actionable approvals are unread automatically. Results without pending changes remain available under All recent results but are quiet by default. Enable “Notify me when routine results are ready” in agent rules to make those results unread too; this preference is snapshotted per run and follows the existing revision/rehearsal flow. Opening an inbox item marks its current state read and opens the original run conversation. You can also mark it read without opening. Reading never approves, rejects or retries a CRM action. An unexpired approval resurfaces once as it enters the final hour; expiry attention updates within approximately one minute while Orbit is open. Resolved/expired proposals, rehearsal proposals and proposals belonging to paused or revised agents do not show as actionable pending approvals. Normal approval authority is checked again when a user applies a change. The inbox derives its state from the latest 100 owner/account jobs and their stored actions, discloses truncation, and preserves read state on each job. It covers existing runs as well as new runs without a backfill. This is an in-Orbit inbox and unread indicator, not OS push, email, SMS or a native Seedly bell integration. No outbound delivery service or new credentials are needed. A closed browser does not stop agent execution; notifications are visible when Orbit is reopened. ### Install and extend Deploy the updated optional schema fields, owner/account jobs index and backend functions before deploying the matching UI. Install with the module installer, generate Convex bindings, run host tests and deploy the dedicated target. No data migration or new environment variable is needed. Older agents default to no conditions and quiet successes. Keep `agentConditions.js` shared by draft validation, saved agent validation and event handling. New conditions must have bounded validators, server-verified tenant data, job snapshots, rehearsal invalidation and tests for nonmatches and revoked access. Never evaluate arbitrary model-generated predicates or accept a caller's record snapshot as trusted event data. --- # Using Orbit Orbit is a staff tool inside your Seedly CRM. It can read authorized CRM data, build inline tables/charts, and propose actions you review before execution. It uses your connected AI provider and your installation's CRM API. ## A normal conversation Choose the right subaccount, start a conversation, and ask one concrete question. Specify date range, timezone and whether you need a sample or a complete report. Review source disclosures and pagination limits before treating a chart as an account total. Continue in the same conversation when following up; start a new one for a different task. An AI reply is not evidence that a write completed. Orbit creates a review card with the actual operation, account and fields. Approve or dismiss it. Approval expires after 15 minutes and execution rechecks permissions. After a timeout or unknown result, inspect the native CRM before proposing the action again. API acceptance of an email or campaign is not delivery confirmation. ## Workspace and floating chat The full workspace puts Chat, Code changes, Agents and Inbox above your conversation history. Support, Saved prompts, Capabilities and Settings sit below it. The floating popup has one header: history, new conversation, expand and close. Open history to reach secondary tools; expand for account switching and conversation management. Rename, pin and archive are in the full workspace toolbar. Rename edits the title in place. Archive is reversible; conversations are private to their creator. On small screens, history opens as a drawer; select a conversation or press Escape to return to your work. Move the closed launcher by dragging or with arrow keys. Escape closes the popup. Settings offers the standard bubble, pixel companions, a custom PNG/JPEG/WebP upload or Hidden. Uploads remain on that browser for that user/location; they do not go to the AI. The agency's Floating chat switch takes precedence. The message box grows as you type. Enter sends; Shift + Enter adds a new line. You can copy a message from its header. Reading earlier messages keeps your place when a reply arrives; Back to latest returns to the newest reply. When Local Codex is connected, the selector in the message box switches between code help and the CRM assistant. The choice is remembered for that conversation during the browser session. CRM starter prompts choose the CRM assistant. Voice and screen controls open from Voice when enabled for the selected assistant. An administrator can open a code request directly from chat. The review occupies the conversation area so there is space for source selection and the complete diff. Back to chat restores your draft and reading position. Existing requests keep their setup collapsed while you review; expand New code request to prepare another proposal. Creating a draft PR still requires the explicit review checkboxes. ## Account settings Agency owners/admins with settings permission configure location enablement, agency access, floating chat, reviewed writes, provider/model, daily turn allowance and approved extension routes. A staff user's native CRM permissions still apply even if the backend API key has broader scopes. Account-wide resource access is currently required; own/team scopes are refused. Connect OpenRouter, select a tool-capable model and Save settings. The daily allowance counts turns, not dollars. Use provider-side spending limits. Key verification checks the credential without making an inference request; a real reply is needed to confirm credits and model access. Appearance can follow the account's brand tokens, use Clear light or Clear dark, or set custom background/accent colors. Changes apply to the workspace and popup for that subaccount. Launcher choice and position are personal browser preferences. ## Data and limits Selected CRM results and bounded conversation history are sent to the chosen provider. Keys stay server-side and saved OpenRouter keys are encrypted per location. Do not put credentials in a chat or a tool description. Retrieved CRM text is data, not authorization to run instructions contained in a note or message. Orbit does not provide arbitrary database, shell, URL or browser execution. The installed catalog defines supported operations. A CRM screen does not prove there is an API for it. Generic extension calls are manager-only, require an exact allowlist and live granted discovery. New integrations need implementation and testing. Replies appear when a bounded run completes; token streaming is not implemented. Search covers loaded conversation titles; load older chats to include more. Charts describe retrieved data unless a verified reporting endpoint returns complete aggregates. Provider/tool availability and charges depend on your configured account. See Validation for the evidence and limits of this release. ## Guided agents (0.2.0-alpha.1) See [Guided agents](AGENTS.md) for setup, rehearsals, schedules, review, limits and upgrade verification. Deploy the new backend before the frontend. Existing conversations remain available; the upgrade adds two private tables and does not enable any scheduled job automatically. --- # Install Orbit in your Seedly CRM This guide is for the customer who owns and deploys the CRM. Orbit installs original add-on code into a separately licensed Seedly checkout. It does not include a hosted AI service or provider credits. ## Prerequisites - Seedly 5.8.4, extension API 1. Later 5.8.x versions need integration verification. - Node 22+, existing host dependencies, access to the intended Convex development deployment and web hosting. - An OpenRouter inference API key with credits and access to a tool-capable model. Existing direct OpenAI connections remain supported. - A CRM API key created through the native Settings → Integrations → API Keys screen. Use an agency-scoped key for agency management, with authorized-subaccount restrictions where appropriate. Select only the scopes needed by your users. - A backup and a clean reviewable source checkpoint. Keep credentials out of Git and archives. ## 1. Install and inspect the changes From the extracted module folder: ```sh node bin/install.mjs --seedly /absolute/path/to/seedly node bin/install.mjs --seedly /absolute/path/to/seedly --apply node bin/doctor.mjs --seedly /absolute/path/to/seedly ``` The first command is a dry run. The installer writes module-owned source, private-table registration, native permission and plan-feature entries, navigation, and a narrow dashboard floating-chat contribution. It records file checksums in `.seedly-addons/orbit/receipt.json`. Customer edits cause a refusal rather than an overwrite. The dashboard contribution wraps the existing CommandPalette with the optional Orbit launcher. Other modules remain independently installable. No deployment, role enablement, API key creation, provider call, or CRM write occurs during installation. ## 2. Configure server-only connections Set these variables through the intended Convex deployment's environment settings. Do not use `NEXT_PUBLIC_` names. | Variable | Meaning | |---|---| | `ORBIT_KEY_ENCRYPTION_SECRET` | Deployment-owned 32-byte random secret encoded as 64 hex characters; required to encrypt connected OpenRouter keys | | `ORBIT_OPENAI_API_KEY` | Optional existing direct OpenAI connection, only used when OpenAI is selected | | `ORBIT_CRM_KEYS` | JSON object mapping an internal agency ID or internal subaccount ID to its native CRM API key | | `CONVEX_SITE_URL` | Platform-provided URL of this backend; Orbit accepts only this installation's `https://…convex.site` origin | Example **with placeholders only**: ```json { "AGENCY_INTERNAL_ID": "sk_agency_test_REPLACE_IN_SECRET_SETTINGS", "SUBACCOUNT_INTERNAL_ID": "sk_test_REPLACE_IN_SECRET_SETTINGS" } ``` A per-subaccount entry takes precedence over its agency entry. Orbit verifies the key's agency and resolved subaccount against the authenticated user's target before calling the API. An incorrectly mapped key is refused. An agency key's `X-Sub-Account-Id` is injected by the server, never by the model or browser. Native API scope names and the supported operation list are in [API_COVERAGE.md](API_COVERAGE.md). API scopes do not replace the user's native role. Orbit currently requires account-wide permission for a tool's resource; own/team scope is refused. Test keys sandbox external messaging but are not a guarantee that every CRM mutation is a dry run. Use a dedicated test location with synthetic records. Orbit uses `store:false` for model requests. Selected CRM data and the bounded conversation history are sent to the customer's selected AI provider account to answer the user's question. Review your provider settings and data requirements before enabling the feature. Do not put secrets in prompts. ## 3. Generate and validate in a private development host Use the target host's documented deployment configuration; never copy another customer's `.env` or deploy a disposable scratch host. ```sh # From the actual customer host, with the correct development deployment selected: npx convex codegen npx tsc --noEmit -p convex/tsconfig.json # From apps/web: npx tsc --noEmit npm run build ``` Copy `host-tests/seedly-orbit.test.ts` into the private host's `convex/__tests__/` and run its focused test command from `convex/`: ```sh pnpm exec vitest run __tests__/seedly-orbit.test.ts ``` Run the host's extension permission, navigation, private-table/snapshot and purge guards as well. Fresh authenticated component codegen is required before release; a local API-reference regeneration does not establish deployment compatibility. For Code changes, also copy `host-tests/seedly-orbit-code.test.ts` and `host-tests/seedly-orbit-code-analysis.test.ts` into `convex/__tests__/`. Copy `host-tests/web-code-review.test.tsx` into `apps/web/__tests__/` and run each with the host's Vitest setup. The installer installs the pinned dependencies for `packages/orbit-chatgpt` and `packages/orbit-code-review` with lifecycle scripts disabled. Keep those module-owned runtime packages in the installed host; never copy their `node_modules` back into the portable module source. See [Code changes](CODE_CHANGES.md) for supported application files and required review acknowledgements. Deploy Convex schema/functions before deploying the corresponding web app. Follow your customer's existing production workflow. Orbit's installer deliberately does not choose a backend or hosting project for you. ## 4. Enable per location 1. Open `/orbit` as an agency owner/administrator and select a subaccount, or open `/location/LOCATION_PUBLIC_ID/orbit`. 2. In Settings, enable Orbit. Enable Agency access if agency users should manage that location. Enable Floating chat to show the launcher inside its dashboard. 3. In Connect OpenRouter, paste a regular inference key and select Verify & connect. The server checks GET /key and encrypts it for this location; it never returns the key. Select OpenRouter below, choose a tool-capable model ID (default `openai/gpt-5.4-mini`) and Save settings. Verification does not spend inference credits; a real reply is still required to verify model/tool access. Existing direct OpenAI locations retain their provider until changed. 4. Set a daily reply allowance per user/location. This is a turn limit, not a monetary guarantee. Provider requests are further bounded by output tokens, iterations and tool calls; use provider-side spend limits too. 5. Assign Orbit and the required CRM resource permissions to intended roles, and include Orbit in applicable plan features. 6. Leave reviewed writes off for the first read verification; enable them after validating the desired operations. Settings are independent for each location. Cross-account comparisons are currently separate conversations, not a silently mixed dataset. The account selector opens the selected location's workspace. ## 5. Verify the real connection - Ask for a small contact list in an authorized synthetic location. Verify the IDs against the CRM. - Ask for an inline table and a count. Check source disclosure and partial-page labels. - Try a restricted user; confirm a forbidden resource stays forbidden even if the backend key has the scope. - Create a task proposal. Confirm no record exists until approval, then approve once and verify exactly one task. - Revoke the API key or role and confirm subsequent operations fail. - Test agency access disabled/enabled separately and verify the selected account on each action card. - Open/close/move the floating launcher, change conversations, and reload. - Do not test actual customer messaging, broadcasts or destructive operations without authorization for the exact test. ## Operation and recovery A write approval expires after 15 minutes. The stored arguments are immutable. Newly created/rotated webhook signing secrets are returned once to the approving manager’s browser, never to the model or persisted chat. Copy them to the receiving service immediately; leaving the conversation loses that one-time display. Duplicate approval is refused. HTTP acceptance of a message/campaign is not proof of delivery; inspect native CRM state. For an unknown write outcome, check the CRM before issuing a new proposal. Do not blindly retry a send after a timeout. Conversation history is private to its creator. Archive is reversible. Saved prompts can be deleted. Module data follows the host subaccount purge mechanism; no public tokens or durable media are created by Orbit. Configure retention through your own approved host data lifecycle; Orbit does not automatically purge chat history. For an interrupted source installation, use `bin/recover.mjs --seedly /path --apply`. For removal, preview `node bin/uninstall.mjs --seedly /path`, then add `--apply`. Removal preserves database records; decide on retention/export before removing their schema in a deployment. ## Limits of this alpha - No live customer/provider certification is implied by the included fixtures or synthetic UI preview. - Responses appear after each bounded reply completes; token-by-token streaming is not implemented. - Search filters loaded conversation titles; load more pages to include older chats. - Charts aggregate retrieved rows only; larger analyses require paging and/or purpose-built reporting endpoints. - Extension discovery describes paths/scopes, not complete request schemas. Register reviewed typed endpoints for routine staff use; the generic gateway remains agency-manager-only and explicitly allowlisted. - Public widget/form APIs and signed workflow ingress have different authorization contracts and are not exposed as arbitrary management tools. ## OpenRouter credential operations Generate the encryption secret with a cryptographically secure generator (for example, `openssl rand -hex 32`) and save it directly in the intended backend's secret configuration. Never commit its output. The key form stays unavailable until that secret is configured. CRM keys and this wrapping secret must not have `NEXT_PUBLIC_` prefixes. Connected OpenRouter keys are scoped to the selected subaccount. An agency manager may use the same agency-owned provider key in several subaccounts, or separate keys to isolate provider spending limits. Orbit does not silently inherit provider keys between tenants. Only an agency owner/admin with native settings-update permission can connect, replace or disconnect a key. Staff see connection status, never the key or ciphertext; managers see only its last four characters. No key is written to browser local/session storage or chat. Backend administrators with deployment access remain trusted; encryption does not protect against a compromised backend. Do not log action arguments or request headers. Replacing a key verifies the new key before atomically replacing the previous ciphertext. Disconnect removes the saved secret and prevents later replies; it does not revoke the key at OpenRouter. Revoke it in OpenRouter when needed. Keep the encryption secret stable and backed up in your secret manager. Changing it without migrating credentials makes existing keys unreadable; reconnect every affected subaccount after rotation. A disconnection cannot recall an already in-flight provider request. The Responses tool loop uses OpenRouter's documented client tool calling. Orbit still performs permission checks and requires explicit approval for writes. Select models/providers that support function tools; invalid models, exhausted credits, unsupported parameters and revoked keys surface as failed runs rather than silently switching providers. References: [Responses tool calling](https://openrouter.ai/docs/api_reference/responses/tool-calling), [key verification](https://openrouter.ai/docs/api/api-reference/api-keys/get-current-api-key), [create/manage keys](https://openrouter.ai/settings/keys). ## Optional pixel companions Settings → Chat launcher offers Classic, Miso (cat), Pip (frog), Byte (robot), and Hidden. Users can change this without agency settings permission. It is remembered on this browser for this user and location. Hidden removes the launcher; the full Orbit workspace remains available. Agency floating-chat disablement overrides the personal choice. Pets use the same drag, keyboard movement, open and close behavior as the bubble. ## Launcher images and model selection (alpha.3) The launcher picker adds Ember (fox), Hoot (owl), and Boo (ghost). Upload a PNG, JPEG or WebP up to 2 MB and 16 megapixels to use your own image. Orbit fits it into a transparent 96×96 PNG without cropping and stores it in local browser storage for the signed-in user/location. No image leaves the browser, enters the model context, or consumes Convex file storage. Choose another launcher to keep the uploaded image for later; Remove image deletes the browser copy and restores Classic if Custom was selected. Custom launchers do not sync across devices. SVG and animated formats are not accepted. Browser storage restrictions are reported rather than silently claiming a save. OpenRouter's model dropdown refreshes the public model catalog when an agency manager opens settings and offers a Refresh control. It lists text-output models advertising tool support; batch-only entries and unrecognized identifiers are excluded. Search filters by model name/ID. Featured recent choices include GPT-6 Sol/Luna/Astra, Claude Opus 5.5/Sonnet 5, Gemini 3.8 Flash, Grok 4.7, DeepSeek V4.1 Flash and GLM 5.3 Prime, verified against https://openrouter.ai/api/v1/models on September 27, 2026. “Featured” is a shortlist, not an independent quality benchmark. Other supported models sort newest first by OpenRouter creation timestamp. Advertised input/output prices are per million tokens, not a per-task quote; provider costs and availability can change. The catalog request contains no CRM records or provider credentials and requires native agency-management authorization. If discovery fails, a dated bundled list remains usable and is labeled as a fallback. The saved model is retained even if absent from a filtered/current list; opening the selector never silently changes it. Save settings applies a selected model. OpenRouter key/model access still needs real-account verification. Direct OpenAI retains its existing explicit model-ID field. ## Seedly 5.8.4 task API compatibility On a clean base, the first POST /api/v1/tasks can return 500 because pm.apiCreate creates the API Tasks project with an empty createdBy user ID. Before testing task creation, the host maintainer should carry the authenticated API key record’s createdBy through both ApiAuthContext builders in convex/apiHelpers.ts, and pass that trusted value as createdBy in the POST task handler’s internal.pm.apiCreate call in convex/http.ts. Keep request-body createdBy blocked. Verify the first task creates a valid project and task, retains tenant checks, and returns 201. This is a host compatibility fix; the Orbit installer does not overwrite these core files. The isolated September 28 test host includes it. ### Orbit appearance Agency owners and administrators can open Orbit → Settings → Appearance and choose Use account brand (default), Clear light, Clear dark, or Custom colors. Brand mode inherits the CRM's current background, foreground, muted, border, primary and primary-foreground design tokens, including light/dark changes. Custom mode offers background and accent colors with automatic contrasting text. Preview changes, then Save settings. Appearance is stored per subaccount and applies to both the full workspace and floating chat for its users. Launcher character and position remain personal browser preferences. ## Guided agents (0.2.0-alpha.1) See [Guided agents](AGENTS.md) for setup, rehearsals, schedules, review, limits and upgrade verification. Deploy the new backend before the frontend. Existing conversations remain available; the upgrade adds two private tables and does not enable any scheduled job automatically. ## Orbit v1 host integrations The installer contributes a reversible native workflow-trigger bridge and a scoped read endpoint at `GET /api/v1/ext/orbit/contacts/counts`. Grant `orbit:contacts:read` on the CRM API key to use lifecycle reports. Discovery must report this route as granted; the AI cannot override the key's scope. The installer also carries the authenticated API key creator into task creation on supported hosts. An existing equivalent creator fix is preserved. It adds `tasks:create` as a create-only scope for `POST /api/v1/tasks`; update, completion and deletion still require `tasks:write`. Existing `tasks:write` keys continue working. This is an Orbit compatibility contribution, not a claim that unmodified Seedly ships this scope. Run the preflight on modified forks. Unrecognized host anchors stop installation before writes. Reconcile the native trigger, task route and key-auth changes explicitly rather than forcing installation. Native source is never distributed in the module archive. After installation, run `node bin/doctor.mjs --seedly /path/to/seedly`, Convex codegen, host tests, backend/web typechecks and the web build before deploying. Rehearse every agent after edits. See AGENTS.md for event delivery, coalescing and count scan limits. --- # Agent installation runbook Use this runbook from the extracted Orbit package. It installs original module source into a separately licensed Seedly host. Never infer permission to deploy to another customer or shared backend. ## Required handoff Record these non-secret inputs before edits: absolute host path; host version and source commit; Orbit version from module.json; development Convex deployment name; web project and local port; test agency and location public ID; matching internal agency/subaccount IDs; release owner; intended permissions; existing modules. Public location IDs belong in browser URLs; internal IDs belong in ORBIT_CRM_KEYS. Do not interchange them. If a deployment target, host path, or required credential is missing, ask for that specific input. Continue source inspection while waiting. Never substitute an environment from a neighboring checkout. Never ask someone to paste credentials into an AI conversation. ## Copyable agent brief ```text Install Orbit in HOST_PATH, targeting DEVELOPMENT_DEPLOYMENT only. Read the host AGENTS.md, Orbit module.json, INSTALLATION.md, IMPLEMENTATION_CONTRACT.md, API_COVERAGE.md and this runbook. Inventory existing extensions and uncommitted work. Preserve both. Verify the package checksum manifest and use a clean source checkpoint. Run the dry-run installer, inspect its changes, then apply and run doctor. Do not use --verify: the Orbit installer does not support that flag. Configure secrets through the deployment's secret store, never frontend env, Git, logs, chat, generated docs, or command arguments containing literal keys. Generate the real installed Convex API; run backend/web types, Orbit host fixtures, extension guards and the web build. Do not treat mocked tests as live AI verification. Deploy only to the named authorized development target, backend before frontend. Configure one synthetic location, start read-only, verify provider replies and CRM reads, then one approved synthetic write. Report exact commands, exit status, source changes, target identity, tests passed/blocked, rollback checkpoint and remaining limitations. Production deployment requires the customer's established release authorization. ``` ## Checkpoint 1: verify and inspect Verify the archive SHA-256 against archiveSha256 in its adjacent manifest before extraction. On macOS use `shasum -a 256 ARCHIVE.tar.gz`; on Linux use `sha256sum ARCHIVE.tar.gz`. Compare with a manifest received through the trusted delivery channel. A matching hash detects corruption; it does not authenticate an untrusted publisher. Extract to a new directory and compare extracted file hashes with the manifest's files map. Do not extract over the host. Confirm Node 22+ and the host's locked package manager/dependencies. Orbit targets Seedly 5.8.4 / extension API 1; the declared 5.8.x range is not certification of every later host. Read version-specific host source and integration seams. Check `git status --short` and record a rollback commit or backup. Do not discard another developer's changes. From the extracted package: ```sh node bin/install.mjs --seedly /absolute/path/to/seedly node bin/install.mjs --seedly /absolute/path/to/seedly --apply node bin/doctor.mjs --seedly /absolute/path/to/seedly ``` Expected: dry run lists planned files; apply reports local installation; doctor reports matching source/contributions/receipt. A customization refusal is a stop condition: compare the customer diff and integrate deliberately, never delete the receipt to force an overwrite. Keep .seedly-addons/orbit/receipt.json and recovery journal with the host backup. ## Checkpoint 2: connect without leaking secrets Use the intended Convex dashboard's environment settings. ORBIT_KEY_ENCRYPTION_SECRET is 32 random bytes as 64 hex characters, stable across restarts; ORBIT_CRM_KEYS maps internal IDs to native API keys. CONVEX_SITE_URL must be the same backend's platform-provided site origin. Keep the encryption secret backed up in a secret manager. Do not print secret values during verification. Verify deployment identity and frontend NEXT_PUBLIC_CONVEX_URL agree. The public URL is configuration, not a provider key. No CRM key, inference key, or wrapping secret may be exposed through NEXT_PUBLIC variables. Scope the CRM key to the synthetic account and minimum operations. A test key does not make all database writes dry runs. Connect an OpenRouter key in Orbit Settings after deployment; credentials are encrypted per location. Key verification is not an inference test. Credits, model access and function tool support must still be confirmed with a real reply. Select the provider and model, then Save settings. Do not automatically switch to a different provider on failure. ## Checkpoint 3: validate installed source From the licensed host root, using its locked pnpm installation: ```sh pnpm exec convex codegen pnpm exec tsc --noEmit -p convex/tsconfig.json pnpm exec tsc --noEmit -p apps/web/tsconfig.json pnpm --filter @seedly-crm/web build ``` Codegen must use the selected development deployment and installed modules. If the host needs a development push to generate component bindings, use its documented `convex dev --once` workflow only after checking the target. Never fabricate generated types or suppress errors to pass a gate. Copy package host-tests/seedly-orbit.test.ts into host convex/__tests__/seedly-orbit.test.ts. From the host's convex directory: ```sh pnpm exec vitest run __tests__/seedly-orbit.test.ts __tests__/subaccount-purge-index-coverage.test.ts __tests__/plans-schema-extensions.test.ts __tests__/extension-seam-no-dead-code.test.ts ``` If a newer host renamed a guard, identify and run its equivalent; record the difference. Do not silently skip checks. Fixture tests must use an isolated in-memory database. Do not run seed or purge routines against customer data. Build success confirms compilation, not provider or API access. ## Checkpoint 4: deploy and accept Deploy schema/functions before web using the host's approved workflow. Confirm the actual deployment is ready and the browser is using that version. Enable Orbit, Floating chat and appropriate Agency access in one synthetic location; assign native Orbit/resource permissions and plan features. Keep writes disabled first. Acceptance evidence must include: authenticated login; a real model reply; bounded contact read with matching native IDs; table/chart with source and partial-data labels; denied user and wrong-location request; conversation restoration after reload; launcher open/close/move; saved appearance; enabled writes producing a proposal before mutation; exactly one synthetic task after approval; duplicate approval refused. Read INSTALLATION.md's first-task compatibility note before testing clean Seedly 5.8.4. Record separate statuses for source installed, backend deployed, frontend served, provider key verified, inference verified, CRM read verified and reviewed write verified. A missing key leaves inference blocked, not passed. Never claim all API endpoints were exercised because catalog metadata exists. ## Upgrade and rollback Re-run the new package's dry run against the existing receipt, review the diff, apply, run doctor, regenerate APIs and repeat gates. Back up data before schema changes. Preserve old schema fields until backward compatibility and retention are reviewed. Never reinstall by deleting module-owned files manually. For an interrupted installation, preview `node bin/recover.mjs --seedly /absolute/path/to/seedly`, inspect the plan, then add --apply. For removal, preview `node bin/uninstall.mjs --seedly /absolute/path/to/seedly`, then add --apply. Source removal preserves stored records; do not deploy a schema that discards them without a separate retention/export decision. For a runtime regression, disable Orbit or reviewed writes for the affected location, investigate pending/unknown actions, and restore the previous compatible web/backend source checkpoint through the normal release process. Never roll back by deleting customer tables or replaying an unknown write. Reconcile native CRM state first. ## Handoff report template ```text Orbit version / host commit: Host path / named development deployment / web URL: Receipt and source checkpoint: Checks (exact command, exit status, evidence location): Real provider / CRM read / reviewed-write results: Synthetic records created and their IDs: Known gaps and excluded operations: Rollback source checkpoint and compatibility notes: Next action and owner: Secrets: stored in approved secret management; none attached. ``` ## Guided agents (0.2.0-alpha.1) See [Guided agents](AGENTS.md) for setup, rehearsals, schedules, review, limits and upgrade verification. Deploy the new backend before the frontend. Existing conversations remain available; the upgrade adds two private tables and does not enable any scheduled job automatically. --- # Add CRM capabilities to Orbit with an AI coding agent Use this document in your **own licensed Seedly source checkout**. It helps your coding agent add a missing capability without turning the model into a database administrator. Primary reference: https://seedlycrm.com/docs/help/api. Review your installed source because your deployment changes only when you update it. The published reference explicitly says that some features, including campaign reads, are not exposed by the base REST API. Do not invent a URL because a corresponding CRM screen exists. ## Start from a concrete question Examples: - “Show unpaid invoices grouped by age.” Add a bounded invoice-aging read returning totals, currency, date boundaries and authorized invoice links. - “Compare revenue across locations.” Add an agency-authorized reporting endpoint that explicitly returns account labels and never blends currencies. - “Summarize project progress.” Return a minimal project/task projection with current resource permission checks. - “Find contacts that have not been followed up.” Define what follow-up means, which channels count, and the time zone before writing the query. Prefer a narrow reporting operation over returning every table to the model. Do not make the model calculate financial totals from a partial page. ## Copy this brief to your AI coding agent > Work in this licensed Seedly checkout. Read AGENTS.md, convex/_generated/ai/guidelines.md, the native module's schema/auth/business functions, and Orbit's IMPLEMENTATION_CONTRACT.md and API_COVERAGE.md before editing. Implement the following capability: [business request]. First inventory existing endpoints and explain the data source, tenant/record permission, request fields, response fields, pagination, units and time zone. Reuse a supported existing endpoint when possible. Otherwise contribute a narrowly scoped authenticated endpoint through the installed extension API seam, with a typed request and minimal response. Do not add raw SQL, arbitrary table access, shell execution, arbitrary fetch, or model-supplied account IDs. Keep existing native side effects and invariants. Register the operation in Orbit with its exact method/path, schema, native permission resource/action and read/write classification. Add tests for wrong tenant, wrong user, missing scope, own/team scope, archived records, invalid inputs, pagination, duplicate writes, stale approvals and ambiguous provider outcomes. Run fresh Convex API generation, backend/web types, relevant host guards and a production build in the correct private development instance. Document changes and validation. Do not publish, send messages, create charges, or deploy to production unless my instructions authorize those actions. ## Implementation checklist ### 1. Inspect the existing contract Read the current `docs/openapi.yaml`, `convex/http.ts`, `convex/apiHelpers.ts`, `convex/extensions/apiRoutes.ts`, `packages/shared/src/extensions-api-scopes.ts`, and `convex/extensionApiHost.ts`. Names and signatures can change across host versions: use your actual interfaces rather than copying an old route example blindly. Check whether `GET /api/v1/ext` already exposes the capability. Its `granted` field indicates the key's scope, not whether every signed-in user should be able to use the endpoint through Orbit. ### 2. Design the operation Write down: - Exact HTTP method and path, unique operation ID, and whether it can cause side effects. - Request JSON schema, required fields, enums, numeric limits and maximum lengths. - Native resource permission (`deals`, not the REST resource name `opportunities`, for example), action and supported record scope. - Tenant association for every referenced ID; how agency membership and any brand restriction are enforced. - Response projection, currency/unit/time-zone semantics, cursor pagination and whether totals describe the full result set. - External effects, confirmation/approval boundary, idempotency strategy, audit record and ambiguous-outcome handling. A GET must be read-only. A side-effectful POST must always be classified as a reviewed write, even if its name contains “preview.” Only explicitly reviewed POST lookup contracts may be treated as reads (as with the existing verified-customer booking lookups). ### 3. Add the authenticated route Use the extension namespace and scope seam available in your host. Do not overwrite the central extension dispatcher. Preserve its authentication, API-key expiry/revocation, rate limiting, response envelope and error containment. Put atomic data changes in the backend transaction. Call native business helpers instead of patching arbitrary fields around validation, automations or audit. Return a minimal projection, not raw database documents. Never expose API keys, signing secrets, portal tokens, payment credentials, storage IDs, or unbounded free text. If adding an original module table, register it as private, add its exact `by_subAccount` index, register account-purge cleanup and any file cleanup, and preserve tenant separation. Add explicit agency handling only if the business request requires it. ### 4. Register the Orbit tool For a normal typed tool, add an `Operation` to the module catalog or maintain an additive catalog source beside the generated base list. Do not edit the generated file and then regenerate it without preserving your additions. Example **metadata only** (implement and test the actual route first): ```ts { id: 'invoiceAging', method: 'GET', path: '/api/v1/ext/myReporting/invoice-aging', title: 'Invoice aging', description: 'Read authorized unpaid invoice totals by aging bucket, currency and as-of date.', resource: 'invoices', action: 'view', read: true, admin: false, params: { path: { type: 'object', properties: {}, additionalProperties: false }, query: { type: 'object', properties: { asOf: { type: 'string', format: 'date' } }, required: ['asOf'], additionalProperties: false }, body: { type: 'object', properties: {}, additionalProperties: false } } } ``` Keep account context out of the tool arguments. Orbit supplies the approved location. The runtime must verify discovery/granted status for any `/api/v1/ext/` path, including a newly typed route, not just the generic gateway. Explicitly decide and test how the route allowlist and its own permission interact. Never remove that gate just to make a new tool work. For a one-off manager-only integration, the existing generic extension gateway can call exact routes configured under Orbit Settings → Approved extension routes. Only enable endpoints you have reviewed. Discovery summaries do not contain full request schemas, so give the agent the endpoint's actual schema/documentation before asking it to call one. ### 5. Validate with synthetic records Test both positive and refused requests against the actual host functions. Include at least two agencies, two locations, two users in one location, a revoked role/key, missing scopes, partial pages, malformed IDs, and records from another tenant. For writes, simulate a repeated approval and a timeout after the provider may have accepted the request. A timeout must not become a blind retry. Verify chart totals against hand-calculated fixtures. Preserve the distinction between returned-record count and total matching count. A paged response must never render a complete-looking total without fetching all pages or using a verified aggregate endpoint. ### 6. Document and release Update the API coverage table, customer setup/scopes, native permission mapping, validation record and rollback instructions. Generate the full installed Convex API again, run types/tests/build, and deploy backend before web through the customer's established release process. Record real request verification separately from mocked network fixtures. ## Good next extensions Invoice aging and payment summaries; company records; projects; campaign reads and audience previews; workflow inspection; reporting aggregates; module-specific Events/Real Estate/Client Delivery lookups. Each is a distinct typed capability with its own authorization and evidence, not assumed base API coverage. ## Public endpoints are a separate integration The public live-chat widget and form submission APIs are intended for visitor sessions, not staff CRM management. Signed workflow ingress needs a configured slug/secret and HMAC signing. If your use case needs either, add a dedicated adapter with server-owned session/signing context and tests. Never offer an arbitrary URL/header/body tool to bypass CRM permissions. ## Current implementation details an agent must preserve The installed implementation is in convex/seedlyOrbit: core.ts owns Operation, prepare and bounded schema validation; catalog.ts is generated metadata; auth.ts handles native user/feature/record-scope checks; data.ts owns conversation access and proposal claims; runtime.ts owns same-origin requests, extension discovery and provider execution. The frontend renders approved visualization types, never executable model output. Do not assume a schema `format` annotation validates dates or emails. The current core validator enforces types, bounds, required properties, enums and supported patterns; route handlers must independently validate semantic dates, timezones, tenant-bound IDs and native business rules. Treat both model arguments and discovery/CRM text as untrusted input. For additive tools, move custom Operation definitions to a separate file and import them from a maintained catalog entrypoint used consistently by runtime, auth and data. Update the generator/import workflow so regeneration preserves additions. Reject duplicate IDs and method/path collisions in tests. Never append examples to the generated list and forget the generator. A custom ID must resolve consistently for current calls and historical conversation access checks. The current allowlist accepts exact GET or POST extension entries, up to 50, and runtime checks the resolved path without its query string against live discovery. Dynamic path IDs therefore require exact resolved entries; a wildcard-looking string is not a wildcard. For simple reports prefer a fixed route with validated query arguments. Support for another method requires coordinated settings validation, runtime, catalog and tests, not a UI-only change. Example allowlist entry, only after that recipe is implemented, deployed and granted: ```text GET /api/v1/ext/myReporting/contact-completeness ``` Native API scopes are enforced by the host key; Orbit additionally checks the signed-in user's resource/action, feature and account-wide record scope. For custom extension operations, the same exact allowlist and discovery gates apply even when admin:false. Begin admin:true until staff permissions and revocation tests are reviewed. Endpoint authentication alone is insufficient to authorize a different Orbit user. For write tools, require read:false, native action permission, current writes policy, immutable proposal fields and the existing claim/settle path. Use a server-derived idempotency identity bound to the claimed action if your endpoint supports it. Extend the adapter explicitly if needed; do not let model-supplied headers or an arbitrary retry flag choose that identity. One-time approval prevents duplicate execution attempts through Orbit, but cannot make an external provider transaction exactly-once after a timeout. Preserve unknown outcomes and reconcile externally. ## Stable custom catalog seam Add original definitions in `src/convex/seedlyOrbit/customOperations.js`; `catalog.ts` composes them with generated upstream operations. Use the same operation shape and native permission checks. A catalog entry alone does not create a route or grant API access. Contribute routes and distinct scopes through the native registries; add host fixtures for wrong scope, foreign tenant, malformed input and partial results. Keep aggregate calculations server-side and flag incomplete coverage. Never accept a caller-selected agency or account in the query/body. Orbit's lifecycle endpoint is a working example of a scoped aggregate. Do not copy its bounded scan and call it an unlimited or transactional snapshot. Add tests for a matching record beyond page one, deleted records, scope refusal and aggregate chart math. --- # Useful starters and extension recipes Start with saved prompts when existing tools already answer the question. A recipe below is a development brief, not a deployed endpoint or a permission grant. Adding text to an allowlist does not create a route. ## Use today: pipeline snapshot Save this prompt: “List my open opportunities, group the retrieved records by stage, and show a bar chart. Include the number retrieved and whether more pages exist. Keep currencies separate.” Uses existing opportunity reads and the built-in visualization tool. Requires native deals view permission with account-wide scope and the matching API scope. A retrieved sample is not a complete pipeline total. ## Use today: overdue task review Save this prompt: “Find overdue, incomplete tasks. Show title, owner and due date as a table. State the time zone and any paging limits. Do not modify anything.” Uses task reads. Check the installed API filters; page within supported limits instead of inventing an overdue route. Requires native tasks permission and matching key scope. ## Use today: reviewed follow-up task Save this prompt: “Help me create one follow-up task for this contact. Confirm the contact ID, title, assignee and due date, then show the proposed change for my approval.” Uses existing task creation and the write-review flow. Resolve ambiguous contacts first. Enabling writes permits proposals; it does not bypass per-action approval. On clean Seedly 5.8.4, see the installation guide's first-task project compatibility note. ## Build next: contact completeness report Suggested contract: GET /api/v1/ext/myReporting/contact-completeness. This is an example route to implement, not an existing endpoint. Begin with a read-only manager-only tool. Input: optional cursor and integer limit 1–100. Output: contact ID, display name, booleans missingEmail/missingPhone/missingOwner, next cursor, hasMore and generatedAt. Do not return addresses, notes or raw custom fields. Define empty/invalid values consistently; the report identifies missing data, not consent to contact someone. Use the native contacts view permission, contacts feature gate and an explicit extension API scope. Derive the location from the authenticated host context. Check every returned row belongs to it. Tests: wrong tenant, own/team refusal, missing scope, empty account, deleted records, boundary limits and stable pagination. First acceptance: compare five synthetic contacts by hand. ## Build next: overdue task digest Suggested contract: GET /api/v1/ext/myReporting/overdue-tasks. Input: asOf as a validated ISO date-time, a validated IANA time zone, cursor and bounded limit. Output: minimal task rows with dueAt/owner/status, paging and asOf. Exclude completed and deleted tasks according to native semantics. Date-only due dates need an explicit end-of-day rule. Use native tasks view permission and feature gating. Do not implement timezone or recurrence assumptions from field names alone. Test midnight/DST boundaries, unassigned tasks, completed/deleted records, wrong tenant, missing scopes and pagination. This route is useful when the base API cannot express the report efficiently; otherwise use the saved prompt above. ## Build next: invoice aging Suggested contract: GET /api/v1/ext/myReporting/invoice-aging. Input: validated asOf date and timezone. Output: overdue buckets per currency, integer minor-unit amounts, matching invoice count, asOf and completeness. Define treatment of partial payments, refunds, voids and due-today invoices with the native billing rules. Discover the installed native billing permission/feature and API scope; do not assume a resource string from the invoice screen name. Aggregate on the server over the authorized full result set, or return explicit partial status. Never sum different currencies or let the model infer cents versus dollars. Tests include negative/refunded balances, multiple currencies, date boundaries and permission revocation. Keep it read-only; payment collection is a separate tool. ## Copy a recipe to your coding agent ```text Implement only the selected recipe in my licensed Seedly host. Read Orbit's EXTENDING_API_WITH_AI.md and AGENT_INSTALL.md first. Inventory current routes and reuse a supported operation when possible. Write the exact request/response/permission contract before coding. Keep the suggested endpoint disabled until its implementation, discovery, scopes, native authorization, tests and deployment are verified. Add a typed Orbit operation with additionalProperties:false and bounded inputs; enforce semantics again in the host handler. Keep account IDs, headers and secrets out of model arguments. Preserve extension allowlist and discovery gates. Start manager-only and read-only. Use two tenants and restricted staff in tests. Produce fixture and live verification evidence separately. Do not invent unavailable data sources. Return code changes, tests, setup steps and an exact allowlist entry. ``` --- # Troubleshooting Diagnose one layer at a time: source install, deployment, browser session, location policy, provider, CRM key, native permission, endpoint contract. Never fix a failed check by removing authorization. | Symptom | Check | Next step | | --- | --- | --- | | Installer refuses a file | Customer edit or unsupported host seam | Compare the diff and supported host version. Preserve edits; do not delete the receipt. | | Doctor mismatch | Installed source differs from receipt/package | Review local customization or incomplete install; preview recovery. | | Page unavailable | Web process, port, frontend deployment, auth session | Start the correct host web app, verify ready status, then sign in on the same origin. | | Sidebar missing | Navigation contribution, role/plan feature | Run doctor, confirm native Orbit permissions/feature and current deployed build. | | Floating launcher missing | Location enabled, Floating chat, personal Hidden choice, route | It is intentionally hidden on the full Orbit page. Open a CRM page in the same location. | | Agency access disabled | Per-location agencyAccess setting | Have an authorized manager enable the intended location. | | Cannot connect provider | Wrapping secret present and valid; agency/settings rights | Configure the backend secret without exposing it, then verify the key. | | Key verified but reply fails | Credits, selected model, tool support, provider error | Check failed-run details and provider account. Verification does not test inference. | | CRM configured but reads fail | Mapping IDs, key validity, scopes, origin | Configured means the server variable exists, not that each mapped connection works. | | Account-wide access required | User's native record scope | Use an authorized account-wide role or build a separately reviewed scoped endpoint; never widen automatically. | | Extension route refused | Exact METHOD path, live discovery, granted scope | Implement/deploy/register the route first. Allowlisting text alone is insufficient. | | Chart total seems low | hasMore, source rows, date/currency filters | Label the sample or use a complete authorized aggregate endpoint. | | First task fails on Seedly 5.8.4 | API Tasks project createdBy compatibility | Apply the narrowly documented host fix; never accept createdBy from request input. | | Unknown write outcome | Native record/provider state and run audit | Reconcile before a new proposal; never blindly replay a send or payment. | | Old layout after update | Backend/web versions, cached tab | Confirm new build is served and refresh. Keep frontend/backend compatibility. | For support provide module/host versions, route, sanitized error and request/run ID, expected/actual result and reproducible steps using synthetic data. Remove tokens, cookies, authorization headers, provider keys, CRM secrets and customer records. Keep screenshots free of personal data. --- # API coverage Published reference: https://seedlycrm.com/docs/help/api (September 18, 2026). Reconciled September 27, 2026. Input OpenAPI SHA-256: `ef08f173b2824374c7ed609c6f82b9b64bd617f2abbee09e1738f6565c9fe5d0`. Four verified-customer operations supplement the local specification from the published reference. 50 operation definitions including the extension gateway. Runtime authorization and API scopes still apply. No endpoint is a claim of live deployment verification. | Operation | Method | Path | Execution | |---|---|---|---| | listContacts | GET | /api/v1/contacts | Read | | createContact | POST | /api/v1/contacts | Reviewed action | | listContactFields | GET | /api/v1/contacts/fields | Read | | getContact | GET | /api/v1/contacts/{id} | Read | | updateContact | PATCH | /api/v1/contacts/{id} | Reviewed action | | deleteContact | DELETE | /api/v1/contacts/{id} | Reviewed action | | listConversations | GET | /api/v1/conversations | Read | | createConversation | POST | /api/v1/conversations | Reviewed action | | getConversation | GET | /api/v1/conversations/{id} | Read | | updateConversation | PATCH | /api/v1/conversations/{id} | Reviewed action | | listMessages | GET | /api/v1/conversations/{id}/messages | Read | | sendMessage | POST | /api/v1/conversations/{id}/messages | Reviewed action | | listCalendars | GET | /api/v1/calendars | Read | | listAppointmentTypes | GET | /api/v1/calendars/types | Read | | getAvailability | GET | /api/v1/calendars/availability | Read | | listAppointments | GET | /api/v1/calendars/appointments | Read | | bookAppointment | POST | /api/v1/calendars/appointments | Reviewed action | | cancelAppointment | DELETE | /api/v1/calendars/appointments/{id} | Reviewed action | | listWebhookSubscriptions | GET | /api/v1/webhooks | Read · agency admin | | createWebhookSubscription | POST | /api/v1/webhooks | Reviewed action · agency admin | | updateWebhookSubscription | PATCH | /api/v1/webhooks/{id} | Reviewed action · agency admin | | deleteWebhookSubscription | DELETE | /api/v1/webhooks/{id} | Reviewed action · agency admin | | regenerateWebhookSecret | POST | /api/v1/webhooks/{id}/regenerate-secret | Reviewed action · agency admin | | listTasks | GET | /api/v1/tasks | Read | | createTask | POST | /api/v1/tasks | Reviewed action | | getTask | GET | /api/v1/tasks/{id} | Read | | updateTask | PATCH | /api/v1/tasks/{id} | Reviewed action | | deleteTask | DELETE | /api/v1/tasks/{id} | Reviewed action | | completeTask | PUT | /api/v1/tasks/{id}/complete | Reviewed action | | listOpportunities | GET | /api/v1/opportunities | Read | | createOpportunity | POST | /api/v1/opportunities | Reviewed action | | getOpportunity | GET | /api/v1/opportunities/{id} | Read | | updateOpportunity | PATCH | /api/v1/opportunities/{id} | Reviewed action | | deleteOpportunity | DELETE | /api/v1/opportunities/{id} | Reviewed action | | setOpportunityStatus | PUT | /api/v1/opportunities/{id}/status | Reviewed action | | moveOpportunityStage | PUT | /api/v1/opportunities/{id}/stage | Reviewed action | | listPipelines | GET | /api/v1/pipelines | Read | | createCampaign | POST | /api/v1/campaigns | Reviewed action | | sendCampaign | POST | /api/v1/campaigns/{id}/send | Reviewed action | | scheduleCampaign | POST | /api/v1/campaigns/{id}/schedule | Reviewed action | | listSubAccounts | GET | /api/v1/sub-accounts | Read · agency admin | | listBookingServiceTypes | GET | /api/v1/booking/service-types | Read | | listBookingEstimates | GET | /api/v1/booking/estimates | Read | | listExtensionRoutes | GET | /api/v1/ext | Read · agency admin | | callExtensionRouteGet | GET | /api/v1/ext/{namespace}/{path} | Read · agency admin | | callExtensionRoutePost | POST | /api/v1/ext/{namespace}/{path} | Reviewed action · agency admin | | verifiedAppointments | POST | /api/v1/booking/appointments | Read | | verifiedActionableAppointments | POST | /api/v1/booking/appointments/actionable | Read | | verifiedCancelAppointment | POST | /api/v1/booking/appointments/cancel | Reviewed action | | verifiedRescheduleAppointment | POST | /api/v1/booking/appointments/reschedule | Reviewed action | Public live-chat/forms and signed workflow ingress are separate protocols, not authenticated CRM management APIs. They are not exposed as arbitrary bypass tools. Extend through the authenticated extension seam; see EXTENDING_API_WITH_AI.md. ## Original Orbit v1 additions `countContactsByLifecycle`: GET `/api/v1/ext/orbit/contacts/counts`, scope `orbit:contacts:read`, native Contacts view/account-wide permission. Optional `source` is an exact record filter. Returned rows are `{stage, count}`. `meta.hasMore` means incomplete coverage; `meta.matchingContacts` is null until the scan completes. Counts exclude inactive and soft-deleted contacts. The endpoint traverses records before filtering, avoiding the host contacts-list pagination/filter ordering issue. The original catalog contains 51 operations: the 50 upstream/supplemental definitions plus this aggregate. Custom definitions live in `customOperations.js` and survive upstream catalog regeneration. Orbit also contributes `tasks:create` to POST `/api/v1/tasks` only. It does not grant read/update/complete/delete. This is separate from the native task scope contract documented by Seedly. --- # Orbit implementation contract Orbit is a separately installable staff-facing Seedly module. It is not a public customer-support chatbot. Host baseline: Seedly 5.8.4 / extension API 1. Original payload lives under `src/`; host source never belongs in its package. ## Product - Location-bound conversations, saved history, pin/archive/rename, private saved prompts. - Native `/location/[locationId]/orbit` workspace, `/orbit` account entry point, movable floating launcher in location dashboard pages. - Agency owners/administrators configure each location: enablement, floating visibility, agency access, reviewed writes, model, daily reply limit, exact allowed extension routes. - 51 authenticated operation definitions: 50 upstream definitions and the Orbit-owned lifecycle-count extension. Public forms/live-chat and signed workflow ingress remain separate integration protocols. - Inline source disclosures, tables, count/sum metrics and bar charts calculated from retrieved rows. Partial data is labeled. No generated JavaScript or arbitrary HTML executes in the chat. ## Authority and persistence Use native auth, active membership, agency/location ownership, native resource permissions, plan features, and account-wide record scope. An API key cannot widen the signed-in user's role. Extension calls require an agency manager, exact route allowlist and live discovery grant. All module tables are private and indexed by_subAccount. Conversation ownership is user + agency + location. Account IDs are derived server-side; the model has no account/header/URL override. API requests go only to this installation's CONVEX_SITE_URL and refuse redirects. CRM keys stay in backend environment configuration and are revalidated against the host before calls. OpenRouter keys are encrypted at rest in private location settings with deployment-owned AES-GCM wrapping and agency/location associated data; public queries never return ciphertext or plaintext. Only agency managers with native settings-update access can connect/disconnect keys. Writes become immutable proposals with 15-minute expiry in chat and a snapshotted, configurable 15-minute to seven-day expiry for agents. Approval rechecks current policy, claims exactly once in a transaction and executes stored arguments. A network failure or 5xx is outcome-unknown; no automatic replay. Actual provider delivery is distinct from API acceptance. Approved actions can trigger native automation and are not globally undoable. Replies reserve a daily per-user/location slot atomically. Same request ID cannot create duplicate messages/runs. Each reply has bounded history, tool count, output tokens, request/response size and time. Provider usage is token accounting; daily turn limits are not a guaranteed dollar budget. ## Provider OpenRouter Responses API for new setups, with retained direct OpenAI Responses compatibility for existing setups; server-side credentials, store:false, configurable tool-capable model. Key verification uses OpenRouter GET /key without inference; successful verification does not certify model access or credits. Changes/disconnection stop the next model round; an already in-flight request cannot be recalled. Tool definitions are explicit; model output is untrusted. No shell/browser/code execution tool. CRM content is treated as quoted data. API secrets and token fields are removed from model and persisted result payloads. Webhook create/rotation returns its new signing secret only to the approving manager’s current browser state. ## Verification Local source tests, installed-host behavior fixtures, fresh local API types, web/backend typechecks and production build are distinct from authenticated Convex component codegen, provider spend and live CRM verification. Do not label fixture results as production-ready certification. See VALIDATION.md. ## Companion preference Original 16×16 SVG pixel sprites replace the floating button; same launcher behavior and permissions. Users choose a built-in pixel character, classic bubble, custom image or hidden in Settings. Branded choices include a Seedly-inspired sprout, the cobalt DevLaunch companion and GoSeedly’s artichoke luchadora. The choice is per browser/user/location and remains subordinate to agency floating-chat enablement. Pets grant no extra autonomy and have no independent agent or usage. ## Native presentation Orbit is an embedded Seedly tool. Inherit the host HSL theme tokens and typography; use neutral fallbacks. Keep one compact page toolbar, functional field labels and necessary help only. Avoid marketing headings, eyebrow labels, slogans and repeated subtitles. Pixel companions are optional personal launcher choices. The full workspace fills the native dashboard content area with no outer card border, radius or page padding. Scope that layout to the full workspace; floating chat must preserve the underlying CRM page layout. Omit the personal-account footer from the sidebar. The installer contributes the Orbit icon to native sidebar navigation. ## Version 1 additions Native contact-created, contact-updated and tag-added events can queue reviewed agents with durable event-key deduplication, cooldowns, concurrency and daily limits. Nested workflow events are refused. Events arriving during an active run or cooldown are coalesced rather than replayed; the agent view reports this. Agent duplication always produces an unreviewed draft. Pending write proposals are available in the approval inbox and retain permission and expiry checks at execution. The count extension requires `orbit:contacts:read`, scans at most 10,000 contacts within a bounded request, and marks capped results incomplete. It is not an atomic database snapshot. The reversible task contribution supports `tasks:create` only for task creation and obtains `createdBy` from authenticated key metadata. See API_COVERAGE.md and AGENTS.md. ## Conversational drafts and change previews `draft_agent` produces a bounded message block, not a persisted or enabled agent. Only current agency managers can obtain a draft; allowed tools are resolved on the server. The user hands the draft into editable setup and existing rehearsal gates. Agents cannot draft other agents. `soActions.review` is an optional server-generated snapshot for change previews. Only mapped contact/task/opportunity updates fetch current values, under matching read permissions and agent budgets. Missing values remain unknown. Approval rechecks known fields through the same scoped REST read before issuing the write; stale or unverifiable snapshots fail closed. This does not provide atomic compare-and-swap across the REST boundary. Existing proposals without snapshots remain compatible. ## Agent inbox and event conditions Optional structured event conditions and success-notification preference are snapshotted from `soAgents` to `soAgentJobs`. Filtering uses current native contact data and rechecks contact-read access before queuing. Exact required/excluded tags and allowed lifecycle stages combine conjunctively. Old agents retain unrestricted event matching. Changed-field predicates and tag-change attribution are not implemented. The manager-only inbox scans at most 100 recent jobs using the owner/account index and derives actionable approval state from stored proposals. Read keys are persisted per job and compared server-side to avoid marking a newer state read. Approaching expiry gets its own key and client minute refresh; no notification scheduler or outbound side effect is introduced. Optional schema fields preserve compatibility with existing data. Deploy backend/schema before UI. ## Signed-in support mode Support conversations retain requester ownership and normal Orbit authorization. `soSupportPolicies` is private with native tenant-purge indexing, agency defaults and optional locked account overrides. Curated knowledge and instructions grant no authority. Runtime context, tool registration, proposal creation and approval enforce the effective support tool allowlist; approval also matches the policy revision. Privileged diagnostics register a history access requirement. Human handoff uses the existing authenticated native feedback mutation atomically, with an editable preview, verified native destination, source-active-account check and one submission per conversation. Successful handoff cancels AI work and blocks further proposals/approvals. Native intake status does not imply resolution. See SUPPORT.md for configuration, routing, scope, limits and extension requirements. ## Live support (1.6) See LIVE_SUPPORT.md for the complete transport, authority, cancellation, usage and retention contract. Realtime voice delegates into the existing worker from regular or support conversations; it never approves CRM writes. Support conversations retain their additional tool policy. In-app navigation uses fixed permission-checked routes, caller opt-in and browser route acknowledgement. A persistent dashboard voice panel retains the call across same-account navigation and exposes its originating conversation for review. Structured screen controls use an explicit server-checked page allowlist and access level. Native permission checks, caller opt-in, fresh UI revisions and draft-only controls apply; no arbitrary computer-use tool or screenshot access is granted. New sessions are private and tenant-indexed; new schema fields remain optional for 1.5 upgrades. ## Support operations (1.6) Setup/readiness, ten operator rehearsal scripts, draft-only voice handoffs, customer-reported outcomes and bounded account aggregates extend the live-support workflow. Practice threads refuse CRM approval and native support submission on the server. Rehearsals are private requester-owned records; pass requires worker/audio evidence and operator review, and policy/model changes invalidate results. Agency voice pause overrides local settings. New metadata retention is creation-snapshotted; it does not erase chat/audit/native-ticket records. Quality access requires agency management plus settings-update permission and returns aggregates without other users' transcripts. See LIVE_SUPPORT.md for measurement, pricing and validation limits. --- # Validation and installation checks Orbit 1.7.0 has been checked in an isolated Seedly 5.8.4 installation. The release includes the chat and code-review interface, GitHub App connection and optional local Codex connector. The code-review workflow has also been exercised against a private test repository. Module tests, installed-host permission and workflow tests, frontend and backend type checks, and the production web build were run during development. Desktop, mobile and floating chat were checked with example data. These checks do not certify every Seedly version, custom fork or hosting environment. Before using Orbit in your installation: 1. Verify the downloaded archive and run the installer dry run against a backed-up test checkout. 2. Generate the combined Convex API and run the host's backend and frontend type checks, relevant tests and production build. 3. Check administrator and ordinary-user access in separate accounts. Verify account boundaries and a reviewed action using example data. 4. Connect your own provider and repository, then review a small code proposal and create a draft PR. Run your project tests before merging. 5. Verify optional voice with your own microphone and provider configuration; the text and code checks do not certify live audio behavior. ChatGPT web access requires the separately configured registered-client integration. Local Codex requires your own authenticated CLI on the trusted CRM host and an explicit user/account binding. Neither connection, an AI subscription, provider credits, a GitHub App nor any credential is supplied in the download. Generated code remains a proposal. Static source checks do not replace tests, human review or your normal deployment process. Follow [Installation](INSTALLATION.md), [Code changes](CODE_CHANGES.md) and [Local Codex](LOCAL_CODEX.md).