# Orbit 1.5.0 documentation # 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.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. 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 editable excerpts from up to four recent messages, clearly labeling 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. This release does not add bidirectional human chat, staff assignment, internal notes, SLA automation or a resolved/CSAT metric. 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 contains conversations, saved prompts, capabilities and settings. 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. Archive is reversible; conversations are private to their creator. 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. ## 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. 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. --- # Orbit 1.5.0 release validation September 30, 2026. Fresh licensed Seedly 5.8.4 source passes clean installation and doctor checks. A separate clean host installed from the immutable 1.0.0 archive passes the 1.5.0 upgrade and doctor checks. Runtime validation below covers backend/frontend types, build, reviewed actions, native support routing and live synthetic provider checks. The 1.0.0 archive remains unchanged. See UPGRADE_1_5.md and CHANGELOG.md. ## 1.5 development validation — conversational support refinement — September 30, 2026 Shared intent guidance now distinguishes greetings, general assistance, product how-to, troubleshooting, CRM tasks and human requests. Support keeps its configured allowlist even when the topic changes. Saved agency instructions remain intact. Diagnostics explicitly explain all-required tags, any-excluded tags, current-state-only coverage and the difference between configured credentials and provider health. 32 source checks and 65 installed-host Orbit checks pass. Fresh backend generation/typechecking and dedicated sandbox deployment pass; the frontend guidance change passes the production build and final fresh-API frontend typecheck. Live evaluation used the existing Sonnet 5.5 connection against synthetic data: greetings and email drafting used no tools, a setup question retrieved an approved article without diagnostics, task listing used listTasks, and an explicit human request explained the preview without creating a request. Initial evaluation exposed verbose troubleshooting, incorrect tag semantics and unnecessary diagnostics for a vague failure. After refinement, new checks confirmed correct tag/history interpretation, a tool-free writing follow-up, and a clarification question with no tools for “its not working”. Troubleshooting length remains a model instruction, not a hard output-length guarantee. No CRM write or human handoff was submitted. ## 1.5 development validation — signed-in support mode — September 30, 2026 32 source tests, 65 installed-host Orbit tests, 59 native extension checks and 111 repository/installer tests pass (267 total). Fresh backend generation/typechecking and deployment to the dedicated sandbox, frontend typechecking, production build and installer doctor pass. The host retains its existing Sentry instrumentation/Better Auth Edge build warnings. Support fixtures verify agency inheritance and locked overrides, tenant isolation, manager-only configuration, unsafe source URL/unknown tool refusal, optional empty fields, native role scope enforcement, stale proposal refusal, curated retrieval, privileged diagnostic history protection, native brand-admin routing and unbranded fallback, destination checks, inactive destination refusal, idempotent handoff, late-reply cancellation and pending-action rejection. An allowed support write remains a proposal until approved and executes at most once; forbidden writes make no CRM request. Live sandbox validation used the existing OpenRouter connection for read-only support troubleshooting. It retrieved approved Orbit guidance and correctly identified the saved Filtered contact review agent as a draft without an accepted rehearsal. Browser checks verified support configuration, My requests, editable excerpts and a preview routed to Orbit Test Agency. No live handoff was submitted, no staff notification was sent by this validation, and no CRM record was changed. Native handoff delivery behavior was exercised in isolated host fixtures; real recipient delivery is not certified. The first support release is for signed-in CRM users with Orbit access. It uses manually curated article text (not automatic URL ingestion), a bounded personal diagnostics view, reviewed CRM actions and native request intake. Intake acceptance is not resolution. Shared human chat, assignments, SLA scheduling and support resolution/CSAT metrics remain future work. The published 1.0.0 archive remains immutable; these additions ship in 1.5.0. ## 1.5 development validation — inbox and event conditions — September 30, 2026 31 source tests, 51 installed-host Orbit tests and 59 native extension checks pass (141 total). Fresh backend code generation/typechecking, dedicated sandbox deployment, frontend typecheck and production build pass. The final CSS-only checkbox row correction was subsequently browser-verified. Existing host build warnings relate to Sentry instrumentation and Better Auth Edge dependencies. Installer doctor confirms source and receipt match. Regression coverage includes required/excluded tags and lifecycle matching, nonmatches before queueing, snapshotted conditions, contradictory/unknown rule refusal, rehearsal invalidation, owner/tenant inbox isolation, quiet success defaults, persistent read state, and an approval resurfacing near expiry then clearing after rejection. Browser checks confirm All recent results, the empty unread state, rule review and a saved disabled “Filtered contact review” draft. No CRM records were changed and no recurring agent was enabled for validation. Notifications are limited to the in-Orbit inbox/unread indicator, the latest 100 owner/account jobs, and minute-level expiry refresh while open. No OS/email/SMS/native bell delivery is claimed. Filters inspect current stored contact fields; specific changed-field and newly-added-tag attribution remain unsupported. These additions ship in 1.5.0; the original 1.0.0 archive is unchanged. ## 1.5 development validation — workspace additions — September 30, 2026 Conversational agent drafts and before/after approval previews are implemented in the isolated sandbox; the published 1.0.0 archive is unchanged. 29 source tests, 46 installed-host Orbit tests and 59 native extension checks pass. Fresh backend code generation/typechecking, sandbox deployment, frontend types and production build pass. Live synthetic-data checks: a read-only event-agent draft was generated without creating or enabling an agent, and its values transferred to editable rules and the rehearsal review screen. A contact-company update produced a server-read null-to-value comparison. Request changes rejected that proposal and prepared an unsent editable follow-up; no CRM record was changed. Tests prove changed-before-value refusal, one-time unchanged approval, unavailable-tool rejection and draft-only behavior. Before/after snapshots currently cover contact, task and opportunity updates; unavailable fields are marked unknown. REST reread/write checks are not atomic compare-and-swap. # Orbit 1.0.0 validation September 30, 2026. Adds native event agents, an approval inbox, draft duplication, searchable tools, lifecycle counts and a portable create-only task scope. - 27 source tests, 111 repository tests, 42 installed-host Orbit tests and 59 native extension checks passed (239 total). - A fresh licensed Seedly 5.8.4 extraction passed installation and doctor checks, including the previously manual task creator fix. Existing-host upgrade checks also passed. - Event fixtures cover the native trigger hook, duplicate events, cooldowns, nested-event refusal, foreign contacts, revoked owners and draft duplication. HTTP fixtures prove tasks:create permits creation and refuses update/delete; count fixtures check scope and tenant isolation and scan beyond the first page. - Sandbox backend deployment, code generation, frontend types and production build passed. A live OpenRouter reply executed countContactsByLifecycle against five synthetic contacts and produced a verified sum-based chart (lead: 5), with complete-scan metadata and a stored execution receipt. Limits: Seedly 5.8.14 has not been tested locally. Event jobs coalesce events during cooldown or an active run; they are not a guaranteed per-event delivery queue. Counts scan at most 10,000 records and report partial results; concurrent updates can affect pages. No automatic CRM writes, arbitrary cron expressions, public webhook ingress or high-volume certification is claimed. Not every catalog endpoint has been exercised live. ## Previous release evidence # Orbit 0.3.0-alpha.1 validation September 30, 2026. Weekly/monthly schedules, configurable agent approval windows, ranked operation discovery, recorded tool activity, table corrections and launcher collision avoidance. - 26 source tests, 111 repository tests, 35 installed-host Orbit tests and 59 native extension checks passed (231 total). - Fresh Convex code generation and backend typechecking passed on the dedicated Seedly 5.8.4 sandbox. Frontend typechecking and production build passed. - New regression fixtures check invented operation references against real recorded calls, bounded approval settings and immutable job snapshots. Schedule tests cover selected weekdays, short months and leap years alongside existing timezone/DST tests. - Package regression verifies every internal manifest hash and the archive sidecar. Published 0.2.0-alpha.1 is unchanged. - Browser inspection confirmed separate launcher/support hitboxes in the sandbox. AI text remains model-generated; operation warnings are an additional check, not a factuality guarantee. Not verified: the client's modified Seedly 5.8.14 fork, their lifecycle-count endpoint or tasks:create scope. Event-triggered jobs remain a separate integration. No recurring job or CRM write was enabled for this update. ## Previous release evidence # Orbit 0.2.0-alpha.1 validation September 29, 2026. Current release adds guided agents, rehearsals, reviewed enablement, on-demand and daily/weekday schedules, bounded tools and usage, pause controls and run history. - 21 module source tests, 111 repository tests, 33 installed-host Orbit tests and 59 native snapshot/purge/extension checks passed (224 total). - Fresh Convex codegen and backend typechecking passed on a dedicated Seedly 5.8.4 sandbox; backend deployment succeeded. - Frontend typechecking and production build passed. The final UI was inspected in an authenticated browser, including formatted results and the read-only rehearsal evidence view. - A real OpenRouter / Claude Sonnet 5.5 rehearsal retrieved five synthetic contacts through the deployed CRM API. Sources and results were visible, and enablement remained blocked pending acceptance. - Tests cover tenant isolation, current owner authorization, tool allowlists, rehearsal approval refusal, revision invalidation, concurrency, per-agent daily limits, schedule deduplication, interrupted-job recovery and pause behavior. Timezone tests include daylight-saving gaps and weekday rollover. - Installer diagnostics confirm the owned source and receipt match. No recurring demo schedule or CRM write was enabled during this validation. Limits: no CRM event triggers, arbitrary cron expressions, automatic writes, cross-account agents, automatic learning or dollar-spend guarantee. The full catalog has not been exercised against every live provider and customer configuration. Test coverage is not a high-volume or all-host compatibility certification. ## Earlier releases — historical evidence The notes below describe checks at their original dates. The current live-provider and agent validation above supersedes earlier statements that inference had not yet been tested. # Orbit 0.1.0-alpha.4 validation September 27, 2026. Original module source in `seedly-addons/modules/orbit`. ## Completed locally | Check | Evidence | |---|---| | Pure/core and installer tests | 17 passing: endpoint inventory, schema checks, account/header/path injection, secret redaction, real-data aggregates, partial pages, bounded storage, action transitions, floating bounds, reversible installation and customization refusal | | Installed-host backend fixtures | 23 passing: auth/tenant isolation, own-scope refusal, duplicate submit, immutable single-use approvals, policy revocation, agency control, daily limits, model/read/chart loop, write proposal/approval, provider failures, retained-history permission revocation, cancellation, expiry, agency gating and one-time webhook secret disclosure; OpenRouter key verification/encryption/public-query exclusion, unauthorized access, failed replacement, reviewed write loop, tenant-bound decryption and mid-loop disconnection | | Native extension guards | 27 passing across private-table purge-index coverage, plan schema registration and extension seam checks | | Existing repository tests | 111 passing; original module installer/runtime tests remain green | | Installer/doctor | Installed in a new private offline Seedly 5.8.4 copy; module source and receipt match | | Local API references | Regenerated with the installed Convex API codegen template for the full installed module set; real schema-derived types used | | Backend types | Passed on the installed private host | | Web types and production build | Passed in the installed host using nonsecret placeholder public Convex URLs; no deployment or live queries | | Browser review | Actual React workspace with explicit fixture adapters: desktop chart/source view, settings save, floating launcher and keyboard movement, conversation restoration, mobile breakpoint, proposal-to-success flow, light/dark themes | Logs and synthetic captures are private ignored artifacts under `.cache/orbit-*`. The synthetic preview at `http://127.0.0.1:3048/` uses the actual UI components and fake data/network adapters; it is not an authenticated production installation. Its controls do not call AI providers or write to a CRM. ## Not claimed - Authenticated Convex component codegen and deployment verification: the offline host has no deployment configured; normal CLI codegen correctly refused rather than selecting a shared backend. Fresh authenticated codegen remains mandatory in the chosen target. - Real OpenRouter/OpenAI execution, provider charges, live endpoint/version/scope verification, or customer data writes. - Live external message/campaign delivery, calendar/provider behavior, or webhook delivery after rotation. - Every endpoint exercised against a deployed customer CRM. The 50-operation catalog is contract coverage; integration fixtures exercise representative reads/writes, not 50 live operations. - Combined installation-order certification with every other add-on. The existing installer tests pass and Orbit's own install/uninstall is reversible, but the new six-module permutation matrix has not been certified. - High-volume multi-agency load testing, complete cross-account analytics, token streaming, unbounded history search, monetary spending guarantees, or arbitrary public-widget/workflow adapter coverage. No production deployment, API key creation, provider spend, customer message, campaign send, or external CRM mutation occurred during this build. Original source packaging is separate from release/deployment approval. Alpha.2 additionally browser-checked the optional companion picker, hidden launcher, pet chat opening and per-browser persistence. OpenRouter uses mocked provider responses in installed-host tests; no real key was submitted and no inference credits were spent. Updated types, extension guards and host production build are checked locally. Presentation refinement: removed promotional headings and repeated subtitles; compacted settings and launcher choices; adopted native Seedly HSL tokens with neutral fallbacks. Reviewed light/dark preview, regenerated local references, and passed installed-host backend/web types and production build. No backend behavior changed. Alpha.3: catalog normalization tests cover text/tool filtering, batch exclusions, deduplication, newest-first sorting and unavailable pricing. Installed-host tests additionally verify manager-only model discovery without credentials in the request. Public OpenRouter catalog fetched directly for the dated model snapshot; no inference requests. Browser verification includes custom image upload, reload persistence, removal, new pet selection, transparent/shadow-free launcher, model search/select/save and dropdown spacing. All imagery used for upload checks is synthetic. Branded launcher refinement: added original pixel SVG interpretations of a Seedly-inspired sprout, DevLaunch’s cobalt notched companion and GoSeedly’s coral-mask artichoke. Browser-checked all three selections and reload persistence. Fresh local API references, backend/web typechecks, 27 extension guards and installed-host production build passed. No backend behavior or live deployment changed. ## Dedicated instance acceptance — September 28, 2026 Clean Seedly 5.8.4 base, Orbit only, dedicated development backend `nautical-cuttlefish-605` (project `wearehypercat/seedly-orbit-test`), source `../seedly-orbit-testing`, local frontend port 3050. Authenticated Convex deployment and API generation succeeded. Native owner login, two isolated subaccounts, actual model discovery, CRM connection check, saved/pinned/archived chats and cross-location conversation refusal were exercised. Scoped CRM REST checks: five synthetic contacts returned, unauthorized account header refused with 403, task creation returned 201. An explicitly labeled operator-created proposal was approved in the real Orbit UI; it created a task and repeat approval was refused. This tests approval/execution, not AI generation. The private temporary fixture function was removed from the backend after preparing the proposal. A Seedly host defect was found: first task creation builds an API Tasks project with an invalid empty createdBy. The dedicated host carries the API key creator through ApiAuthContext into pm.apiCreate, using authenticated key metadata rather than request input. This narrow host fix is separate from the module distribution; see INSTALLATION.md. The portable installer now contributes an Orbit sidebar icon through the same reversible client-side seam used by Events. No OpenRouter inference key was supplied. Real model replies, model-selected tool calls and AI-generated charts remain unverified. No customer records, external messages, payments or production deployments were involved. Final dedicated-host checks: 17 Orbit tests, 111 repository tests, 50 host tests, backend/web types and the local production build passed. The compiled app was browser-checked for native Contacts data, the Dev launcher, keyboard movement and floating chat restoration. Evidence stays private in seedly-orbit-testing/tmp/captures. Full-page layout refinement: removed the personal-account footer and scoped native page-padding removal to the non-floating workspace. Web typecheck and dedicated-host production build passed. No backend or authorization logic changed. Appearance coverage: persisted custom colors, omitted-field compatibility, invalid-color rejection, tenant isolation, and existing agency-only settings authorization. Popup width is 520px on desktop with larger text and controls, and constrained to the viewport on mobile. Popup simplification: a single header contains history, new chat, expand and close. Account switching and conversation management remain in the full workspace; popup history retains navigation. Removed repeated message labels/timestamps and composer metadata, compacted the composer, and raised the popup above the native feedback launcher. Review cards retain account and approval details. ## September 29 provider compatibility fix Claude Sonnet 5.5 returned HTTP 404 because OpenRouter require_parameters routing excluded providers when parallel_tool_calls:false was supplied. Orbit now omits that optional parameter for OpenRouter; its own sequential tool execution and reviewed writes remain unchanged. Provider 404 errors now distinguish parameter availability and privacy-policy restrictions without echoing provider payloads. Deployed to the dedicated nautical-cuttlefish-605 sandbox. Verified a live Sonnet 5.5 reply and read-only retrieval of five synthetic contacts with the existing saved key. Backend typecheck and 24 Orbit host tests passed. This patch is in module source; the previously published alpha.4 archive remains immutable and has not been replaced.