diff --git a/README.md b/README.md
index a0db4476643..e433acfdc1b 100644
--- a/README.md
+++ b/README.md
@@ -14,8 +14,12 @@
-
+
+
+
+
+
diff --git a/cli/src/__tests__/worktree.test.ts b/cli/src/__tests__/worktree.test.ts
index a12cec24416..6592bf7d6ac 100644
--- a/cli/src/__tests__/worktree.test.ts
+++ b/cli/src/__tests__/worktree.test.ts
@@ -157,12 +157,12 @@ async function seedValidWorktreeSource(
userId,
role: "instance_admin",
});
- await db.insert(companies).values({
- id: companyId,
- name: "Seed Source",
- issuePrefix: "SEED",
- requireBoardApprovalForNewAgents: false,
- });
+ // Seed only columns present in the historical source schema. The current
+ // model includes accounting columns that the worktree migration adds later.
+ await db.$client`
+ insert into companies (id, name, issue_prefix, require_board_approval_for_new_agents)
+ values (${companyId}, 'Seed Source', 'SEED', false)
+ `;
await db.insert(companyMemberships).values({
companyId,
principalType: "user",
@@ -1384,7 +1384,7 @@ describe("worktree helpers", () => {
.select()
.from(executionWorkspaces)
.where(eq(executionWorkspaces.id, executionWorkspaceId));
- expect(executionWorkspace?.metadata).toEqual({
+ expect(executionWorkspace?.metadata).toMatchObject({
keep: "execution-metadata",
config: {
environmentId: "environment-1",
diff --git a/doc/DATABASE.md b/doc/DATABASE.md
index c6d747b45bc..e76e143b6a0 100644
--- a/doc/DATABASE.md
+++ b/doc/DATABASE.md
@@ -226,6 +226,17 @@ When authoring migrations or one-time backfills:
- Split schema changes, index creation, and data backfill into separate phases so each step has clear locking and rollback behavior.
- Treat the `check:migrations` CI gate as the enforcement backstop for these rules. If it flags a migration, rewrite the migration or add a suppression comment with the indexed predicate, batch bound, and reason the remaining scan is safe.
+Private-task migrations `0313` and `0314` are explicitly allowlisted in the
+Paperclip executor to run outside a file-wide transaction. Their idempotent
+keyset batches commit every 1,000 rows, and migration history is recorded only
+when all batches finish. The executor repairs invalid concurrent indexes on
+retry. A reserved connection holds a session advisory lock across all batch
+commits, so concurrent migrators recheck history only after the preceding runner
+finishes. Privacy triggers are replaced atomically. Bootstrap uses the same
+executor; other migrations remain transactional
+per file. Apply these migrations through `pnpm db:migrate` using a direct
+connection, before enabling the new server and UI.
+
## Migration snapshots
`drizzle-kit generate` diffs `packages/db/src/schema/` against the newest snapshot in `packages/db/src/migrations/meta/`. That snapshot must describe the schema that every migration produces when they run in order. A snapshot that drifts from the schema makes the *next* migration wrong, because `generate` folds the drift into it. The drift can add a column that an earlier migration already created, which makes that migration fail on a fresh database. It can also drop a column that the schema still uses.
@@ -290,6 +301,8 @@ These rows are company-scoped and user-scoped. A missing row means the user is j
Both tables use a unique key on `(company_id, user_id, resource_id)` and keep `state` as `joined` or `left`. Join/leave mutations are idempotent board-user `/me` operations and write activity entries when the effective state changes.
+Private-project authorization uses the separate `project_access_members` table. Its user/agent rows are security grants, not sidebar preferences, and are evaluated by the same issue-read predicate as issue-level grants. Do not merge or overload these two concepts.
+
## Decision training snapshot retention
`decision_training_examples` stores a point-in-time copy of an issue, its comments, relevant runs, and the selected decision. Each row carries the `scrub_deleted_comments_v1` retention policy marker, and JSONL exports include that marker alongside the snapshot.
@@ -600,6 +613,7 @@ write requires operator reconciliation before an unattached reservation is
removed. The table stores no response bodies. See `doc/runner-api-tools.md` for
limits and the operator override.
+Project `privacy_owner_user_id` records who may manage its audience independently of project read membership. Creation assigns the authenticated user or run responsible user; migration recovers legacy ownership from creation audit evidence. Missing evidence leaves management with administrators.
## Internal agent commentary
`agent_commentary` stores company-scoped, attributed complaints and suggestions
diff --git a/doc/DEVELOPING.md b/doc/DEVELOPING.md
index d44de552d65..54085a9f195 100644
--- a/doc/DEVELOPING.md
+++ b/doc/DEVELOPING.md
@@ -109,6 +109,11 @@ pnpm build-storybook
These run the `@paperclipai/ui` Storybook on port `6006` and build the static output to `ui/storybook-static/`.
+**HTML artifacts** covers secure rendered/raw attachment previews, interactive
+reports, security probes, workspace previews, and opening a report from a task.
+See [HTML artifact previews](html-artifact-previews.md) for the security boundary,
+supported content, and browser verification command.
+
**Composer → New task** includes agent/user/project/task mentions, skill and
routine slash commands, and populated rich chips on desktop and mobile. Agent
mentions use the same avatars in suggestions, inserted chips, and the mocked
@@ -755,6 +760,36 @@ PAPERCLIP_HOME=/custom/path PAPERCLIP_INSTANCE_ID=dev pnpm paperclipai run
No Docker or external database is required for this mode.
+## Issue Privacy Rollout
+
+`PAPERCLIP_ISSUE_PRIVACY_MODE` controls the canonical opt-in issue/project privacy predicate:
+
+- `enforce` (default): return private issues only to implicit principals, issue grantees, or private-project access members; hide private projects from non-members
+- `shadow`: log structured would-deny decisions but preserve existing reads; use only for rollout diagnosis
+- `off`: skip the predicate and shadow logging
+
+Grant checks read current database state; there is no positive privacy cache.
+Sharing a task grants access to that task and its private descendants. Parents
+and siblings need separate grants. An agent's access is intersected with its
+run's responsible user's current access.
+
+`enforce` is the production default. `shadow` and `off` disclose private data and
+are only temporary diagnostic overrides. The old branch's historical sign-off
+does not qualify the current runtime. See [ISSUE-PRIVACY.md](./ISSUE-PRIVACY.md)
+for the model, validation coverage, break-glass behavior, and residual risks.
+
+Issue-bound heartbeat runs inherit the same read predicate through the stored
+`heartbeat_runs.scope_kind = 'issue'` and `issue_id` binding. Issue deletion
+nulls the foreign key but preserves the explicit issue scope as a fail-closed
+tombstone. Workspace-operation history is either deleted with its direct issue
+or run binding, or remains bound to that fail-closed run tombstone, so it cannot
+become company-level maintenance data through foreign-key nulling. In enforce mode, direct run detail, transcript,
+event, log, and workspace-operation reads return `404` to non-members. Company
+run-history and live-run lists retain a metadata-only row with timing, status,
+token usage, and cost for budget oversight; issue identifiers, summaries, and
+run content are omitted. Runs without an issue binding keep company-level
+maintenance-run visibility.
+
## Storage in Dev (Auto-Handled)
For local development, the default storage provider is `local_disk`, which persists uploaded images/attachments at:
@@ -829,7 +864,7 @@ If a repository is detached or its source configuration changes, its previous ta
## Config Freshness
-Agent, project, environment, secret, skill, and workspace config edits are sampled at the next run boundary. A heartbeat that is already running finishes with the config it started with.
+Agent, project, environment, secret, skill, and workspace config edits are sampled at the next run boundary. A heartbeat that is already running finishes with the config it started with. Native runners project explicitly configured task environment variables into provider processes and tool commands, including custom `PAPERCLIP_*` names such as `PAPERCLIP_PAGE_BUCKET`. Adding, changing, or removing a projected variable replaces a retained provider process at the next run boundary. Unchanged variables permit process reuse. The projection contains names only; secret values stay in the child environment. Ambient host secrets are not projected. Native projections allow up to 128 variable names, 64 KiB per entry, and 256 KiB of values in total. These native launch limits do not apply to legacy adapter configuration. Runtime authority, provider login credentials, and process-loader settings use their existing restricted paths.
When effective run config changes, Paperclip may intentionally skip a saved adapter session, refresh persisted workspace runtime config, replace a reused execution workspace, or avoid reusing a sandbox/environment lease. Fresh execution can lose adapter-specific session, workspace, or sandbox state; correctness of the next run's config takes priority over continuity. Plain environment values affect freshness through value hashes; run result JSON and workspace operation logs expose only the non-sensitive freshness decision categories, without storing secret values, full env maps, provider credentials, or private path details.
diff --git a/doc/ISSUE-PRIVACY.md b/doc/ISSUE-PRIVACY.md
new file mode 100644
index 00000000000..fde0b89e48c
--- /dev/null
+++ b/doc/ISSUE-PRIVACY.md
@@ -0,0 +1,204 @@
+# Private tasks and projects
+
+Paperclip work is company-open by default. A task or project can instead be
+marked private when its title, discussion, documents, attachments, work
+products, or agent run traces should be limited to named participants.
+
+## Who can read private work
+
+A private task is readable by its responsible user, creating user, current
+user or agent assignee, active task grantees, and members of its private
+project. Restrictions flow down through children and run-created handoffs. Sharing or
+assigning a task grants access to that task and its descendants; ancestors and
+siblings require a separate grant. An assignment grant stays
+active until it is explicitly revoked. Current assignment, ownership, private-project
+membership, and inherited access remain independent reasons for access. The
+sharing panel shows the source; revoking one grant does not remove other reasons.
+Making a parent private protects existing descendants in the same transaction.
+Moving a task under a private parent inherits privacy. A child cannot be made
+public while it inherits a private boundary; making a parent public leaves its
+existing private children private.
+
+Private projects have a separate access-member list. A task-level grant can
+expose one task without exposing its containing private project. Direct reads
+by non-members return `404`, and list, count, search, attention, status-card,
+activity, run-history, and tree-control surfaces apply the same predicate.
+Visible blocker and mention edges may show a locked identifier-only stub; they
+never include the private task's title or content.
+
+Audit logs remain company-wide because they are the sanctioned oversight path.
+They contain entity identifiers rather than private task content. Dashboard and
+sidebar aggregate counts also remain company-wide: they may include private
+work in totals, but do not expose titles, descriptions, or identifiers. The
+issue list/count APIs themselves are viewer-filtered.
+
+## Audited break-glass
+
+Company owners and admins do not silently inherit private-task access. A normal
+task detail request still returns `404`. When an owner or admin has a legitimate
+emergency need, they must deliberately request the task with
+`?breakGlass=true`.
+
+Every successful break-glass read writes both:
+
+- an `issue.break_glass_read` audit row containing the actor, task id, and time;
+- a warning system notice on the private task so its owners can see that access occurred.
+
+The flag does not change the canonical read predicate, create a grant, or make
+future reads implicit. Non-admin members and agents cannot use it.
+
+Cloud customer-success inspection is a separate operator capability. When an
+operator enables it, the dedicated Cloud-signed permit can read private task
+content within its company scope. Ordinary users, agent API keys, and plugins
+cannot use that permit. Cloud enforces the inspection grant, expiration,
+revocation, replay protection, and audit trail; this path does not create a task
+grant or a task break-glass notice. Operators who require task ACLs on every
+content read must leave `PAPERCLIP_CUSTOMER_SUCCESS_INSPECTION_ENABLED` disabled.
+See [Cloud customer-success inspection support](CUSTOMER-SUCCESS-INSPECTION.md).
+
+## Agent runs and shared-agent residual risk
+
+Issue-bound run detail, events, transcripts, logs, and workspace operations use
+the task ACL. Run authority is the intersection of the agent and the run's responsible user.
+Reusing an agent does not transfer a different user's private-task permission.
+Company run lists retain only timing/status/token/cost metadata for
+non-members so budget oversight continues without exposing task identity or run
+content.
+
+Workspace operation records retain their original task and run sources even if
+those entities are deleted or the operation is relinked. Deletion preserves the
+audit record; unresolved sources make its details and log inaccessible. A
+company-scoped run does not override a private task linked to the operation.
+
+> **Residual risk — trusted agents (`trust-agent`).** Paperclip enforces privacy
+> on reads from the control plane, but an agent that legitimately processes a
+> private task may write learned content into shared persistent memory, its home
+> directory, an external tool, or a later public response. V1 deliberately
+> trusts the agent not to exfiltrate that context. Use isolated execution
+> workspaces and appropriately trusted agents for sensitive work; task ACLs are
+> not a sandbox or data-loss-prevention system.
+
+## Plugins and notification/digest surfaces
+
+Plugins (including any Slack notifier or digest plugin) are **non-member
+principals**: they hold no company membership, task grant, or private-project
+access. Rather than an allowlist of individually patched methods, the plugin
+host centralizes the synthetic non-member check into shared helpers
+(`requirePluginReadableIssue`, `pluginReadableIssueIdsByIds`,
+`pluginRedactRelationSummary`) and routes **every** issue-derived read through
+them. The complete inventory of issue-derived reads and their disposition:
+
+- **Direct issue content** — `issues.list` (SQL predicate), `issues.get`,
+ `issues.listComments`, `issues.listAttachments`, `issues.getAttachmentContent`,
+ `issueDocuments.list`, `issueDocuments.get`: a private task is filtered from
+ list results, returns `null`/empty on soft reads, and reports "not found"
+ (indistinguishable from missing) on document reads.
+- **Subtree / orchestration** — `issues.getSubtree` and
+ `issues.getOrchestrationSummary`: a private *root* reports "not found"; an
+ open root drops private descendants **before** any relation, document, run,
+ or assignee is fetched, so no private row or its metadata enters the payload.
+- **Relationship metadata** — `issues.getRelations` (and the summaries echoed
+ by `issues.setBlockedBy` / `addBlockers` / `removeBlockers`, and the subtree
+ relation maps): blocker/blocks edges pointing at a private task are dropped,
+ recursing into nested terminal blockers, so its title, status, and assignee
+ never surface even on a public task.
+- **Interactions** — `issues.listInteractions`: a private task yields no
+ interaction payloads.
+
+A synthetic `{ type: "none" }` actor resolves to the same public-only scope as
+any other non-member. This is why a digest broadcast to a shared channel —
+whose audience is non-members by definition — cannot carry private issue
+content. Writes that operate on a task must also satisfy its read predicate; plugin
+capabilities do not substitute for task access. Returned relationship summaries
+remain redacted.
+
+There is intentionally **no plugin oversight exception**: unlike the
+company-wide audit log, no plugin read path bypasses the predicate. A plugin
+that must surface private work would need an explicit, separately designed
+oversight capability; none exists today.
+
+> **Residual metadata disclosure.** A plugin still learns aggregate,
+> content-free signals about private work that mirror the accepted
+> dashboard/count disclosure: `issues.getOrchestrationSummary` returns
+> company-wide `openBudgetIncidents`. Its `costs`/token roll-up is limited to
+> the readable subtree, and unreadable relationship edges are omitted entirely.
+> No private title, body, comment, attachment, identifier, relationship target,
+> or locked-edge signal is exposed.
+
+## Rollout modes
+
+`PAPERCLIP_ISSUE_PRIVACY_MODE=enforce` is the default. `shadow` records
+structured would-deny decisions without enforcing them and exists only for
+rollout diagnosis. `off` disables the task predicate. Operators should not use
+`shadow` or `off` when private-task confidentiality is required.
+
+The production gate includes positive and negative checks: an authorized reader
+can read a shared child and its descendants, an unrelated reader cannot, and a
+warm HTTP or live subscription loses that grant after revocation. Privacy grants
+are read from the database without a cross-request positive cache.
+
+## Migration and current runtime integration
+
+Migration `0313_private_task_access.sql` adds the task/project ACL tables and
+backfills privacy parent edges with indexed keyset batches. Run binding is derived
+from native task identity, explicit issue identity, or legacy `issueId`/`taskId` context. Missing
+source tasks remain issue-scoped tombstones. Context changes cannot turn those
+runs into company-wide history. The migration is idempotent for preview installs;
+existing explicit grants are preserved. Operators upgrading an unreleased preview
+should inspect root grants created under its former whole-tree sharing semantics.
+
+Migration `0314_private_task_draft_assets.sql` accompanies enforcement and binds
+historical inline images to their first owned task. Unbound drafts remain
+uploader-only under the new asset-content guard.
+
+Both privacy migrations use the Paperclip migration executor's explicit
+nontransactional path. Indexes on existing tables build concurrently; invalid builds are repaired on
+retry. DDL statements commit individually and each 1,000-row
+keyset batch commits before advancing, releasing schema and row locks. The
+migration journal is written only after all batches succeed; an interruption
+leaves the migration pending and its idempotent statements can be replayed.
+Bootstrap uses the same executor, and other migrations retain a transaction per
+file. Apply these migrations with `pnpm db:migrate`, before enabling the new
+server or private-task UI.
+
+Private output uses the same predicate on native tool searches and task context,
+linked approvals, training exports, execution workspace APIs, stored run-response
+assets, and WebSocket delivery. Workspace access requires permission for every
+linked task. Chat publications recheck recipient identity and task access at the
+provider boundary: private output is withheld from shared channels and from DMs
+whose known recipients no longer qualify. This does not revoke Gmail or other
+connection credentials; connection permissions continue to apply independently.
+
+## CI leak-test inventory
+
+The privacy regression gate is part of the normal server Vitest suite. Its
+surface coverage is intentionally distributed beside the routes and services
+it protects:
+
+| Surface | Non-member regression coverage |
+| --- | --- |
+| Downward sharing, responsible-user intersection, mutation denial, provenance, live revocation | `privacy-production-review.test.ts` |
+| Task detail, list, count, grants, documents, work products | `issue-access-grants-routes.test.ts`, `company-search-service.test.ts` |
+| Search and machine extract | `company-search-service.test.ts`, `company-search-extract-service.test.ts` |
+| Attention feed | `attention-service.test.ts` |
+| Status-card hydrate and dry-run | `status-cards.test.ts` |
+| Activity stream | `activity-service.test.ts`, `activity-routes.test.ts` |
+| Run list, live run, detail, transcript, events, logs, operation history | `heartbeat-run-privacy-routes.test.ts` |
+| Tree holds and tree control | `issue-tree-control-routes.test.ts` |
+| Blocker and mention identifier-only stubs | `issue-access-grants-routes.test.ts` |
+| Attachment content | `issue-attachment-routes.test.ts` |
+| Private-project list and direct read | `projects-list-archived-routes.test.ts` |
+| Plugin issue reads (list, get, comments, attachments, orchestration, subtree, relations, interactions, documents) | `plugin-orchestration-apis.test.ts` |
+
+Adding a new task-derived read surface requires a non-member fixture in this
+gate before the surface can ship.
+
+Project privacy management belongs to its recorded creator (the responsible user
+for agent-created projects), the personal-project owner, and administrators.
+Project read membership alone never allows publishing the project or changing
+its audience. Legacy projects recover ownership from their creation audit event;
+when that evidence is missing, an administrator manages their privacy.
+
+### Task privacy management hints
+
+`GET /api/issues/:id/privacy-constraints` is available only to a principal who can read and manage that task. It returns the blocked scope kind and whether publishing leaves a personal project. It does not return protected parent or project names, identifiers, owners, or contents. This lets task owners manage their task without requiring access to its surrounding project. Visibility writes still enforce the canonical rules under the privacy-tree lock; these hints do not authorize a write.
diff --git a/doc/PRODUCT.md b/doc/PRODUCT.md
index 502b1d42dd9..e53dcafe773 100644
--- a/doc/PRODUCT.md
+++ b/doc/PRODUCT.md
@@ -30,6 +30,15 @@ Example: A CEO agent's adapter config tells it to "review what your executives a
Then you define who reports to the CEO: a CTO managing programmers, a CMO managing the marketing team, and so on. Every agent in the tree gets their own adapter configuration.
+Each person also has a personal primary agent per company. Their first human-created
+agent becomes primary automatically; they can choose another from its profile.
+An existing primary is replaced only after confirmation. The crown appears on the
+profile and roster, while the primary stays first in the Agents sidebar without a
+sidebar crown. Stars remain independent. Task drafts, explicit assignments, and
+recent choices take precedence over the primary; Chat similarly reopens a valid
+recent conversation before falling back to the primary. Opening Chat does not
+start execution. This preference does not change the org chart or permissions.
+
### Agent Execution
Paperclip supports several ways to run an agent's heartbeat:
@@ -135,7 +144,7 @@ Paperclip’s core identity is a **control plane for autonomous AI companies**,
- Do not make the core product a general chat app. The current product definition is explicitly task/comment-centric and “not a chatbot,” and that boundary is valuable.
- Do not build a complete Jira/GitHub replacement. The repo/docs already position Paperclip as organization orchestration, not focused on pull-request review.
- Do not build enterprise-grade RBAC first. Paperclip now has authenticated mode, company memberships, instance roles, and permission grants, but fine-grained enterprise governance should remain secondary to the core company control plane.
-- Do not interpret agent-level privacy flags as a project/issue privacy feature in V1; work visibility stays company-scoped.
+- Do not interpret agent-profile privacy flags as project/issue privacy. Work remains company-open by default, while explicitly private issues and projects use their own task ACLs.
- Do not lead with raw bash logs and transcripts. Default view should be human-readable intent/progress, with raw detail beneath.
- Do not force users to understand provider/API-key plumbing unless absolutely necessary. There are active onboarding/auth issues already; friction here is clearly real.
@@ -232,3 +241,12 @@ to Tasks. A Views menu on the task list covers the inbox views (Mine, Unread,
Blocked, Recent, Everything) and the task-status views (All, Active, Backlog,
Done). Bare `/issues` opens the last-used view, defaulting to Mine; links that
carry a task filter open All. Old `/inbox` links redirect to the matching view.
+
+### CSV file previews
+
+Task attachment and workspace file tabs render CSV files as tables by default.
+The first record supplies column headers. Row numbers, row and column counts,
+and sticky headers help operators scan exports. Rendered and raw view icons
+remain next to download; raw view preserves the original source. The table
+shows up to 500 data rows and 100 columns, with a notice when the preview is
+limited. Download retains the complete file.
diff --git a/doc/SPEC-implementation.md b/doc/SPEC-implementation.md
index 2ea723810c9..1ad4d830359 100644
--- a/doc/SPEC-implementation.md
+++ b/doc/SPEC-implementation.md
@@ -37,7 +37,7 @@ These decisions close open questions from `SPEC.md` for V1.
| Company model | Company is first-order; all business entities are company-scoped |
| Board | Single human board operator per deployment |
| Org graph | Strict tree (`reports_to` nullable root); no multi-manager reporting |
-| Visibility | Company-scoped visibility: board + all in-company agents can see all work objects by default; public/private deployment flags affect external exposure only and do **not** imply project/issue privacy |
+| Visibility | Issues remain company-open by default. Opt-in `private` issues use task ACLs; deployment exposure flags remain independent of work-object privacy. |
| Communication | Tasks + comments only (no separate chat system) |
| Task ownership | Single assignee; atomic checkout required for `in_progress` transition |
| Task watchdogs | A task watchdog is an explicitly configured, issue-subtree-scoped verification and recovery capacity. It may restore live task paths inside the watched subtree; for issue-thread interaction resolution it is an ordinary agent subject to the same audience and containment checks, not board authority, active-run output monitoring, or general liveness recovery. |
@@ -220,6 +220,8 @@ Invariant: at least one root `company` level goal per company.
- `goal_id` uuid fk `goals.id` null
- `name` text not null
- `description` text null
+- `visibility` enum-like text: `open | private`, default `open`
+- `personal_owner_user_id` text null; unique with `company_id` when present
- `status` enum: `backlog | planned | in_progress | completed | cancelled`
- `lead_agent_id` uuid fk `agents.id` null
- `target_date` date null
@@ -258,6 +260,9 @@ retain their titles and default to no generation request.
- `project_workspace_id` uuid fk `project_workspaces.id` null
- `goal_id` uuid fk `goals.id` null
- `parent_id` uuid fk `issues.id` null
+- `visibility` enum-like text: `open | private`, default `open`
+- `privacy_root_issue_id` uuid fk `issues.id` null; private-boundary metadata
+- `privacy_parent_issue_id` uuid fk `issues.id` null; downward access inheritance, including standalone run-created handoffs
- `title` text not null
- `description` text null
- `status` enum: `backlog | todo | in_progress | in_review | done | blocked | cancelled`
@@ -310,11 +315,39 @@ Invariants:
- `author_user_id` uuid fk `users.id` null
- `body` text not null
+## 7.7.1 `issue_access_grants`
+
+- `issue_id` uuid fk `issues.id` not null
+- `subject_type` enum-like text: `user | agent`
+- `subject_id` text not null
+- `source` enum-like text: `explicit | assignment | project`
+- `granted_by_user_id` text null
+- `granted_by_agent_id` uuid fk `agents.id` null
+- `created_at` timestamptz not null
+- `revoked_at` timestamptz null
+
+An issue is readable when it is open outside a private project, the actor is an implicit principal (`responsible_user_id`, `created_by_user_id`, `assignee_user_id`, or current `assignee_agent_id`), the actor has an unrevoked grant on the issue or a private ancestor, or the actor is an access member of its private project. This is one canonical predicate shared by detail, list, count, search, and run-derived reads. Instance administrators retain platform-wide access; company owner/admin roles do not imply private-issue read access. Sharing a child covers that child and descendants; ancestors and siblings require separate access. Agent reads also require the responsible user to qualify. A private parent protects existing and newly created descendants; making a parent public does not publish private descendants.
+
+## 7.7.2 `project_access_members`
+
+Authorization membership for private projects, distinct from the personal-sidebar `project_memberships` table:
+
+- `id` uuid pk
+- `company_id` uuid fk `companies.id` not null
+- `project_id` uuid fk `projects.id` not null
+- `subject_type` enum-like text: `user | agent`
+- `subject_id` text not null
+- `created_at` timestamptz not null
+- unique `(project_id, subject_type, subject_id)`
+
+Private projects are absent from list and search results for non-members, and direct reads return `404`. An issue-level grant can still expose its issue without exposing the containing project. A user's `My private tasks` project is created lazily and concurrency-safely on their first unprojected private task; the owning user is its initial and non-removable project member. An agent-created private root also grants that creator issue-level access while retaining the responsible user as the human principal.
+
## 7.8 `heartbeat_runs`
- `id` uuid pk
- `company_id` uuid fk not null
- `agent_id` uuid fk not null
+- `issue_id` uuid fk `issues.id` null; first-class binding for issue-scoped run confidentiality
- `invocation_source` enum: `scheduler | manual | callback`
- `status` enum: `queued | running | succeeded | failed | cancelled | timed_out`
- `started_at` timestamptz null
@@ -417,6 +450,7 @@ Operational policy:
- `cost_events(company_id, occurred_at)`
- `cost_events(company_id, agent_id, occurred_at)`
- `heartbeat_runs(company_id, agent_id, started_at desc)`
+- `heartbeat_runs(company_id, issue_id, created_at)`
- `approvals(company_id, status, type)`
- `activity_log(company_id, created_at desc)`
- `assets(company_id, created_at desc)`
@@ -453,6 +487,7 @@ Operational policy:
- Attachment reads are company-scoped and expose stable path metadata: `contentPath`/`openPath` for inline-safe viewing and `downloadPath` for forced download.
- Inline-safe responses use `Content-Disposition: inline`; unsafe types and explicit download requests use `attachment`.
- Script-capable content such as HTML is always served as an attachment with `X-Content-Type-Options: nosniff` and a sandboxed, deny-by-default CSP; it is never rendered inline on the Paperclip origin.
+ - The board can fetch bounded HTML source for a rich preview in an opaque-origin iframe (`sandbox="allow-scripts"`, without `allow-same-origin`). A trusted CSP precedes artifact markup and blocks remote subresources, API connections, forms, and embeds. Rendered/raw icons sit beside Download. Workspace HTML previews return UTF-8 inside JSON under the existing text limits. See `doc/html-artifact-previews.md`.
- Video attachments are inline-safe and support single `Range: bytes=start-end` requests with `206`, `Content-Range`, and `Accept-Ranges: bytes` for browser playback/seeking.
- Attachment-backed artifact work products use `type: "artifact"`, `provider: "paperclip"`, and metadata with `attachmentId`, `contentType`, `byteSize`, `contentPath`, `openPath`, `downloadPath`, and optional `originalFilename`.
- Workspace-only file references use work product `metadata.resourceRef` with `kind: "workspace_file"`, `issueId`, `workspaceKind` (`execution_workspace` or `project_workspace`), `workspaceId`, `relativePath`, optional `line`/`column`, and `displayPath`. These references point at files in a workspace; they do not replace attachment-backed artifacts for deliverables that must be inspectable without workspace access.
@@ -508,6 +543,32 @@ Decision-desk triage uses company-scoped sidecars rather than adding queue field
- `decision_archive_notification_outbox` records one retry-safe origin-agent notification per source/archive version. The 90-day internal sweeper archives only unkept rows and coalesces delivery per origin agent.
- Queue membership never grants source visibility. Item writes re-authorize the referenced source, and queue reads re-authorize every member before returning rows or counts.
+## 7.17 Personal primary agent (2026-10-07)
+
+`user_company_preferences` has a unique company/user key, nullable `primary_agent_id`,
+and sticky `primary_agent_initialized` flag. GET/PUT
+`/api/companies/:companyId/primary-agent/me` derives the human identity from auth,
+checks company access and agent visibility, rejects agent actors, and audits changes.
+PUT accepts an approved, non-terminated agent; choosing a previously left agent
+rejoins it under the existing membership rules. There is no explicit removal UI or
+nullable PUT. Leaving, termination, and deletion clear the reference without
+allowing a later creation to initialize it again. Pausing and errors retain it.
+
+Initialization runs in the human-attributed creation transaction, including
+onboarding, with uniqueness arbitrating concurrent creation. System provisioning
+and agent-authored hires cannot initialize a human preference. Migration backfill
+uses the earliest attributable human creation, preserving empty initialized state
+when the original is gone, terminated, or left; unknown ownership stays unset.
+
+The profile is the only setting surface. Replacing a primary requires the reviewed
+avatar-to-avatar confirmation. A first choice has no modal. Only the profile and
+roster show the accessible crown; the Agents sidebar pins the primary first without
+duplication. Tasks preserve explicit/draft assignments, then choose a recent
+eligible assignee, the eligible primary, or the existing fallback. Chat preserves
+a valid recent conversation, then opens the primary, then retains its chooser.
+Navigation alone does not create an execution. Failed preference mutations restore
+the previous state and offer retry. Preferences and caches are company/user scoped.
+
## 8. State Machines
## 8.1 Agent Status
@@ -706,7 +767,7 @@ changes so both agent and board edits are visible in the issue activity stream.
## 9.4 Permission Terminology and Default Visibility Rule
-Paperclip V1 keeps a company-scoped visibility model as the default because centralized authorization and scoped work-object controls are not yet a core V1 control surface.
+Paperclip keeps company-scoped visibility as the default. The task-ACL foundation adds opt-in private issues while preserving `open` for all existing and unspecified issues.
The approved term set is:
@@ -720,8 +781,8 @@ The approved term set is:
## 9.5 Core V1 Rule: what “private” means
- A **private marker** on an agent profile (where represented) does **not** make company-visible work private.
-- Company-visible work objects (issues, comments, work products, costs, activity, project/task state) remain visible to the board and in-company agents by default.
-- Project/issue-level privacy, scoped assignment-only object visibility, and organization-wide custom ACLs are deferred to Pro/Enterprise controls.
+- Work objects remain company-open by default. An issue or project can opt into the shared private-read predicate.
+- Organization-wide custom ACL policy remains deferred to Pro/Enterprise controls.
## 9.6 V1 vs Pro/Enterprise Controls (recommended target split)
@@ -732,7 +793,7 @@ The approved term set is:
| Profile visibility | Full profile visibility for coordination and audit | Optional profile redaction / selective sharing for external surfaces |
| Config visibility | Board full read with redacted secret fields; agent config read/write constrained by own agent identity | Scoped config visibility controls and central policy enforcement |
| Assignment/invocation | Assignment creates execution authority; board can reassign or force release | Delegation policies and scoped invokers with deny-listed tool classes |
-| Work-object visibility | All issues and projects in-company are visible to board and agents | Project/issue ACLs and reviewer-only channels |
+| Work-object visibility | Company-open by default; opt-in private issues/projects with explicit user or agent access | Policy-driven ACLs and reviewer-only channels |
| Tool/secret policy | Secret refs, log redaction, and adapter-level command/webhook restrictions | Tool allowlists with centralized policy evaluation |
| Company skills | Open to authenticated company agents; core enforces invariants and any stored restriction policy | Paperclip EE policy editor, protected-skill controls, presets, simulation, and policy audit UX |
| Inbox management | Responsible agent may archive/unarchive its responsible user's Mine items under a default-open user policy; explicit cross-user access requires saved target-user opt-in or `inbox:manage`; all mutations are audited | Policy administration UX, organization presets, simulations, bulk controls, and richer audit/reporting surfaces |
@@ -1139,6 +1200,9 @@ Invites tab does not hide this Cloud action.
- `POST /companies/:companyId/issues`
- `GET /issues/:issueId`
- `PATCH /issues/:issueId`
+- `GET /issues/:issueId/access-grants`
+- `POST /issues/:issueId/access-grants`
+- `POST /issues/:issueId/access-grants/:grantId/revoke`
- `GET /issues/:issueId/documents`
- `GET /issues/:issueId/documents/:key`
- `PUT /issues/:issueId/documents/:key`
@@ -1198,6 +1262,11 @@ assignee/run ownership checks, and the `issue.released` activity event still app
- `POST /companies/:companyId/projects`
- `GET /projects/:projectId`
- `PATCH /projects/:projectId`
+- `GET /projects/:projectId/access-members`
+- `POST /projects/:projectId/access-members`
+- `DELETE /projects/:projectId/access-members/:memberId`
+
+Project list, search, direct reads, and nested project routes apply private-project access. Non-members receive the same not-found behavior as missing projects.
## 10.6 Current-user Resource Memberships
@@ -1485,6 +1554,20 @@ for contracts, recovery behavior, Storybook, and acceptance workflows.
Board may override by raising budget or explicitly resuming agent.
+Native runs retain final usage receipts during a bounded accounting-only drain
+after a governed wait cancels provider work. This does not accept late messages,
+tool calls, or new completion proposals. Missing or incomplete receipts continue
+to block budget admission.
+A controller that detaches for server restart loses checkpoint and completion
+write authority. A closing event stream is not proof that the governed run
+finished; the replacement controller must adopt and settle the original run.
+
+Complete direct Anthropic API receipts for `claude-sonnet-5` can use a versioned
+list-price estimate when the provider supplies no run price. The receipt records
+the rates and assumptions. Aggregate cache writes use the one-hour rate because
+their TTL is unknown. Estimates are not invoices. Other models, billers, unknown
+billing types, and incomplete receipts remain unpriced.
+
## 13.3 Cost Event Ingestion
`POST /companies/:companyId/cost-events` body:
@@ -2015,3 +2098,9 @@ as free-form text in the instance database. Legacy agents use the default
in standard, ask, and planning modes. Submission never changes task disposition
or routes feedback externally. See [Agent commentary](agent-commentary.md) for
authentication, replay, document-sized limits, inspection, and deletion semantics.
+
+## Company decision-model service
+
+Company Settings → General can configure one shared API-key connection for optional internal decisions. V1 supports OpenAI Decisions and Jev through OpenRouter. Companies start unconfigured; background sponsorship defaults on when configured, while an explicit off setting persists. Human and agent calls retain current responsible-user, connection audience, resource, and agent installation checks. Only explicitly registered internal background features can use company sponsorship.
+
+The internal service provides local-only availability and bounded, reauthorized execution. It records metadata-only invocation history and independent fractional service charges in the existing cost ledger, applying company and applicable agent/project budgets under the accounting lock. Unknown dispatch charges retain reservations until audited resolution. Settings/testing require connection management permission; history uses existing cost visibility. See [decision-models.md](decision-models.md) for the contract, supported models, accounting, privacy, and endpoints.
diff --git a/doc/SPEC.md b/doc/SPEC.md
index b892429d97a..3608565f43f 100644
--- a/doc/SPEC.md
+++ b/doc/SPEC.md
@@ -91,6 +91,13 @@ The Board sets Company-level budgets. The CEO can set budgets for Agents below t
## 2. Agent Model [DRAFT]
+A human's personal primary agent is a company-scoped navigation and assignment
+preference, independent of the org chart, roles, stars, and authority. First human
+creation initializes it automatically. Later explicit choices persist across
+devices; recent task/chat choices take precedence. The profile owns the setting
+and replacement confirmation. See the personal-primary addendum in
+`SPEC-implementation.md` for persistence and lifecycle rules.
+
Every employee is an agent. Agents are the workforce.
### Cryptographic identity
@@ -178,7 +185,7 @@ Hierarchical reporting structure. CEO at top, reports cascade down.
**Full visibility across the org.** Every agent can see the entire org chart, all tasks, all agents. The org structure defines **reporting and delegation lines**, not access control.
-Visibility settings on an agent profile (where supported) do not alter company-level visibility for tasks, projects, issues, comments, costs, or activity. Those work-object privacy controls are not a V1 feature until centralized scoped authorization is in place.
+Visibility settings on an agent profile do not control task privacy. Work is company-open by default; opt-in private tasks and projects use centralized authorization as specified in `SPEC-implementation.md` and `ISSUE-PRIVACY.md`. Sharing a child grants access to it and its descendants. Ancestors and siblings require separate access.
Each agent publishes a short description of their responsibilities and capabilities — almost like skills ("when I'm relevant"). This lets other agents discover who can help with what.
@@ -326,6 +333,8 @@ recipients must be valid and authorized in the company before a question is
saved. See `SPEC-implementation.md` §9.8.1 for the resolver contract.
+Experimental Agent Chat presents one persistent task per person and agent as a simplified conversation. Chat has a searchable secondary sidebar with agent avatars; adding an agent starts or reopens their single conversation. It retains the task composer, transcript, tools, attachments, documents, and existing Subtasks panel, with the task's selected visibility. New execution tasks are ordinary project tasks, not structural children of the conversation; private-source restrictions still flow through their run provenance. Idle conversations wait for a message without entering execution-task work queues. Agents clarify goals here and create assigned tasks for substantial execution. `/new` resets provider context at an ordered session boundary within the same task while preserving visible history. `enableAgentChat` is disabled by default; the V1 lifecycle and rollout contract is specified in `SPEC-implementation.md`.
+
### Implications
- An agent's "inbox" is: tasks assigned to them + comments on tasks they're involved in
@@ -487,6 +496,10 @@ No separate "agent API" vs. "board API." Same endpoints, different authorization
Paperclip manages task-linked work artifacts: issue documents (rich-text plans, specs, notes attached to issues) and file attachments. Agents read and write these through the API as part of normal task execution. Full delivery infrastructure (code repos, deployments, production runtime) remains the agent's domain — Paperclip orchestrates the work, not the build pipeline.
+Self-contained HTML reports can render in an opaque-origin sandbox. The report
+cannot access the board's cookies, storage, or DOM. Users can switch to the raw
+source beside Download, which returns the original file.
+
Users may start a task with only a prompt. Paperclip uses a short prompt slice as
its initial title and asks the assigned agent to name the task early. Explicit
user titles are preserved, and naming does not change task execution state.
@@ -737,3 +750,7 @@ as free-form text in the instance database. Legacy agents use the default
in standard, ask, and planning modes. Submission never changes task disposition
or routes feedback externally. See [Agent commentary](agent-commentary.md) for
authentication, replay, document-sized limits, inspection, and deletion semantics.
+
+### Managed decision models
+
+A company may configure a shared decision model for optional Paperclip features. The instance owns credential resolution, authorization, budget admission, and attributable service charges. Company-sponsored background use is enabled by default during configuration; explicit opt-out persists. User and agent requests keep their own access boundaries and cannot become sponsored background requests after denial. Availability is a cheap local capability check, and metadata-only request history makes service usage inspectable. The implemented V1 contract is in [decision-models.md](decision-models.md).
diff --git a/doc/acp-run-lifecycle.md b/doc/acp-run-lifecycle.md
index 0e75f3e7d7f..f5a4019b8d8 100644
--- a/doc/acp-run-lifecycle.md
+++ b/doc/acp-run-lifecycle.md
@@ -58,6 +58,15 @@ removes it if startup fails. The child's environment values remain unchanged.
If the launch shell fails before the wrapper emits a protocol event, the run
log retains the shell's stderr alongside the exit code.
+The process-session bridge also writes one bounded terminal diagnostic to the
+run's stderr. It distinguishes a remote event, input delivery failure, output
+poll failure, output stream failure, and unexpected authenticated proxy closure.
+Exit codes and signals are validated; unavailable values are `unknown`. The line
+contains no raw error message, command, path, or environment value. It records
+the first observed terminal event, not proof of remote shutdown. An error frame
+drains to the local proxy before the connection closes, and a failed or stalled
+diagnostic write does not delay failure delivery or teardown.
+
The settlement sequence is the one live cleanup owner for every settled path. It
claims the ledger once, makes the pure reuse decision, then runs the ordered
steps:
diff --git a/doc/adapter-model-audit-2026-10-02.md b/doc/adapter-model-audit-2026-10-02.md
index 5c86e25bd68..133e81b2e3c 100644
--- a/doc/adapter-model-audit-2026-10-02.md
+++ b/doc/adapter-model-audit-2026-10-02.md
@@ -10,7 +10,7 @@ No agent defaults or saved model selections are migrated.
| Adapter | Changes from the audit |
| --- | --- |
-| Codex and the Codex runner catalog | Add GPT-6.1 Sol (`gpt-6.1-sol`). Expose efforts through Ultra and Fast mode, as documented. Keep `gpt-5.6-sol` as the default. |
+| Codex and the Codex runner catalog | Add GPT-6.1 Sol (`gpt-6.1-sol`). Expose efforts through Ultra and Fast mode, as documented. Keep `gpt-5.6-sol` as the default. Follow-up (October 6, 2026): with ChatGPT sign-in the Codex backend accepts `gpt-6.1-sol` only from Codex CLI 0.159.0 or newer (0.156.1 and older are rejected with "The 'gpt-6.1-sol' model is not supported when using Codex with a ChatGPT account."), and `gpt-6-sol` / `gpt-6-luna` entered the bundled catalog in 0.157.0. The adapter now records these floors; the environment Test and the remote runner compare the installed `codex --version` against them, so a sandbox image baked before the pin moved reports the stale CLI instead of an account error. |
| Claude on Bedrock | Add Sonnet 5.5 (`us.anthropic.claude-sonnet-5-5`), using the catalog's existing US inference-profile convention. Sonnet 5.5 IDs (direct or Bedrock-qualified) get the documented `xhigh` and `max` efforts and require Claude Code 2.1.284 or later on the CLI lane. |
| OpenCode | Add `openai/gpt-6.1-sol` and `anthropic/claude-sonnet-5-5` to the static fallback used by remote environments. Both IDs are present in the OpenCode model registry. |
| Claude Code (direct) | No change in this audit. [#14993](https://github.com/paperclipai/paperclip/pull/14993) (merged October 5, 2026, superseding #14816) adds Sonnet 5.5 (`claude-sonnet-5-5`, Claude Code 2.1.284 or later) and refreshes the Claude runtime. |
diff --git a/doc/agent-files.md b/doc/agent-files.md
index a4154551f19..f037cb25515 100644
--- a/doc/agent-files.md
+++ b/doc/agent-files.md
@@ -37,6 +37,12 @@ workspace: their independent agent copy therefore lives under the excluded
`.paperclip-runtime/agent-files///` area. It is not included in task
workspace sync, Git staging, or task deliverables.
+Claude CLI runs keep the working-copy location in each run's prompt, separate
+from the cached system instructions. A new copy path alone does not reset the
+task session. Each turn names the current copy for relative file references;
+instruction or enabled skill content changes still invalidate the prompt bundle.
+Sessions saved with the older path-bearing bundle start fresh once after upgrade.
+
Regular files (including binary bytes) and directories are supported, up to
100,000 entries (files and folders), 256 MiB per file and 2 GiB total. Symlinks,
hardlinks, and special
diff --git a/doc/connections/CONNECTION-SEARCH.md b/doc/connections/CONNECTION-SEARCH.md
index 9c0630e21e1..594b10a66ec 100644
--- a/doc/connections/CONNECTION-SEARCH.md
+++ b/doc/connections/CONNECTION-SEARCH.md
@@ -57,6 +57,12 @@ grants consent. A provider connection is not proof that its underlying app is
authorized. Multiple matching aggregator apps are returned as candidates; the
agent searches the selected `aggregator.targetService` to get its provider question.
+A fuzzy or partial external app match remains a suggestion alongside authorized
+installed capability matches. It cannot replace those matches with a mandatory
+provider question. For example, a query for a page service can return the
+installed page tools alongside a Page X suggestion; selecting the exact Page X
+service is required before that external route asks for provider consent.
+
## Regression coverage
```sh
@@ -69,3 +75,10 @@ Circleback/Attio/ClickUp, indexed Executor tools, and provider consent. The nati
tool authority test searches a paragraph longer than the old 200-character limit
and then creates a real connection interaction. Existing tests retain checks for
private metadata, administrative denials, stale identities, and saved declines.
+
+When `connection_request` rejects an unknown `toolNames` entry, its error includes
+up to twenty exact names from that eligible connection's active tool catalog.
+This is discovery metadata: the request still fails with 422, grants no access,
+and creates no approval card. The agent must select the needed exact names and
+submit a new request; normal user approval, catalog-version and policy checks
+still apply. Ineligible connections and inactive catalog entries are excluded.
diff --git a/doc/decision-models.md b/doc/decision-models.md
new file mode 100644
index 00000000000..f41bf6acb4e
--- /dev/null
+++ b/doc/decision-models.md
@@ -0,0 +1,73 @@
+# Company decision models
+
+Company Settings → General → **Decision model** configures one shared API connection for optional Paperclip features. New companies remain unconfigured. A connection manager selects or adds an OpenAI or OpenRouter connection, saves, and can run a small billed setup test. Test answers appear only in that session; request metadata and charges appear under Activity → Costs → Decisions.
+
+**Allow company-sponsored background decisions defaults on.** Saving authorizes internal background features to charge the selected connection without a responsible human. An explicit off setting survives later edits, including changing the connection or omitting the field from an update. Deleting the selected connection or grant preserves the setting and blocks calls until a valid replacement is selected. Disabling decisions prevents new calls. It does not cancel or erase calls already dispatched.
+
+V1 supports native OpenAI Decisions (`gpt-6-luna`) and OpenRouter Decisions (`typesafe/jev-1.13`). It accepts company-owned API keys only. Personal grants, subscription credentials, custom endpoints, fallback chains, images, and public agent/plugin execution tools are outside this version. Decision compatibility is separate from CLI-adapter compatibility.
+
+## Internal service
+
+Register a feature once in its server module, then call `decisionModelService(db)` with trusted server context:
+
+```ts
+const classifyTask = defineDecisionFeature("tasks.classify");
+const service = decisionModelService(db, { budgetHooks });
+const context = { companyId, actor: req.actor, feature: classifyTask, issueId };
+const available = await service.availability(context);
+if (!available.available) return existingBehavior();
+const result = await service.decide(context, {
+ state: { title: task.title },
+ questions: {
+ billing: { type: "boolean", instructions: "Is this about billing?" },
+ team: { type: "choice", instructions: "Which team should handle it?",
+ criteria: { billing: "Payments", support: "Product support" } },
+ urgency: { type: "score", instructions: "How urgent is it?",
+ criteria: ["Routine", "Soon", "Immediately"] },
+ },
+});
+```
+
+The setup test is the only product caller in this release. Future callers must supply the existing budget enforcement hooks, handle unavailable/failure outcomes, and select their own thresholds. Boolean answers are probabilities, choice answers select a category, and scores use the ordered criteria's zero-based positions. Available distributions and provider confidence are preserved in returned answers. `succeeded` and `failed` results include an invocation ID and usage with reported, estimated, or unknown cost. Refusals and invalid responses never become invented answers.
+
+`availability` reads local configuration and permissions only. It does not decrypt credentials, contact a provider, or promise reachability/budget admission. `availabilityForRequest()` returns a memoizing function; keep that function and its context object within one request. Dispatch never trusts this cached authorization.
+
+Human calls use the authenticated user and retain the connection's audience checks. Agent calls reread the active persisted run and its current responsible user, check that user's current membership/resource access, and require an applicable agent/company connection installation. Task and project references must belong to that run/company. Attribution snapshots the effective identity at dispatch. Explicit internal system contexts additionally require a feature registered with `{ background: true }` and company sponsorship. A denied user/agent call cannot fall back to system context.
+
+Credentials are resolved through the existing secret service immediately before admission, with the actual user/agent/system audit attribution. Authorization, connection/configuration revisions, current run identity, and budgets are rechecked before dispatch. Requests allow 1–20 named questions, text/JSON state, and at most 32 KB serialized request data. Execution is limited to 30 seconds and SDK paid retries are disabled.
+
+## Accounting and privacy
+
+`decision_invocations` records feature, actor/responsible user, applicable task/project/agent/run and identity revision, connection/grant, provider/model, request ID, timing, status, question types/count, token counters, and a cost-ledger reference. It does not store state, question text, answers, or raw provider payloads. SDK input/output telemetry is disabled and provider errors are reduced to bounded codes. These are local database records, not first-party telemetry events.
+
+Cost events have `usageKind: decision` and may have no agent. Agentless reporting uses **Paperclip services**. The public agent cost-reporting API still requires an agent; only the internal service receipt path accepts agentless charges. Decision events snapshot responsible-user attribution; historical run costs continue to use their existing attribution rules. Decision events have no heartbeat receipt reference, so run receipt reconciliation cannot count them again.
+
+Admission and settlement use the company accounting lock. Company and applicable agent/project budgets include held reservations and observed spend. Reservations use the largest configured applicable reservation amount. Settlement is idempotent. Explicit provider authentication/validation/rate-limit rejection releases the hold when no model work occurred. Uncertain dispatches, timeouts, and unknown prices remain unpriced with the reservation held. Startup/periodic accounting recovery marks stale invocations interrupted without resubmitting them. Use the existing audited cost adjustment workflow to resolve the charge and release its hold, including a verified zero charge when appropriate.
+
+OpenRouter-reported USD costs are converted to fractional cents. OpenAI uses a dedicated, versioned Decisions rate snapshot: $0.10 per million input tokens for the bounded short requests at the native default endpoint. No chat-model price is substituted. Missing usage or an unsupported rate stays unknown; it is never displayed as a free request. The ledger retains seven decimal places in cents. Pricing provenance accompanies the cost event and remains available to accounting corrections.
+
+History follows company cost visibility and rechecks task access before returning task/run links. It shows the latest 100 requests in the selected date window. Input/output contents remain absent after refresh.
+
+## HTTP surface
+
+All paths are under `/api/companies/:companyId/decision-model`:
+
+| Method/path | Access and behavior |
+| --- | --- |
+| `GET /` | Board; returns manager capability and settings/compatible choices to connection managers |
+| `PUT /` | Connection manager; validates and audits configuration |
+| `GET /availability` | Authenticated company caller; local authorization check |
+| `POST /test` | Connection manager; fixed server-owned three-question sample, ignoring client prompts/identity |
+| `GET /history` | Existing company cost-read rules; date bounds and limit up to 500 |
+
+There is no general HTTP decision execution endpoint.
+
+## Provider dependencies and verification
+
+The experimental Vercel contract is hidden behind Paperclip-owned types. Dependencies are pinned to `ai@7.0.130`, `@ai-sdk/openai@4.0.86`, and `@openrouter/ai-sdk-provider@3.1.0`. That OpenRouter release calls its compatible model factory `evaluationModel`; the wrapper adapts it to the current Decisions interface. Upgrade these together and rerun native wire-format tests.
+
+CI owns lockfile updates. Before a direct Docker build of a feature checkout whose dependency manifests changed, refresh the local build context with `pnpm install --resolution-only --ignore-scripts --no-frozen-lockfile`. Do not commit that generated lockfile; the hosted Docker workflow performs the same preparation and the lockfile bot updates master.
+
+References: [OpenAI Decisions](https://developers.openai.com/api/docs/guides/decisions), [Vercel AI SDK](https://ai-sdk.dev/docs/reference/ai-sdk-core/decide), [OpenRouter Decisions](https://openrouter.ai/docs/api/api-reference/alphadecisions/submit-a-decisions-questions-and-answers-request).
+
+Automated coverage lives in the provider contract and database-backed decision service tests. Provider tests use actual pinned SDK adapters with simulated HTTP responses; they do not establish live account/model availability. Storybook's **Decision models** group uses production components and includes settings states, metadata history, and a settings-to-history journey. A live acceptance check must run the fixed setup test with each authorized shared provider connection and inspect the corresponding persisted invocation/charge. Record live and simulated evidence separately.
diff --git a/doc/execution-semantics.md b/doc/execution-semantics.md
index fe946031175..c923e18c66f 100644
--- a/doc/execution-semantics.md
+++ b/doc/execution-semantics.md
@@ -211,6 +211,22 @@ New comments received during an execution hold retain their individual deferred
The conversation groups repeated empty pre-start reconciliation cancellations into a neutral waiting notice. Started runs, actual startup failures, and run history remain inspectable. No historical run records are deleted.
+An unstarted legacy conversation retry waits on its existing `scheduled_retry`
+row while a previous execution still owns a process or environment lease. Each
+sweep moves the next check forward without creating another run or incrementing
+retry accounting. The wait survives a controller restart. A queued retry that
+encounters the same ownership hold returns to that scheduled state. Once
+ownership is released, normal promotion and dispatch gates still apply,
+including reassignment, cancellation, budget limits, and no-replay holds.
+The **Retry now** action returns `waiting` with the saved retry schedule while
+cleanup holds ownership. Its controls show the wait without claiming that a run
+started, and another click can check the gate again.
+
+Recovery instructions in a wake describe only an active or escalated recovery
+action. Resolving or cancelling that action removes its repair instructions from
+subsequent wakes, so the original worker can resume the task. This prompt change
+does not clear any persisted execution reconciliation hold.
+
Workspace contention (`workspace_busy`) displays **Waiting for workspace** and
continues automatically when the workspace is available. Internal scheduling
attempts remain in the run log without conversation cancellation markers,
@@ -656,6 +672,21 @@ An issue monitor is a one-shot deferred action path for agent-owned issues in `i
Use a monitor when the current assignee owns a future check against an async system or external service. Examples include Greptile review loops, GitHub checks, Vercel deployments, or provider jobs where the agent should come back later and decide what happens next.
+Native runners in standard execution use `set_task_monitor({ taskId?, idempotencyKey, monitor })`. Omit `taskId` for the current task. An explicit target must be accessible, in the same company, assigned to the caller with no human assignee, and `in_progress` or `in_review`. Runtime-management permission still applies. Ask, planning, and review-only runs cannot use this tool. Generic `call_api` lifecycle restrictions remain in force.
+
+To wait for a check:
+
+1. Set a future `monitor.nextCheckAt` and short `monitor.notes` describing the check, with optional service context and bounds.
+2. Confirm the receipt's persisted task ID, monitor state, next-check time, and bounds.
+3. Call `paperclip_finish` with `reportedWorkDisposition: "yielded"` and `continuation: { kind: "monitor", summary, idempotencyKey }`. Report outstanding work honestly; the scheduled check may still block completion.
+4. End the run. Paperclip keeps the task active, releases execution ownership, and the one-shot scheduler later wakes it with `issue_monitor_due`. This does not enqueue an immediate continuation. On resume, `get_task_context.activeTask.monitor` includes the consumed monitor’s notes and attempt count.
+
+Only a valid persisted monitor on the current task authorizes that finish; scheduling another owned task does not. Authority is checked again under the final disposition lock. A timer that becomes due during an active native execution remains scheduled until execution releases it. Dispatch checks the current schedule, claim, status, and assignee so an older dispatch cannot clear a replacement monitor.
+
+The service name `AI provider quota` is reserved for server-owned recovery of legacy runs. Native task monitors reject it; use ordinary service context and notes when scheduling a provider-usage check.
+
+Use a new idempotency key to replace the schedule or clear it with `monitor: null`. Retrying the original call returns current monitor state without re-arming a consumed, replaced, or cleared timer. Monitor changes, audit activity, and mutation receipts are committed together, and unrelated execution/review policy is preserved. Legacy agents continue to use the issue API.
+
Monitor policy lives under `executionPolicy.monitor` and includes:
- `nextCheckAt`: when Paperclip should wake the assignee
@@ -1351,6 +1382,23 @@ controller must recover it through the authenticated ownership checks. This
preserves active work and queued messages without treating a server restart as
user cancellation.
+When a native turn creates a governed approval wait, its checkpoint retains the
+exact committed triggering event and yielded disposition before interrupting the
+provider. Shutdown gives these turns a shared, bounded 20-second window to finish
+settling their usage and terminal evidence before detaching. Recovery verifies
+the trigger against the retained event ledger and settles that same turn, even
+if the user has already answered the interaction. It replays retained accounting
+through the ordinary control-plane observers without starting another model turn.
+When a later heartbeat run reuses the provider session, it clears that prior
+run's wait marker along with its terminal, result and pending-request authority.
+Already-numbered cancellation acknowledgements and cancelled/expired runtime requests
+are retained during shutdown so recovery can replay a contiguous journal. They
+carry no permission to start work. Stream closure, stream failure or drain timeout
+after complete usage leaves the saved wait unfinalized until a provider terminal
+is retained; complete token counters alone cannot certify a stopped provider.
+A timeout, missing accounting, or an unproven provider terminal remains a failure;
+the saved wait does not certify successful provider execution.
+
Before either shutdown path exits, idle warm sessions close through their
normal suspend-and-checkpoint path. Remote sessions therefore leave verified
backup authority for the next controller even though their last run is already
diff --git a/doc/html-artifact-previews.md b/doc/html-artifact-previews.md
new file mode 100644
index 00000000000..cfb9fafbe99
--- /dev/null
+++ b/doc/html-artifact-previews.md
@@ -0,0 +1,43 @@
+# HTML artifact previews
+
+HTML attachments and workspace `.html`/`.htm` files open rendered by default.
+The eye and code icons beside Download switch between the report and its original
+source. Download always returns the original file. Empty and oversized attachments
+use the existing text-viewer states and limits.
+
+The shared `HtmlArtifactPreview` uses `srcdoc` in an iframe with
+`sandbox="allow-scripts"`. **Never add `allow-same-origin`.** Its opaque origin
+prevents artifact JavaScript from reading Paperclip cookies, storage, or the parent
+DOM. Forms, popups, downloads from inside the frame, and top navigation are not
+granted. The host does not accept messages or privileged requests from artifacts.
+
+A trusted CSP is installed before any artifact markup. It permits inline scripts
+and styles for self-contained tables, charts, filtering, and other report controls.
+It blocks API connections, remote scripts/styles/images/fonts/media, child frames,
+objects, base URLs, and form submissions. Embedded data images/fonts/media work.
+An artifact's own CSP cannot weaken the first policy. No artifact HTML is parsed
+or inserted into the host DOM. The iframe sends no referrer.
+
+This supports self-contained reports. Reports that need CDN libraries or external
+resources must embed them instead. Ordinary external links cannot open new tabs
+or navigate the host. The sandbox does allow navigation within the artifact frame;
+its opaque-origin restrictions remain after navigation. This is not a claim of
+complete network isolation or protection against resource exhaustion by scripts.
+
+Attachment HTTP serving retains forced download, `nosniff`, and its existing
+sandbox CSP. Workspace previews return bounded UTF-8 inside JSON, and workspace
+downloads retain `Content-Disposition: attachment`. No database or API shape changes
+are needed.
+
+Review **HTML artifacts** in Storybook for the production viewer, security probes,
+workspace panel/file sheet, and a task-to-report journey. Run the browser security
+checks with:
+
+```sh
+pnpm exec playwright test --config tests/html-preview/playwright.config.ts
+```
+
+These checks use Chromium and simulated report data. They verify working report
+controls, raw mode, cookie/storage/parent access denials, blocked resource and API
+requests, and denied top navigation/popups. They do not replace testing the actual
+attachment journey in a running Paperclip instance.
diff --git a/doc/observability.md b/doc/observability.md
index 5c1e57c1784..c09b7219296 100644
--- a/doc/observability.md
+++ b/doc/observability.md
@@ -269,9 +269,9 @@ environment variables: `SENTRY_DSN_FRONTEND` for the browser and
`SENTRY_DSN_BACKEND` for the server. Each variable is optional. A
specific variable always wins for its own component; a legacy variable,
`SENTRY_DSN`, supplies a component that has no specific value set. An
-empty string counts as absent for all three variables. The feature uses
-built-in Sentry options only. It adds no `beforeSend` hook and no custom
-filter code.
+empty string counts as absent for all three variables. SDK configuration uses
+built-in Sentry options only. It adds no `beforeSend` hook. The run-failure
+reporter selects reportable outcomes before calling the SDK, as described below.
The server is inactive when the backend DSN resolves to `null`; then it
imports no Sentry package. The browser is inactive when the front-end DSN
@@ -434,6 +434,15 @@ They do not change the ambient Sentry scope, whose isolation is unavailable
without an OpenTelemetry context manager. Later, unrelated exceptions must
not inherit a previous run's identity or fingerprint.
+Known missing-secret configuration blockers are kept in the task's run log,
+blocked state, and owner recovery action, without a Sentry run-failure event.
+This requires a failed `configuration_incomplete` run in the preparing stage,
+a setup-phase report, explicit proof that provider work did not start, and a
+nonempty list of recognized missing or inactive secret bindings. Process exit
+evidence, unknown binding reasons, secret-provider failures, ambiguous missing
+secret-definition lookups, and workspace failures remain reportable. This filter
+does not change task recovery, credentials, or execution policy.
+
The `run_failure` context also includes the recorded process `exitCode` and
`signal`, so a generic adapter error can still distinguish a nonzero exit from
a signal termination. Exit codes must fit the database's signed 32-bit integer;
@@ -515,6 +524,19 @@ and native runs:
- `run_exception_0` through `run_exception_3`: exception names, codes, HTTP
statuses, and request IDs for a caught exception and up to three causes.
+The orphan reaper records a bounded `processLossDiagnostic` before status writes
+or cleanup. For `process_lost` failures, `run_execution` includes
+`processLossPidRecorded`, `processLossGroupRecorded`, and `processLossLocalCheck`
+(`not_observed_alive`, `not_checked`, or `no_identifiers`). It also includes
+`processLossRunPredatesObserver`, `processLossObserverUptimeMs`, and
+`processLossLastOutputAgeMs` when the timestamps are available and valid. Ages
+above seven days are omitted. These are observations, not proof of an OOM,
+provider failure, or deployment. The last-output age can include system output.
+`processLossRetryEligible` records eligibility for the existing process-loss retry
+at detection; it does not claim that a retry was queued or succeeded. This data
+contains no process IDs, task text, paths, or credentials and changes no recovery
+or ownership decisions.
+
ACP turns record `acpLastEventAgeMs`, `acpObservedEventCount`,
`acpPendingToolCount`, and `acpToolInventoryComplete` at finalization, before
usage reads, error logging, and cleanup. The age measures time since the last
@@ -554,6 +576,13 @@ integers from 1 through 255. These fields accompany a known restore failure code
only. They omit error messages, raw command lines, paths, process output, and arbitrary
cause data. Git error wrappers preserve only these safe codes and numbers for
diagnostics, without adding the original error as a cause.
+Native sandbox `environmentSyncOut` failures carry the same allowlisted codes
+and bounded HTTP/exit statuses across the plugin worker RPC boundary. The host
+revalidates that optional envelope and retains it only for restore diagnostics.
+The envelope excludes provider messages, response bodies, names, paths, and
+credentials. The existing RPC error message and code remain unchanged, as do
+restore classification, retries, and source retention. Older workers without the
+envelope still report `unknown` when no structured cause is available.
For `git_integration`, optional `workspaceRestoreGitCommand` identifies the fixed
command family: `rev_parse`, `symbolic_ref`, `merge_base`, `merge_tree`,
`commit_tree`, `update_ref`, or `log`. `workspaceRestoreGitFailureKind` is
diff --git a/doc/openai-dot-runner.md b/doc/openai-dot-runner.md
index fa067da97f7..773cef4c1c9 100644
--- a/doc/openai-dot-runner.md
+++ b/doc/openai-dot-runner.md
@@ -61,7 +61,7 @@ Manual browser and device consent still require an operator role. Device codes a
and organization. The gateway's Connections invitations remain personal
assistant invitations; use the agent's Dot connection panel for Runner pairing.
-Database migration `0312_broken_sentinels.sql` adds only Dot tables and extensions
+Database migration `0317_messy_famine.sql` adds only Dot tables and extensions
after the merged gateway migrations. It is safe to reapply. The earlier
prototype migration number is retired; published master migrations are intact.
@@ -348,7 +348,7 @@ server-side authorization.
| Area | Runner tools |
| --- | --- |
| Identity and people | `get_identity`, `list_people`, `list_agents`, `get_agent` |
-| Task work | `get_task_context`, `get_task_history`, `search_tasks`, `get_task`, `report_progress`, `set_task_title`, `create_task`, `reassign_task`, `set_dependencies`, `comment_on_task` |
+| Task work | `get_task_context`, `get_task_history`, `search_tasks`, `get_task`, `report_progress`, `set_task_title`, `set_task_monitor`, `create_task`, `reassign_task`, `set_dependencies`, `comment_on_task` |
| Human input and approvals | `request_human_input`, `list_approvals`, `get_approval`, `get_approval_context` |
| Documents | `list_documents`, `read_document`, `list_document_revisions`, `write_document`, `list_task_documents`, `read_task_document`, `write_task_document` |
| Agent instructions | `read_agent_instructions`, `update_agent_instructions`, `get_agent_instruction_history`, `restore_agent_instructions` |
diff --git a/doc/plans/2026-10-02-openai-dot-runner-adapter.md b/doc/plans/2026-10-02-openai-dot-runner-adapter.md
index bb37a2f309c..61fb2c43a5b 100644
--- a/doc/plans/2026-10-02-openai-dot-runner-adapter.md
+++ b/doc/plans/2026-10-02-openai-dot-runner-adapter.md
@@ -71,7 +71,7 @@ Verified client metadata, durable verification quotas, event secret rotation,
subscription refresh races and warm-standby gates use the merged implementation.
Personal and Dot event workers consume their own subscription resources.
-The generated Dot-only migration is now `0312_broken_sentinels.sql`, after the
+The generated Dot-only migration is now `0317_messy_famine.sql`, after the
published master migrations. Its table, column, index and constraint additions
are safe to reapply. Both consent UIs retain the merged organization branding
and request layout while explaining agent access. Runner provider selection
diff --git a/doc/plans/2026-10-07-native-connection-baseline-repair.md b/doc/plans/2026-10-07-native-connection-baseline-repair.md
new file mode 100644
index 00000000000..6bb798b8a28
--- /dev/null
+++ b/doc/plans/2026-10-07-native-connection-baseline-repair.md
@@ -0,0 +1,96 @@
+# Native connection baseline repair — 2026-10-07
+
+The original baseline remains **0 PASS / 15 FAIL**. It did not exercise the intended user decisions and does not qualify a production instruction reduction. This repair makes a new baseline possible; it does not change the old grades.
+
+## Original evidence
+
+- [Campaign 37562577199, attempt 1](https://github.com/paperclipai/paperclip/actions/runs/37562577199).
+- [Original public report](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-37562577199-1/index.html).
+- Source and trusted workflow: `caf120105c487532db769670fcd39249483e1d99`.
+- Suite hash: `d7bd6c177fe97e9cba28497555d475b545824796d33178fd0372ae21dbb06429`.
+- Definition digest: `e2298d2e190448aa112167e8f2989b8d087766482af145007d86a36f8ab29830`.
+- Five cases on native Codex `gpt-5.6-sol`, ACPX Claude `claude-sonnet-5`, and OpenCode `openrouter/deepseek/deepseek-v4-flash-0731`.
+- One attempt per cell, 15 actual run records: 14 succeeded and one failed. No harness retries. All 15 cleanup and budget readbacks passed. A succeeded run record is not a passing behavioral grade.
+- Recorded LLM cost subtotal: $0.01824843. Positive costs were reported only by the five OpenCode cells. Twelve of 15 runs had token coverage. Zero or missing Codex/Claude billing is unknown, not free; actual charges and local/hosted runtime cost are unknown.
+
+| Cells | Observed failure | Supported diagnosis |
+| --- | --- | --- |
+| 10 | Browser could not find the creation-time title; renamed title and pending interaction were visible | Stale-title harness assertion, before any intended user decision |
+| 2 Codex provider-choice cells | Native `request_human_input` schema denial before Paperclip execution | Rejected input; retained diagnostics omit the invalid field. Four rejections in the positive cell are calls within one run, not four paid harness attempts |
+| 2 OpenCode provider-choice cells | Used the preinstalled HubSpot tool once without a choice card | Fixture had already granted real tool access. This does not prove a consent violation or disregard of a decline; no decline was sent |
+| 1 Claude provider-decline cell | `native_finalization_missing: session returned no semantic result` | Native session failed before choice; retained evidence does not establish the underlying cause |
+
+The schema accepts both canonical and legacy question forms. Conflicting native/legacy guidance is observable, but is not proven to have caused the old Codex denials. Do not infer that a corrected run explains the old Claude failure.
+
+## Repair contract
+
+1. Match the requested browser route and visible task identifier, then wait for the loaded conversation. Agent title changes are allowed; the wrong task still fails.
+2. Configure the deterministic company Arcade gateway with zero agent installs and zero allowed tool entries. Verify public effective-access records before task creation.
+3. The positive provider case requires the saved Arcade choice, followed by one real access card for the same agent, connection, selected interaction and exact HubSpot read tool. The browser grants access. The oracle requires the accepted result, exactly one provider call, and the independently observed fixture marker. The expected run count is three. Declines still require one decision, no tool calls and an attributed explanation.
+4. Return a canonical `providerQuestionSet` alongside the legacy `providerQuestion`. Native guidance uses the canonical form. Both forms preserve the exact prompt and option IDs that validate saved consent.
+5. Invalid native question input remains rejected before execution. Bounded feedback identifies authorized schema locations and required fields, without echoing submitted values or arbitrary keys. No schema or authorization gate is relaxed.
+
+The historical Everyday fixture and prompts remain unchanged. The new fixture and production correctness fixes change the measured contract. Results from the new source must be reported separately; they cannot be treated as a matched comparison with the invalid original baseline.
+
+## Validation and remaining gate
+
+Credential-free checks pass: eval typecheck; 1,801 support tests plus 128 Node tests (one intentional support skip); 51 connection/schema tests; one real-server fixture test; one focused Rust feedback test; and local browser wrong-task/title calibration. Repository typecheck and build pass. The full local repository test run was stopped after five failures outside the changed paths; those five passed in a separate focused invocation. The full run is incomplete, not passing, and the original failures remain retained. Exact-head normal CI at `162cc90fdabe7f505b88ae095044531b82784c92` passed (52 successful checks, four intentional skips, separate Snyk success); its fresh review completed 5/5.
+
+The corrected Codex provider-choice canary passed before the other 14 distinct cells were dispatched. The completed corrected baseline is **10 PASS / 5 FAIL**, with further continuation defects described below. It is not ready to qualify an instruction reduction. Preserve every attempt, decision, actual run, cost gap and failure. No instruction reduction or general integration quality claim is qualified yet.
+
+## Initial corrected campaign stopped before provider execution
+
+[Campaign 37574251834](https://github.com/paperclipai/paperclip/actions/runs/37574251834) resolved source `cbf1c4fba8eabbf779435f550c455f6a66c5aae5` on trusted master workflow `99a9de9940bf5974352d9dbfbb2f21e62e89689f`. It was cancelled during the shared build after review identified another browser precondition defect. The matrix job has no steps and no runner execution; no provider cell or behavioral grade occurred. Preserve this cancelled campaign separately.
+
+The initial stable-ID check assumed whitespace around the identifier. The real breadcrumb uses adjacent title/identifier spans. A regression reproduces the failure with `Renamed taskRUN-1`; the corrected check targets the visible identifier element under the current breadcrumb and matches its text exactly. All five browser checks now pass, including wrong route, wrong/partial identifier and an identifier present only in the mutable title or elsewhere on the page. Seven focused suite checks and eval typecheck pass. This review correction changes only browser support and this report; production logic is unchanged.
+
+
+## Continuation failures exposed by the corrected baseline
+
+Frozen measured source: `162cc90fdabe7f505b88ae095044531b82784c92`; trusted workflow: `99a9de9940bf5974352d9dbfbb2f21e62e89689f`. These results do not retroactively change the original baseline.
+
+- [Codex provider-second canary 37575158761](https://github.com/paperclipai/paperclip/actions/runs/37575158761): PASS, 17/17 checks, three actual succeeded runs. The saved Arcade choice, separate exact HubSpot access approval, one authorized provider call, persisted Ada Fixture response and actual verification marker all pass. No harness retry. Cleanup and both budget readbacks pass.
+- [Remaining 14 distinct cells, campaign 37576261807](https://github.com/paperclipai/paperclip/actions/runs/37576261807): preserve every first-attempt original grade. Claude provider-decline and provider-second fail after the saved choice on `run.attach`: their run-scoped instruction working-copy path changes while runtime content identity is unchanged. This is not evidence for the unrelated old missing-final failure.
+- Claude service-approve executes the approved service call, then the evaluator fails fast in the gap between the first blocked run finalizing and its continuation appearing. The final ledger retains a second run that starts and is cancelled by cleanup. The earlier workflow snapshot misses it; count both records and do not claim the continuation behavior passed.
+- Codex service-approve executes the approved call, but a yielded result requests another human approval for the same referenced card. Finalization materializes a redundant completion-review card. The original FAIL is retained.
+
+The corrected fifteen-cell result is:
+
+| Profile | Connection decline | Provider decline | Provider second | Service approve | Service decline |
+| --- | --- | --- | --- | --- | --- |
+| Codex | PASS | PASS | PASS (separate canary) | FAIL | PASS |
+| ACPX Claude | PASS | FAIL | FAIL | FAIL | PASS |
+| OpenCode | PASS | PASS | FAIL | PASS | PASS |
+
+OpenCode provider-second saved both the Arcade choice and the exact access grant. Gateway discovery occurred twice, but the fixture observed zero HubSpot calls. The third run reached the existing deadline without a final answer. The facade was dropping canonical tool events, so retained outer logs cannot establish the exact tool-rejection cause. This is a real incomplete workflow; do not infer its cause from the model's self-diagnosis or treat a larger timeout as a fix.
+
+The final ledgers contain **31 actual runs: 27 succeeded, two failed, two cancelled during cleanup**. Earlier polling counted 30; the final Claude service-approve ledger adds a late continuation absent from its workflow snapshot. Its API snapshot has that run queued, and its final ledger records start and cancellation. OpenCode's third run is running in the failure snapshot and cancelled in the final ledger. Preserve these capture-time differences. All result/API/final-ledger run-ID sets agree; Claude service-approve's earlier workflow run set does not. All fifteen cleanup and 1,000-cent company/agent readbacks pass, and all attempts are first attempts with no harness retries. The independent local audit retains 279 evidence-file hashes, source/suite/model/attempt identities and original grades. The [remaining campaign's original public report](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-37576261807-1/index.html) is accessible (HTTP 200).
+
+Recorded LLM subtotal for the corrected fifteen cells is **$0.04553787**, with incomplete token/cost coverage. Only OpenCode reports positive amounts. Codex/Claude zeros have unknown billing type, invoices are unknown, and local/hosted runtime is unmetered. Count the cancelled continuations as actual executions; do not describe zero reports as free.
+
+The next source correction admits only Claude's authenticated registered-copy path rotation while preserving prompt/custom-entry bytes, content identities, model, permissions, session and lifecycle guards. TypeScript/Rust shared fixtures bind the exact canonical asset suffix. It rejects stale paths and changed custom text instead of replacing arbitrary path strings. Cursor's separate authenticated run-grant policy is unchanged.
+
+Completion feedback rejects a duplicate human-approval request when a response-wake result references this exact run/agent/task's tool-action card. A resolved reference plus a repeated human approval request is rejected when no different pending interaction or approval exists. General evidence of a completed action does not prevent a valid wait on a new question; waiting without any real pending condition still fails. Unrelated reviews and other runs' cards are not silently dismissed. The evaluator waits for the specifically recorded executed-action continuation within its existing deadline; a consumed response followed by another blocker still fails. No expected outcome, service-call limit, approval requirement, overall deadline, automatic retry policy or paid prompt is relaxed.
+
+Provider-free regression evidence: the original Claude reattachment error and duplicate approval acceptance both reproduce before their fixes. Nine Rust attachment checks (including cross-language suffix parity), 127 ACPX runtime/adapter checks, 33 completion/control-plane tests, 1,802 evaluator support tests plus 128 Node tests pass; one support skip is intentional. New live qualification is still required for these source changes. Recorded zero costs do not establish free calls or complete billing; runtime and actual invoices remain unknown.
+
+The OpenCode repair forwards bounded tool start/progress/completion events through the existing provider facade, retaining the actual execution-part identity, tool name, status and provider-visible result. It does not invent a host-call-ID join, expose tool arguments, or change the model prompt, permissions, tool catalog, timeouts or grading. A real bundled-proxy regression emits an invalid-tool failure: the old forwarding path drops all three events, and the repaired path retains all three. Runnerd normalizes builtin tool activity and preserves the error while redacting secret patterns. The output digest describes the bounded forwarded result, not an unretained full provider payload. This closes an evidence gap; it does not establish the old OpenCode failure's cause or claim its behavior fixed.
+
+New local verification also passes repository typecheck and build, nine continuation deadline tests, 59 OpenCode driver/proxy checks and the focused Rust tool-error/redaction check. The earlier interrupted full repository suite remains incomplete; current-source full CI and live canaries remain required. The next paid selection is bounded to Claude provider-decline (restart repair), Codex service-approve (duplicate approval repair), and OpenCode provider-second (one diagnostic attempt with repaired evidence). Other failed cells wait for usable canary evidence. Preserve all old outcomes, frozen aliases and costs.
+
+
+## Bounded continuation canaries and retained-evidence correction
+
+[Campaign 37581023494](https://github.com/paperclipai/paperclip/actions/runs/37581023494), on measured source `a704a0b9128ab54c1707c1a7ce04c6f969d3a8cb` and trusted master workflow `03cf6a6ecb0caf5e6f9c4e6af87dc723e5e3bca2`, completed **2 PASS / 1 FAIL** on the first and only attempts. Its [original public report](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-37581023494-1/index.html) is accessible (HTTP 200). Suite hash `246bcce46091a96be43340213467adc4412f1031836191fc224158322ebff576`; definition digest `7f0b96fd202e68170e30acc10221c6fe012413adb33f932f1a845b13b8109e4c`.
+
+- **Codex service-approve: PASS**, 17/17 checks. Two succeeded runs, exactly one approved service call, a saved briefing with both returned titles and the actual verification code, no extra pending approval.
+- **OpenCode provider-second: PASS**, 17/17 checks. Three succeeded runs, saved Arcade choice, separate accepted access grant, exactly one `Hubspot_ListContacts`, and a run-attributed final reply containing Ada Fixture and the independently observed marker. The repaired evidence carrier does not establish why the earlier source timed out; a single later pass does not prove the old cause fixed.
+- **Claude provider-decline: original FAIL**, 18/20 checks (the explanation check and resulting workflow-completed check fail). Both actual runs succeed, including attachment after the controller restart. The saved, run-attributed reply states that HubSpot “isn't connected” because the user selected None, and explains why contacts cannot be fetched. The old matcher omits this contraction. All decision, no-use, task completion, identity, and cleanup checks pass. This is a demonstrated grader false negative, not missing agent output.
+
+The matcher correction recognizes contracted negative connection/retrieval statements, with positive and unrelated negative controls. Replaying the exact retained Claude input against old and corrected functions reproduces the old explanation FAIL and corrected explanation PASS, with **zero provider runs**. The original live grade stays FAIL. The unchanged no-use replay uses the original retained connection-identity PASS receipt and independently counts zero tool calls in the gateway snapshot; it does not invent a new connection snapshot. No attribution, timestamp, successful-run join, decision, no-use, or marker gate is removed. This is a separately labeled grader correction, not a new live pass or a rewritten campaign.
+
+Seven actual runs are retained across these canaries, all succeeded, with no harness retry or recovery. All result, workflow, API and final-ledger run-ID sets agree. All three cleanup checks and both 1,000-cent budget readbacks pass; 59 retained evidence-file hashes are audited. Reported LLM subtotal is $0.006246754, entirely from OpenCode. Codex/Claude zero reports have unknown billing type; invoices and local/hosted runtime remain unknown.
+
+Review also exposed an overbroad resolved-approval guard: completed action A could block a valid new question B. A real database regression fails before the correction for both accepted and rejected A, then passes after narrowing the check. The stale-wait and duplicate-approval regressions remain passing. The formatting-only follow-up `cac06f9259daee24beeee7d6b65bbc7c39ca82dd` changes one Rust regression test (wrapping and a trailing argument comma); it is distinct from the measured source. The subsequent guard and matcher corrections are also not relabeled as the frozen canary source.
+
+Current local validation: seven completion-feedback database checks, 1,805 evaluator support checks plus 128 Node checks (one intentional support skip), and repository/evaluator typechecks pass. Repository build and fresh-head CI/review remain separate readiness gates. The only remaining authorized paid selection is the two previously held Claude cases, provider-second and service-approve, on a newly frozen corrected source. Instruction reductions remain held pending a usable, consistently measured baseline.
diff --git a/doc/plans/2026-10-07-personal-primary-agent.md b/doc/plans/2026-10-07-personal-primary-agent.md
new file mode 100644
index 00000000000..9ce1100de55
--- /dev/null
+++ b/doc/plans/2026-10-07-personal-primary-agent.md
@@ -0,0 +1,180 @@
+# Personal primary agent
+
+## Current boundary
+
+The user approved the revised Storybook design on 2026-10-07 and requested full
+implementation plus acceptance testing in a real isolated test drive. This branch
+now includes persistence, API wiring, and production defaults.
+
+- Branch: `codex/personal-primary-agent-storybook`.
+- Preview: http://localhost:6017/?path=/story/primary-agent-00-review-guide--start-here
+- Source: `ui/storybook/stories/primary-agent/` (one feature folder).
+- Shared presentation: `ui/src/components/primary-agent/PrimaryAgentPresentation.tsx`.
+- Stories keep simulated state as the approved reference. The application now
+ mounts a separate provider backed by a user/company preference endpoint.
+- Delivery includes real test-drive acceptance on desktop/mobile and required
+ repository checks. After reviewing the working feature, the user requested a
+ pull request with passing checks and merge into master.
+
+## Agreed product contract
+
+Each person has one primary agent per company, marked with an accessible
+"My primary agent" crown on the profile and agent list. Neither the Agents
+sidebar nor the Chat sidebar shows a crown. Different people can choose different agents; the
+preference will persist across devices. Crowning does not change roles,
+reporting lines, permissions, tasks, routines, or shared Board Operations.
+
+- The first human-attributed creation silently initializes the primary, including
+ onboarding. Later creations, system provisioning, and agent-authored hires do
+ not replace or establish a person's preference.
+- Tasks preserve explicit assignments and restored drafts, then prefer a recent
+ eligible assignee, then the primary, then the existing fallback.
+- Chat reopens a valid recent conversation, otherwise the primary's conversation,
+ otherwise its existing chooser. Opening Chat does not start execution.
+- The individual agent page offers Set as my primary beneath the agent details.
+ Kebab menus have no primary action, and there is no explicit removal option.
+ Standalone component examples do not offer this action. The current primary
+ shows its crown with no redundant set action. When a primary already exists,
+ switching requires a modal with the two agents' avatars and an arrow above.
+ The incoming primary has an outlined avatar and a crown beside its name:
+ "This will make [new name] your primary agent, do you want to do this?"
+ Cancel leaves the current primary unchanged. When none exists,
+ choosing one applies immediately without the modal. Stars remain independent.
+ Failures roll back and offer an actionable retry. These review decisions
+ supersede the original menu, removal, and immediate-switching design.
+- The primary stays first in the Agents sidebar, even when idle; other ordering
+ is preserved and the primary appears only once in that section.
+- Pausing and errors retain the crown and existing execution restrictions.
+ Leaving or terminating clears it without resetting initialization. Crowning a
+ previously left agent rejoins it under existing membership rules.
+
+## Review coverage and implementation notes
+
+Stories use the actual streamlined and classic Layout components, roster/profile
+pages, composer, Chat pages/navigation, existing menus, and shared crown components.
+Fixtures include idle/active, first-created result, absent/cleared/unavailable,
+paused/error, independent stars, long names, loading, failed mutations, desktop,
+mobile, and light theme. Interactive stories cover setting from the profile,
+absence of primary menu actions, leaving, starring, rollback/retry, and opening
+a task or Chat after switching, cancellation, and first choice without confirmation.
+
+The streamlined Sidebar now includes the reviewed Agents section by default.
+Stories can still supply it through Layout's existing sidebar slot for review.
+The icon rail is retired in SidebarContext; collapsed coverage uses the supported
+collapsible Agents section plus the mobile drawer. No rail is reintroduced.
+
+Reloading resets the fixture preference. Task fallback is simulated through the
+existing composer's defaults/recent-assignee input. Chat entry routing and the
+first-created result are also simulations. These stories are design references,
+not evidence of authorization, persistence, concurrency, or real execution.
+
+## Verification at review handoff
+
+- UI TypeScript build (`tsc -b ui`).
+- 61 existing tests across SidebarAgents, AgentActionButtons, EntityRow, Agents,
+ and AgentOverview.
+- Token gates and palette/character synchronization checks.
+- Full static Storybook build.
+- Browser walkthroughs: switch crown and sidebar order, independent stars,
+ rollback and Retry, leave/rejoin, direct profile action, task assignment/draft
+ precedence, recent Chat history, Chat fallback/chooser, and mobile drawer,
+ composer, and profile at 390 by 844.
+
+## Implementation delivered
+
+1. Added a company/user preference with nullable primaryAgentId and initialization
+ state; enforce uniqueness. Synchronize db/shared/server/ui contracts.
+2. Added authenticated GET/PUT `/api/companies/:companyId/primary-agent/me`, deriving
+ the user from authentication, enforcing company access and agent visibility,
+ rejecting agent actors, and recording mutation activity.
+3. Initialized transactionally during human-attributed creation. Concurrent
+ creations establish one primary and cannot overwrite an explicit choice or
+ lifecycle-cleared preference. Backfill from the earliest attributable human creation;
+ if that original agent is gone or terminated, leave the crown empty. Unknown
+ ownership remains unset.
+4. Added lifecycle cleanup and existing membership rejoin behavior. Connected a
+ user/company-scoped query hook to the reviewed presentation and defaults.
+5. Verified concurrency, backfill, lifecycle cleanup, user/company isolation
+ (including local trusted mode), drafts, recent selections, unavailable agents,
+ and real desktop/mobile task and Chat journeys.
+
+## Real test-drive acceptance (2026-10-07)
+
+- Isolated CLI test drive: `/tmp/paperclip-primary-agent-test-drive`, company
+ **Primary Agent Test Drive**, prefix `PRI`, at http://localhost:3104.
+- Maia was crowned automatically through the real creation API. Creating Alex
+ preserved Maia. The simplified creation wizard's model-connection step rejected
+ the disposable placeholder credential; Alex was created through the real API
+ with the existing local Codex login instead. No creation-wizard success is claimed.
+- Desktop: profile-only setting, cancel/confirm, persistence after reload, roster
+ crown, sidebar ordering, absent sidebar crowns and menu actions, leave/clear,
+ first choice without a modal, rejoin, and paused crown retention passed.
+- Fresh browser-origin task composer selected Alex from the primary. After switching
+ to Maia, the composer preserved recent Alex and Chat reopened Alex's recent
+ conversation. An existing draft on the other origin remained intact.
+- Opening Chat used the primary with no new execution. Sending a message produced
+ **“Alex received this primary-agent chat.”** from a successful real Codex run.
+- Real task **PRI-3, Acknowledge Alex’s task receipt**, completed with
+ **“Task received by Alex”** and status `done`. The initial probe used an unsupported
+ `gpt-5.4` subscription model; both agents were changed to `gpt-6.1-sol`, the successful
+ checks were repeated, and the obsolete probe task was cancelled.
+- Mobile at 390 × 844: the reviewed modal fits, confirmation switches the crown,
+ and the page has no horizontal overflow. Viewport override reset afterward.
+- Focused tests cover initialization, simultaneous creation/selection, audit order,
+ leave races, backfill, visibility boundaries, viewer self-service, auth-derived
+ user/company isolation, optimistic rollback/retry, session retry, task defaults,
+ and recent Chat precedence.
+
+## Verification results
+
+- Repository typecheck passed with `pnpm -r --workspace-concurrency=1 typecheck`.
+ Final server/UI typechecks also passed after the last feature refinements.
+- `pnpm build`, `pnpm check:token-gates`, and `git diff --check` passed.
+- Entire UI suite: **698 files, 7,760 tests passed**.
+- Entire DB suite, run serially: **47 files, 166 tests passed**. Parallel attempts
+ failed to initialize embedded PostgreSQL before migrations; the serial run
+ resolves that migration-verification concern.
+- Focused primary/default/provider checks passed: **106 tests** across final
+ runs (9 database/API tests, plus provider, composer, and Chat tests).
+- Existing onboarding, hire idempotency, resource membership, and company import
+ suites passed: **125 tests**. Legacy approval plus terminalization checks:
+ **15 tests passed**. Import/approval expectations now assert original creator
+ attribution rather than dropping the new creation option.
+- **Repository-wide tests are not green.** `pnpm test:run` was stopped after
+ roughly an hour with failures, rather than being represented as a complete pass.
+ `adapter-cost-failure-paths.test.ts` still has OpenCode timeout failures in a
+ fresh rerun. `workspace-git-snapshot-streaming.test.ts` timed out after 300 seconds.
+ Heartbeat database-setup timeouts passed isolated reruns. The broad run began
+ before the final edits and also reported primary/approval failures; those suites
+ passed in fresh processes against final source. Later broad-run groups did not
+ complete. These local failures remain disclosed; PR checks must pass on the
+ current head before merge.
+
+The final-code test drive remains running at http://localhost:3104 with **Alex**
+primary and **Maia's profile** open. Choose **Set as my primary**, confirm, and
+reload to try persistence. New Task and Chat retain recent Alex choices by design;
+the primary is their fallback when no eligible recent choice or draft exists.
+
+## Pull request verification
+
+- PR: https://github.com/paperclipai/paperclip/pull/15470. The user authorized
+ passing PR checks and merging into master.
+- The rebased branch passes repository typecheck and build, token gates, and
+ 114 focused tests. Migration replay now runs twice without replacing choices.
+- The earlier OpenCode timeouts pass all 31 tests with an isolated XDG config
+ directory; the local config copy caused the delay. The large Git streaming test
+ also passes when run alone (296 seconds).
+- Initial CI identified stale creation-option assertions and app remounts on
+ company changes. Preserve mounted app children and bind each pending mutation
+ to its original user/company. Refresh membership caches for primary changes
+ received from other devices.
+- Security review identified agent mappings in company activity. Preference
+ events now record only the affected user and action, with no selected agent IDs.
+ An authenticated cross-user activity endpoint test covers this boundary.
+- Review fixes pass 96 database/permission-route tests and 127 provider,
+ live-update, and skill-route tests. Final merge requires fresh-head CI and review.
+- The affected browser suites pass all 10 tests, including onboarding, archived
+ company navigation, Chat fallback without execution, and slow-CPU reloads.
+- The second PR run passed 52 checks and Greptile 5/5, with one OpenAPI inventory
+ failure. Both personal endpoints now have board-only request/response contracts
+ in OpenAPI. Its 14 tests and the remaining 28 tests in that shard pass locally.
diff --git a/doc/run-log-events.md b/doc/run-log-events.md
index ed8f723652c..10557d8b6bb 100644
--- a/doc/run-log-events.md
+++ b/doc/run-log-events.md
@@ -280,6 +280,14 @@ warnings and errors remain visible.
Recovery lifecycle events retain the original structured failure code, retry attempt, next retry time, and predecessor/successor identifiers. Durable status delivery uses an idempotency marker; delivery grants no provider authority. Failed publication is retried without repeating provider work. These records are not first-party Telemetry.
+An unstarted legacy conversation retry waiting for execution cleanup retains
+`resultJson.executionWait` with the issue, blocking run, and
+`execution_owner_active` cause. A local lifecycle event records the wait and the
+unchanged scheduled retry attempt once per blocking run. Repeated scheduler
+checks update the same retry row without repeating that event. Promotion removes
+this ownership-wait marker after cleanup; other execution holds retain their
+existing dispatch gates.
+
If execution-continuation setup finds that a task no longer exists, is closed,
or its owner changed, the existing cancellation settlement records
`continuation_task_ownership_changed`. The run and wake request become cancelled
@@ -335,6 +343,12 @@ the enclosing workspace task. The original error and restore safety policy are
unchanged. These lines stay in the instance run log and its configured durable
storage, and are not new first-party telemetry events.
+Native sandbox `environmentSyncOut` errors preserve allowlisted error codes and
+bounded HTTP/exit statuses across worker RPC for this diagnostic line. The host
+revalidates the envelope and keeps the original failure and recovery policy.
+Provider messages, paths, response bodies, credentials, and arbitrary error data
+are not copied into the new envelope. Older workers can still report `unknown`.
+
The optional `step` identifies the failed restore operation. For
`phase=workspace` and `step=git_integration`, `gitCommand` identifies one fixed
command family (`rev_parse`, `symbolic_ref`, `merge_base`, `merge_tree`,
diff --git a/doc/runner-api-tools.md b/doc/runner-api-tools.md
index 62451ba6b2c..a8dd849d49e 100644
--- a/doc/runner-api-tools.md
+++ b/doc/runner-api-tools.md
@@ -1,7 +1,10 @@
# Runner API escape hatch
`search_api` and `call_api` extend the native runner when an available dedicated
-operation cannot express the requested work. Existing tools remain preferred;
+operation cannot express the requested work. Use `set_task_monitor` to schedule or clear a one-shot task check; after confirming
+the receipt, finish with `yielded` and `continuation.kind: "monitor"` to await that
+task’s timer. `call_api` still rejects monitor/execution-policy lifecycle writes.
+Existing tools remain preferred;
agents do not have to search before using them. Only two tool definitions are
advertised. The API catalog is returned on demand, never injected into the
initial prompt.
diff --git a/doc/workspace-restore-locks.md b/doc/workspace-restore-locks.md
index 60a00fc0b7c..62acf88b793 100644
--- a/doc/workspace-restore-locks.md
+++ b/doc/workspace-restore-locks.md
@@ -54,3 +54,46 @@ is safe to remove from its age, an absent PID, or a successful task response.
This change prevents new orphaned ownership. It cannot recover file changes
that an earlier failed collection discarded.
+
+## Required remote restore failures
+
+When a legacy sandbox run cannot copy required workspace files back, the server
+keeps the original allocation for repair. It writes the failed run, the exact
+lease retention intent, and a board-owned repair hold in one transaction. The
+hold survives reassignment and conversation resets and coexists with newer
+recovery incidents; it never supersedes them.
+Cleanup stops that allocation and verifies its provider receipt. It does not
+use ordinary ephemeral destruction or return the source to warm reuse. Stop
+failures use the existing cleanup retry and backoff policy.
+
+The retained source uses `retain_on_failure`. A stopped source can still incur
+provider storage charges. It stays available until an operator recovers or
+explicitly discards it; elapsed time never proves that its files were copied.
+The task's `GET /api/issues/:id/recovery-actions` response lists these repair holds
+alongside any newer active incident, including the original lease IDs. Inspect
+those exact leases through `GET /api/environment-leases/:leaseId`,
+confirm that cleanup stopped them, recover the missing files, and record
+`workspaceRepairEvidence` through the existing recovery-action resolution API.
+Send `POST /api/issues/:id/recovery-actions/resolve` with the exact recovery action
+ID, `outcome: "restored"`, the task's **unchanged**
+`sourceIssueStatus`, and `executionReconciliation` for the recorded source run.
+Only a board operator can record this repair. It preserves the current task
+owner, conversation generation, status, and execution locks. It does not queue a
+continuation or replay the stopped run; after repair, any new work still follows
+the normal admission rules.
+The board currently shows repair guidance and an Inspect run link, not a repair
+form. Recording the decision is an operator API/runbook workflow; the recovery
+API response contains the exact action and lease IDs. Provider access may require
+an instance administrator or Cloud support. This change does not add a repair UI.
+Then use the provider's operator console to remove that exact retained
+allocation when its files are no longer needed. Verify its immutable provider
+allocation ID against the recorded lease before removal. The ordinary reusable
+sandbox cleanup does not select `retain_on_failure` sources; do not use
+environment deletion as proof that this allocation was removed. Keep the
+environment and its provider credentials until recovery is complete. Recording a
+repair decision does not automatically destroy it.
+
+A new message, Retry, or `/new` cannot clear this workspace repair hold. Ordinary
+local lock-timeout retries and runs without a required remote copy-back failure
+keep their existing policy. This change preserves future failures; it cannot
+recover files from an allocation that was already destroyed.
diff --git a/packages/adapter-utils/src/execution-target-sandbox.test.ts b/packages/adapter-utils/src/execution-target-sandbox.test.ts
index 51ab309890f..0655c9f0b26 100644
--- a/packages/adapter-utils/src/execution-target-sandbox.test.ts
+++ b/packages/adapter-utils/src/execution-target-sandbox.test.ts
@@ -1107,6 +1107,7 @@ describe("sandbox adapter execution targets", () => {
// ACP keeps stdin open while it waits for a handshake. A remote child can
// exit before replying; that must close the proxy and fail the handshake.
const output = "final output\n".repeat(16_384);
+ const logs: string[] = [];
const bridge = await startAdapterExecutionTargetProcessSessionBridge({
runId: "run-open-stdin",
target: {
@@ -1124,11 +1125,16 @@ describe("sandbox adapter execution targets", () => {
env: {},
timeoutSec: 10,
streamOutputViaSession,
+ onLog: async (stream, chunk) => { if (stream === "stderr") logs.push(chunk); },
});
expect(bridge).not.toBeNull();
try {
const result = await runProxyWithInput(bridge!.agentCommand, "initialize\n", true);
expect(result.code).toBe(exitCode ?? 1);
+ const terminal = logs.filter((line) => line.includes("ACP process session terminal:"));
+ expect(terminal).toEqual([
+ `[paperclip] ACP process session terminal: source=remote_event outcome=${exitCode === null ? "error" : "exit"} exitCode=${exitCode ?? "unknown"} signal=unknown.\n`,
+ ]);
if (exitCode === null) {
expect(result.stdout).toBe("");
expect(result.stderr).toContain("ENOENT");
@@ -1141,6 +1147,194 @@ describe("sandbox adapter execution targets", () => {
}
}, 15_000);
+ it("flushes remote errors under backpressure and retains only bounded terminal evidence", async () => {
+ const rootDir = await mkdtemp(path.join(os.tmpdir(), "paperclip-terminal-flush-"));
+ cleanupDirs.push(rootDir);
+ const delegate = createLocalSandboxRunner();
+ const logs: string[] = [];
+ let emit!: (frame: string) => Promise;
+ let complete!: () => void;
+ let failInput!: (error: Error) => void;
+ let inputStarted = false;
+ const inputFailure = new Promise((_resolve, reject) => { failInput = reject; });
+ void inputFailure.catch(() => {});
+ const commandComplete = new Promise((resolve) => { complete = resolve; });
+ const frame = {
+ type: "error", message: "synthetic-private-detail".repeat(200_000),
+ code: 1e100, signal: "untrusted-private-signal",
+ };
+ const bridge = await startAdapterExecutionTargetProcessSessionBridge({
+ runId: "terminal-flush", adapterKey: "acpx", runtimeRootDir: rootDir,
+ target: {
+ kind: "remote", transport: "sandbox", remoteCwd: rootDir,
+ runner: { execute: async (input) => {
+ if (!input.useSession) {
+ const script = input.args?.[1] ?? "";
+ if (script.startsWith("mkdir -p") && script.includes("/stdin/000000000001.json")) {
+ inputStarted = true;
+ return inputFailure;
+ }
+ return delegate.execute(input);
+ }
+ emit = async (text) => { await input.onLog?.("stdout", text); };
+ await commandComplete;
+ return { exitCode: 1, stdout: "", stderr: "", timedOut: false, signal: null, pid: null, startedAt: null };
+ } },
+ },
+ command: "cat", args: [], cwd: rootDir, env: {}, streamOutputViaSession: true,
+ onLog: async (stream, chunk) => { if (stream === "stderr") logs.push(chunk); },
+ });
+ let peer: net.Socket | undefined;
+ try {
+ const source = await readFile(bridge!.agentCommand, "utf8");
+ const port = Number(/port: (\d+)/.exec(source)![1]);
+ const token = JSON.parse(/const token = (".*?");/.exec(source)![1]) as string;
+ peer = net.createConnection({ host: "127.0.0.1", port });
+ peer.on("error", () => {});
+ peer.setEncoding("utf8");
+ let output = "";
+ peer.on("data", (chunk) => { output += chunk; });
+ const closed = new Promise((resolve) => peer!.once("close", resolve));
+ await new Promise((resolve) => peer!.once("connect", resolve));
+ peer.write(JSON.stringify({ token, type: "hello" }) + "\n");
+ // Confirm authentication by receiving a marker before applying backpressure.
+ await emit(JSON.stringify({ type: "data", stream: "stdout", data: "" }) + "\n");
+ await waitForCondition(() => output.length > 0, "Missing authenticated marker.");
+ output = "";
+ peer.write(JSON.stringify({ token, type: "stdin", data: "aW5wdXQ=" }) + "\n");
+ await waitForCondition(() => inputStarted, "Input write did not start.");
+ peer.pause();
+ // The real wrapper emits error then exit when a child fails to spawn.
+ // A later frame must not write after end() and abort the pending error.
+ await emit([
+ frame,
+ { type: "exit", code: 1 },
+ { type: "data", stream: "stdout", data: "bGF0ZQ==" },
+ { type: "shutdownAck" },
+ ].map((event) => JSON.stringify(event) + "\n").join(""));
+ // The reverse race matters too: an already-accepted input write can
+ // reject after the remote error started draining. Its end(data) must
+ // not abort or replace the first terminal frame.
+ failInput(new Error("synthetic-private-input-detail"));
+ await waitForCondition(
+ () => logs.some((line) => line.includes("ACP process session input delivery failed.")),
+ "Input failure was not handled.",
+ );
+ peer.resume();
+ await closed;
+ expect(JSON.parse(output)).toEqual(frame);
+ expect(logs.filter((line) => line.includes("ACP process session terminal:"))).toEqual([
+ "[paperclip] ACP process session terminal: source=remote_event outcome=error exitCode=unknown signal=unknown.\n",
+ ]);
+ } finally {
+ failInput(new Error("test cleanup"));
+ complete();
+ peer?.destroy();
+ await bridge?.stop();
+ }
+ }, 15_000);
+
+ it("reports a streamed transport failure even when diagnostic persistence stalls", async () => {
+ const rootDir = await mkdtemp(path.join(os.tmpdir(), "paperclip-terminal-stream-"));
+ cleanupDirs.push(rootDir);
+ const delegate = createLocalSandboxRunner();
+ const logs: string[] = [];
+ let releaseLog!: () => void;
+ const stalledLog = new Promise((resolve) => { releaseLog = resolve; });
+ const bridge = await startAdapterExecutionTargetProcessSessionBridge({
+ runId: "terminal-stream", adapterKey: "acpx", runtimeRootDir: rootDir,
+ target: {
+ kind: "remote", transport: "sandbox", remoteCwd: rootDir,
+ runner: { execute: async (input) => {
+ if (input.useSession) throw new Error("synthetic-private-provider-detail");
+ return delegate.execute(input);
+ } },
+ },
+ command: "cat", args: [], cwd: rootDir, env: {}, streamOutputViaSession: true,
+ onLog: async (stream, chunk) => {
+ if (stream === "stderr") { logs.push(chunk); await stalledLog; }
+ },
+ });
+ try {
+ const result = await runProxyWithInput(bridge!.agentCommand, "", true);
+ expect(result.code).toBe(1);
+ expect(logs).toEqual([
+ "[paperclip] ACP process session terminal: source=output_stream outcome=error exitCode=unknown signal=unknown.\n",
+ ]);
+ } finally {
+ releaseLog();
+ await bridge?.stop();
+ }
+ }, 10_000);
+
+ it("closes a failed output poll without waiting for the run log", async () => {
+ const rootDir = await mkdtemp(path.join(os.tmpdir(), "paperclip-terminal-poll-"));
+ cleanupDirs.push(rootDir);
+ const delegate = createLocalSandboxRunner();
+ const logs: string[] = [];
+ let releaseLog!: () => void;
+ const stalledLog = new Promise((resolve) => { releaseLog = resolve; });
+ const bridge = await startAdapterExecutionTargetProcessSessionBridge({
+ runId: "terminal-poll", adapterKey: "acpx", runtimeRootDir: rootDir,
+ target: {
+ kind: "remote", transport: "sandbox", remoteCwd: rootDir,
+ runner: { execute: async (input) => {
+ const script = input.args?.[1] ?? "";
+ if (script.includes("/events'/*.json")) throw new Error("synthetic-private-provider-detail");
+ return delegate.execute(input);
+ } },
+ },
+ command: "cat", args: [], cwd: rootDir, env: {},
+ onLog: async (stream, chunk) => {
+ if (stream === "stderr") { logs.push(chunk); await stalledLog; }
+ },
+ });
+ try {
+ const result = await runProxyWithInput(bridge!.agentCommand, "", true);
+ expect(result.code).toBe(1);
+ expect(logs).toEqual([
+ "[paperclip] ACP process session terminal: source=output_poll outcome=error exitCode=unknown signal=unknown.\n",
+ ]);
+ } finally {
+ releaseLog();
+ await bridge?.stop();
+ }
+ }, 10_000);
+
+ it("records an unexpected authenticated proxy close once and ignores unauthenticated peers", async () => {
+ const rootDir = await mkdtemp(path.join(os.tmpdir(), "paperclip-terminal-proxy-"));
+ cleanupDirs.push(rootDir);
+ const logs: string[] = [];
+ const bridge = await startAdapterExecutionTargetProcessSessionBridge({
+ runId: "terminal-proxy", adapterKey: "acpx", runtimeRootDir: rootDir,
+ target: { kind: "remote", transport: "sandbox", remoteCwd: rootDir, runner: createLocalSandboxRunner() },
+ command: "cat", args: [], cwd: rootDir, env: {},
+ onLog: async (stream, chunk) => { if (stream === "stderr") logs.push(chunk); },
+ });
+ try {
+ const source = await readFile(bridge!.agentCommand, "utf8");
+ const port = Number(/port: (\d+)/.exec(source)![1]);
+ const token = JSON.parse(/const token = (".*?");/.exec(source)![1]) as string;
+ for (const authenticated of [false, true]) {
+ const peer = net.createConnection({ host: "127.0.0.1", port });
+ peer.on("error", () => {});
+ const closed = new Promise((resolve) => peer.once("close", resolve));
+ await new Promise((resolve) => peer.once("connect", resolve));
+ if (authenticated) peer.end(JSON.stringify({ token, type: "hello" }) + "\n");
+ else peer.end();
+ await closed;
+ if (!authenticated) expect(logs).toEqual([]);
+ }
+ await waitForCondition(() => logs.length === 1, "Missing proxy-close diagnostic.");
+ await bridge!.stop();
+ expect(logs.filter((line) => line.includes("ACP process session terminal:"))).toEqual([
+ "[paperclip] ACP process session terminal: source=proxy_close outcome=error exitCode=unknown signal=unknown.\n",
+ ]);
+ } finally {
+ await bridge?.stop();
+ }
+ }, 10_000);
+
it("buffers sandbox process session output until the local proxy connects", async () => {
const rootDir = await mkdtemp(path.join(os.tmpdir(), "paperclip-process-session-buffer-"));
cleanupDirs.push(rootDir);
diff --git a/packages/adapter-utils/src/execution-target.ts b/packages/adapter-utils/src/execution-target.ts
index aa66d00ddb8..42a05cbb895 100644
--- a/packages/adapter-utils/src/execution-target.ts
+++ b/packages/adapter-utils/src/execution-target.ts
@@ -2165,6 +2165,26 @@ export async function startAdapterExecutionTargetProcessSessionBridge(input: {
}
};
let pollTimer: NodeJS.Timeout | null = null;
+ let terminalEvidenceRecorded = false;
+ const recordTerminalEvidence = (
+ source: "remote_event" | "input_delivery" | "output_poll" | "output_stream" | "proxy_close",
+ event: { type?: string; code?: number | null; signal?: string | null },
+ ) => {
+ if (terminalEvidenceRecorded) return;
+ terminalEvidenceRecorded = true;
+ // Remote frames are untrusted. Keep the retained diagnostic bounded and
+ // independent of messages, commands, paths, payloads, and provider errors.
+ const outcome = event.type === "exit" ? "exit" : "error";
+ const code = typeof event.code === "number" && Number.isInteger(event.code)
+ && event.code >= 0 && event.code <= 255 ? event.code : "unknown";
+ const signal = typeof event.signal === "string" && [
+ "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", "SIGFPE", "SIGKILL",
+ "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", "SIGBUS", "SIGXCPU", "SIGXFSZ",
+ ].includes(event.signal) ? event.signal : "unknown";
+ logFailureWithoutWaiting(
+ `[paperclip] ACP process session terminal: source=${source} outcome=${outcome} exitCode=${code} signal=${signal}.\n`,
+ );
+ };
const pendingRemoteEvents: Array<{
type?: string;
stream?: "stdout" | "stderr";
@@ -2191,22 +2211,30 @@ export async function startAdapterExecutionTargetProcessSessionBridge(input: {
const writeRemoteEventToSocket = (event: (typeof pendingRemoteEvents)[number]) => {
if (!socket) return false;
+ // `stopping` can already be set by a terminal frame buffered before auth.
+ // Use the socket's outbound state instead: once end() has been called,
+ // another write would destroy it and truncate the frame still draining.
+ // This also covers input-delivery failure, which ends the socket directly.
+ if (socket.writableEnded || socket.destroyed) return true;
socket.write(jsonLine(event));
- if (event.type === "exit") {
+ if (event.type === "exit" || event.type === "error") {
stopping = true;
+ // Flush the terminal frame and all earlier output before closing. An
+ // immediate destroy can discard the cause and leave only connection_close.
socket.end();
- } else if (event.type === "error") {
- stopping = true;
- socket.destroy();
}
return true;
};
- const deliverRemoteEvent = (event: (typeof pendingRemoteEvents)[number]) => {
+ const deliverRemoteEvent = (
+ event: (typeof pendingRemoteEvents)[number],
+ source: "remote_event" | "output_poll" | "output_stream" = "remote_event",
+ ) => {
if (event.type === "shutdownAck") {
signalShutdownAcknowledged();
return;
}
+ if (event.type === "exit" || event.type === "error") recordTerminalEvidence(source, event);
if (socket) {
writeRemoteEventToSocket(event);
return;
@@ -2248,6 +2276,7 @@ export async function startAdapterExecutionTargetProcessSessionBridge(input: {
nextSocket.on("close", () => {
clearTimeout(authTimer);
liveSockets.delete(nextSocket);
+ if (authenticated && !stopping) recordTerminalEvidence("proxy_close", { type: "error" });
});
nextSocket.on("data", (chunk) => {
connectionBuffer += chunk;
@@ -2304,11 +2333,17 @@ export async function startAdapterExecutionTargetProcessSessionBridge(input: {
} catch {
stdinDeliveryFailed = true;
stopping = true;
+ recordTerminalEvidence("input_delivery", { type: "error" });
const message = "ACP process session input delivery failed.";
// Flush the diagnostic before closing; destroy() can discard it
// and leave only ACP's generic connection_close error. Do not
// expose provider error text, which may contain a command payload.
- nextSocket.end(jsonLine({ type: "error", message }));
+ // A remote terminal frame may already be draining while this
+ // accepted stdin write fails. end(data) would write after end
+ // and discard that first failure just like socket.write(data).
+ if (!nextSocket.writableEnded && !nextSocket.destroyed) {
+ nextSocket.end(jsonLine({ type: "error", message }));
+ }
// stop() awaits this input chain before sending shutdown. Run-log
// persistence must not hold teardown open when it stalls or fails.
logFailureWithoutWaiting(`[paperclip] ${message}\n`);
@@ -2340,8 +2375,8 @@ export async function startAdapterExecutionTargetProcessSessionBridge(input: {
}
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
- await onLog("stderr", `[paperclip] ACP process session bridge poll failed: ${message}\n`);
- deliverRemoteEvent({ type: "error", message });
+ // A stuck log sink must not strand the adapter waiting for this failure.
+ deliverRemoteEvent({ type: "error", message }, "output_poll");
return;
} finally {
if (!stopping) {
@@ -2467,14 +2502,15 @@ export async function startAdapterExecutionTargetProcessSessionBridge(input: {
deliverRemoteEvent({
type: "exit",
code: typeof result.exitCode === "number" ? result.exitCode : null,
- });
+ signal: result.signal,
+ }, "output_stream");
}
} catch (error) {
if (!stopping) {
deliverRemoteEvent({
type: "error",
message: error instanceof Error ? error.message : String(error),
- });
+ }, "output_stream");
}
}
})();
diff --git a/packages/adapters/claude-local/src/server/execute.remote.test.ts b/packages/adapters/claude-local/src/server/execute.remote.test.ts
index 9ccc3ef77ea..cbb6ed55013 100644
--- a/packages/adapters/claude-local/src/server/execute.remote.test.ts
+++ b/packages/adapters/claude-local/src/server/execute.remote.test.ts
@@ -285,6 +285,34 @@ describe("claude remote execution", () => {
expect(call?.[2]).not.toContain("--resume");
});
+ it("explains a remote-to-local session reset even when the cwd matches", async () => {
+ const rootDir = await mkdtemp(path.join(os.tmpdir(), "paperclip-claude-local-reset-"));
+ cleanupDirs.push(rootDir);
+ vi.stubEnv("PAPERCLIP_HOME", rootDir);
+ const onLog = vi.fn(async () => {});
+
+ await execute({
+ runId: "run-local-reset",
+ agent: { id: "agent-1", companyId: "company-1", name: "Claude Coder", adapterType: "claude_local", adapterConfig: {} },
+ runtime: {
+ sessionId: "12345678-1234-4abc-9def-123456789012",
+ sessionParams: {
+ cwd: rootDir,
+ remoteExecution: { transport: "ssh", host: "remote.test", port: 22, username: "fixture", remoteCwd: rootDir },
+ },
+ sessionDisplayId: null,
+ taskKey: null,
+ },
+ config: { engine: "cli", command: "claude", cwd: rootDir, paperclipRuntimeSkills: [] },
+ context: {},
+ onLog,
+ });
+
+ expect(runChildProcess.mock.calls[0]?.[2]).not.toContain("--resume");
+ expect(onLog).toHaveBeenCalledWith("stdout", expect.stringContaining("does not match the current execution target"));
+ expect(onLog).not.toHaveBeenCalledWith("stdout", expect.stringContaining("was saved for cwd"));
+ });
+
it("resumes saved Claude sessions for remote SSH execution when the remote identity matches", async () => {
const rootDir = await mkdtemp(path.join(os.tmpdir(), "paperclip-claude-remote-resume-match-"));
cleanupDirs.push(rootDir);
diff --git a/packages/adapters/claude-local/src/server/execute.ts b/packages/adapters/claude-local/src/server/execute.ts
index ee1f3e35a76..de03c588c03 100644
--- a/packages/adapters/claude-local/src/server/execute.ts
+++ b/packages/adapters/claude-local/src/server/execute.ts
@@ -499,19 +499,21 @@ export async function execute(ctx: AdapterExecutionContext): Promise 0 &&
isValidUuid &&
hasMatchingPromptBundle &&
// Each CLI invocation loads --mcp-config, including --resume invocations.
// Refreshing tools does not invalidate the saved conversation.
- claudeSessionCwdMatchesExecutionTarget({
- runtimeSessionCwd,
- effectiveExecutionCwd,
- executionTargetIsRemote,
- }) &&
- adapterExecutionTargetSessionMatches(runtimeRemoteExecution, runtimeExecutionTarget);
+ hasMatchingSessionCwd &&
+ hasMatchingExecutionTarget;
const sessionId = canResumeSession ? runtimeSessionId : null;
if (runtimeSessionId && !isValidUuid) {
await onLog(
@@ -798,26 +802,20 @@ export async function execute(ctx: AdapterExecutionContext): Promise 0 &&
- path.resolve(runtimeSessionCwd) !== path.resolve(effectiveExecutionCwd)
+ !hasMatchingSessionCwd
) {
- await onLog(
- "stdout",
- `[paperclip] Claude session "${runtimeSessionId}" does not match the current remote execution identity and will not be resumed in "${effectiveExecutionCwd}". Starting a fresh remote session.\n`,
- );
- } else if (runtimeSessionId && isValidUuid && !canResumeSession) {
await onLog(
"stdout",
`[paperclip] Claude session "${runtimeSessionId}" was saved for cwd "${runtimeSessionCwd}" and will not be resumed in "${effectiveExecutionCwd}".\n`,
@@ -916,6 +914,7 @@ export async function execute(ctx: AdapterExecutionContext): Promise 0) {
diff --git a/packages/adapters/codex-local/src/index.test.ts b/packages/adapters/codex-local/src/index.test.ts
index 5269c9b0174..fcb53825d60 100644
--- a/packages/adapters/codex-local/src/index.test.ts
+++ b/packages/adapters/codex-local/src/index.test.ts
@@ -1,12 +1,58 @@
import { describe, expect, it } from "vitest";
import {
+ CODEX_CHATGPT_MODEL_REJECTION_RE,
+ codexCliVersionAtLeast,
codexLocalReasoningEffortsForModel,
DEFAULT_CODEX_LOCAL_MODEL,
isCodexLocalFastModeSupported,
+ minimumCodexCliVersionForModel,
models,
normalizeCodexModel,
+ parseCodexCliVersionOutput,
} from "./index.js";
+describe("codex model CLI floors", () => {
+ it("records the oldest Codex CLI verified to run each gated model with ChatGPT sign-in", () => {
+ expect(minimumCodexCliVersionForModel("gpt-6.1-sol")).toBe("0.159.0");
+ expect(minimumCodexCliVersionForModel(" gpt-6.1-sol ")).toBe("0.159.0");
+ expect(minimumCodexCliVersionForModel("gpt-6-sol")).toBe("0.157.0");
+ expect(minimumCodexCliVersionForModel("gpt-6-luna")).toBe("0.157.0");
+ });
+
+ it.each([DEFAULT_CODEX_LOCAL_MODEL, "gpt-5.6", "gpt-6-astra", "gpt-5.5", "custom-model", "", null, undefined])(
+ "has no floor for %s so callers skip the version probe", (model) => {
+ expect(minimumCodexCliVersionForModel(model)).toBeNull();
+ },
+ );
+
+ it("compares stable versions numerically and rejects prerelease or ambiguous input", () => {
+ expect(codexCliVersionAtLeast("0.159.0", "0.159.0")).toBe(true);
+ expect(codexCliVersionAtLeast("0.160.1", "0.159.0")).toBe(true);
+ expect(codexCliVersionAtLeast("1.0.0", "0.159.0")).toBe(true);
+ expect(codexCliVersionAtLeast("0.156.1", "0.159.0")).toBe(false);
+ expect(codexCliVersionAtLeast("0.16.0", "0.159.0")).toBe(false);
+ expect(codexCliVersionAtLeast("0.160.0-alpha.1", "0.159.0")).toBe(false);
+ expect(codexCliVersionAtLeast("", "0.159.0")).toBe(false);
+ });
+
+ it("parses only a single stable `codex-cli x.y.z` line from --version output", () => {
+ expect(parseCodexCliVersionOutput("codex-cli 0.160.0\n")).toBe("0.160.0");
+ expect(parseCodexCliVersionOutput("WARNING: PATH unchanged\r\ncodex-cli 0.156.0\r\n")).toBe("0.156.0");
+ expect(parseCodexCliVersionOutput("codex-cli 0.162.0-alpha.17")).toBeNull();
+ expect(parseCodexCliVersionOutput("codex 0.160.0")).toBeNull();
+ expect(parseCodexCliVersionOutput("codex-cli 0.149.0\ncodex-cli 0.160.0")).toBeNull();
+ expect(parseCodexCliVersionOutput("")).toBeNull();
+ });
+
+ it("matches the backend's ChatGPT model rejection and captures the model", () => {
+ const match = CODEX_CHATGPT_MODEL_REJECTION_RE.exec(
+ "{\"type\":\"error\",\"status\":400,\"error\":{\"type\":\"invalid_request_error\",\"message\":\"The 'gpt-6.1-sol' model is not supported when using Codex with a ChatGPT account.\"}}",
+ );
+ expect(match?.[1]).toBe("gpt-6.1-sol");
+ expect(CODEX_CHATGPT_MODEL_REJECTION_RE.test("Model metadata for `gpt-6.1-sol` not found")).toBe(false);
+ });
+});
+
describe("codex local adapter metadata", () => {
it("advertises current Codex-capable OpenAI models without changing the default", () => {
const modelIds = models.map((model) => model.id);
diff --git a/packages/adapters/codex-local/src/index.ts b/packages/adapters/codex-local/src/index.ts
index f1036a67828..0ffe729b928 100644
--- a/packages/adapters/codex-local/src/index.ts
+++ b/packages/adapters/codex-local/src/index.ts
@@ -85,6 +85,60 @@ export function codexLocalReasoningEffortsForModel(
}
}
+// The Codex backend accepts a model for ChatGPT sign-in only from a client that identifies as a
+// recent enough CLI (the request carries the CLI version). An older `codex` fails every turn with
+// "The '' model is not supported when using Codex with a ChatGPT account.", which reads
+// like an account problem when it is really a stale install, typically a sandbox image baked
+// before the catalog gained the model. Record the oldest stable release verified to work so the
+// Test and the remote runner can name the actual gap. Omit models with no verified floor; the
+// install pin in the runner and images is always at or above every floor listed here.
+const CODEX_LOCAL_MODEL_MINIMUM_CLI_VERSIONS: Readonly> = {
+ // 0.156.1 and older are rejected (openai/codex#49396); 0.159.0 and 0.159.2 are accepted
+ // (openai/codex#49464). No stable release between those was verified either way.
+ "gpt-6.1-sol": "0.159.0",
+ // Codex 0.157.0 release notes: "Add GPT-6 Sol and Luna to the model catalog".
+ "gpt-6-sol": "0.157.0",
+ "gpt-6-luna": "0.157.0",
+};
+
+export function minimumCodexCliVersionForModel(model: string | null | undefined): string | null {
+ return CODEX_LOCAL_MODEL_MINIMUM_CLI_VERSIONS[normalizeCodexModel(model)] ?? null;
+}
+
+const STABLE_CODEX_CLI_VERSION = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
+
+function stableCodexCliVersionParts(version: string): number[] | null {
+ const match = STABLE_CODEX_CLI_VERSION.exec(version.trim());
+ if (!match) return null;
+ const parts = match.slice(1).map(Number);
+ return parts.every(Number.isSafeInteger) ? parts : null;
+}
+
+/** Read the version from `codex --version` output; prerelease or ambiguous output yields null. */
+export function parseCodexCliVersionOutput(output: string): string | null {
+ const versions = output
+ .split(/\r?\n/)
+ .map((line) => /^codex-cli (\S+)$/.exec(line.trim())?.[1])
+ .filter((version): version is string => version !== undefined);
+ if (versions.length !== 1 || !stableCodexCliVersionParts(versions[0]!)) return null;
+ return versions[0]!;
+}
+
+export function codexCliVersionAtLeast(version: string, minimum: string): boolean {
+ const parsedVersion = stableCodexCliVersionParts(version);
+ const parsedMinimum = stableCodexCliVersionParts(minimum);
+ if (!parsedVersion || !parsedMinimum) return false;
+ for (let index = 0; index < parsedMinimum.length; index += 1) {
+ if (parsedVersion[index] !== parsedMinimum[index]) {
+ return parsedVersion[index]! > parsedMinimum[index]!;
+ }
+ }
+ return true;
+}
+
+export const CODEX_CHATGPT_MODEL_REJECTION_RE =
+ /The '([^']+)' model is not supported when using Codex with a ChatGPT account\./;
+
export function isCodexLocalKnownModel(model: string | null | undefined): boolean {
const normalizedModel = normalizeModelId(model);
if (!normalizedModel) return false;
@@ -175,6 +229,7 @@ Notes:
- Paperclip injects desired local skills into the effective CODEX_HOME/skills/ directory at execution time so Codex can discover "$paperclip" and related skills without polluting the project working directory. For new and updated agents, Paperclip assigns an isolated managed home at ~/.paperclip/instances//companies//agents//codex-home/skills/; when CODEX_HOME is explicitly overridden in adapter config, that override is used instead.
- New and updated codex_local agents persist an empty OPENAI_API_KEY override by default so a host-level OPENAI_API_KEY cannot leak into Codex runs through process inheritance. Explicit CODEX_HOME overrides must not point at the shared company codex-home, $CODEX_HOME, or ~/.codex.
- Some model/tool combinations reject certain effort levels (for example minimal with web search enabled).
+- With ChatGPT sign-in, the Codex backend accepts a model only from a recent enough Codex CLI: GPT-6.1 Sol needs 0.159.0 or newer, GPT-6 Sol and GPT-6 Luna need 0.157.0 or newer. An older CLI fails every turn with "The '' model is not supported when using Codex with a ChatGPT account." The environment Test and the remote runner compare the installed \`codex --version\` against these floors before running; in a managed sandbox, the fix is a sandbox image that ships the Codex version Paperclip pins.
- Fast mode is supported on GPT-6 (astra/sol/luna), GPT-6.1 Sol, GPT-5.6 (sol/terra/luna), GPT-5.5, GPT-5.4 and manual model IDs. When enabled for those models, Paperclip applies \`service_tier="fast"\` and \`features.fast_mode=true\`.
- When Paperclip realizes a workspace/runtime for a run, it injects PAPERCLIP_WORKSPACE_* and PAPERCLIP_RUNTIME_* env vars for agent-side tooling.
- The ACP engine keeps its workspace sandbox and enables network access on each turn. Explicit sandbox_workspace_write.network_access overrides in extraArgs (or env.PAPERCLIP_CODEX_ACP_NETWORK_ACCESS="false") disable it; execution-target network denial wins. The bundled ACP patch is needed because upstream mode presets override Codex config.toml on every turn.
diff --git a/packages/adapters/codex-local/src/server/acp.cli-version.test.ts b/packages/adapters/codex-local/src/server/acp.cli-version.test.ts
new file mode 100644
index 00000000000..0ed7dce3a5f
--- /dev/null
+++ b/packages/adapters/codex-local/src/server/acp.cli-version.test.ts
@@ -0,0 +1,182 @@
+import fs from "node:fs/promises";
+import os from "node:os";
+import path from "node:path";
+import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
+import type { AdapterExecutionTarget } from "@paperclipai/adapter-utils/execution-target";
+
+const { ensureAdapterExecutionTargetCommandResolvable, runAdapterExecutionTargetProcess } = vi.hoisted(() => ({
+ ensureAdapterExecutionTargetCommandResolvable: vi.fn(async () => {}),
+ runAdapterExecutionTargetProcess: vi.fn(async () => ({
+ exitCode: 0,
+ signal: null,
+ timedOut: false,
+ stdout: "codex-cli 0.156.0\n",
+ stderr: "",
+ pid: 1,
+ startedAt: new Date().toISOString(),
+ })),
+}));
+
+vi.mock("@paperclipai/adapter-utils/execution-target", async () => {
+ const actual = await vi.importActual(
+ "@paperclipai/adapter-utils/execution-target",
+ );
+ return { ...actual, ensureAdapterExecutionTargetCommandResolvable, runAdapterExecutionTargetProcess };
+});
+
+import { testCodexAcpEnvironment } from "./acp.js";
+
+describe("codex ACP lane model CLI floor", () => {
+ let cwd: string;
+
+ beforeEach(async () => {
+ cwd = await fs.mkdtemp(path.join(os.tmpdir(), "paperclip-codex-acp-version-"));
+ vi.stubEnv("CODEX_HOME", await fs.mkdtemp(path.join(os.tmpdir(), "paperclip-codex-acp-home-")));
+ vi.stubEnv("PAPERCLIP_HOME", await fs.mkdtemp(path.join(os.tmpdir(), "paperclip-codex-acp-instance-")));
+ vi.stubEnv("PAPERCLIP_INSTANCE_ID", "default");
+ });
+
+ afterEach(async () => {
+ vi.clearAllMocks();
+ vi.unstubAllEnvs();
+ await fs.rm(cwd, { recursive: true, force: true }).catch(() => undefined);
+ });
+
+ function sandboxTarget(): AdapterExecutionTarget {
+ return {
+ kind: "remote",
+ transport: "sandbox",
+ providerKey: "daytona",
+ remoteCwd: "/remote/workspace",
+ runner: {
+ execute: async () => ({
+ exitCode: 0,
+ signal: null,
+ timedOut: false,
+ stdout: "",
+ stderr: "",
+ pid: null,
+ startedAt: new Date().toISOString(),
+ }),
+ },
+ };
+ }
+
+ it("fails the sandbox Test when the shared codex is older than the model's floor", async () => {
+ const result = await testCodexAcpEnvironment({
+ companyId: "company-1",
+ adapterType: "codex_local",
+ config: { cwd, model: "gpt-6.1-sol", env: { OPENAI_API_KEY: "sk-test" } },
+ executionTarget: sandboxTarget(),
+ environmentName: "QA Daytona",
+ });
+
+ expect(result.status).toBe("fail");
+ expect(result.checks.find((check) => check.code === "codex_cli_version_incompatible")).toMatchObject({
+ level: "error",
+ message: "gpt-6.1-sol requires Codex CLI 0.159.0 or newer with ChatGPT sign-in.",
+ detail: "Detected Codex CLI 0.156.0.",
+ });
+ expect(runAdapterExecutionTargetProcess).toHaveBeenCalledTimes(1);
+ const call = runAdapterExecutionTargetProcess.mock.calls[0] as unknown as [
+ string,
+ AdapterExecutionTarget,
+ string,
+ string[],
+ { env: Record },
+ ];
+ expect(call[1]).toMatchObject({ kind: "remote", transport: "sandbox" });
+ expect(call[2]).toBe("codex");
+ expect(call[3]).toEqual(["--version"]);
+ expect(call[4].env).toEqual({ OPENAI_API_KEY: "sk-test" });
+ });
+
+ it("probes the codex the agent's configured env selects, not the image default", async () => {
+ runAdapterExecutionTargetProcess.mockResolvedValueOnce({
+ exitCode: 0,
+ signal: null,
+ timedOut: false,
+ stdout: "codex-cli 0.160.0\n",
+ stderr: "",
+ pid: 1,
+ startedAt: new Date().toISOString(),
+ });
+
+ const result = await testCodexAcpEnvironment({
+ companyId: "company-1",
+ adapterType: "codex_local",
+ config: {
+ cwd,
+ model: "gpt-6.1-sol",
+ env: {
+ OPENAI_API_KEY: "sk-test",
+ PATH: "/opt/codex-0.160.0/bin:/usr/local/bin:/usr/bin",
+ CODEX_HOME: "/remote/codex-home",
+ PAPERCLIP_CODEX_ACP_NETWORK_ACCESS: false,
+ },
+ },
+ executionTarget: sandboxTarget(),
+ environmentName: "QA Daytona",
+ });
+
+ expect(result.status).toBe("pass");
+ expect(result.checks.find((check) => check.code === "codex_cli_version_compatible")).toMatchObject({
+ message: "Codex CLI 0.160.0 satisfies the 0.159.0 minimum for gpt-6.1-sol.",
+ });
+ expect(runAdapterExecutionTargetProcess).toHaveBeenCalledTimes(1);
+ const call = runAdapterExecutionTargetProcess.mock.calls[0] as unknown as [
+ string,
+ AdapterExecutionTarget,
+ string,
+ string[],
+ { env: Record },
+ ];
+ expect(call[3]).toEqual(["--version"]);
+ // String-valued entries are forwarded exactly as the ACP run receives them;
+ // non-string values are dropped the same way buildCodexAcpConfig consumers do.
+ expect(call[4].env).toEqual({
+ OPENAI_API_KEY: "sk-test",
+ PATH: "/opt/codex-0.160.0/bin:/usr/local/bin:/usr/bin",
+ CODEX_HOME: "/remote/codex-home",
+ });
+ });
+
+ it("passes the sandbox Test when the shared codex satisfies the floor", async () => {
+ runAdapterExecutionTargetProcess.mockResolvedValueOnce({
+ exitCode: 0,
+ signal: null,
+ timedOut: false,
+ stdout: "codex-cli 0.160.0\n",
+ stderr: "",
+ pid: 1,
+ startedAt: new Date().toISOString(),
+ });
+
+ const result = await testCodexAcpEnvironment({
+ companyId: "company-1",
+ adapterType: "codex_local",
+ config: { cwd, model: "gpt-6.1-sol", env: { OPENAI_API_KEY: "sk-test" } },
+ executionTarget: sandboxTarget(),
+ environmentName: "QA Daytona",
+ });
+
+ expect(result.status).toBe("pass");
+ expect(result.checks.find((check) => check.code === "codex_cli_version_compatible")).toMatchObject({
+ message: "Codex CLI 0.160.0 satisfies the 0.159.0 minimum for gpt-6.1-sol.",
+ });
+ });
+
+ it("does not probe the sandbox for models without a verified floor", async () => {
+ const result = await testCodexAcpEnvironment({
+ companyId: "company-1",
+ adapterType: "codex_local",
+ config: { cwd, model: "gpt-5.6-sol", env: { OPENAI_API_KEY: "sk-test" } },
+ executionTarget: sandboxTarget(),
+ environmentName: "QA Daytona",
+ });
+
+ expect(result.status).toBe("pass");
+ expect(runAdapterExecutionTargetProcess).not.toHaveBeenCalled();
+ expect(result.checks.some((check) => check.code.startsWith("codex_cli_version_"))).toBe(false);
+ });
+});
diff --git a/packages/adapters/codex-local/src/server/acp.ts b/packages/adapters/codex-local/src/server/acp.ts
index 7eb2b87bfd6..ed57d8aa983 100644
--- a/packages/adapters/codex-local/src/server/acp.ts
+++ b/packages/adapters/codex-local/src/server/acp.ts
@@ -49,6 +49,7 @@ import {
stageCodexHomeForSync,
} from "./codex-home.js";
import { ADAPTER_AUTH_MISSING_CHECK_CODE } from "./auth-check.js";
+import { checkCodexCliVersionForModel } from "./cli-version.js";
const moduleDir = path.dirname(fileURLToPath(import.meta.url));
const packageRootDir = path.resolve(moduleDir, "../..");
@@ -648,6 +649,32 @@ export async function testCodexAcpEnvironment(
}
}
+ if (targetIsRemote && commandResolvable) {
+ // The ACP server spawns the shared `codex` installed in the environment.
+ // Models with a verified CLI floor are checked against that executable so
+ // a stale sandbox image is named here, before a run fails on every turn
+ // with the backend's "not supported when using Codex with a ChatGPT
+ // account" rejection. Models without a floor skip the probe.
+ //
+ // Remote ACP runs receive the adapter's string-valued env entries (see
+ // buildCodexAcpConfig), so the probe gets the same ones. An agent that
+ // selects its Codex install through PATH is then measured against that
+ // install rather than the image default.
+ const probeEnv: Record = {};
+ for (const [key, value] of Object.entries(envConfig)) {
+ if (typeof value === "string") probeEnv[key] = value;
+ }
+ const versionCheck = await checkCodexCliVersionForModel({
+ runId: `codex-acp-envtest-${Date.now()}-${Math.random().toString(16).slice(2)}`,
+ model: asString(config.model, ""),
+ command: "codex",
+ target,
+ cwd: resolveAdapterExecutionTargetCwd(target, asString(config.cwd, ""), process.cwd()),
+ env: probeEnv,
+ });
+ if (versionCheck) checks.push(versionCheck.check);
+ }
+
const mode = firstNonEmptyString(config.mode, config.acpMode) ?? DEFAULT_ACP_ENGINE_MODE;
const warmHandleIdleMs = asNumber(
config.warmHandleIdleMs ?? config.acpWarmHandleIdleMs,
diff --git a/packages/adapters/codex-local/src/server/cli-version.ts b/packages/adapters/codex-local/src/server/cli-version.ts
new file mode 100644
index 00000000000..aaafc9479af
--- /dev/null
+++ b/packages/adapters/codex-local/src/server/cli-version.ts
@@ -0,0 +1,125 @@
+import type { AdapterEnvironmentCheck } from "@paperclipai/adapter-utils";
+import type { AdapterExecutionTarget } from "@paperclipai/adapter-utils/execution-target";
+import { runAdapterExecutionTargetProcess } from "@paperclipai/adapter-utils/execution-target";
+import {
+ CODEX_CHATGPT_MODEL_REJECTION_RE,
+ codexCliVersionAtLeast,
+ minimumCodexCliVersionForModel,
+ normalizeCodexModel,
+ parseCodexCliVersionOutput,
+} from "../index.js";
+
+export const CODEX_CLI_VERSION_INCOMPATIBLE_CHECK_CODE = "codex_cli_version_incompatible";
+export const CODEX_CLI_VERSION_COMPATIBLE_CHECK_CODE = "codex_cli_version_compatible";
+export const CODEX_HELLO_PROBE_MODEL_REJECTED_CHECK_CODE = "codex_hello_probe_model_rejected";
+
+/**
+ * Run `codex --version` where the run would execute it. Never cached: an
+ * operator may upgrade Codex, or promote a new sandbox image, while the
+ * Paperclip server keeps running, and the next Test should see the change.
+ */
+export async function readCodexCommandVersion(input: {
+ runId: string;
+ command: string;
+ target: AdapterExecutionTarget | null | undefined;
+ cwd: string;
+ env: Record;
+}): Promise {
+ try {
+ const result = await runAdapterExecutionTargetProcess(
+ input.runId,
+ input.target,
+ input.command,
+ ["--version"],
+ {
+ cwd: input.cwd,
+ env: input.env,
+ timeoutSec: 20,
+ graceSec: 5,
+ onLog: async () => {},
+ },
+ );
+ if (result.timedOut || result.exitCode !== 0) return null;
+ return parseCodexCliVersionOutput(`${result.stdout}\n${result.stderr}`);
+ } catch {
+ return null;
+ }
+}
+
+function sandboxUpgradeHint(targetIsSandbox: boolean): string {
+ return targetIsSandbox
+ ? "Promote a sandbox image that ships the Codex CLI version Paperclip pins, then retry the Test. Adding a model to the catalog does not update the Codex CLI baked into existing sandbox images."
+ : "Upgrade Codex (for example `npm install -g @openai/codex@latest`) where this agent runs, then retry the Test.";
+}
+
+/**
+ * Compare the installed Codex CLI with the floor the configured model needs
+ * for ChatGPT sign-in. Returns null when the model has no verified floor, so
+ * callers skip the version probe entirely for such models.
+ */
+export async function checkCodexCliVersionForModel(input: {
+ runId: string;
+ model: string | null | undefined;
+ command: string;
+ target: AdapterExecutionTarget | null | undefined;
+ cwd: string;
+ env: Record;
+}): Promise<{ check: AdapterEnvironmentCheck; compatible: boolean; detectedVersion: string | null } | null> {
+ const minimum = minimumCodexCliVersionForModel(input.model);
+ if (!minimum) return null;
+ const model = normalizeCodexModel(input.model);
+ const targetIsSandbox = input.target?.kind === "remote" && input.target.transport === "sandbox";
+ const detected = await readCodexCommandVersion(input);
+ if (detected && codexCliVersionAtLeast(detected, minimum)) {
+ return {
+ compatible: true,
+ detectedVersion: detected,
+ check: {
+ code: CODEX_CLI_VERSION_COMPATIBLE_CHECK_CODE,
+ level: "info",
+ message: `Codex CLI ${detected} satisfies the ${minimum} minimum for ${model}.`,
+ },
+ };
+ }
+ return {
+ compatible: false,
+ detectedVersion: detected,
+ check: {
+ code: CODEX_CLI_VERSION_INCOMPATIBLE_CHECK_CODE,
+ level: "error",
+ message: `${model} requires Codex CLI ${minimum} or newer with ChatGPT sign-in.`,
+ detail: detected
+ ? `Detected Codex CLI ${detected}.`
+ : "Could not determine the installed Codex CLI version from `codex --version`.",
+ hint: sandboxUpgradeHint(targetIsSandbox),
+ },
+ };
+}
+
+/**
+ * The backend rejects a model for ChatGPT sign-in with one fixed sentence.
+ * Map it to a dedicated check so the cause (stale CLI, or a plan that does
+ * not include the model) is named instead of a generic probe failure.
+ */
+export function codexHelloProbeModelRejectionCheck(input: {
+ evidence: string;
+ detectedVersion: string | null;
+ targetIsSandbox: boolean;
+}): AdapterEnvironmentCheck | null {
+ const match = CODEX_CHATGPT_MODEL_REJECTION_RE.exec(input.evidence);
+ if (!match) return null;
+ const model = match[1]!;
+ const minimum = minimumCodexCliVersionForModel(model);
+ const versionNote = input.detectedVersion
+ ? ` Detected Codex CLI ${input.detectedVersion}.`
+ : "";
+ return {
+ code: CODEX_HELLO_PROBE_MODEL_REJECTED_CHECK_CODE,
+ level: "error",
+ message: `The Codex backend rejected ${model} for this ChatGPT account.`,
+ detail: `${match[0]}${versionNote}`,
+ hint: minimum
+ ? `${model} needs Codex CLI ${minimum} or newer with ChatGPT sign-in. ${sandboxUpgradeHint(input.targetIsSandbox)} If the CLI is already new enough, the plan does not include this model (Enterprise and Edu administrators must enable it) or the rollout has not reached the account; choose another model or use an OpenAI API key.`
+ : `The ChatGPT plan does not include ${model}, the rollout has not reached the account, or the installed Codex CLI is older than the model requires. ${sandboxUpgradeHint(input.targetIsSandbox)} Otherwise choose another model or use an OpenAI API key.`,
+ };
+}
diff --git a/packages/adapters/codex-local/src/server/test.remote.test.ts b/packages/adapters/codex-local/src/server/test.remote.test.ts
index 6376a001ae8..9efe9ebfd90 100644
--- a/packages/adapters/codex-local/src/server/test.remote.test.ts
+++ b/packages/adapters/codex-local/src/server/test.remote.test.ts
@@ -253,6 +253,125 @@ describe("codex remote environment diagnostics", () => {
expect(probeCall?.[3]).toContain("--skip-git-repo-check");
});
+ // `sandboxTarget()` is declared later in this describe block; function
+ // declarations hoist, so the version-floor cases below reuse it.
+ function versionProbeResult(stdout: string) {
+ return {
+ exitCode: 0,
+ signal: null,
+ timedOut: false,
+ stdout,
+ stderr: "",
+ pid: 111,
+ startedAt: new Date().toISOString(),
+ };
+ }
+
+ it("fails before the hello probe when the sandbox Codex CLI is older than the model's floor", async () => {
+ // A sandbox image baked before gpt-6.1-sol reached the catalog still runs
+ // Codex 0.156.0. The backend would reject every turn with "not supported
+ // when using Codex with a ChatGPT account"; the Test must name the real
+ // gap (the CLI in the image) instead of running that doomed probe.
+ runAdapterExecutionTargetProcess.mockResolvedValueOnce(versionProbeResult("codex-cli 0.156.0\n"));
+
+ const result = await testEnvironment({
+ companyId: "company-1",
+ adapterType: "codex_local",
+ config: { engine: "cli", command: "codex", model: "gpt-6.1-sol" },
+ executionTarget: sandboxTarget(),
+ environmentName: "QA Daytona",
+ });
+
+ expect(result.status).toBe("fail");
+ const incompatible = result.checks.find((check) => check.code === "codex_cli_version_incompatible");
+ expect(incompatible).toMatchObject({
+ level: "error",
+ message: "gpt-6.1-sol requires Codex CLI 0.159.0 or newer with ChatGPT sign-in.",
+ detail: "Detected Codex CLI 0.156.0.",
+ });
+ expect(incompatible?.hint).toContain("sandbox image");
+ expect(result.checks.some((check) => check.code === "codex_hello_probe_skipped_cli_version")).toBe(true);
+ expect(result.checks.some((check) => check.code.startsWith("codex_hello_probe_") && !check.code.includes("skipped"))).toBe(false);
+ expect(runAdapterExecutionTargetProcess).toHaveBeenCalledTimes(1);
+ const versionCall = runAdapterExecutionTargetProcess.mock.calls[0] as unknown as [string, AdapterExecutionTarget, string, string[]];
+ expect(versionCall[2]).toBe("codex");
+ expect(versionCall[3]).toEqual(["--version"]);
+ expect(prepareAdapterExecutionTargetRuntime).not.toHaveBeenCalled();
+ });
+
+ it("runs the hello probe when the sandbox Codex CLI satisfies the model's floor", async () => {
+ runAdapterExecutionTargetProcess.mockResolvedValueOnce(versionProbeResult("codex-cli 0.160.0\n"));
+
+ const result = await testEnvironment({
+ companyId: "company-1",
+ adapterType: "codex_local",
+ config: { engine: "cli", command: "codex", model: "gpt-6.1-sol" },
+ executionTarget: sandboxTarget(),
+ environmentName: "QA Daytona",
+ });
+
+ expect(result.status).toBe("pass");
+ expect(result.checks.find((check) => check.code === "codex_cli_version_compatible")).toMatchObject({
+ level: "info",
+ message: "Codex CLI 0.160.0 satisfies the 0.159.0 minimum for gpt-6.1-sol.",
+ });
+ expect(result.checks.some((check) => check.code === "codex_hello_probe_passed")).toBe(true);
+ expect(runAdapterExecutionTargetProcess).toHaveBeenCalledTimes(2);
+ });
+
+ it("skips the version probe for models without a verified floor", async () => {
+ const result = await testEnvironment({
+ companyId: "company-1",
+ adapterType: "codex_local",
+ config: { engine: "cli", command: "codex", model: "gpt-5.6-sol" },
+ executionTarget: sandboxTarget(),
+ environmentName: "QA Daytona",
+ });
+
+ expect(result.status).toBe("pass");
+ expect(result.checks.some((check) => check.code.startsWith("codex_cli_version_"))).toBe(false);
+ expect(runAdapterExecutionTargetProcess).toHaveBeenCalledTimes(1);
+ const helloCall = runAdapterExecutionTargetProcess.mock.calls[0] as unknown as [string, AdapterExecutionTarget, string, string[]];
+ expect(helloCall[3]).not.toEqual(["--version"]);
+ });
+
+ it("names the backend's ChatGPT model rejection instead of a generic probe failure", async () => {
+ // The CLI is new enough, but the account's plan or rollout does not include
+ // the model. The backend answers with one fixed sentence; surface it with
+ // the detected CLI version so the operator can tell the two causes apart.
+ runAdapterExecutionTargetProcess.mockResolvedValueOnce(versionProbeResult("codex-cli 0.160.0\n"));
+ runAdapterExecutionTargetProcess.mockResolvedValueOnce({
+ exitCode: 1,
+ signal: null,
+ timedOut: false,
+ stdout: "",
+ stderr: "ERROR: {\"type\":\"error\",\"status\":400,\"error\":{\"type\":\"invalid_request_error\",\"message\":\"The 'gpt-6.1-sol' model is not supported when using Codex with a ChatGPT account.\"}}",
+ pid: 222,
+ startedAt: new Date().toISOString(),
+ });
+
+ const result = await testEnvironment({
+ companyId: "company-1",
+ adapterType: "codex_local",
+ config: { engine: "cli", command: "codex", model: "gpt-6.1-sol" },
+ executionTarget: sandboxTarget(),
+ environmentName: "QA Daytona",
+ });
+
+ expect(result.status).toBe("fail");
+ const rejected = result.checks.find((check) => check.code === "codex_hello_probe_model_rejected");
+ expect(rejected).toMatchObject({
+ level: "error",
+ message: "The Codex backend rejected gpt-6.1-sol for this ChatGPT account.",
+ detail: "The 'gpt-6.1-sol' model is not supported when using Codex with a ChatGPT account. Detected Codex CLI 0.160.0.",
+ });
+ expect(rejected?.hint).toContain("0.159.0");
+ expect(rejected?.hint).toContain("plan");
+ expect(result.checks.some((check) => check.code === "codex_hello_probe_failed")).toBe(false);
+ // Not an auth failure: the managed-connection flow must not invalidate the credential.
+ expect(result.checks.some((check) => check.code === "codex_hello_probe_auth_required")).toBe(false);
+ });
+
it("emits the canonical adapter_auth_missing check when a sandbox hello probe reports missing auth", async () => {
// The sandbox has no seedable credentials, so the hello probe returns an
// authentication-required error. The Test must emit the neutral canonical
diff --git a/packages/adapters/codex-local/src/server/test.ts b/packages/adapters/codex-local/src/server/test.ts
index 0679b0c7b90..10cbcb8d395 100644
--- a/packages/adapters/codex-local/src/server/test.ts
+++ b/packages/adapters/codex-local/src/server/test.ts
@@ -37,6 +37,7 @@ import {
} from "./codex-auth-cache.js";
import { resolveCodexExecutionEngineForRun, testCodexAcpEnvironment } from "./acp.js";
import { ADAPTER_AUTH_MISSING_CHECK_CODE } from "./auth-check.js";
+import { checkCodexCliVersionForModel, codexHelloProbeModelRejectionCheck } from "./cli-version.js";
function summarizeStatus(checks: AdapterEnvironmentCheck[]): AdapterEnvironmentTestResult["status"] {
if (checks.some((check) => check.level === "error")) return "fail";
@@ -383,7 +384,34 @@ export async function testEnvironment(
const canRunProbe =
checks.every((check) => check.code !== "codex_cwd_invalid" && check.code !== "codex_command_unresolvable");
- if (canRunProbe) {
+ // Models with a verified CLI floor are compared against the installed Codex
+ // before the hello probe. A probe on an older CLI only produces the backend's
+ // "not supported when using Codex with a ChatGPT account" rejection, which
+ // hides the real gap: the CLI (often a stale sandbox image), not the account.
+ let detectedCliVersion: string | null = null;
+ let configuredModelIsCompatible = true;
+ if (canRunProbe && commandLooksLike(command, "codex")) {
+ const versionCheck = await checkCodexCliVersionForModel({
+ runId,
+ model: asString(config.model, ""),
+ command,
+ target,
+ cwd,
+ env,
+ });
+ if (versionCheck) {
+ checks.push(versionCheck.check);
+ configuredModelIsCompatible = versionCheck.compatible;
+ detectedCliVersion = versionCheck.detectedVersion;
+ }
+ }
+ if (canRunProbe && !configuredModelIsCompatible) {
+ checks.push({
+ code: "codex_hello_probe_skipped_cli_version",
+ level: "info",
+ message: "Skipped hello probe because the installed Codex CLI cannot use the configured model.",
+ });
+ } else if (canRunProbe) {
if (!commandLooksLike(command, "codex")) {
checks.push({
code: "codex_hello_probe_skipped_custom_command",
@@ -525,7 +553,12 @@ export async function testEnvironment(
});
}
} else {
- checks.push({
+ const modelRejection = codexHelloProbeModelRejectionCheck({
+ evidence: `${parsed.errorMessage ?? ""}\n${providerStderr}\n${probe.stdout}`,
+ detectedVersion: detectedCliVersion,
+ targetIsSandbox,
+ });
+ checks.push(modelRejection ?? {
code: "codex_hello_probe_failed",
level: "error",
message: "Codex hello probe failed.",
diff --git a/packages/adapters/cursor-local/src/server/execute.test.ts b/packages/adapters/cursor-local/src/server/execute.test.ts
index 866cdd952e0..61f5a05dd3f 100644
--- a/packages/adapters/cursor-local/src/server/execute.test.ts
+++ b/packages/adapters/cursor-local/src/server/execute.test.ts
@@ -291,6 +291,15 @@ exit 7
const remoteWorkspace = path.join(rootDir, "remote-workspace");
const systemHomeDir = path.join(rootDir, "system-home");
const managedCaptureDir = path.join(rootDir, "managed-capture");
+ const fixtureBinDir = path.join(rootDir, "fixture-bin");
+ const networkAttemptPath = path.join(rootDir, "network-attempted");
+ await fs.mkdir(fixtureBinDir, { recursive: true });
+ // A regression in installer interception must fail locally, not download
+ // and execute the real CLI or depend on an external server's latency.
+ await fs.writeFile(path.join(fixtureBinDir, "curl"), `#!/bin/sh
+: > "$FIXTURE_CURL_ATTEMPT_PATH"
+exit 97
+`, { mode: 0o755 });
await fs.mkdir(managedCaptureDir, { recursive: true });
await fs.mkdir(workspaceDir, { recursive: true });
await fs.mkdir(remoteWorkspace, { recursive: true });
@@ -337,6 +346,7 @@ printf '%s\\n' '{"type":"result","subtype":"success","session_id":"cursor-sessio
const runnerState = {
commands: [] as string[],
+ installCommands: [] as string[],
};
// The managed-runtime restore path probes the generated archive with
// `wc -c` before reading bounded `dd | base64` chunks. Keep this fixture's
@@ -345,11 +355,23 @@ printf '%s\\n' '{"type":"result","subtype":"success","session_id":"cursor-sessio
const runner = {
execute: async (input: { command: string; args?: string[]; env?: Record; stdin?: string }) => {
runnerState.commands.push(input.command);
+ const args = [...(input.args ?? [])];
+ if (args[1] === SANDBOX_INSTALL_COMMAND) {
+ runnerState.installCommands.push(args[1]);
+ args[1] = buildInstallSimulationCommand(
+ path.join(systemHomeDir, ".local", "bin", "agent"),
+ managedCaptureDir,
+ );
+ }
// Exercise actual bounded file reads during managed-home restoration;
// reporting empty success for every shell command hides missing bytes.
- return runChildProcess(`cursor-fresh-lease-${runnerState.commands.length}`, input.command, input.args ?? [], {
+ return runChildProcess(`cursor-fresh-lease-${runnerState.commands.length}`, input.command, args, {
cwd: remoteWorkspace,
- env: { ...input.env, PATH: `${input.env?.PATH ?? ""}:/usr/bin:/bin` },
+ env: {
+ ...input.env,
+ PATH: `${fixtureBinDir}:${input.env?.PATH ?? ""}:/usr/bin:/bin`,
+ FIXTURE_CURL_ATTEMPT_PATH: networkAttemptPath,
+ },
stdin: input.stdin,
timeoutSec: 30,
graceSec: 5,
@@ -402,7 +424,11 @@ printf '%s\\n' '{"type":"result","subtype":"success","session_id":"cursor-sessio
});
expect(result.exitCode).toBe(0);
+ await expect(fs.stat(networkAttemptPath)).rejects.toMatchObject({ code: "ENOENT" });
+ expect(runnerState.installCommands).toEqual([SANDBOX_INSTALL_COMMAND]);
expect(prepareInputs).toHaveLength(2);
+ expect(prepareInputs[1].env.HOME).toBeTruthy();
+ expect(prepareInputs[1].env.HOME).not.toBe(systemHomeDir);
expect(finalPreparedCommand).not.toBeNull();
expect(finalPreparedCommand).toMatch(/\.local\/(bin|sbin)\/agent$/);
const resolvedCommand = runMeta.find(Boolean)?.command as string | undefined;
diff --git a/packages/adapters/hermes/README.md b/packages/adapters/hermes/README.md
index fb9d267e7bf..1ee190c753c 100644
--- a/packages/adapters/hermes/README.md
+++ b/packages/adapters/hermes/README.md
@@ -312,6 +312,43 @@ up where the last one left off, maintaining conversation context,
memories, and tool state across heartbeats. The `sessionCodec` validates
and migrates session state between runs.
+### Managed instructions and resumed turns
+
+The local adapter reads `instructionsFilePath` on every run. It sends that
+bundle, its relative-reference base directory, and the standard Paperclip API
+guidance through Hermes's native `HERMES_EPHEMERAL_SYSTEM_PROMPT` overlay.
+Hermes applies this overlay at each model request, including after context
+compression. It does not append the overlay to saved user turns. This requires
+a Hermes CLI that supports the [documented environment hook](https://github.com/NousResearch/hermes-agent/blob/main/website/docs/reference/environment-variables.md).
+
+Fresh sessions, resumed sessions, and session resets all receive the current
+bundle. Edits take effect on the next run; removing the bundle removes it from
+the next overlay. The server's session compatibility and conversation generation
+checks still control session reuse. A missing or failed resume remains a failed
+run and requires an explicit session reset; it does not automatically restart
+work. The next fresh run receives the complete current instruction overlay.
+
+The `-q` user turn contains current runtime identity, task/wake context, handoff
+content, and the rendered custom `promptTemplate`, if configured. Custom templates
+run on every normal wake. `quiet` changes CLI display only. Disabling persistence
+uses full fresh-session context even if old session parameters are supplied.
+
+An explicit `HERMES_EPHEMERAL_SYSTEM_PROMPT` in `env` is preserved before the
+Paperclip overlay. Hermes gives this environment hook precedence over its profile's
+configured personality/system prompt. Put required additional profile guidance in
+that explicit environment value or in the managed bundle. Paperclip does not write
+Hermes profile files or modify the parent process environment. Existing copies in
+old user turns remain in history until Hermes compresses them or the session resets.
+
+Run the credential-free capture-process regression tests with:
+
+```sh
+pnpm --filter @paperclipai/hermes-paperclip-adapter test -- src/server/execute.instructions.test.ts
+```
+
+These tests verify actual child-process arguments and environment, not provider
+billing, model behavior, or measured token savings.
+
### Skills Integration
The adapter scans two skill sources and merges them:
diff --git a/packages/adapters/hermes/src/index.ts b/packages/adapters/hermes/src/index.ts
index 1c1b9d33984..4ff7488b997 100644
--- a/packages/adapters/hermes/src/index.ts
+++ b/packages/adapters/hermes/src/index.ts
@@ -114,6 +114,14 @@ tools, persistent memory, session persistence, skills, and MCP support.
| env | object | {} | Extra environment variables |
| promptTemplate | string | (default) | Custom prompt template with {{variable}} placeholders |
+Managed \`instructionsFilePath\` bundles and standard Paperclip API guidance use
+Hermes's native \`HERMES_EPHEMERAL_SYSTEM_PROMPT\` overlay on every run, including
+resume and reset. They are applied at request time and are not appended to user
+history. The query keeps current runtime identity, wake/task content, and custom
+templates. Use a Hermes CLI that supports this environment hook. An explicit
+overlay in \`env\` is preserved; the hook takes precedence over Hermes's configured
+profile personality/system prompt.
+
## Hermes-Originated Paperclip Tasks
This adapter package also ships a Hermes-facing Paperclip task bridge skill:
diff --git a/packages/adapters/hermes/src/server/execute.instructions.test.ts b/packages/adapters/hermes/src/server/execute.instructions.test.ts
new file mode 100644
index 00000000000..5423e5568d2
--- /dev/null
+++ b/packages/adapters/hermes/src/server/execute.instructions.test.ts
@@ -0,0 +1,210 @@
+import fs from "node:fs/promises";
+import os from "node:os";
+import path from "node:path";
+import { afterEach, beforeEach, describe, expect, it } from "vitest";
+import type { AdapterExecutionContext } from "@paperclipai/adapter-utils";
+
+import { execute } from "./execute.js";
+import { sessionCodec } from "./index.js";
+
+const SESSION_ID = "20261006_200000_abcdef";
+const INSTRUCTIONS = "Synthetic governance marker: request approval before governed actions.";
+
+interface Invocation {
+ args: string[];
+ systemPrompt: string | null;
+ runId: string;
+}
+
+describe("Hermes managed instruction delivery (real capture process)", () => {
+ let dir: string;
+ let command: string;
+ let instructionsFilePath: string;
+ let capturePath: string;
+
+ beforeEach(async () => {
+ dir = await fs.mkdtemp(path.join(os.tmpdir(), "paperclip-hermes-instructions-"));
+ command = path.join(dir, "hermes.cjs");
+ instructionsFilePath = path.join(dir, "instructions.md");
+ capturePath = path.join(dir, "invocations.jsonl");
+ await fs.writeFile(instructionsFilePath, INSTRUCTIONS);
+ await fs.writeFile(command, `#!${process.execPath}
+const fs = require("node:fs");
+const args = process.argv.slice(2);
+fs.appendFileSync(process.env.CAPTURE_PATH, JSON.stringify({
+ args,
+ systemPrompt: process.env.HERMES_EPHEMERAL_SYSTEM_PROMPT ?? null,
+ runId: process.env.PAPERCLIP_RUN_ID,
+}) + "\\n");
+if (process.env.FIXTURE_STDOUT) console.log(process.env.FIXTURE_STDOUT);
+if (args.includes("missing-session")) {
+ console.error("\\u001b[1;31mSession missing-session not found.\\u001b[0m");
+ process.exit(1);
+}
+if (process.env.FIXTURE_PROVIDER_ERROR) {
+ console.error(process.env.FIXTURE_PROVIDER_ERROR);
+ process.exit(1);
+}
+console.log("Fixture completed\\nsession_id: ${SESSION_ID}");
+`, { mode: 0o700 });
+ });
+
+ afterEach(async () => {
+ await fs.rm(dir, { recursive: true, force: true });
+ });
+
+ function context(overrides: Partial = {}): AdapterExecutionContext {
+ return {
+ runId: "run-fresh",
+ agent: {
+ id: "agent-synthetic", companyId: "company-synthetic", name: "Hermes fixture",
+ adapterType: "hermes_local", adapterConfig: {},
+ },
+ runtime: { sessionId: null, sessionParams: null, sessionDisplayId: null, taskKey: "task-synthetic" },
+ config: {
+ hermesCommand: command, provider: "openrouter", model: "fixture-model", cwd: dir,
+ instructionsFilePath, env: { CAPTURE_PATH: capturePath }, timeoutSec: 10, graceSec: 1,
+ },
+ context: {
+ issueId: "task-synthetic",
+ paperclipTaskMarkdownAssignment: "Complete current synthetic task.",
+ paperclipTaskMarkdownCompact: "Current synthetic task.",
+ paperclipWake: {
+ reason: "issue_commented",
+ issue: { id: "task-synthetic", title: "Synthetic task", status: "in_progress" },
+ comments: [{ id: "comment-synthetic", body: "Fresh human direction." }],
+ commentWindow: { requestedCount: 1, includedCount: 1, missingCount: 0 },
+ fallbackFetchNeeded: false,
+ },
+ },
+ onLog: async () => {},
+ ...overrides,
+ };
+ }
+
+ async function invocations(): Promise {
+ return (await fs.readFile(capturePath, "utf8")).trim().split("\n").map((line) => JSON.parse(line));
+ }
+
+ function query(invocation: Invocation): string {
+ return invocation.args[invocation.args.indexOf("-q") + 1];
+ }
+
+ it.each([false, true])("keeps instructions out of fresh and resumed user turns (conversation=%s)", async (conversationMode) => {
+ const fresh = context();
+ fresh.context.conversationMode = conversationMode;
+ const first = await execute(fresh);
+ const params = sessionCodec.deserialize(sessionCodec.serialize(first.sessionParams ?? null));
+ expect(params?.sessionId).toBe(SESSION_ID);
+ await execute({ ...fresh, runId: "run-resumed", runtime: { ...fresh.runtime, sessionParams: params } });
+
+ const [initial, resumed] = await invocations();
+ expect(initial.args).not.toContain("--resume");
+ expect(resumed.args.slice(resumed.args.indexOf("--resume"))).toEqual(["--resume", SESSION_ID]);
+ for (const invocation of [initial, resumed]) {
+ expect(invocation.systemPrompt).toContain(INSTRUCTIONS);
+ expect(invocation.systemPrompt).toContain(`Resolve any relative file references from ${dir}/`);
+ expect(query(invocation)).not.toContain(INSTRUCTIONS);
+ expect(query(invocation)).not.toContain("Safe multiline update pattern:");
+ expect(query(invocation)).toContain("Fresh human direction.");
+ expect(query(invocation)).toContain(invocation.runId);
+ expect(query(invocation)).toContain("company-synthetic");
+ expect(invocation.systemPrompt).toContain("$PAPERCLIP_API_KEY");
+ expect(invocation.systemPrompt).toContain('-H "X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID"');
+ expect(invocation.systemPrompt).toContain("body=$(cat <<'MD'");
+ expect(invocation.systemPrompt).toContain("--data-binary @-");
+ expect(invocation.systemPrompt).toContain('$api/issues/$PAPERCLIP_TASK_ID');
+ expect(invocation.systemPrompt).not.toContain(invocation.runId);
+ }
+ });
+
+ it("reapplies current instructions after edits and a session reset", async () => {
+ const ctx = context();
+ await execute(ctx);
+ await fs.writeFile(instructionsFilePath, "Updated governance marker.");
+ await execute({ ...ctx, runtime: { ...ctx.runtime, sessionParams: { sessionId: SESSION_ID } } });
+ await execute({ ...ctx, runId: "run-reset" });
+ const [, edited, reset] = await invocations();
+ for (const invocation of [edited, reset]) {
+ expect(invocation.systemPrompt).toContain("Updated governance marker.");
+ expect(invocation.systemPrompt).not.toContain(INSTRUCTIONS);
+ expect(query(invocation)).not.toContain("Updated governance marker.");
+ }
+ expect(reset.args).not.toContain("--resume");
+ });
+
+ it("uses fresh wake context when persistence is disabled despite stored session params", async () => {
+ const ctx = context();
+ const result = await execute({ ...ctx, config: { ...ctx.config, persistSession: false }, runtime: { ...ctx.runtime, sessionParams: { sessionId: SESSION_ID } } });
+ const [invocation] = await invocations();
+ expect(invocation.args).not.toContain("--resume");
+ expect(query(invocation)).toContain("## Paperclip Wake Payload");
+ expect(query(invocation)).not.toContain("## Paperclip Resume Delta");
+ expect(invocation.systemPrompt).toContain(INSTRUCTIONS);
+ expect(result.sessionParams).toBeUndefined();
+ });
+
+ it("keeps custom templates and quiet mode dynamic while preserving a configured system overlay", async () => {
+ const ctx = context();
+ await execute({ ...ctx, config: {
+ ...ctx.config, quiet: true, promptTemplate: "Current custom direction for {{runId}}.",
+ env: { CAPTURE_PATH: capturePath, HERMES_EPHEMERAL_SYSTEM_PROMPT: "User configured system guidance." },
+ }, runtime: { ...ctx.runtime, sessionParams: { sessionId: SESSION_ID } } });
+ const [invocation] = await invocations();
+ expect(invocation.args).toContain("-Q");
+ expect(query(invocation)).toContain("Current custom direction for run-fresh.");
+ expect(query(invocation)).not.toContain(INSTRUCTIONS);
+ expect(invocation.systemPrompt).toContain("User configured system guidance.");
+ expect(invocation.systemPrompt).toContain(INSTRUCTIONS);
+ });
+
+ it.each([false, true])("keeps an empty wake runnable with current identity (conversation=%s)", async (conversationMode) => {
+ await execute(context({ context: { conversationMode } }));
+ const [invocation] = await invocations();
+ expect(query(invocation)).toContain("run-fresh");
+ expect(query(invocation)).not.toContain(INSTRUCTIONS);
+ expect(invocation.systemPrompt).toContain(INSTRUCTIONS);
+ });
+
+ it("surfaces a missing session without automatically restarting work", async () => {
+ const ctx = context();
+ const result = await execute({ ...ctx, runtime: { ...ctx.runtime, sessionParams: { sessionId: "missing-session" } } });
+ const calls = await invocations();
+ expect(calls).toHaveLength(1);
+ expect(calls[0].args).toContain("--resume");
+ expect(calls[0].systemPrompt).toContain(INSTRUCTIONS);
+ expect(result.exitCode).toBe(1);
+ expect(result.sessionParams).toBeUndefined();
+ });
+
+ it("does not retry provider failures as a missing session", async () => {
+ const ctx = context();
+ const result = await execute({ ...ctx, config: { ...ctx.config, env: { CAPTURE_PATH: capturePath, FIXTURE_PROVIDER_ERROR: "Error: provider unavailable" } }, runtime: { ...ctx.runtime, sessionParams: { sessionId: SESSION_ID } } });
+ expect(await invocations()).toHaveLength(1);
+ expect(result.exitCode).toBe(1);
+ expect(result.errorMessage).toBe("Error: provider unavailable");
+ });
+
+ it("preserves failed work even when its output contains a missing-session diagnostic", async () => {
+ const ctx = context();
+ const result = await execute({ ...ctx, config: { ...ctx.config, env: {
+ CAPTURE_PATH: capturePath,
+ FIXTURE_STDOUT: `Already updated the task.\nSession ${SESSION_ID} not found.`,
+ FIXTURE_PROVIDER_ERROR: "Error: provider unavailable after tool execution",
+ } }, runtime: { ...ctx.runtime, sessionParams: { sessionId: SESSION_ID } } });
+ expect(await invocations()).toHaveLength(1);
+ expect(result.exitCode).toBe(1);
+ expect(result.summary).toContain("Already updated the task.");
+ expect(result.errorMessage).toBe("Error: provider unavailable after tool execution");
+ });
+
+ it("removes an obsolete instruction overlay when the bundle is removed", async () => {
+ const ctx = context();
+ await execute(ctx);
+ await execute({ ...ctx, config: { ...ctx.config, instructionsFilePath: undefined }, runtime: { ...ctx.runtime, sessionParams: { sessionId: SESSION_ID } } });
+ const [, resumed] = await invocations();
+ expect(resumed.systemPrompt).not.toContain(INSTRUCTIONS);
+ expect(resumed.systemPrompt).toContain("Paperclip API guidance:");
+ expect(query(resumed)).toContain("Fresh human direction.");
+ });
+});
diff --git a/packages/adapters/hermes/src/server/execute.ts b/packages/adapters/hermes/src/server/execute.ts
index 828a3e2e002..98a5d85846e 100644
--- a/packages/adapters/hermes/src/server/execute.ts
+++ b/packages/adapters/hermes/src/server/execute.ts
@@ -34,7 +34,6 @@ import {
renderTemplate,
ensureAbsoluteDirectory,
DEFAULT_PAPERCLIP_AGENT_PROMPT_TEMPLATE,
- DEFAULT_PAPERCLIP_CONVERSATION_PROMPT_TEMPLATE,
joinPromptSections,
selectPaperclipPromptSections,
stringifyPaperclipWakePayload,
@@ -82,7 +81,7 @@ export function resolveHermesCommand(config: Record): string {
// Wake-up prompt builder
// ---------------------------------------------------------------------------
-const HERMES_DEFAULT_PROMPT_TEMPLATE = [
+const HERMES_RUNTIME_IDENTITY_TEMPLATE = [
'You are "{{agent.name}}", an AI agent employee in a Paperclip-managed company.',
"",
"Paperclip runtime identity:",
@@ -90,7 +89,11 @@ const HERMES_DEFAULT_PROMPT_TEMPLATE = [
"- Company ID: {{agent.companyId}}",
"- Run ID: {{run.id}}",
"- API base: {{paperclipApiUrl}}",
- "",
+].join("\n");
+
+// Hermes applies this overlay at each API call, including after compaction,
+// without storing it in conversation history. Keep run/task deltas in -q.
+const HERMES_SYSTEM_PROMPT_TEMPLATE = [
"Paperclip API guidance:",
"- Use `curl` from the terminal for Paperclip API calls; browser/web extraction tools may not reach localhost.",
"- Use `$PAPERCLIP_API_URL`, `$PAPERCLIP_API_KEY`, and `$PAPERCLIP_RUN_ID`; do not hard-code local ports or copy secrets into comments.",
@@ -112,7 +115,7 @@ const HERMES_DEFAULT_PROMPT_TEMPLATE = [
"MD",
")",
"jq -n --arg status done --arg comment \"$body\" '{status:$status, comment:$comment}' | \\",
- " curl -sS -X PATCH \"$api/issues/{{context.issueId}}\" \\",
+ " curl -sS -X PATCH \"$api/issues/$PAPERCLIP_TASK_ID\" \\",
" -H \"Authorization: Bearer $PAPERCLIP_API_KEY\" \\",
" -H \"X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID\" \\",
" -H \"Content-Type: application/json\" \\",
@@ -141,9 +144,7 @@ export function buildPrompt(
options: { resumedSession?: boolean } = {},
): string {
const context = (ctx as any).context || {};
- const template = cfgString(config.promptTemplate) || (context.conversationMode === true
- ? DEFAULT_PAPERCLIP_CONVERSATION_PROMPT_TEMPLATE
- : HERMES_DEFAULT_PROMPT_TEMPLATE);
+ const template = cfgString(config.promptTemplate);
const taskId = cfgString(context.taskId) || cfgString(context.issueId) || cfgString(ctx.config?.taskId);
const taskTitle = cfgString(context.taskTitle) || cfgString(ctx.config?.taskTitle) || "";
const taskBody = cfgString(context.taskBody) || cfgString(ctx.config?.taskBody) || "";
@@ -200,10 +201,11 @@ export function buildPrompt(
paperclipRunIdEnv: "PAPERCLIP_RUN_ID",
};
- const rendered = isPaperclipRecoveryWakePayload(context.paperclipWake)
- ? ""
- : renderTemplate(renderConditionalSections(template, vars), vars);
+ const rendered = template && !isPaperclipRecoveryWakePayload(context.paperclipWake)
+ ? renderTemplate(renderConditionalSections(template, vars), vars)
+ : "";
return joinPromptSections([
+ renderTemplate(HERMES_RUNTIME_IDENTITY_TEMPLATE, vars),
wakePrompt,
sessionHandoffMarkdown,
taskContextMarkdown,
@@ -404,7 +406,7 @@ export async function execute(
// ── Load agent instructions file (Paperclip instruction bundles) ──────
// Paperclip can materialize managed instructions into instructionsFilePath;
- // when present, inject that bundle into the Hermes prompt.
+ // when present, reapply that bundle through Hermes's native system overlay.
const instructionsFilePath = cfgString(config.instructionsFilePath);
let agentInstructions = "";
if (instructionsFilePath) {
@@ -430,10 +432,8 @@ export async function execute(
}
// ── Build prompt ───────────────────────────────────────────────────────
- let prompt = buildPrompt(ctx, config, { resumedSession: Boolean(prevSessionId) });
- if (agentInstructions) {
- prompt = agentInstructions + "\n\n---\n\n" + prompt;
- }
+ const sessionId = persistSession ? prevSessionId : undefined;
+ const prompt = buildPrompt(ctx, config, { resumedSession: Boolean(sessionId) });
// ── Build command args ─────────────────────────────────────────────────
// Use -Q (quiet) to get clean output: just response + session_id line
@@ -474,13 +474,9 @@ export async function execute(
// system is designed for human-attended interactive sessions.
args.push("--yolo");
- if (persistSession && prevSessionId) {
- args.push("--resume", prevSessionId);
- }
-
- if (extraArgs?.length) {
- args.push(...extraArgs);
- }
+ // Failed resumes remain failures. Do not infer a safe restart from CLI text.
+ if (sessionId) args.push("--resume", sessionId);
+ if (extraArgs?.length) args.push(...extraArgs);
// ── Build environment ──────────────────────────────────────────────────
const userEnv = config.env as Record | undefined;
@@ -491,6 +487,17 @@ export async function execute(
...buildRuntimeToolsEnv(ctx.runtimeTools),
};
+ // Scope the overlay to this child process. Read the current bundle on every
+ // invocation; never infer its availability from a persisted session ID.
+ // Preserve an operator's explicit overlay before Paperclip's instructions.
+ env.HERMES_EPHEMERAL_SYSTEM_PROMPT = joinPromptSections([
+ env.HERMES_EPHEMERAL_SYSTEM_PROMPT,
+ agentInstructions,
+ renderTemplate(HERMES_SYSTEM_PROMPT_TEMPLATE, {
+ agent: ctx.agent,
+ }),
+ ]);
+
if (ctx.runId) env.PAPERCLIP_RUN_ID = ctx.runId;
// PAPERCLIP_API_KEY is never accepted from config — the harness-minted run
@@ -527,10 +534,10 @@ export async function execute(
"stdout",
`[hermes] Starting Hermes Agent (model=${model}, provider=${resolvedProvider} [${resolvedFrom}], timeout=${timeoutSec}s${maxTurns ? `, max_turns=${maxTurns}` : ""})\n`,
);
- if (prevSessionId) {
+ if (sessionId) {
await ctx.onLog(
"stdout",
- `[hermes] Resuming session: ${prevSessionId}\n`,
+ `[hermes] Resuming session: ${sessionId}\n`,
);
}
diff --git a/packages/adapters/hermes/src/server/prompt-rendering.test.ts b/packages/adapters/hermes/src/server/prompt-rendering.test.ts
index b47dca03619..dc6ba503110 100644
--- a/packages/adapters/hermes/src/server/prompt-rendering.test.ts
+++ b/packages/adapters/hermes/src/server/prompt-rendering.test.ts
@@ -234,19 +234,16 @@ test("keeps authoritative parent and ancestor context from task markdown", () =>
expect(prompt).not.toContain("check the issue body or comments for references");
});
-test("renders safe Paperclip API examples from environment variables with multiline update preservation", () => {
+test("keeps current runtime identity in the user turn without repeating static API examples", () => {
const prompt = buildPrompt(baseContext(), {
paperclipApiUrl: "http://paperclip.local/api",
});
- expect(prompt).toContain("Use `$PAPERCLIP_API_URL`, `$PAPERCLIP_API_KEY`, and `$PAPERCLIP_RUN_ID`");
- expect(prompt).toContain("Displayed command logs may redact secrets");
- expect(prompt).toContain('-H "Authorization: Bearer $PAPERCLIP_API_KEY"');
- expect(prompt).toContain('-H "X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID"');
- expect(prompt).toContain("body=$(cat <<'MD'");
- expect(prompt).toContain("jq -n --arg status done --arg comment \"$body\"");
- expect(prompt).toContain("--data-binary @-");
- expect(prompt).not.toContain("Authorization: Bearer <");
+ expect(prompt).toContain("- Agent ID: agent-1");
+ expect(prompt).toContain("- Company ID: company-1");
+ expect(prompt).toContain("- Run ID: run-1");
+ expect(prompt).toContain("- API base: http://paperclip.local/api");
+ expect(prompt).not.toContain("Safe multiline update pattern:");
});
test("preserves custom prompt templates while exposing runtime and wake variables", () => {
@@ -276,7 +273,7 @@ test("preserves custom prompt templates while exposing runtime and wake variable
expect(prompt).toContain('"reason":"issue_assigned"');
expect(prompt).toContain("## Paperclip Wake Payload");
expect(prompt).toContain("Issue description:\n```text\nUse the wake payload as runtime authority.\n```");
- expect(prompt).not.toContain("Paperclip runtime identity:");
+ expect(prompt).toContain("Paperclip runtime identity:");
});
test("keeps historical task markdown available to custom templates while automatic context uses assignment markdown", () => {
diff --git a/packages/db/src/client.ts b/packages/db/src/client.ts
index 3df9e543082..c1b34d21eb6 100644
--- a/packages/db/src/client.ts
+++ b/packages/db/src/client.ts
@@ -1,6 +1,5 @@
import { createHash } from "node:crypto";
import { drizzle as drizzlePg } from "drizzle-orm/postgres-js";
-import { migrate as migratePg } from "drizzle-orm/postgres-js/migrator";
import { readFile, readdir } from "node:fs/promises";
import { fileURLToPath } from "node:url";
import postgres from "postgres";
@@ -463,6 +462,14 @@ async function recordMigrationHistoryEntry(
);
}
+// These idempotent privacy migrations commit keyset batches inside their DO
+// blocks. Execute each statement at top level so DDL locks and completed batches
+// are released before the next batch. History is recorded only after completion.
+const MIGRATIONS_WITH_BATCH_COMMITS = new Set([
+ "0313_private_task_access.sql",
+ "0314_private_task_draft_assets.sql",
+]);
+
async function applyPendingMigrationsManually(
url: string,
pendingMigrations: string[],
@@ -475,47 +482,81 @@ async function applyPendingMigrationsManually(
journalEntries.map((entry) => [entry.fileName, normalizeFolderMillis(entry.folderMillis)]),
);
- const sql = createUtilitySql(url);
+ const pool = createUtilitySql(url);
try {
- const { migrationTableSchema, columnNames } = await ensureMigrationJournalTable(sql);
- const qualifiedTable = `${quoteIdentifier(migrationTableSchema)}.${quoteIdentifier(DRIZZLE_MIGRATIONS_TABLE)}`;
+ const sql = await pool.reserve();
+ try {
+ // A session lock survives each batch COMMIT. Reserve the connection so
+ // pool rotation cannot release it while another migrator is waiting.
+ await sql`SELECT pg_advisory_lock(hashtextextended('paperclip:migrations', 0))`;
+ const { migrationTableSchema, columnNames } = await ensureMigrationJournalTable(sql);
+ const qualifiedTable = `${quoteIdentifier(migrationTableSchema)}.${quoteIdentifier(DRIZZLE_MIGRATIONS_TABLE)}`;
- for (const migrationFile of orderedPendingMigrations) {
- const migrationContent = await readMigrationFileContent(migrationFile);
- const hash = createHash("sha256").update(migrationContent).digest("hex");
- const existingEntry = await migrationHistoryEntryExists(
- sql,
- qualifiedTable,
- columnNames,
- migrationFile,
- hash,
- );
- if (existingEntry) continue;
-
- await runInTransaction(sql, async () => {
- for (const statement of splitMigrationStatements(migrationContent)) {
- // Older dev schemas can already lack a constraint that the next
- // migration replaces. Keep the published SQL/hash intact and let
- // that harmless drop proceed; the replacement still runs normally.
- const executable = statement.replace(
- /^(\s*ALTER TABLE "[^"]+" DROP CONSTRAINT) (?!IF EXISTS\b)/i,
- "$1 IF EXISTS ",
- );
- await sql.unsafe(executable);
- }
-
- await recordMigrationHistoryEntry(
+ for (const migrationFile of orderedPendingMigrations) {
+ const migrationContent = await readMigrationFileContent(migrationFile);
+ const hash = createHash("sha256").update(migrationContent).digest("hex");
+ const existingEntry = await migrationHistoryEntryExists(
sql,
qualifiedTable,
columnNames,
migrationFile,
hash,
- folderMillisByFileName.get(migrationFile) ?? Date.now(),
);
- });
+ if (existingEntry) continue;
+
+ const applyMigration = async () => {
+ for (const statement of splitMigrationStatements(migrationContent)) {
+ if (MIGRATIONS_WITH_BATCH_COMMITS.has(migrationFile)) {
+ // A cancelled concurrent build leaves an invalid index. IF NOT
+ // EXISTS alone would skip it on retry and journal an incomplete index.
+ const index = statement.replace(/^\s*--.*$/gm, "").trim()
+ .match(/^CREATE (?:UNIQUE )?INDEX CONCURRENTLY IF NOT EXISTS "([A-Za-z_][A-Za-z0-9_]*)"/i);
+ if (index) {
+ const invalid = await sql<{ invalid: boolean }[]>`
+ SELECT NOT i.indisvalid AS invalid FROM pg_index i
+ JOIN pg_class c ON c.oid = i.indexrelid
+ JOIN pg_namespace n ON n.oid = c.relnamespace
+ WHERE n.nspname = 'public' AND c.relname = ${index[1]}`;
+ if (invalid[0]?.invalid) {
+ await sql.unsafe(`DROP INDEX CONCURRENTLY ${quoteIdentifier("public")}.${quoteIdentifier(index[1])}`);
+ }
+ }
+ }
+ // Older dev schemas can lack a replaced constraint. Preserve the
+ // published SQL/hash while allowing the harmless drop to proceed.
+ const executable = statement.replace(
+ /^(\s*ALTER TABLE "[^"]+" DROP CONSTRAINT) (?!IF EXISTS\b)/i,
+ "$1 IF EXISTS ",
+ );
+ await sql.unsafe(executable);
+ }
+
+ await recordMigrationHistoryEntry(
+ sql,
+ qualifiedTable,
+ columnNames,
+ migrationFile,
+ hash,
+ folderMillisByFileName.get(migrationFile) ?? Date.now(),
+ );
+ };
+ if (MIGRATIONS_WITH_BATCH_COMMITS.has(migrationFile)) {
+ await applyMigration();
+ } else {
+ await runInTransaction(sql, applyMigration);
+ }
+ }
+ } finally {
+ try {
+ await sql`SELECT pg_advisory_unlock(hashtextextended('paperclip:migrations', 0))`;
+ } catch {
+ // Preserve the migration error if the session died; PostgreSQL releases
+ // its lock on disconnect, and pool.end() closes any remaining connection.
+ }
+ sql.release();
}
} finally {
- await sql.end();
+ await pool.end();
}
}
@@ -1040,26 +1081,10 @@ export async function applyPendingMigrations(url: string): Promise {
if (initialState.status === "upToDate") return;
if (initialState.reason === "no-migration-journal-empty-db") {
- const sql = createUtilitySql(url);
- try {
- const db = drizzlePg(sql);
- await migratePg(db, { migrationsFolder: MIGRATIONS_FOLDER });
- } finally {
- await sql.end();
- }
-
- let bootstrappedState = await inspectMigrations(url);
- if (bootstrappedState.status === "upToDate") return;
- if (bootstrappedState.reason === "pending-migrations") {
- const repair = await reconcilePendingMigrationHistory(url);
- if (repair.repairedMigrations.length > 0) {
- bootstrappedState = await inspectMigrations(url);
- }
- if (bootstrappedState.status === "needsMigrations" && bootstrappedState.reason === "pending-migrations") {
- await applyPendingMigrationsManually(url, bootstrappedState.pendingMigrations);
- bootstrappedState = await inspectMigrations(url);
- }
- }
+ // Use the same per-file executor for bootstrap and upgrades: Drizzle wraps
+ // the whole journal in one transaction and cannot run committing backfills.
+ await applyPendingMigrationsManually(url, initialState.pendingMigrations);
+ const bootstrappedState = await inspectMigrations(url);
if (bootstrappedState.status === "upToDate") return;
throw new Error(
`Failed to bootstrap migrations: ${bootstrappedState.pendingMigrations.join(", ")}`,
@@ -1123,8 +1148,7 @@ export async function migratePostgresIfEmpty(url: string): Promise Promise> = [];
+const embeddedPostgresSupport = await getEmbeddedPostgresTestSupport();
+if (!embeddedPostgresSupport.supported) console.warn(`Private-task migration checks unavailable: ${embeddedPostgresSupport.reason}`);
+const describeEmbeddedPostgres = embeddedPostgresSupport.supported ? describe : describe.skip;
+
+async function migrationHash() {
+ const content = await fs.promises.readFile(new URL(`./migrations/${MIGRATION_FILE}`, import.meta.url), "utf8");
+ return createHash("sha256").update(content).digest("hex");
+}
+
+afterEach(async () => {
+ while (cleanups.length > 0) await cleanups.pop()?.();
+});
+
+describeEmbeddedPostgres("heartbeat run issue privacy migration", () => {
+ it("backfills every valid context issue binding and preserves maintenance runs", async () => {
+ const database = await startEmbeddedPostgresTestDatabase("paperclip-run-issue-privacy-");
+ cleanups.push(database.cleanup);
+ const sql = postgres(database.connectionString, { max: 1, onnotice: () => {} });
+ cleanups.push(async () => sql.end());
+
+ await sql`DELETE FROM "drizzle"."__drizzle_migrations" WHERE "hash" = ${await migrationHash()}`;
+
+ await sql`DROP TRIGGER IF EXISTS heartbeat_runs_set_scope_kind ON heartbeat_runs`;
+ const companyId = randomUUID();
+ const agentId = randomUUID();
+ const firstIssueId = randomUUID();
+ const secondIssueId = randomUUID();
+ const firstRunId = randomUUID();
+ const secondRunId = randomUUID();
+ const maintenanceRunId = randomUUID();
+
+ await sql`
+ INSERT INTO "companies" ("id", "name", "issue_prefix")
+ VALUES (${companyId}, 'Run Privacy', 'RPR')
+ `;
+ await sql`
+ INSERT INTO "agents" ("id", "company_id", "name", "role", "adapter_type", "adapter_config")
+ VALUES (${agentId}, ${companyId}, 'Runner', 'engineer', 'process', '{}'::jsonb)
+ `;
+ await sql`
+ INSERT INTO "issues" ("id", "company_id", "title", "identifier")
+ VALUES
+ (${firstIssueId}, ${companyId}, 'First private task', 'RPR-1'),
+ (${secondIssueId}, ${companyId}, 'Second private task', 'RPR-2')
+ `;
+ await sql`
+ INSERT INTO "heartbeat_runs" (
+ "id", "company_id", "agent_id", "status", "issue_id", "context_snapshot"
+ )
+ VALUES
+ (${firstRunId}, ${companyId}, ${agentId}, 'succeeded', NULL, ${sql.json({ issueId: firstIssueId })}),
+ (${secondRunId}, ${companyId}, ${agentId}, 'failed', NULL, ${sql.json({ taskId: secondIssueId })}),
+ (${maintenanceRunId}, ${companyId}, ${agentId}, 'succeeded', NULL, ${sql.json({ wakeReason: "heartbeat_timer" })})
+ `;
+
+ const legacyProjectId = randomUUID();
+ await sql`INSERT INTO projects (id, company_id, name, visibility) VALUES (${legacyProjectId}, ${companyId}, 'Legacy private project', 'private')`;
+ await sql`INSERT INTO activity_log (company_id, actor_type, actor_id, action, entity_type, entity_id)
+ VALUES (${companyId}, 'user', 'original-owner', 'project.created', 'project', ${legacyProjectId})`;
+ await sql`INSERT INTO project_access_members (company_id, project_id, subject_type, subject_id)
+ VALUES (${companyId}, ${legacyProjectId}, 'user', 'ordinary-reader')`;
+
+ const agentProjectId = randomUUID(), runProjectId = randomUUID(), preferredProjectId = randomUUID();
+ await sql`UPDATE heartbeat_runs SET responsible_user_id = 'run-owner' WHERE id = ${secondRunId}`;
+ await sql`INSERT INTO projects (id, company_id, name, visibility) VALUES
+ (${agentProjectId}, ${companyId}, 'Agent API project', 'private'),
+ (${runProjectId}, ${companyId}, 'Run-backed project', 'private'),
+ (${preferredProjectId}, ${companyId}, 'Recorded owner project', 'private')`;
+ await sql`INSERT INTO activity_log (company_id, actor_type, actor_id, responsible_user_id, run_id, action, entity_type, entity_id) VALUES
+ (${companyId}, 'agent', ${agentId}, 'activity-owner', NULL, 'project.created', 'project', ${agentProjectId}),
+ (${companyId}, 'agent', ${agentId}, NULL, ${secondRunId}, 'project.created', 'project', ${runProjectId}),
+ (${companyId}, 'agent', ${agentId}, 'activity-owner', ${secondRunId}, 'project.created', 'project', ${preferredProjectId})`;
+
+ await applyPendingMigrations(database.connectionString);
+ for (const [projectId, owner] of [[agentProjectId, 'activity-owner'], [runProjectId, 'run-owner'], [preferredProjectId, 'activity-owner']]) {
+ expect(await sql`SELECT privacy_owner_user_id FROM projects WHERE id = ${projectId}`).toEqual([{ privacy_owner_user_id: owner }]);
+ expect(await sql`SELECT subject_id FROM project_access_members WHERE project_id = ${projectId}`).toEqual([{ subject_id: owner }]);
+ }
+ const [legacyProject] = await sql`SELECT privacy_owner_user_id FROM projects WHERE id = ${legacyProjectId}`;
+ expect(legacyProject.privacy_owner_user_id).toBe('original-owner');
+ expect(await sql`SELECT subject_id FROM project_access_members WHERE project_id = ${legacyProjectId} ORDER BY subject_id`)
+ .toEqual([{ subject_id: 'ordinary-reader' }, { subject_id: 'original-owner' }]);
+
+
+ const rows = await sql<{ id: string; issue_id: string | null; scope_kind: string }[]>`
+ SELECT "id", "issue_id", "scope_kind"
+ FROM "heartbeat_runs"
+ WHERE "id" IN (${firstRunId}, ${secondRunId}, ${maintenanceRunId})
+ ORDER BY "id"
+ `;
+ const issueByRun = new Map(rows.map((row) => [row.id, row.issue_id]));
+ expect(issueByRun.get(firstRunId)).toBe(firstIssueId);
+ expect(issueByRun.get(secondRunId)).toBe(secondIssueId);
+ expect(issueByRun.get(maintenanceRunId)).toBeNull();
+ expect(rows.find((row) => row.id === firstRunId)?.scope_kind).toBe("issue");
+ expect(rows.find((row) => row.id === secondRunId)?.scope_kind).toBe("issue");
+ expect(rows.find((row) => row.id === maintenanceRunId)?.scope_kind).toBe("company");
+
+ const [parity] = await sql<{ expected_count: number; populated_count: number }[]>`
+ SELECT
+ count(*) FILTER (WHERE "context_snapshot" ? 'issueId' OR "context_snapshot" ? 'taskId')::int AS "expected_count",
+ count(*) FILTER (WHERE ("context_snapshot" ? 'issueId' OR "context_snapshot" ? 'taskId') AND "issue_id" IS NOT NULL)::int AS "populated_count"
+ FROM "heartbeat_runs"
+ WHERE "id" IN (${firstRunId}, ${secondRunId}, ${maintenanceRunId})
+ `;
+ expect(parity).toEqual({ expected_count: 2, populated_count: 2 });
+
+ const [newRun] = await sql<{ id: string; issue_id: string | null; scope_kind: string }[]>`
+ INSERT INTO heartbeat_runs (company_id, agent_id, status, context_snapshot)
+ VALUES (${companyId}, ${agentId}, 'succeeded', ${sql.json({ taskId: secondIssueId })})
+ RETURNING id, issue_id, scope_kind`;
+ expect(newRun).toMatchObject({ issue_id: secondIssueId, scope_kind: "issue" });
+ await sql`UPDATE heartbeat_runs SET context_snapshot = '{}'::jsonb, scope_kind = 'company' WHERE id = ${newRun.id}`;
+ expect(await sql`SELECT issue_id, scope_kind FROM heartbeat_runs WHERE id = ${newRun.id}`)
+ .toEqual([{ issue_id: secondIssueId, scope_kind: "issue" }]);
+
+ const indexes = await sql<{ indexname: string }[]>`
+ SELECT "indexname"
+ FROM "pg_indexes"
+ WHERE "schemaname" = 'public'
+ AND "indexname" = 'heartbeat_runs_company_issue_created_idx'
+ `;
+ expect(indexes).toHaveLength(1);
+ }, 30_000);
+
+ it("fails closed when a legacy issue claim cannot be resolved", async () => {
+ const database = await startEmbeddedPostgresTestDatabase("paperclip-run-issue-privacy-invalid-");
+ cleanups.push(database.cleanup);
+ const sql = postgres(database.connectionString, { max: 1, onnotice: () => {} });
+ cleanups.push(async () => sql.end());
+
+ await sql`DELETE FROM "drizzle"."__drizzle_migrations" WHERE "hash" = ${await migrationHash()}`;
+
+ await sql`DROP TRIGGER IF EXISTS heartbeat_runs_set_scope_kind ON heartbeat_runs`;
+ const companyId = randomUUID();
+ const otherCompanyId = randomUUID();
+ const agentId = randomUUID();
+ const foreignIssueId = randomUUID();
+ await sql`
+ INSERT INTO "companies" ("id", "name", "issue_prefix")
+ VALUES
+ (${companyId}, 'Run Privacy', 'RPI'),
+ (${otherCompanyId}, 'Other Company', 'RPO')
+ `;
+ await sql`
+ INSERT INTO "agents" ("id", "company_id", "name", "role", "adapter_type", "adapter_config")
+ VALUES (${agentId}, ${companyId}, 'Runner', 'engineer', 'process', '{}'::jsonb)
+ `;
+ await sql`
+ INSERT INTO "issues" ("id", "company_id", "title", "identifier")
+ VALUES (${foreignIssueId}, ${otherCompanyId}, 'Foreign task', 'RPO-1')
+ `;
+ await sql`
+ INSERT INTO "heartbeat_runs" ("company_id", "agent_id", "status", "context_snapshot")
+ VALUES
+ (${companyId}, ${agentId}, 'succeeded', ${sql.json({ issueId: "not-a-uuid" })}),
+ (${companyId}, ${agentId}, 'succeeded', ${sql.json({ issueId: randomUUID() })}),
+ (${companyId}, ${agentId}, 'succeeded', ${sql.json({ issueId: foreignIssueId })}),
+ (${companyId}, ${agentId}, 'succeeded', ${sql.json({ taskId: "not-a-uuid" })}),
+ (${companyId}, ${agentId}, 'succeeded', ${sql.json({ taskId: randomUUID() })}),
+ (${companyId}, ${agentId}, 'succeeded', ${sql.json({ taskId: foreignIssueId })}),
+ (${companyId}, ${agentId}, 'succeeded', ${sql.json({ taskId: null })})
+ `;
+
+ await applyPendingMigrations(database.connectionString);
+ const rows = await sql<{ issue_id: string | null; scope_kind: string }[]>`
+ SELECT issue_id, scope_kind FROM heartbeat_runs WHERE company_id = ${companyId}`;
+ expect(rows).toHaveLength(7);
+ expect(rows.every(row => row.scope_kind === "issue" && row.issue_id === null)).toBe(true);
+ // Re-running the migration preserves fail-closed tombstones and constraints.
+ await sql`DELETE FROM "drizzle"."__drizzle_migrations" WHERE "hash" = ${await migrationHash()}`;
+ await applyPendingMigrations(database.connectionString);
+ }, 30_000);
+
+ it("releases schema and completed-batch row locks and resumes after interruption", async () => {
+ const database = await startEmbeddedPostgresTestDatabase("paperclip-privacy-batch-commits-");
+ cleanups.push(database.cleanup);
+ const sql = postgres(database.connectionString, { max: 1, onnotice: () => {} });
+ cleanups.push(async () => sql.end());
+ const companyId = randomUUID(), agentId = randomUUID(), issueId = randomUUID();
+ const runId = (n: number) => `00000000-0000-0000-0000-${String(n).padStart(12, "0")}`;
+ await sql`INSERT INTO companies (id, name, issue_prefix) VALUES (${companyId}, 'Batch commits', 'BCH')`;
+ await sql`INSERT INTO agents (id, company_id, name, adapter_type) VALUES (${agentId}, ${companyId}, 'Runner', 'process')`;
+ await sql`INSERT INTO issues (id, company_id, title, visibility) VALUES (${issueId}, ${companyId}, 'Private task', 'private')`;
+ await sql`DROP TRIGGER heartbeat_runs_set_scope_kind ON heartbeat_runs`;
+ await sql`INSERT INTO heartbeat_runs (id, company_id, agent_id, status, context_snapshot)
+ SELECT ('00000000-0000-0000-0000-' || lpad(n::text, 12, '0'))::uuid,
+ ${companyId}::uuid, ${agentId}::uuid, 'succeeded', ${sql.json({ taskId: issueId })}::jsonb
+ FROM generate_series(1, 1001) n`;
+ // A failed concurrent build must be repaired rather than skipped by
+ // CREATE INDEX IF NOT EXISTS when the migration is retried.
+ await sql`DROP INDEX heartbeat_runs_company_issue_created_idx`;
+ await expect(sql.unsafe("CREATE UNIQUE INDEX CONCURRENTLY heartbeat_runs_company_issue_created_idx ON heartbeat_runs (company_id)"))
+ .rejects.toThrow();
+ await sql.unsafe(`CREATE FUNCTION interrupt_privacy_batch_fixture() RETURNS trigger LANGUAGE plpgsql AS $$
+ BEGIN
+ PERFORM pg_advisory_xact_lock(736319937);
+ RAISE EXCEPTION 'fixture interrupted second batch';
+ END $$`);
+ await sql.unsafe(`CREATE TRIGGER zzz_interrupt_privacy_batch_fixture BEFORE UPDATE ON heartbeat_runs
+ FOR EACH ROW WHEN (OLD.scope_kind = 'company' AND NEW.id = '${runId(1001)}'::uuid)
+ EXECUTE FUNCTION interrupt_privacy_batch_fixture()`);
+ const hash = await migrationHash();
+ await sql`DELETE FROM drizzle.__drizzle_migrations WHERE hash = ${hash}`;
+ await sql`SELECT pg_advisory_lock(736319937)`;
+ const migration = applyPendingMigrations(database.connectionString).then(() => null, error => error);
+ let contender: Promise | undefined;
+ try {
+ // The second batch is blocked while another session can see the first
+ // committed batch and write a row whose lock has already been released.
+ await expect.poll(async () => {
+ const [row] = await sql`SELECT count(*)::int AS n FROM heartbeat_runs
+ WHERE company_id = ${companyId} AND scope_kind = 'issue'`;
+ return row.n;
+ }, { timeout: 10_000 }).toBe(1000);
+ // The session lock survives batch commits and blocks another migrator.
+ contender = applyPendingMigrations(database.connectionString).then(() => null, error => error);
+ await expect.poll(async () => {
+ const [row] = await sql`SELECT count(*)::int AS n FROM pg_stat_activity
+ WHERE datname = current_database() AND wait_event = 'advisory'
+ AND strpos(query, 'paperclip:migrations') > 0`;
+ return row.n;
+ }, { timeout: 10_000 }).toBe(1);
+ expect(await sql`SELECT hash FROM drizzle.__drizzle_migrations WHERE hash = ${hash}`).toHaveLength(0);
+ await sql`SET lock_timeout = '500ms'`;
+ await sql`UPDATE heartbeat_runs SET context_snapshot = context_snapshot || '{"probe":"visible"}'::jsonb
+ WHERE id = ${runId(1)}`;
+ expect(await sql`SELECT context_snapshot->>'probe' AS probe FROM heartbeat_runs WHERE id = ${runId(1)}`)
+ .toEqual([{ probe: "visible" }]);
+ } finally {
+ await sql`SELECT pg_advisory_unlock(736319937)`;
+ await sql`RESET lock_timeout`;
+ await migration;
+ await contender;
+ }
+ expect(await migration).toMatchObject({ message: "fixture interrupted second batch" });
+ expect(await contender).toMatchObject({ message: "fixture interrupted second batch" });
+ expect(await sql`SELECT hash FROM drizzle.__drizzle_migrations WHERE hash = ${hash}`).toHaveLength(0);
+ await sql`DROP TRIGGER zzz_interrupt_privacy_batch_fixture ON heartbeat_runs`;
+ await sql`DROP FUNCTION interrupt_privacy_batch_fixture()`;
+ await Promise.all([applyPendingMigrations(database.connectionString), applyPendingMigrations(database.connectionString)]);
+ const [finished] = await sql`SELECT count(*)::int AS n FROM heartbeat_runs
+ WHERE company_id = ${companyId} AND scope_kind = 'issue' AND issue_id = ${issueId}`;
+ expect(finished.n).toBe(1001);
+ expect(await sql`SELECT indisvalid FROM pg_index WHERE indexrelid = 'heartbeat_runs_company_issue_created_idx'::regclass`)
+ .toEqual([{ indisvalid: true }]);
+ expect(await sql`SELECT hash FROM drizzle.__drizzle_migrations WHERE hash = ${hash}`).toHaveLength(1);
+ }, 30_000);
+
+ it("keeps all privacy triggers installed when replacement is interrupted", async () => {
+ const database = await startEmbeddedPostgresTestDatabase("paperclip-privacy-trigger-atomic-");
+ cleanups.push(database.cleanup);
+ const sql = postgres(database.connectionString, { max: 1, onnotice: () => {} });
+ cleanups.push(async () => sql.end());
+ const content = await fs.promises.readFile(new URL(`./migrations/${MIGRATION_FILE}`, import.meta.url), "utf8");
+ const replacements = content.split("--> statement-breakpoint").filter(statement => /DROP TRIGGER IF EXISTS/.test(statement));
+ expect(replacements).toHaveLength(4);
+ for (const statement of replacements) {
+ const name = statement.match(/DROP TRIGGER IF EXISTS ([A-Za-z_]+)/)![1];
+ const interrupted = statement.replace("CREATE TRIGGER", "RAISE EXCEPTION 'fixture interrupted trigger replacement';\n CREATE TRIGGER");
+ await expect(sql.unsafe(interrupted)).rejects.toThrow("fixture interrupted trigger replacement");
+ expect(await sql`SELECT tgname FROM pg_trigger WHERE tgname = ${name} AND NOT tgisinternal`).toEqual([{ tgname: name }]);
+ }
+ const companyId = randomUUID(), agentId = randomUUID(), issueId = randomUUID();
+ await sql`INSERT INTO companies (id, name, issue_prefix) VALUES (${companyId}, 'Atomic triggers', 'ATR')`;
+ await sql`INSERT INTO agents (id, company_id, name, adapter_type) VALUES (${agentId}, ${companyId}, 'Runner', 'process')`;
+ await sql`INSERT INTO issues (id, company_id, title, visibility) VALUES (${issueId}, ${companyId}, 'Private', 'private')`;
+ expect(await sql`INSERT INTO heartbeat_runs (company_id, agent_id, status, context_snapshot)
+ VALUES (${companyId}, ${agentId}, 'succeeded', ${sql.json({ taskId: issueId })}) RETURNING issue_id, scope_kind`)
+ .toEqual([{ issue_id: issueId, scope_kind: "issue" }]);
+ }, 30_000);
+
+});
diff --git a/packages/db/src/migrations/0312_easy_eternity.sql b/packages/db/src/migrations/0312_easy_eternity.sql
new file mode 100644
index 00000000000..b02c9dae3a3
--- /dev/null
+++ b/packages/db/src/migrations/0312_easy_eternity.sql
@@ -0,0 +1,232 @@
+-- Preserve values while upgrading exact accounting. Additions are replay-safe.
+CREATE TABLE IF NOT EXISTS "accounting_runtime_baselines" (
+ "agent_id" uuid PRIMARY KEY NOT NULL,
+ "company_id" uuid NOT NULL,
+ "cost_cents" numeric(24, 7) NOT NULL,
+ "input_tokens" numeric(30, 0) NOT NULL,
+ "cached_input_tokens" numeric(30, 0) NOT NULL,
+ "output_tokens" numeric(30, 0) NOT NULL,
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "billing_invoice_lines" (
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
+ "company_id" uuid NOT NULL,
+ "invoice_id" uuid NOT NULL,
+ "external_id" text NOT NULL,
+ "kind" text NOT NULL,
+ "amount_cents" numeric(24, 7) NOT NULL,
+ "occurred_at" timestamp with time zone NOT NULL,
+ "cost_event_id" uuid,
+ "run_id" uuid,
+ "provider_request_id" text,
+ "model" text,
+ "pricing" jsonb DEFAULT '{}'::jsonb NOT NULL,
+ CONSTRAINT "billing_invoice_lines_amount_check" CHECK ("billing_invoice_lines"."amount_cents" >= 0),
+ CONSTRAINT "billing_invoice_lines_kind_check" CHECK ("billing_invoice_lines"."kind" in ('inference', 'fee', 'credit'))
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "billing_invoices" (
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
+ "company_id" uuid NOT NULL,
+ "biller" text NOT NULL,
+ "external_id" text NOT NULL,
+ "currency" text NOT NULL,
+ "receipt_hash" text NOT NULL,
+ "imported_by" text NOT NULL,
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "budget_reservations" (
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
+ "company_id" uuid NOT NULL,
+ "run_id" uuid NOT NULL,
+ "agent_id" uuid NOT NULL,
+ "project_id" uuid,
+ "amount_cents" numeric(24, 7) NOT NULL,
+ "state" text DEFAULT 'held' NOT NULL,
+ "provider_started_at" timestamp with time zone,
+ "settled_at" timestamp with time zone,
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
+ CONSTRAINT "budget_reservations_state_check" CHECK ("budget_reservations"."state" in ('held', 'settled', 'released')),
+ CONSTRAINT "budget_reservations_amount_check" CHECK ("budget_reservations"."amount_cents" >= 0)
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "cost_adjustments" (
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
+ "company_id" uuid NOT NULL,
+ "cost_event_id" uuid NOT NULL,
+ "invoice_line_id" uuid,
+ "idempotency_key" text NOT NULL,
+ "receipt_hash" text NOT NULL,
+ "previous_cents" numeric(24, 7) NOT NULL,
+ "corrected_cents" numeric(24, 7) NOT NULL,
+ "previous_status" text NOT NULL,
+ "previous_pricing" jsonb DEFAULT '{}'::jsonb NOT NULL,
+ "reason" text NOT NULL,
+ "actor_id" text NOT NULL,
+ "pricing" jsonb DEFAULT '{}'::jsonb NOT NULL,
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
+ CONSTRAINT "cost_adjustments_amount_check" CHECK ("cost_adjustments"."previous_cents" >= 0 and "cost_adjustments"."corrected_cents" >= 0)
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "provider_billing_snapshots" (
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
+ "company_id" uuid NOT NULL,
+ "provider" text NOT NULL,
+ "account_id" text NOT NULL,
+ "scope_id" text NOT NULL,
+ "day" text NOT NULL,
+ "amount_cents" numeric(24, 7) NOT NULL,
+ "revision" integer DEFAULT 1 NOT NULL,
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
+ CONSTRAINT "provider_billing_snapshots_amount_check" CHECK ("provider_billing_snapshots"."amount_cents" >= 0)
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "run_usage_receipts" (
+ "id" uuid PRIMARY KEY NOT NULL,
+ "company_id" uuid NOT NULL,
+ "run_id" uuid NOT NULL,
+ "source_id" uuid NOT NULL,
+ "sequence" integer NOT NULL,
+ "receipt_hash" text NOT NULL,
+ "receipt_json" jsonb NOT NULL,
+ "complete" boolean NOT NULL,
+ "received_at" timestamp with time zone NOT NULL,
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
+ CONSTRAINT "run_usage_receipts_positive_sequence" CHECK ("run_usage_receipts"."sequence" > 0)
+);
+--> statement-breakpoint
+DROP INDEX IF EXISTS "budget_incidents_policy_window_threshold_idx";--> statement-breakpoint
+ALTER TABLE "agent_runtime_state" ALTER COLUMN "total_cost_cents" SET DATA TYPE numeric(24, 7);--> statement-breakpoint
+ALTER TABLE "agents" ALTER COLUMN "spent_monthly_cents" SET DATA TYPE numeric(24, 7);--> statement-breakpoint
+ALTER TABLE "budget_incidents" ALTER COLUMN "amount_observed" SET DATA TYPE numeric(24, 7);--> statement-breakpoint
+ALTER TABLE "companies" ALTER COLUMN "spent_monthly_cents" SET DATA TYPE numeric(24, 7);--> statement-breakpoint
+ALTER TABLE "cost_events" ALTER COLUMN "cost_cents" SET DATA TYPE numeric(24, 7);--> statement-breakpoint
+ALTER TABLE "finance_events" ALTER COLUMN "amount_cents" SET DATA TYPE numeric(24, 7);--> statement-breakpoint
+ALTER TABLE "agents" ADD COLUMN IF NOT EXISTS "spend_month_utc" text;--> statement-breakpoint
+ALTER TABLE "budget_policies" ADD COLUMN IF NOT EXISTS "reservation_cents" numeric(24, 7) DEFAULT '0' NOT NULL;--> statement-breakpoint
+ALTER TABLE "budget_policies" ADD COLUMN IF NOT EXISTS "unpriced_usage_policy" text DEFAULT 'block' NOT NULL;--> statement-breakpoint
+ALTER TABLE "budget_policies" ADD COLUMN IF NOT EXISTS "enforcement_version" integer DEFAULT 0 NOT NULL;--> statement-breakpoint
+ALTER TABLE "budget_policies" ADD COLUMN IF NOT EXISTS "enforcement_delivered_version" integer DEFAULT 0 NOT NULL;--> statement-breakpoint
+ALTER TABLE "companies" ADD COLUMN IF NOT EXISTS "spend_month_utc" text;--> statement-breakpoint
+ALTER TABLE "cost_events" ADD COLUMN IF NOT EXISTS "idempotency_key" text;--> statement-breakpoint
+ALTER TABLE "cost_events" ADD COLUMN IF NOT EXISTS "receipt_hash" text;--> statement-breakpoint
+ALTER TABLE "cost_events" ADD COLUMN IF NOT EXISTS "provider_request_id" text;--> statement-breakpoint
+ALTER TABLE "cost_events" ADD COLUMN IF NOT EXISTS "reported_cost_cents" numeric(24, 7);--> statement-breakpoint
+ALTER TABLE "cost_events" ADD COLUMN IF NOT EXISTS "pricing_provenance" jsonb;--> statement-breakpoint
+ALTER TABLE "finance_events" ADD COLUMN IF NOT EXISTS "idempotency_key" text;--> statement-breakpoint
+ALTER TABLE "finance_events" ADD COLUMN IF NOT EXISTS "receipt_hash" text;--> statement-breakpoint
+ALTER TABLE "heartbeat_runs" ADD COLUMN IF NOT EXISTS "cost_accounting_pending" boolean DEFAULT false NOT NULL;--> statement-breakpoint
+ALTER TABLE "heartbeat_runs" ADD COLUMN IF NOT EXISTS "cost_accounted_at" timestamp with time zone;--> statement-breakpoint
+ALTER TABLE "heartbeat_runs" ADD COLUMN IF NOT EXISTS "accounting_projection_version" text;--> statement-breakpoint
+ALTER TABLE "heartbeat_runs" ADD COLUMN IF NOT EXISTS "accounting_last_attempt_at" timestamp with time zone;--> statement-breakpoint
+ALTER TABLE "heartbeat_runs" ADD COLUMN IF NOT EXISTS "accounting_last_error" text;--> statement-breakpoint
+ALTER TABLE "heartbeat_runs" ADD COLUMN IF NOT EXISTS "accounting_attempt_count" integer DEFAULT 0 NOT NULL;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'accounting_runtime_baselines_agent_id_agents_id_fk' AND conrelid = 'public.accounting_runtime_baselines'::regclass) THEN
+ ALTER TABLE "accounting_runtime_baselines" ADD CONSTRAINT "accounting_runtime_baselines_agent_id_agents_id_fk" FOREIGN KEY ("agent_id") REFERENCES "public"."agents"("id") ON DELETE cascade ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'accounting_runtime_baselines_company_id_companies_id_fk' AND conrelid = 'public.accounting_runtime_baselines'::regclass) THEN
+ ALTER TABLE "accounting_runtime_baselines" ADD CONSTRAINT "accounting_runtime_baselines_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'billing_invoice_lines_company_id_companies_id_fk' AND conrelid = 'public.billing_invoice_lines'::regclass) THEN
+ ALTER TABLE "billing_invoice_lines" ADD CONSTRAINT "billing_invoice_lines_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'billing_invoice_lines_invoice_id_billing_invoices_id_fk' AND conrelid = 'public.billing_invoice_lines'::regclass) THEN
+ ALTER TABLE "billing_invoice_lines" ADD CONSTRAINT "billing_invoice_lines_invoice_id_billing_invoices_id_fk" FOREIGN KEY ("invoice_id") REFERENCES "public"."billing_invoices"("id") ON DELETE cascade ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'billing_invoice_lines_cost_event_id_cost_events_id_fk' AND conrelid = 'public.billing_invoice_lines'::regclass) THEN
+ ALTER TABLE "billing_invoice_lines" ADD CONSTRAINT "billing_invoice_lines_cost_event_id_cost_events_id_fk" FOREIGN KEY ("cost_event_id") REFERENCES "public"."cost_events"("id") ON DELETE cascade ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'billing_invoices_company_id_companies_id_fk' AND conrelid = 'public.billing_invoices'::regclass) THEN
+ ALTER TABLE "billing_invoices" ADD CONSTRAINT "billing_invoices_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'budget_reservations_company_id_companies_id_fk' AND conrelid = 'public.budget_reservations'::regclass) THEN
+ ALTER TABLE "budget_reservations" ADD CONSTRAINT "budget_reservations_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'budget_reservations_run_id_heartbeat_runs_id_fk' AND conrelid = 'public.budget_reservations'::regclass) THEN
+ ALTER TABLE "budget_reservations" ADD CONSTRAINT "budget_reservations_run_id_heartbeat_runs_id_fk" FOREIGN KEY ("run_id") REFERENCES "public"."heartbeat_runs"("id") ON DELETE cascade ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'budget_reservations_agent_id_agents_id_fk' AND conrelid = 'public.budget_reservations'::regclass) THEN
+ ALTER TABLE "budget_reservations" ADD CONSTRAINT "budget_reservations_agent_id_agents_id_fk" FOREIGN KEY ("agent_id") REFERENCES "public"."agents"("id") ON DELETE cascade ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'cost_adjustments_company_id_companies_id_fk' AND conrelid = 'public.cost_adjustments'::regclass) THEN
+ ALTER TABLE "cost_adjustments" ADD CONSTRAINT "cost_adjustments_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'cost_adjustments_cost_event_id_cost_events_id_fk' AND conrelid = 'public.cost_adjustments'::regclass) THEN
+ ALTER TABLE "cost_adjustments" ADD CONSTRAINT "cost_adjustments_cost_event_id_cost_events_id_fk" FOREIGN KEY ("cost_event_id") REFERENCES "public"."cost_events"("id") ON DELETE cascade ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'cost_adjustments_invoice_line_id_billing_invoice_lines_id_fk' AND conrelid = 'public.cost_adjustments'::regclass) THEN
+ ALTER TABLE "cost_adjustments" ADD CONSTRAINT "cost_adjustments_invoice_line_id_billing_invoice_lines_id_fk" FOREIGN KEY ("invoice_line_id") REFERENCES "public"."billing_invoice_lines"("id") ON DELETE cascade ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'provider_billing_snapshots_company_id_companies_id_fk' AND conrelid = 'public.provider_billing_snapshots'::regclass) THEN
+ ALTER TABLE "provider_billing_snapshots" ADD CONSTRAINT "provider_billing_snapshots_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'run_usage_receipts_company_id_companies_id_fk' AND conrelid = 'public.run_usage_receipts'::regclass) THEN
+ ALTER TABLE "run_usage_receipts" ADD CONSTRAINT "run_usage_receipts_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'run_usage_receipts_run_id_heartbeat_runs_id_fk' AND conrelid = 'public.run_usage_receipts'::regclass) THEN
+ ALTER TABLE "run_usage_receipts" ADD CONSTRAINT "run_usage_receipts_run_id_heartbeat_runs_id_fk" FOREIGN KEY ("run_id") REFERENCES "public"."heartbeat_runs"("id") ON DELETE cascade ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "accounting_runtime_baselines_company_idx" ON "accounting_runtime_baselines" USING btree ("company_id");--> statement-breakpoint
+CREATE UNIQUE INDEX IF NOT EXISTS "billing_invoice_lines_identity_idx" ON "billing_invoice_lines" USING btree ("invoice_id","external_id");--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "billing_invoice_lines_company_idx" ON "billing_invoice_lines" USING btree ("company_id","invoice_id");--> statement-breakpoint
+CREATE UNIQUE INDEX IF NOT EXISTS "billing_invoices_identity_idx" ON "billing_invoices" USING btree ("company_id","biller","external_id");--> statement-breakpoint
+CREATE UNIQUE INDEX IF NOT EXISTS "budget_reservations_run_idx" ON "budget_reservations" USING btree ("company_id","run_id");--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "budget_reservations_active_idx" ON "budget_reservations" USING btree ("company_id","agent_id","project_id") WHERE "budget_reservations"."state" = 'held';--> statement-breakpoint
+CREATE UNIQUE INDEX IF NOT EXISTS "cost_adjustments_receipt_idx" ON "cost_adjustments" USING btree ("company_id","idempotency_key");--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "cost_adjustments_event_idx" ON "cost_adjustments" USING btree ("company_id","cost_event_id","created_at");--> statement-breakpoint
+CREATE UNIQUE INDEX IF NOT EXISTS "cost_adjustments_invoice_line_idx" ON "cost_adjustments" USING btree ("company_id","invoice_line_id");--> statement-breakpoint
+CREATE UNIQUE INDEX IF NOT EXISTS "provider_billing_snapshots_identity_idx" ON "provider_billing_snapshots" USING btree ("company_id","provider","account_id","scope_id","day");--> statement-breakpoint
+CREATE UNIQUE INDEX IF NOT EXISTS "run_usage_receipts_source_sequence_idx" ON "run_usage_receipts" USING btree ("company_id","run_id","source_id","sequence");--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "run_usage_receipts_run_latest_idx" ON "run_usage_receipts" USING btree ("company_id","run_id","received_at");--> statement-breakpoint
+CREATE UNIQUE INDEX IF NOT EXISTS "cost_events_company_receipt_idx" ON "cost_events" USING btree ("company_id","idempotency_key");--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "cost_events_provider_request_idx" ON "cost_events" USING btree ("company_id","biller","provider_request_id");--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "cost_events_company_project_occurred_idx" ON "cost_events" USING btree ("company_id","project_id","occurred_at");--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "cost_events_unpriced_idx" ON "cost_events" USING btree ("company_id","occurred_at","id") WHERE "cost_events"."cost_status" = 'unpriced' and "cost_events"."billing_type" <> 'subscription_included';--> statement-breakpoint
+CREATE UNIQUE INDEX IF NOT EXISTS "finance_events_company_receipt_idx" ON "finance_events" USING btree ("company_id","idempotency_key");--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "heartbeat_runs_cost_accounting_pending_idx" ON "heartbeat_runs" USING btree ("updated_at","id") WHERE "heartbeat_runs"."cost_accounting_pending" = true;--> statement-breakpoint
+CREATE UNIQUE INDEX IF NOT EXISTS "budget_incidents_policy_window_threshold_idx" ON "budget_incidents" USING btree ("policy_id","window_start","threshold_type") WHERE "budget_incidents"."status" = 'open';--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'budget_policies_reservation_nonnegative' AND conrelid = 'public.budget_policies'::regclass) THEN
+ ALTER TABLE "budget_policies" ADD CONSTRAINT "budget_policies_reservation_nonnegative" CHECK ("budget_policies"."reservation_cents" >= 0);
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'cost_events_nonnegative_amounts' AND conrelid = 'public.cost_events'::regclass) THEN
+ ALTER TABLE "cost_events" ADD CONSTRAINT "cost_events_nonnegative_amounts" CHECK ("cost_events"."cost_cents" >= 0 and "cost_events"."input_tokens" >= 0 and "cost_events"."cached_input_tokens" >= 0 and "cost_events"."output_tokens" >= 0);
+ END IF;
+END $$;
+--> statement-breakpoint
+-- Preserve the ledger precision in status-card update snapshots. Reapplying this type widening is safe.
+ALTER TABLE "status_card_updates" ALTER COLUMN "cost_cents" SET DATA TYPE numeric(24, 7);
diff --git a/packages/db/src/migrations/0313_private_task_access.sql b/packages/db/src/migrations/0313_private_task_access.sql
new file mode 100644
index 00000000000..480a3387400
--- /dev/null
+++ b/packages/db/src/migrations/0313_private_task_access.sql
@@ -0,0 +1,278 @@
+-- Runs through the Paperclip migration executor outside a file-wide transaction.
+-- Each idempotent keyset batch commits before advancing; history is recorded last.
+CREATE TABLE IF NOT EXISTS "issue_access_grants" (
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
+ "issue_id" uuid NOT NULL,
+ "subject_type" text NOT NULL,
+ "subject_id" text NOT NULL,
+ "source" text NOT NULL,
+ "granted_by_user_id" text,
+ "granted_by_agent_id" uuid,
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
+ "revoked_at" timestamp with time zone,
+ CONSTRAINT "issue_access_grants_subject_type_check" CHECK ("issue_access_grants"."subject_type" in ('user', 'agent')),
+ CONSTRAINT "issue_access_grants_source_check" CHECK ("issue_access_grants"."source" in ('explicit', 'assignment', 'project'))
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "project_access_members" (
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
+ "company_id" uuid NOT NULL,
+ "project_id" uuid NOT NULL,
+ "subject_type" text NOT NULL,
+ "subject_id" text NOT NULL,
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
+ CONSTRAINT "project_access_members_subject_type_check" CHECK ("project_access_members"."subject_type" in ('user', 'agent'))
+);
+--> statement-breakpoint
+ALTER TABLE "workspace_operations" DROP CONSTRAINT IF EXISTS "workspace_operations_heartbeat_run_id_heartbeat_runs_id_fk";
+--> statement-breakpoint
+ALTER TABLE "workspace_operations" DROP CONSTRAINT IF EXISTS "workspace_operations_issue_id_issues_id_fk";
+--> statement-breakpoint
+ALTER TABLE "heartbeat_runs" ADD COLUMN IF NOT EXISTS "scope_kind" text DEFAULT 'company' NOT NULL;--> statement-breakpoint
+ALTER TABLE "heartbeat_runs" ADD COLUMN IF NOT EXISTS "issue_id" uuid;--> statement-breakpoint
+ALTER TABLE "issues" ADD COLUMN IF NOT EXISTS "visibility" text DEFAULT 'open' NOT NULL;--> statement-breakpoint
+ALTER TABLE "issues" ADD COLUMN IF NOT EXISTS "privacy_root_issue_id" uuid;--> statement-breakpoint
+ALTER TABLE "issues" ADD COLUMN IF NOT EXISTS "privacy_parent_issue_id" uuid;--> statement-breakpoint
+ALTER TABLE "projects" ADD COLUMN IF NOT EXISTS "visibility" text DEFAULT 'open' NOT NULL;--> statement-breakpoint
+ALTER TABLE "projects" ADD COLUMN IF NOT EXISTS "personal_owner_user_id" text;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'issue_access_grants_issue_id_issues_id_fk' AND conrelid = 'public.issue_access_grants'::regclass) THEN
+ ALTER TABLE "issue_access_grants" ADD CONSTRAINT "issue_access_grants_issue_id_issues_id_fk" FOREIGN KEY ("issue_id") REFERENCES "public"."issues"("id") ON DELETE cascade ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'issue_access_grants_granted_by_agent_id_agents_id_fk' AND conrelid = 'public.issue_access_grants'::regclass) THEN
+ ALTER TABLE "issue_access_grants" ADD CONSTRAINT "issue_access_grants_granted_by_agent_id_agents_id_fk" FOREIGN KEY ("granted_by_agent_id") REFERENCES "public"."agents"("id") ON DELETE set null ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'project_access_members_company_id_companies_id_fk' AND conrelid = 'public.project_access_members'::regclass) THEN
+ ALTER TABLE "project_access_members" ADD CONSTRAINT "project_access_members_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'project_access_members_project_id_projects_id_fk' AND conrelid = 'public.project_access_members'::regclass) THEN
+ ALTER TABLE "project_access_members" ADD CONSTRAINT "project_access_members_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "issue_access_grants_subject_active_issue_idx" ON "issue_access_grants" USING btree ("subject_type","subject_id","revoked_at","issue_id");--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "issue_access_grants_issue_idx" ON "issue_access_grants" USING btree ("issue_id","created_at");--> statement-breakpoint
+CREATE UNIQUE INDEX IF NOT EXISTS "project_access_members_project_subject_uq" ON "project_access_members" USING btree ("project_id","subject_type","subject_id");--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "project_access_members_subject_lookup_idx" ON "project_access_members" USING btree ("company_id","subject_type","subject_id","project_id");--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'heartbeat_runs_issue_id_issues_id_fk' AND conrelid = 'public.heartbeat_runs'::regclass) THEN
+ ALTER TABLE "heartbeat_runs" ADD CONSTRAINT "heartbeat_runs_issue_id_issues_id_fk" FOREIGN KEY ("issue_id") REFERENCES "public"."issues"("id") ON DELETE set null ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'issues_privacy_root_issue_id_issues_id_fk' AND conrelid = 'public.issues'::regclass) THEN
+ ALTER TABLE "issues" ADD CONSTRAINT "issues_privacy_root_issue_id_issues_id_fk" FOREIGN KEY ("privacy_root_issue_id") REFERENCES "public"."issues"("id") ON DELETE no action ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'issues_privacy_parent_issue_id_issues_id_fk' AND conrelid = 'public.issues'::regclass) THEN
+ ALTER TABLE "issues" ADD CONSTRAINT "issues_privacy_parent_issue_id_issues_id_fk" FOREIGN KEY ("privacy_parent_issue_id") REFERENCES "public"."issues"("id") ON DELETE set null ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'workspace_operations_heartbeat_run_id_heartbeat_runs_id_fk' AND conrelid = 'public.workspace_operations'::regclass) THEN
+ ALTER TABLE "workspace_operations" ADD CONSTRAINT "workspace_operations_heartbeat_run_id_heartbeat_runs_id_fk" FOREIGN KEY ("heartbeat_run_id") REFERENCES "public"."heartbeat_runs"("id") ON DELETE set null ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'workspace_operations_issue_id_issues_id_fk' AND conrelid = 'public.workspace_operations'::regclass) THEN
+ ALTER TABLE "workspace_operations" ADD CONSTRAINT "workspace_operations_issue_id_issues_id_fk" FOREIGN KEY ("issue_id") REFERENCES "public"."issues"("id") ON DELETE set null ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+CREATE INDEX CONCURRENTLY IF NOT EXISTS "heartbeat_runs_company_issue_created_idx" ON "heartbeat_runs" USING btree ("company_id","issue_id","created_at");--> statement-breakpoint
+CREATE INDEX CONCURRENTLY IF NOT EXISTS "issues_company_privacy_parent_idx" ON "issues" USING btree ("company_id","privacy_parent_issue_id");--> statement-breakpoint
+CREATE INDEX CONCURRENTLY IF NOT EXISTS "issues_company_privacy_root_idx" ON "issues" USING btree ("company_id","privacy_root_issue_id");--> statement-breakpoint
+CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS "projects_company_personal_owner_uq" ON "projects" USING btree ("company_id","personal_owner_user_id") WHERE "projects"."personal_owner_user_id" is not null;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'heartbeat_runs_scope_binding_check' AND conrelid = 'public.heartbeat_runs'::regclass) THEN
+ ALTER TABLE "heartbeat_runs" ADD CONSTRAINT "heartbeat_runs_scope_binding_check" CHECK (("heartbeat_runs"."scope_kind" = 'company' AND "heartbeat_runs"."issue_id" IS NULL)
+ OR "heartbeat_runs"."scope_kind" = 'issue');
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'issues_visibility_check' AND conrelid = 'public.issues'::regclass) THEN
+ ALTER TABLE "issues" ADD CONSTRAINT "issues_visibility_check" CHECK ("issues"."visibility" in ('open', 'private'));
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'projects_visibility_check' AND conrelid = 'public.projects'::regclass) THEN
+ ALTER TABLE "projects" ADD CONSTRAINT "projects_visibility_check" CHECK ("projects"."visibility" in ('open', 'private'));
+ END IF;
+END $$;
+--> statement-breakpoint
+CREATE OR REPLACE FUNCTION set_heartbeat_run_scope_kind() RETURNS trigger LANGUAGE plpgsql AS $$
+DECLARE candidate uuid;
+BEGIN
+ -- A private run never becomes a company run through context edits or deletion.
+ IF TG_OP = 'UPDATE' AND OLD.scope_kind = 'issue' THEN
+ IF OLD.issue_id IS NOT NULL AND NEW.issue_id IS NOT NULL AND OLD.issue_id <> NEW.issue_id THEN
+ RAISE EXCEPTION 'run task binding is immutable';
+ END IF;
+ IF OLD.issue_id IS NOT NULL AND NEW.native_issue_id IS NOT NULL AND OLD.issue_id <> NEW.native_issue_id THEN
+ RAISE EXCEPTION 'native run task binding disagrees with privacy binding';
+ END IF;
+ NEW.scope_kind := 'issue';
+ RETURN NEW;
+ END IF;
+ candidate := coalesce(NEW.native_issue_id, NEW.issue_id);
+ IF candidate IS NULL AND coalesce(NEW.context_snapshot->>'issueId', NEW.context_snapshot->>'taskId') ~* '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' THEN
+ candidate := coalesce(NEW.context_snapshot->>'issueId', NEW.context_snapshot->>'taskId')::uuid;
+ END IF;
+ IF candidate IS NOT NULL OR NEW.context_snapshot ? 'issueId' OR NEW.context_snapshot ? 'taskId' OR NEW.scope_kind = 'issue' THEN
+ NEW.scope_kind := 'issue';
+ SELECT id INTO NEW.issue_id FROM issues WHERE id = candidate AND company_id = NEW.company_id;
+ ELSE
+ NEW.scope_kind := 'company';
+ END IF;
+ RETURN NEW;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ DROP TRIGGER IF EXISTS heartbeat_runs_set_scope_kind ON heartbeat_runs;
+ CREATE TRIGGER heartbeat_runs_set_scope_kind BEFORE INSERT OR UPDATE OF issue_id, native_issue_id, context_snapshot, scope_kind
+ ON heartbeat_runs FOR EACH ROW EXECUTE FUNCTION set_heartbeat_run_scope_kind();
+END $$;
+--> statement-breakpoint
+-- Indexed primary-key keyset batches visit each historical run once. Missing
+-- source tasks become issue-scoped tombstones, never company-visible run content.
+DO $$ DECLARE cursor_id uuid := '00000000-0000-0000-0000-000000000000'; next_id uuid;
+BEGIN LOOP
+ WITH batch AS MATERIALIZED (SELECT id FROM heartbeat_runs WHERE id > cursor_id ORDER BY id LIMIT 1000),
+ changed AS (UPDATE heartbeat_runs r SET scope_kind = r.scope_kind FROM batch b WHERE r.id = b.id RETURNING r.id)
+ SELECT id INTO next_id FROM changed ORDER BY id DESC LIMIT 1;
+ EXIT WHEN next_id IS NULL;
+ cursor_id := next_id;
+ COMMIT;
+END LOOP; END $$;
+--> statement-breakpoint
+-- Existing structural children acquire downward inheritance without widening
+-- any task's visibility. New provenance edges are written at task creation.
+DO $$ DECLARE cursor_id uuid := '00000000-0000-0000-0000-000000000000'; next_id uuid;
+BEGIN LOOP
+ WITH batch AS MATERIALIZED (SELECT id FROM issues WHERE id > cursor_id ORDER BY id LIMIT 1000),
+ changed AS (UPDATE issues i SET privacy_parent_issue_id = coalesce(i.privacy_parent_issue_id, i.parent_id)
+ FROM batch b WHERE i.id = b.id RETURNING i.id)
+ SELECT id INTO next_id FROM changed ORDER BY id DESC LIMIT 1;
+ EXIT WHEN next_id IS NULL;
+ cursor_id := next_id;
+ COMMIT;
+END LOOP; END $$;
+--> statement-breakpoint
+-- Keep workspace provenance after reassignment/deletion. A previous task may
+-- have left files behind; losing the live FK must not publish those files.
+CREATE OR REPLACE FUNCTION retain_workspace_privacy_sources() RETURNS trigger LANGUAGE plpgsql AS $$
+DECLARE sources jsonb := '{}'::jsonb; linked jsonb;
+BEGIN
+ IF TG_OP = 'UPDATE' AND jsonb_typeof(OLD.metadata->'_issuePrivacySources') = 'object' THEN
+ sources := OLD.metadata->'_issuePrivacySources';
+ END IF;
+ IF NEW.source_issue_id IS NOT NULL THEN
+ sources := sources || jsonb_build_object(NEW.source_issue_id::text, true);
+ END IF;
+ SELECT jsonb_object_agg(id::text, true) INTO linked FROM issues
+ WHERE execution_workspace_id = NEW.id AND company_id = NEW.company_id;
+ sources := sources || coalesce(linked, '{}'::jsonb);
+ NEW.metadata := coalesce(NEW.metadata, '{}'::jsonb) || jsonb_build_object('_issuePrivacySources', sources);
+ RETURN NEW;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ DROP TRIGGER IF EXISTS execution_workspaces_privacy_sources ON execution_workspaces;
+ CREATE TRIGGER execution_workspaces_privacy_sources BEFORE INSERT OR UPDATE OF source_issue_id, metadata
+ ON execution_workspaces FOR EACH ROW EXECUTE FUNCTION retain_workspace_privacy_sources();
+END $$;
+--> statement-breakpoint
+CREATE OR REPLACE FUNCTION record_issue_workspace_privacy_source() RETURNS trigger LANGUAGE plpgsql AS $$
+BEGIN
+ IF NEW.execution_workspace_id IS NOT NULL THEN
+ UPDATE execution_workspaces SET metadata = metadata
+ WHERE id = NEW.execution_workspace_id AND company_id = NEW.company_id;
+ END IF;
+ RETURN NEW;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ DROP TRIGGER IF EXISTS issues_record_workspace_privacy_source ON issues;
+ CREATE TRIGGER issues_record_workspace_privacy_source AFTER INSERT OR UPDATE OF execution_workspace_id
+ ON issues FOR EACH ROW EXECUTE FUNCTION record_issue_workspace_privacy_source();
+END $$;
+--> statement-breakpoint
+DO $$ DECLARE cursor_id uuid := '00000000-0000-0000-0000-000000000000'; next_id uuid;
+BEGIN LOOP
+ WITH batch AS MATERIALIZED (SELECT id FROM execution_workspaces WHERE id > cursor_id ORDER BY id LIMIT 1000),
+ changed AS (UPDATE execution_workspaces w SET metadata = metadata FROM batch b WHERE w.id = b.id RETURNING w.id)
+ SELECT id INTO next_id FROM changed ORDER BY id DESC LIMIT 1;
+ EXIT WHEN next_id IS NULL;
+ cursor_id := next_id;
+ COMMIT;
+END LOOP; END $$;
+
+--> statement-breakpoint
+-- Preserve operation history while retaining every original task/run boundary.
+CREATE OR REPLACE FUNCTION paperclip_keep_operation_privacy_sources() RETURNS trigger AS $$
+DECLARE issue_sources jsonb := '{}'::jsonb; run_sources jsonb := '{}'::jsonb;
+BEGIN
+ IF TG_OP = 'UPDATE' THEN
+ issue_sources := COALESCE(OLD.metadata->'_issuePrivacySources', '{}'::jsonb);
+ run_sources := COALESCE(OLD.metadata->'_runPrivacySources', '{}'::jsonb);
+ IF OLD.issue_id IS NOT NULL THEN issue_sources := issue_sources || jsonb_build_object(OLD.issue_id::text, true); END IF;
+ IF OLD.heartbeat_run_id IS NOT NULL THEN run_sources := run_sources || jsonb_build_object(OLD.heartbeat_run_id::text, true); END IF;
+ END IF;
+ IF NEW.issue_id IS NOT NULL THEN issue_sources := issue_sources || jsonb_build_object(NEW.issue_id::text, true); END IF;
+ IF NEW.heartbeat_run_id IS NOT NULL THEN run_sources := run_sources || jsonb_build_object(NEW.heartbeat_run_id::text, true); END IF;
+ NEW.metadata := COALESCE(NEW.metadata, '{}'::jsonb) || jsonb_build_object('_issuePrivacySources', issue_sources, '_runPrivacySources', run_sources);
+ RETURN NEW;
+END;
+$$ LANGUAGE plpgsql;
+--> statement-breakpoint
+DO $$ BEGIN
+ DROP TRIGGER IF EXISTS workspace_operations_keep_privacy_sources ON workspace_operations;
+ CREATE TRIGGER workspace_operations_keep_privacy_sources BEFORE INSERT OR UPDATE ON workspace_operations
+ FOR EACH ROW EXECUTE FUNCTION paperclip_keep_operation_privacy_sources();
+END $$;
+--> statement-breakpoint
+DO $$
+DECLARE cursor_id uuid := '00000000-0000-0000-0000-000000000000'; batch_ids uuid[];
+BEGIN
+ LOOP
+ SELECT array_agg(id ORDER BY id) INTO batch_ids FROM (
+ SELECT id FROM workspace_operations WHERE id > cursor_id ORDER BY id LIMIT 1000
+ ) batch;
+ EXIT WHEN batch_ids IS NULL;
+ UPDATE workspace_operations SET metadata = metadata WHERE id = ANY(batch_ids);
+ cursor_id := batch_ids[array_length(batch_ids, 1)];
+ COMMIT;
+ END LOOP;
+END $$;
+
+--> statement-breakpoint
+ALTER TABLE projects ADD COLUMN IF NOT EXISTS privacy_owner_user_id text;
+--> statement-breakpoint
+-- Recover management authority from creation evidence, never from read grants.
+DO $$
+DECLARE cursor_id uuid := '00000000-0000-0000-0000-000000000000'; batch_ids uuid[];
+BEGIN
+ LOOP
+ SELECT array_agg(id ORDER BY id) INTO batch_ids FROM (
+ SELECT id FROM projects WHERE id > cursor_id ORDER BY id LIMIT 1000
+ ) batch;
+ EXIT WHEN batch_ids IS NULL;
+ UPDATE projects p SET privacy_owner_user_id = COALESCE(p.personal_owner_user_id, (
+ SELECT CASE WHEN a.actor_type = 'user' THEN a.actor_id ELSE coalesce(a.responsible_user_id, r.responsible_user_id) END
+ FROM activity_log a LEFT JOIN heartbeat_runs r ON r.id = a.run_id AND r.company_id = a.company_id
+ WHERE a.company_id = p.company_id AND a.entity_type = 'project' AND a.entity_id = p.id::text AND a.action = 'project.created'
+ ORDER BY a.created_at, a.id LIMIT 1
+ )) WHERE p.id = ANY(batch_ids) AND p.privacy_owner_user_id IS NULL;
+ INSERT INTO project_access_members (company_id, project_id, subject_type, subject_id)
+ SELECT company_id, id, 'user', privacy_owner_user_id FROM projects
+ WHERE id = ANY(batch_ids) AND visibility = 'private' AND privacy_owner_user_id IS NOT NULL
+ ON CONFLICT (project_id, subject_type, subject_id) DO NOTHING;
+ cursor_id := batch_ids[array_length(batch_ids, 1)];
+ COMMIT;
+ END LOOP;
+END $$;
diff --git a/packages/db/src/migrations/0314_private_task_draft_assets.sql b/packages/db/src/migrations/0314_private_task_draft_assets.sql
new file mode 100644
index 00000000000..a7591cf72f9
--- /dev/null
+++ b/packages/db/src/migrations/0314_private_task_draft_assets.sql
@@ -0,0 +1,28 @@
+-- Runs through the Paperclip migration executor outside a file-wide transaction.
+-- Each idempotent keyset batch commits before advancing; history is recorded last.
+-- Bind historical inline draft images to their first owned task. Unbound drafts
+-- remain uploader-only. Attachment deletion never makes the draft company-open.
+DO $$
+DECLARE cursor_id uuid := '00000000-0000-0000-0000-000000000000'; next_id uuid;
+BEGIN
+ LOOP
+ SELECT max(id::text)::uuid INTO next_id FROM (
+ SELECT id FROM assets WHERE id > cursor_id AND object_key LIKE company_id::text || '/assets/issues/drafts/%'
+ ORDER BY id LIMIT 1000
+ ) batch;
+ EXIT WHEN next_id IS NULL;
+ INSERT INTO issue_attachments (company_id, issue_id, asset_id)
+ SELECT a.company_id, first_issue.id, a.id FROM assets a
+ CROSS JOIN LATERAL (
+ SELECT i.id FROM issues i WHERE i.company_id = a.company_id
+ AND (i.created_by_user_id = a.created_by_user_id OR i.responsible_user_id = a.created_by_user_id
+ OR i.created_by_agent_id = a.created_by_agent_id)
+ AND strpos(coalesce(i.description, ''), '/api/assets/' || a.id::text || '/content') > 0
+ ORDER BY i.created_at, i.id LIMIT 1
+ ) first_issue
+ WHERE a.id > cursor_id AND a.id <= next_id AND a.object_key LIKE a.company_id::text || '/assets/issues/drafts/%'
+ ON CONFLICT DO NOTHING;
+ cursor_id := next_id;
+ COMMIT;
+ END LOOP;
+END $$;
diff --git a/packages/db/src/migrations/0315_rapid_emma_frost.sql b/packages/db/src/migrations/0315_rapid_emma_frost.sql
new file mode 100644
index 00000000000..95330211675
--- /dev/null
+++ b/packages/db/src/migrations/0315_rapid_emma_frost.sql
@@ -0,0 +1,44 @@
+CREATE TABLE IF NOT EXISTS "user_company_preferences" (
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
+ "company_id" uuid NOT NULL,
+ "user_id" text NOT NULL,
+ "primary_agent_id" uuid,
+ "primary_agent_initialized" boolean DEFAULT false NOT NULL,
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL
+);
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "user_company_preferences" ADD CONSTRAINT "user_company_preferences_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION WHEN duplicate_object THEN NULL;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "user_company_preferences" ADD CONSTRAINT "user_company_preferences_primary_agent_id_agents_id_fk" FOREIGN KEY ("primary_agent_id") REFERENCES "public"."agents"("id") ON DELETE set null ON UPDATE no action;
+EXCEPTION WHEN duplicate_object THEN NULL;
+END $$;
+--> statement-breakpoint
+CREATE UNIQUE INDEX IF NOT EXISTS "user_company_preferences_company_user_uq" ON "user_company_preferences" USING btree ("company_id","user_id");--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "user_company_preferences_primary_agent_idx" ON "user_company_preferences" USING btree ("primary_agent_id");--> statement-breakpoint
+-- Attribute only explicit human creation events. Select the original event
+-- before joining the agent: deletion/termination must not promote a later hire.
+WITH first_creations AS (
+ SELECT DISTINCT ON (company_id, actor_id)
+ company_id, actor_id AS user_id, entity_id AS agent_id
+ FROM activity_log
+ WHERE actor_type = 'user'
+ AND actor_id NOT IN ('', 'board', 'system', 'unknown', 'unknown-user')
+ AND entity_type = 'agent'
+ AND action IN ('agent.created', 'agent.hire_created')
+ ORDER BY company_id, actor_id, created_at, id
+)
+INSERT INTO user_company_preferences (company_id, user_id, primary_agent_id, primary_agent_initialized)
+SELECT c.company_id, c.user_id,
+ CASE WHEN a.status != 'terminated' AND m.state IS DISTINCT FROM 'left'
+ THEN a.id ELSE NULL END,
+ true
+FROM first_creations c
+LEFT JOIN agents a ON a.id::text = c.agent_id AND a.company_id = c.company_id
+LEFT JOIN agent_memberships m ON m.company_id = c.company_id AND m.user_id = c.user_id AND m.agent_id = a.id
+WHERE a.metadata->'paperclipBuiltInAgent' IS NULL
+ON CONFLICT (company_id, user_id) DO NOTHING;
diff --git a/packages/db/src/migrations/0316_premium_slayback.sql b/packages/db/src/migrations/0316_premium_slayback.sql
new file mode 100644
index 00000000000..5c2965133ce
--- /dev/null
+++ b/packages/db/src/migrations/0316_premium_slayback.sql
@@ -0,0 +1,81 @@
+-- Idempotent for installations that applied the pre-merge decision migration.
+CREATE TABLE IF NOT EXISTS "company_decision_models" (
+ "company_id" uuid PRIMARY KEY NOT NULL,
+ "connection_id" uuid,
+ "grant_id" uuid,
+ "enabled" boolean DEFAULT false NOT NULL,
+ "allow_background" boolean DEFAULT true NOT NULL,
+ "provider" text,
+ "model" text,
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
+ CONSTRAINT "company_decisions_configured" CHECK (("company_decision_models"."connection_id" is null) = ("company_decision_models"."grant_id" is null) and (not "company_decision_models"."enabled" or ("company_decision_models"."connection_id" is not null and "company_decision_models"."provider" is not null and "company_decision_models"."model" is not null)))
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "decision_invocations" (
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
+ "company_id" uuid NOT NULL,
+ "feature" text NOT NULL,
+ "actor_type" text NOT NULL,
+ "actor_id" text NOT NULL,
+ "responsible_user_id" text,
+ "agent_id" uuid,
+ "issue_id" uuid,
+ "project_id" uuid,
+ "run_id" uuid,
+ "identity_context_id" uuid,
+ "connection_id" uuid NOT NULL,
+ "grant_id" uuid NOT NULL,
+ "provider" text NOT NULL,
+ "model" text NOT NULL,
+ "question_types" jsonb NOT NULL,
+ "status" text DEFAULT 'running' NOT NULL,
+ "error_code" text,
+ "provider_request_id" text,
+ "cost_event_id" uuid,
+ "started_at" timestamp with time zone DEFAULT now() NOT NULL,
+ "finished_at" timestamp with time zone,
+ "duration_ms" integer,
+ "input_tokens" integer,
+ "output_tokens" integer,
+ CONSTRAINT "decision_invocations_status_check" CHECK ("decision_invocations"."status" in ('running', 'succeeded', 'failed', 'unknown'))
+);
+--> statement-breakpoint
+ALTER TABLE "budget_reservations" ALTER COLUMN "run_id" DROP NOT NULL;--> statement-breakpoint
+ALTER TABLE "budget_reservations" ALTER COLUMN "agent_id" DROP NOT NULL;--> statement-breakpoint
+ALTER TABLE "cost_events" ALTER COLUMN "agent_id" DROP NOT NULL;--> statement-breakpoint
+ALTER TABLE "budget_reservations" ADD COLUMN IF NOT EXISTS "decision_invocation_id" uuid;--> statement-breakpoint
+ALTER TABLE "cost_events" ADD COLUMN IF NOT EXISTS "usage_kind" text DEFAULT 'agent' NOT NULL;--> statement-breakpoint
+ALTER TABLE "cost_events" ADD COLUMN IF NOT EXISTS "responsible_user_id" text;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'company_decision_models_company_id_companies_id_fk' AND conrelid = 'company_decision_models'::regclass) THEN
+ ALTER TABLE "company_decision_models" ADD CONSTRAINT "company_decision_models_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'decision_invocations_company_id_companies_id_fk' AND conrelid = 'decision_invocations'::regclass) THEN
+ ALTER TABLE "decision_invocations" ADD CONSTRAINT "decision_invocations_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'decision_invocations_cost_event_id_cost_events_id_fk' AND conrelid = 'decision_invocations'::regclass) THEN
+ ALTER TABLE "decision_invocations" ADD CONSTRAINT "decision_invocations_cost_event_id_cost_events_id_fk" FOREIGN KEY ("cost_event_id") REFERENCES "public"."cost_events"("id") ON DELETE no action ON UPDATE no action;
+ END IF;
+END $$;--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "decision_invocations_company_started_idx" ON "decision_invocations" USING btree ("company_id","started_at","id");--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "decision_invocations_pending_idx" ON "decision_invocations" USING btree ("started_at") WHERE "decision_invocations"."status" = 'running';--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "decision_invocations_cost_idx" ON "decision_invocations" USING btree ("cost_event_id");--> statement-breakpoint
+CREATE UNIQUE INDEX IF NOT EXISTS "budget_reservations_decision_idx" ON "budget_reservations" USING btree ("company_id","decision_invocation_id");--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'budget_reservations_source_check' AND conrelid = 'budget_reservations'::regclass) THEN
+ ALTER TABLE "budget_reservations" ADD CONSTRAINT "budget_reservations_source_check" CHECK (("budget_reservations"."run_id" is not null)::int + ("budget_reservations"."decision_invocation_id" is not null)::int = 1);
+ END IF;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'cost_events_usage_kind_check' AND conrelid = 'cost_events'::regclass) THEN
+ ALTER TABLE "cost_events" ADD CONSTRAINT "cost_events_usage_kind_check" CHECK ("cost_events"."usage_kind" = 'decision' or ("cost_events"."usage_kind" = 'agent' and "cost_events"."agent_id" is not null));
+ END IF;
+END $$;
+--> statement-breakpoint
+ALTER TABLE "company_decision_models" DROP CONSTRAINT IF EXISTS "company_decision_models_connection_id_tool_connections_id_fk";
+--> statement-breakpoint
+ALTER TABLE "company_decision_models" DROP CONSTRAINT IF EXISTS "company_decision_models_grant_id_connection_grants_id_fk";
diff --git a/packages/db/src/migrations/0312_broken_sentinels.sql b/packages/db/src/migrations/0317_messy_famine.sql
similarity index 100%
rename from packages/db/src/migrations/0312_broken_sentinels.sql
rename to packages/db/src/migrations/0317_messy_famine.sql
diff --git a/packages/db/src/migrations/meta/0312_snapshot.json b/packages/db/src/migrations/meta/0312_snapshot.json
index 3e78a034fd9..d9bcd5c6a63 100644
--- a/packages/db/src/migrations/meta/0312_snapshot.json
+++ b/packages/db/src/migrations/meta/0312_snapshot.json
@@ -1,9 +1,1079 @@
{
- "id": "9259d643-50ce-465c-a381-9d4cc4277334",
+ "id": "9134843c-7e84-421e-915b-beab3c30acb3",
"prevId": "53940222-21d7-4ccc-8b24-d8db300f4ec3",
"version": "7",
"dialect": "postgresql",
"tables": {
+ "public.accounting_runtime_baselines": {
+ "name": "accounting_runtime_baselines",
+ "schema": "",
+ "columns": {
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cost_cents": {
+ "name": "cost_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "input_tokens": {
+ "name": "input_tokens",
+ "type": "numeric(30, 0)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cached_input_tokens": {
+ "name": "cached_input_tokens",
+ "type": "numeric(30, 0)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "output_tokens": {
+ "name": "output_tokens",
+ "type": "numeric(30, 0)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "accounting_runtime_baselines_company_idx": {
+ "name": "accounting_runtime_baselines_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "accounting_runtime_baselines_agent_id_agents_id_fk": {
+ "name": "accounting_runtime_baselines_agent_id_agents_id_fk",
+ "tableFrom": "accounting_runtime_baselines",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "accounting_runtime_baselines_company_id_companies_id_fk": {
+ "name": "accounting_runtime_baselines_company_id_companies_id_fk",
+ "tableFrom": "accounting_runtime_baselines",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.billing_invoice_lines": {
+ "name": "billing_invoice_lines",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "invoice_id": {
+ "name": "invoice_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "occurred_at": {
+ "name": "occurred_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cost_event_id": {
+ "name": "cost_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_request_id": {
+ "name": "provider_request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "model": {
+ "name": "model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "pricing": {
+ "name": "pricing",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ }
+ },
+ "indexes": {
+ "billing_invoice_lines_identity_idx": {
+ "name": "billing_invoice_lines_identity_idx",
+ "columns": [
+ {
+ "expression": "invoice_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "billing_invoice_lines_company_idx": {
+ "name": "billing_invoice_lines_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "invoice_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "billing_invoice_lines_company_id_companies_id_fk": {
+ "name": "billing_invoice_lines_company_id_companies_id_fk",
+ "tableFrom": "billing_invoice_lines",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "billing_invoice_lines_invoice_id_billing_invoices_id_fk": {
+ "name": "billing_invoice_lines_invoice_id_billing_invoices_id_fk",
+ "tableFrom": "billing_invoice_lines",
+ "tableTo": "billing_invoices",
+ "columnsFrom": [
+ "invoice_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "billing_invoice_lines_cost_event_id_cost_events_id_fk": {
+ "name": "billing_invoice_lines_cost_event_id_cost_events_id_fk",
+ "tableFrom": "billing_invoice_lines",
+ "tableTo": "cost_events",
+ "columnsFrom": [
+ "cost_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "billing_invoice_lines_amount_check": {
+ "name": "billing_invoice_lines_amount_check",
+ "value": "\"billing_invoice_lines\".\"amount_cents\" >= 0"
+ },
+ "billing_invoice_lines_kind_check": {
+ "name": "billing_invoice_lines_kind_check",
+ "value": "\"billing_invoice_lines\".\"kind\" in ('inference', 'fee', 'credit')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.billing_invoices": {
+ "name": "billing_invoices",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "biller": {
+ "name": "biller",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "currency": {
+ "name": "currency",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "imported_by": {
+ "name": "imported_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "billing_invoices_identity_idx": {
+ "name": "billing_invoices_identity_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "biller",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "billing_invoices_company_id_companies_id_fk": {
+ "name": "billing_invoices_company_id_companies_id_fk",
+ "tableFrom": "billing_invoices",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.budget_reservations": {
+ "name": "budget_reservations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "state": {
+ "name": "state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'held'"
+ },
+ "provider_started_at": {
+ "name": "provider_started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "settled_at": {
+ "name": "settled_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "budget_reservations_run_idx": {
+ "name": "budget_reservations_run_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "budget_reservations_active_idx": {
+ "name": "budget_reservations_active_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"budget_reservations\".\"state\" = 'held'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "budget_reservations_company_id_companies_id_fk": {
+ "name": "budget_reservations_company_id_companies_id_fk",
+ "tableFrom": "budget_reservations",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "budget_reservations_run_id_heartbeat_runs_id_fk": {
+ "name": "budget_reservations_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "budget_reservations",
+ "tableTo": "heartbeat_runs",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "budget_reservations_agent_id_agents_id_fk": {
+ "name": "budget_reservations_agent_id_agents_id_fk",
+ "tableFrom": "budget_reservations",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "budget_reservations_state_check": {
+ "name": "budget_reservations_state_check",
+ "value": "\"budget_reservations\".\"state\" in ('held', 'settled', 'released')"
+ },
+ "budget_reservations_amount_check": {
+ "name": "budget_reservations_amount_check",
+ "value": "\"budget_reservations\".\"amount_cents\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.cost_adjustments": {
+ "name": "cost_adjustments",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cost_event_id": {
+ "name": "cost_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "invoice_line_id": {
+ "name": "invoice_line_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_cents": {
+ "name": "previous_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "corrected_cents": {
+ "name": "corrected_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_status": {
+ "name": "previous_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_pricing": {
+ "name": "previous_pricing",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "reason": {
+ "name": "reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_id": {
+ "name": "actor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pricing": {
+ "name": "pricing",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "cost_adjustments_receipt_idx": {
+ "name": "cost_adjustments_receipt_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_adjustments_event_idx": {
+ "name": "cost_adjustments_event_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "cost_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_adjustments_invoice_line_idx": {
+ "name": "cost_adjustments_invoice_line_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "invoice_line_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "cost_adjustments_company_id_companies_id_fk": {
+ "name": "cost_adjustments_company_id_companies_id_fk",
+ "tableFrom": "cost_adjustments",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "cost_adjustments_cost_event_id_cost_events_id_fk": {
+ "name": "cost_adjustments_cost_event_id_cost_events_id_fk",
+ "tableFrom": "cost_adjustments",
+ "tableTo": "cost_events",
+ "columnsFrom": [
+ "cost_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "cost_adjustments_invoice_line_id_billing_invoice_lines_id_fk": {
+ "name": "cost_adjustments_invoice_line_id_billing_invoice_lines_id_fk",
+ "tableFrom": "cost_adjustments",
+ "tableTo": "billing_invoice_lines",
+ "columnsFrom": [
+ "invoice_line_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "cost_adjustments_amount_check": {
+ "name": "cost_adjustments_amount_check",
+ "value": "\"cost_adjustments\".\"previous_cents\" >= 0 and \"cost_adjustments\".\"corrected_cents\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.provider_billing_snapshots": {
+ "name": "provider_billing_snapshots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope_id": {
+ "name": "scope_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "day": {
+ "name": "day",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revision": {
+ "name": "revision",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "provider_billing_snapshots_identity_idx": {
+ "name": "provider_billing_snapshots_identity_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "account_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scope_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "day",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "provider_billing_snapshots_company_id_companies_id_fk": {
+ "name": "provider_billing_snapshots_company_id_companies_id_fk",
+ "tableFrom": "provider_billing_snapshots",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "provider_billing_snapshots_amount_check": {
+ "name": "provider_billing_snapshots_amount_check",
+ "value": "\"provider_billing_snapshots\".\"amount_cents\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.run_usage_receipts": {
+ "name": "run_usage_receipts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_id": {
+ "name": "source_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sequence": {
+ "name": "sequence",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_json": {
+ "name": "receipt_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "complete": {
+ "name": "complete",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "received_at": {
+ "name": "received_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "run_usage_receipts_source_sequence_idx": {
+ "name": "run_usage_receipts_source_sequence_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sequence",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "run_usage_receipts_run_latest_idx": {
+ "name": "run_usage_receipts_run_latest_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "received_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "run_usage_receipts_company_id_companies_id_fk": {
+ "name": "run_usage_receipts_company_id_companies_id_fk",
+ "tableFrom": "run_usage_receipts",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "run_usage_receipts_run_id_heartbeat_runs_id_fk": {
+ "name": "run_usage_receipts_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "run_usage_receipts",
+ "tableTo": "heartbeat_runs",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "run_usage_receipts_positive_sequence": {
+ "name": "run_usage_receipts_positive_sequence",
+ "value": "\"run_usage_receipts\".\"sequence\" > 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
"public.activity_log": {
"name": "activity_log",
"schema": "",
@@ -1820,7 +2890,7 @@
},
"total_cost_cents": {
"name": "total_cost_cents",
- "type": "bigint",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true,
"default": 0
@@ -2859,9 +3929,15 @@
"notNull": true,
"default": 0
},
+ "spend_month_utc": {
+ "name": "spend_month_utc",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
"spent_monthly_cents": {
"name": "spent_monthly_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true,
"default": 0
@@ -5262,7 +6338,7 @@
},
"amount_observed": {
"name": "amount_observed",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true
},
@@ -5378,7 +6454,7 @@
}
],
"isUnique": true,
- "where": "\"budget_incidents\".\"status\" <> 'dismissed'",
+ "where": "\"budget_incidents\".\"status\" = 'open'",
"concurrently": false,
"method": "btree",
"with": {}
@@ -5480,6 +6556,13 @@
"notNull": true,
"default": 0
},
+ "reservation_cents": {
+ "name": "reservation_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
"warn_percent": {
"name": "warn_percent",
"type": "integer",
@@ -5494,6 +6577,13 @@
"notNull": true,
"default": true
},
+ "unpriced_usage_policy": {
+ "name": "unpriced_usage_policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'block'"
+ },
"notify_enabled": {
"name": "notify_enabled",
"type": "boolean",
@@ -5508,6 +6598,20 @@
"notNull": true,
"default": true
},
+ "enforcement_version": {
+ "name": "enforcement_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "enforcement_delivered_version": {
+ "name": "enforcement_delivered_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
"created_by_user_id": {
"name": "created_by_user_id",
"type": "text",
@@ -5654,7 +6758,12 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
- "checkConstraints": {},
+ "checkConstraints": {
+ "budget_policies_reservation_nonnegative": {
+ "name": "budget_policies_reservation_nonnegative",
+ "value": "\"budget_policies\".\"reservation_cents\" >= 0"
+ }
+ },
"isRLSEnabled": false
},
"public.built_in_managed_resources": {
@@ -11306,9 +12415,15 @@
"notNull": true,
"default": 0
},
+ "spend_month_utc": {
+ "name": "spend_month_utc",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
"spent_monthly_cents": {
"name": "spent_monthly_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true,
"default": 0
@@ -16201,6 +17316,36 @@
"primaryKey": false,
"notNull": false
},
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_request_id": {
+ "name": "provider_request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "reported_cost_cents": {
+ "name": "reported_cost_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "pricing_provenance": {
+ "name": "pricing_provenance",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
"provider": {
"name": "provider",
"type": "text",
@@ -16257,7 +17402,7 @@
},
"cost_cents": {
"name": "cost_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true
},
@@ -16276,6 +17421,109 @@
}
},
"indexes": {
+ "cost_events_company_receipt_idx": {
+ "name": "cost_events_company_receipt_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_events_provider_request_idx": {
+ "name": "cost_events_provider_request_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "biller",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_request_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_events_company_project_occurred_idx": {
+ "name": "cost_events_company_project_occurred_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "occurred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_events_unpriced_idx": {
+ "name": "cost_events_unpriced_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "occurred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"cost_events\".\"cost_status\" = 'unpriced' and \"cost_events\".\"billing_type\" <> 'subscription_included'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"cost_events_company_occurred_idx": {
"name": "cost_events_company_occurred_idx",
"columns": [
@@ -16483,7 +17731,12 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
- "checkConstraints": {},
+ "checkConstraints": {
+ "cost_events_nonnegative_amounts": {
+ "name": "cost_events_nonnegative_amounts",
+ "value": "\"cost_events\".\"cost_cents\" >= 0 and \"cost_events\".\"input_tokens\" >= 0 and \"cost_events\".\"cached_input_tokens\" >= 0 and \"cost_events\".\"output_tokens\" >= 0"
+ }
+ },
"isRLSEnabled": false
},
"public.decision_archive_notification_outbox": {
@@ -20361,746 +21614,6 @@
"checkConstraints": {},
"isRLSEnabled": false
},
- "public.dot_agent_bindings": {
- "name": "dot_agent_bindings",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "uuid",
- "primaryKey": true,
- "notNull": true,
- "default": "gen_random_uuid()"
- },
- "company_id": {
- "name": "company_id",
- "type": "uuid",
- "primaryKey": false,
- "notNull": true
- },
- "agent_id": {
- "name": "agent_id",
- "type": "uuid",
- "primaryKey": false,
- "notNull": true
- },
- "operator_id": {
- "name": "operator_id",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "grant_id": {
- "name": "grant_id",
- "type": "uuid",
- "primaryKey": false,
- "notNull": false
- },
- "generation": {
- "name": "generation",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 1
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'pairing'"
- },
- "pairing_code_hash": {
- "name": "pairing_code_hash",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "pairing_expires_at": {
- "name": "pairing_expires_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "dot_url": {
- "name": "dot_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "challenge_hash": {
- "name": "challenge_hash",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "challenge_expires_at": {
- "name": "challenge_expires_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "ready_at": {
- "name": "ready_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "revoked_at": {
- "name": "revoked_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "dot_bindings_active_agent_uq": {
- "name": "dot_bindings_active_agent_uq",
- "columns": [
- {
- "expression": "company_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "agent_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "where": "\"dot_agent_bindings\".\"revoked_at\" IS NULL",
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "dot_bindings_active_grant_uq": {
- "name": "dot_bindings_active_grant_uq",
- "columns": [
- {
- "expression": "grant_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "where": "\"dot_agent_bindings\".\"revoked_at\" IS NULL AND \"dot_agent_bindings\".\"grant_id\" IS NOT NULL",
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "dot_bindings_pairing_code_uq": {
- "name": "dot_bindings_pairing_code_uq",
- "columns": [
- {
- "expression": "pairing_code_hash",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "dot_agent_bindings_company_id_companies_id_fk": {
- "name": "dot_agent_bindings_company_id_companies_id_fk",
- "tableFrom": "dot_agent_bindings",
- "tableTo": "companies",
- "columnsFrom": [
- "company_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "dot_agent_bindings_agent_id_agents_id_fk": {
- "name": "dot_agent_bindings_agent_id_agents_id_fk",
- "tableFrom": "dot_agent_bindings",
- "tableTo": "agents",
- "columnsFrom": [
- "agent_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "dot_agent_bindings_grant_id_mcp_oauth_grants_id_fk": {
- "name": "dot_agent_bindings_grant_id_mcp_oauth_grants_id_fk",
- "tableFrom": "dot_agent_bindings",
- "tableTo": "mcp_oauth_grants",
- "columnsFrom": [
- "grant_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "set null",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {},
- "policies": {},
- "checkConstraints": {},
- "isRLSEnabled": false
- },
- "public.dot_mailbox_items": {
- "name": "dot_mailbox_items",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "company_id": {
- "name": "company_id",
- "type": "uuid",
- "primaryKey": false,
- "notNull": true
- },
- "binding_id": {
- "name": "binding_id",
- "type": "uuid",
- "primaryKey": false,
- "notNull": true
- },
- "binding_generation": {
- "name": "binding_generation",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "assignment_id": {
- "name": "assignment_id",
- "type": "uuid",
- "primaryKey": false,
- "notNull": false
- },
- "kind": {
- "name": "kind",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "source_event_id": {
- "name": "source_event_id",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "references": {
- "name": "references",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "dot_mailbox_event_uq": {
- "name": "dot_mailbox_event_uq",
- "columns": [
- {
- "expression": "binding_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "binding_generation",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "source_event_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "dot_mailbox_binding_cursor_idx": {
- "name": "dot_mailbox_binding_cursor_idx",
- "columns": [
- {
- "expression": "binding_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "binding_generation",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "dot_mailbox_items_company_id_companies_id_fk": {
- "name": "dot_mailbox_items_company_id_companies_id_fk",
- "tableFrom": "dot_mailbox_items",
- "tableTo": "companies",
- "columnsFrom": [
- "company_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "dot_mailbox_items_binding_id_dot_agent_bindings_id_fk": {
- "name": "dot_mailbox_items_binding_id_dot_agent_bindings_id_fk",
- "tableFrom": "dot_mailbox_items",
- "tableTo": "dot_agent_bindings",
- "columnsFrom": [
- "binding_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "dot_mailbox_items_assignment_id_dot_runner_assignments_id_fk": {
- "name": "dot_mailbox_items_assignment_id_dot_runner_assignments_id_fk",
- "tableFrom": "dot_mailbox_items",
- "tableTo": "dot_runner_assignments",
- "columnsFrom": [
- "assignment_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {},
- "policies": {},
- "checkConstraints": {},
- "isRLSEnabled": false
- },
- "public.dot_runner_assignments": {
- "name": "dot_runner_assignments",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "uuid",
- "primaryKey": true,
- "notNull": true,
- "default": "gen_random_uuid()"
- },
- "company_id": {
- "name": "company_id",
- "type": "uuid",
- "primaryKey": false,
- "notNull": true
- },
- "binding_id": {
- "name": "binding_id",
- "type": "uuid",
- "primaryKey": false,
- "notNull": true
- },
- "binding_generation": {
- "name": "binding_generation",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "run_id": {
- "name": "run_id",
- "type": "uuid",
- "primaryKey": false,
- "notNull": true
- },
- "agent_id": {
- "name": "agent_id",
- "type": "uuid",
- "primaryKey": false,
- "notNull": true
- },
- "normalized_session_id": {
- "name": "normalized_session_id",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "turn_id": {
- "name": "turn_id",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "revision": {
- "name": "revision",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 1
- },
- "controller_generation": {
- "name": "controller_generation",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "catalog_digest": {
- "name": "catalog_digest",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "projection": {
- "name": "projection",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "accept_by": {
- "name": "accept_by",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true
- },
- "expires_at": {
- "name": "expires_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true
- },
- "accepted_at": {
- "name": "accepted_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "settled_at": {
- "name": "settled_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "last_activity_at": {
- "name": "last_activity_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "dot_assignments_turn_uq": {
- "name": "dot_assignments_turn_uq",
- "columns": [
- {
- "expression": "run_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "turn_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "dot_assignments_active_binding_uq": {
- "name": "dot_assignments_active_binding_uq",
- "columns": [
- {
- "expression": "binding_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "where": "\"dot_runner_assignments\".\"status\" IN ('offered', 'accepted')",
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "dot_assignments_company_idx": {
- "name": "dot_assignments_company_idx",
- "columns": [
- {
- "expression": "company_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "dot_runner_assignments_company_id_companies_id_fk": {
- "name": "dot_runner_assignments_company_id_companies_id_fk",
- "tableFrom": "dot_runner_assignments",
- "tableTo": "companies",
- "columnsFrom": [
- "company_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "dot_runner_assignments_binding_id_dot_agent_bindings_id_fk": {
- "name": "dot_runner_assignments_binding_id_dot_agent_bindings_id_fk",
- "tableFrom": "dot_runner_assignments",
- "tableTo": "dot_agent_bindings",
- "columnsFrom": [
- "binding_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "dot_runner_assignments_run_id_heartbeat_runs_id_fk": {
- "name": "dot_runner_assignments_run_id_heartbeat_runs_id_fk",
- "tableFrom": "dot_runner_assignments",
- "tableTo": "heartbeat_runs",
- "columnsFrom": [
- "run_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "dot_runner_assignments_agent_id_agents_id_fk": {
- "name": "dot_runner_assignments_agent_id_agents_id_fk",
- "tableFrom": "dot_runner_assignments",
- "tableTo": "agents",
- "columnsFrom": [
- "agent_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {},
- "policies": {},
- "checkConstraints": {},
- "isRLSEnabled": false
- },
- "public.dot_runner_operations": {
- "name": "dot_runner_operations",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "uuid",
- "primaryKey": true,
- "notNull": true,
- "default": "gen_random_uuid()"
- },
- "company_id": {
- "name": "company_id",
- "type": "uuid",
- "primaryKey": false,
- "notNull": true
- },
- "assignment_id": {
- "name": "assignment_id",
- "type": "uuid",
- "primaryKey": false,
- "notNull": true
- },
- "request_id": {
- "name": "request_id",
- "type": "uuid",
- "primaryKey": false,
- "notNull": true
- },
- "digest": {
- "name": "digest",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "command": {
- "name": "command",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'reserved'"
- },
- "outcome": {
- "name": "outcome",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "source_event_id": {
- "name": "source_event_id",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "dot_operations_request_uq": {
- "name": "dot_operations_request_uq",
- "columns": [
- {
- "expression": "assignment_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "request_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "dot_runner_operations_company_id_companies_id_fk": {
- "name": "dot_runner_operations_company_id_companies_id_fk",
- "tableFrom": "dot_runner_operations",
- "tableTo": "companies",
- "columnsFrom": [
- "company_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "dot_runner_operations_assignment_id_dot_runner_assignments_id_fk": {
- "name": "dot_runner_operations_assignment_id_dot_runner_assignments_id_fk",
- "tableFrom": "dot_runner_operations",
- "tableTo": "dot_runner_assignments",
- "columnsFrom": [
- "assignment_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {},
- "policies": {},
- "checkConstraints": {},
- "isRLSEnabled": false
- },
"public.email_endpoints": {
"name": "email_endpoints",
"schema": "",
@@ -24461,6 +24974,18 @@
"primaryKey": false,
"notNull": false
},
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
"billing_code": {
"name": "billing_code",
"type": "text",
@@ -24536,7 +25061,7 @@
},
"amount_cents": {
"name": "amount_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true
},
@@ -24581,6 +25106,27 @@
}
},
"indexes": {
+ "finance_events_company_receipt_idx": {
+ "name": "finance_events_company_receipt_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"finance_events_company_occurred_idx": {
"name": "finance_events_company_occurred_idx",
"columns": [
@@ -25807,6 +26353,44 @@
"primaryKey": false,
"notNull": false
},
+ "cost_accounting_pending": {
+ "name": "cost_accounting_pending",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "cost_accounted_at": {
+ "name": "cost_accounted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_projection_version": {
+ "name": "accounting_projection_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_last_attempt_at": {
+ "name": "accounting_last_attempt_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_last_error": {
+ "name": "accounting_last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_attempt_count": {
+ "name": "accounting_attempt_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
"usage_json": {
"name": "usage_json",
"type": "jsonb",
@@ -26143,6 +26727,28 @@
}
},
"indexes": {
+ "heartbeat_runs_cost_accounting_pending_idx": {
+ "name": "heartbeat_runs_cost_accounting_pending_idx",
+ "columns": [
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"heartbeat_runs\".\"cost_accounting_pending\" = true",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"heartbeat_runs_execution_status_delivery_idx": {
"name": "heartbeat_runs_execution_status_delivery_idx",
"columns": [
@@ -43130,7 +43736,7 @@
},
"cost_cents": {
"name": "cost_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true,
"default": 0
@@ -52571,13 +53177,7 @@
"name": "activity_id",
"type": "uuid",
"primaryKey": false,
- "notNull": false
- },
- "mailbox_item_id": {
- "name": "mailbox_item_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
+ "notNull": true
},
"event": {
"name": "event",
@@ -52613,27 +53213,6 @@
}
},
"indexes": {
- "mcp_event_deliveries_mailbox_uq": {
- "name": "mcp_event_deliveries_mailbox_uq",
- "columns": [
- {
- "expression": "subscription_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "mailbox_item_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
"mcp_event_deliveries_activity_uq": {
"name": "mcp_event_deliveries_activity_uq",
"columns": [
@@ -52689,12 +53268,7 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
- "checkConstraints": {
- "mcp_delivery_source_check": {
- "name": "mcp_delivery_source_check",
- "value": "(\"mcp_event_deliveries\".\"activity_id\" IS NOT NULL AND \"mcp_event_deliveries\".\"mailbox_item_id\" IS NULL) OR (\"mcp_event_deliveries\".\"activity_id\" IS NULL AND \"mcp_event_deliveries\".\"mailbox_item_id\" IS NOT NULL)"
- }
- },
+ "checkConstraints": {},
"isRLSEnabled": false
},
"public.mcp_event_subscriptions": {
@@ -52729,13 +53303,7 @@
"name": "task_id",
"type": "uuid",
"primaryKey": false,
- "notNull": false
- },
- "binding_id": {
- "name": "binding_id",
- "type": "uuid",
- "primaryKey": false,
- "notNull": false
+ "notNull": true
},
"arguments": {
"name": "arguments",
@@ -52845,12 +53413,7 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
- "checkConstraints": {
- "mcp_subscription_resource_check": {
- "name": "mcp_subscription_resource_check",
- "value": "(\"mcp_event_subscriptions\".\"task_id\" IS NOT NULL AND \"mcp_event_subscriptions\".\"binding_id\" IS NULL) OR (\"mcp_event_subscriptions\".\"task_id\" IS NULL AND \"mcp_event_subscriptions\".\"binding_id\" IS NOT NULL)"
- }
- },
+ "checkConstraints": {},
"isRLSEnabled": false
},
"public.mcp_file_tickets": {
@@ -53406,19 +53969,6 @@
"primaryKey": false,
"notNull": true
},
- "purpose": {
- "name": "purpose",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'personal'"
- },
- "agent_id": {
- "name": "agent_id",
- "type": "uuid",
- "primaryKey": false,
- "notNull": false
- },
"scopes": {
"name": "scopes",
"type": "jsonb",
@@ -53501,19 +54051,6 @@
],
"onDelete": "cascade",
"onUpdate": "no action"
- },
- "mcp_oauth_grants_agent_id_agents_id_fk": {
- "name": "mcp_oauth_grants_agent_id_agents_id_fk",
- "tableFrom": "mcp_oauth_grants",
- "tableTo": "agents",
- "columnsFrom": [
- "agent_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
diff --git a/packages/db/src/migrations/meta/0311_snapshot.json b/packages/db/src/migrations/meta/0313_snapshot.json
similarity index 96%
rename from packages/db/src/migrations/meta/0311_snapshot.json
rename to packages/db/src/migrations/meta/0313_snapshot.json
index e10ef09bc9b..5ffb0b3b0b0 100644
--- a/packages/db/src/migrations/meta/0311_snapshot.json
+++ b/packages/db/src/migrations/meta/0313_snapshot.json
@@ -1,9 +1,1079 @@
{
- "id": "53940222-21d7-4ccc-8b24-d8db300f4ec3",
- "prevId": "8a60ce2b-6ab6-435d-90b9-7dc7fc67d53f",
+ "id": "adf783f2-c391-4fd5-b93a-d85e6d3c60a0",
+ "prevId": "9134843c-7e84-421e-915b-beab3c30acb3",
"version": "7",
"dialect": "postgresql",
"tables": {
+ "public.accounting_runtime_baselines": {
+ "name": "accounting_runtime_baselines",
+ "schema": "",
+ "columns": {
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cost_cents": {
+ "name": "cost_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "input_tokens": {
+ "name": "input_tokens",
+ "type": "numeric(30, 0)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cached_input_tokens": {
+ "name": "cached_input_tokens",
+ "type": "numeric(30, 0)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "output_tokens": {
+ "name": "output_tokens",
+ "type": "numeric(30, 0)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "accounting_runtime_baselines_company_idx": {
+ "name": "accounting_runtime_baselines_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "accounting_runtime_baselines_agent_id_agents_id_fk": {
+ "name": "accounting_runtime_baselines_agent_id_agents_id_fk",
+ "tableFrom": "accounting_runtime_baselines",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "accounting_runtime_baselines_company_id_companies_id_fk": {
+ "name": "accounting_runtime_baselines_company_id_companies_id_fk",
+ "tableFrom": "accounting_runtime_baselines",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.billing_invoice_lines": {
+ "name": "billing_invoice_lines",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "invoice_id": {
+ "name": "invoice_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "occurred_at": {
+ "name": "occurred_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cost_event_id": {
+ "name": "cost_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_request_id": {
+ "name": "provider_request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "model": {
+ "name": "model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "pricing": {
+ "name": "pricing",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ }
+ },
+ "indexes": {
+ "billing_invoice_lines_identity_idx": {
+ "name": "billing_invoice_lines_identity_idx",
+ "columns": [
+ {
+ "expression": "invoice_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "billing_invoice_lines_company_idx": {
+ "name": "billing_invoice_lines_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "invoice_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "billing_invoice_lines_company_id_companies_id_fk": {
+ "name": "billing_invoice_lines_company_id_companies_id_fk",
+ "tableFrom": "billing_invoice_lines",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "billing_invoice_lines_invoice_id_billing_invoices_id_fk": {
+ "name": "billing_invoice_lines_invoice_id_billing_invoices_id_fk",
+ "tableFrom": "billing_invoice_lines",
+ "tableTo": "billing_invoices",
+ "columnsFrom": [
+ "invoice_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "billing_invoice_lines_cost_event_id_cost_events_id_fk": {
+ "name": "billing_invoice_lines_cost_event_id_cost_events_id_fk",
+ "tableFrom": "billing_invoice_lines",
+ "tableTo": "cost_events",
+ "columnsFrom": [
+ "cost_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "billing_invoice_lines_amount_check": {
+ "name": "billing_invoice_lines_amount_check",
+ "value": "\"billing_invoice_lines\".\"amount_cents\" >= 0"
+ },
+ "billing_invoice_lines_kind_check": {
+ "name": "billing_invoice_lines_kind_check",
+ "value": "\"billing_invoice_lines\".\"kind\" in ('inference', 'fee', 'credit')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.billing_invoices": {
+ "name": "billing_invoices",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "biller": {
+ "name": "biller",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "currency": {
+ "name": "currency",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "imported_by": {
+ "name": "imported_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "billing_invoices_identity_idx": {
+ "name": "billing_invoices_identity_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "biller",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "billing_invoices_company_id_companies_id_fk": {
+ "name": "billing_invoices_company_id_companies_id_fk",
+ "tableFrom": "billing_invoices",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.budget_reservations": {
+ "name": "budget_reservations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "state": {
+ "name": "state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'held'"
+ },
+ "provider_started_at": {
+ "name": "provider_started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "settled_at": {
+ "name": "settled_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "budget_reservations_run_idx": {
+ "name": "budget_reservations_run_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "budget_reservations_active_idx": {
+ "name": "budget_reservations_active_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"budget_reservations\".\"state\" = 'held'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "budget_reservations_company_id_companies_id_fk": {
+ "name": "budget_reservations_company_id_companies_id_fk",
+ "tableFrom": "budget_reservations",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "budget_reservations_run_id_heartbeat_runs_id_fk": {
+ "name": "budget_reservations_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "budget_reservations",
+ "tableTo": "heartbeat_runs",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "budget_reservations_agent_id_agents_id_fk": {
+ "name": "budget_reservations_agent_id_agents_id_fk",
+ "tableFrom": "budget_reservations",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "budget_reservations_state_check": {
+ "name": "budget_reservations_state_check",
+ "value": "\"budget_reservations\".\"state\" in ('held', 'settled', 'released')"
+ },
+ "budget_reservations_amount_check": {
+ "name": "budget_reservations_amount_check",
+ "value": "\"budget_reservations\".\"amount_cents\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.cost_adjustments": {
+ "name": "cost_adjustments",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cost_event_id": {
+ "name": "cost_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "invoice_line_id": {
+ "name": "invoice_line_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_cents": {
+ "name": "previous_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "corrected_cents": {
+ "name": "corrected_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_status": {
+ "name": "previous_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_pricing": {
+ "name": "previous_pricing",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "reason": {
+ "name": "reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_id": {
+ "name": "actor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pricing": {
+ "name": "pricing",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "cost_adjustments_receipt_idx": {
+ "name": "cost_adjustments_receipt_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_adjustments_event_idx": {
+ "name": "cost_adjustments_event_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "cost_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_adjustments_invoice_line_idx": {
+ "name": "cost_adjustments_invoice_line_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "invoice_line_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "cost_adjustments_company_id_companies_id_fk": {
+ "name": "cost_adjustments_company_id_companies_id_fk",
+ "tableFrom": "cost_adjustments",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "cost_adjustments_cost_event_id_cost_events_id_fk": {
+ "name": "cost_adjustments_cost_event_id_cost_events_id_fk",
+ "tableFrom": "cost_adjustments",
+ "tableTo": "cost_events",
+ "columnsFrom": [
+ "cost_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "cost_adjustments_invoice_line_id_billing_invoice_lines_id_fk": {
+ "name": "cost_adjustments_invoice_line_id_billing_invoice_lines_id_fk",
+ "tableFrom": "cost_adjustments",
+ "tableTo": "billing_invoice_lines",
+ "columnsFrom": [
+ "invoice_line_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "cost_adjustments_amount_check": {
+ "name": "cost_adjustments_amount_check",
+ "value": "\"cost_adjustments\".\"previous_cents\" >= 0 and \"cost_adjustments\".\"corrected_cents\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.provider_billing_snapshots": {
+ "name": "provider_billing_snapshots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope_id": {
+ "name": "scope_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "day": {
+ "name": "day",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revision": {
+ "name": "revision",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "provider_billing_snapshots_identity_idx": {
+ "name": "provider_billing_snapshots_identity_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "account_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scope_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "day",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "provider_billing_snapshots_company_id_companies_id_fk": {
+ "name": "provider_billing_snapshots_company_id_companies_id_fk",
+ "tableFrom": "provider_billing_snapshots",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "provider_billing_snapshots_amount_check": {
+ "name": "provider_billing_snapshots_amount_check",
+ "value": "\"provider_billing_snapshots\".\"amount_cents\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.run_usage_receipts": {
+ "name": "run_usage_receipts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_id": {
+ "name": "source_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sequence": {
+ "name": "sequence",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_json": {
+ "name": "receipt_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "complete": {
+ "name": "complete",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "received_at": {
+ "name": "received_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "run_usage_receipts_source_sequence_idx": {
+ "name": "run_usage_receipts_source_sequence_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sequence",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "run_usage_receipts_run_latest_idx": {
+ "name": "run_usage_receipts_run_latest_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "received_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "run_usage_receipts_company_id_companies_id_fk": {
+ "name": "run_usage_receipts_company_id_companies_id_fk",
+ "tableFrom": "run_usage_receipts",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "run_usage_receipts_run_id_heartbeat_runs_id_fk": {
+ "name": "run_usage_receipts_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "run_usage_receipts",
+ "tableTo": "heartbeat_runs",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "run_usage_receipts_positive_sequence": {
+ "name": "run_usage_receipts_positive_sequence",
+ "value": "\"run_usage_receipts\".\"sequence\" > 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
"public.activity_log": {
"name": "activity_log",
"schema": "",
@@ -1820,7 +2890,7 @@
},
"total_cost_cents": {
"name": "total_cost_cents",
- "type": "bigint",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true,
"default": 0
@@ -2859,9 +3929,15 @@
"notNull": true,
"default": 0
},
+ "spend_month_utc": {
+ "name": "spend_month_utc",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
"spent_monthly_cents": {
"name": "spent_monthly_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true,
"default": 0
@@ -5262,7 +6338,7 @@
},
"amount_observed": {
"name": "amount_observed",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true
},
@@ -5378,7 +6454,7 @@
}
],
"isUnique": true,
- "where": "\"budget_incidents\".\"status\" <> 'dismissed'",
+ "where": "\"budget_incidents\".\"status\" = 'open'",
"concurrently": false,
"method": "btree",
"with": {}
@@ -5480,6 +6556,13 @@
"notNull": true,
"default": 0
},
+ "reservation_cents": {
+ "name": "reservation_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
"warn_percent": {
"name": "warn_percent",
"type": "integer",
@@ -5494,6 +6577,13 @@
"notNull": true,
"default": true
},
+ "unpriced_usage_policy": {
+ "name": "unpriced_usage_policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'block'"
+ },
"notify_enabled": {
"name": "notify_enabled",
"type": "boolean",
@@ -5508,6 +6598,20 @@
"notNull": true,
"default": true
},
+ "enforcement_version": {
+ "name": "enforcement_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "enforcement_delivered_version": {
+ "name": "enforcement_delivered_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
"created_by_user_id": {
"name": "created_by_user_id",
"type": "text",
@@ -5654,7 +6758,12 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
- "checkConstraints": {},
+ "checkConstraints": {
+ "budget_policies_reservation_nonnegative": {
+ "name": "budget_policies_reservation_nonnegative",
+ "value": "\"budget_policies\".\"reservation_cents\" >= 0"
+ }
+ },
"isRLSEnabled": false
},
"public.built_in_managed_resources": {
@@ -11306,9 +12415,15 @@
"notNull": true,
"default": 0
},
+ "spend_month_utc": {
+ "name": "spend_month_utc",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
"spent_monthly_cents": {
"name": "spent_monthly_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true,
"default": 0
@@ -16201,6 +17316,36 @@
"primaryKey": false,
"notNull": false
},
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_request_id": {
+ "name": "provider_request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "reported_cost_cents": {
+ "name": "reported_cost_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "pricing_provenance": {
+ "name": "pricing_provenance",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
"provider": {
"name": "provider",
"type": "text",
@@ -16257,7 +17402,7 @@
},
"cost_cents": {
"name": "cost_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true
},
@@ -16276,6 +17421,109 @@
}
},
"indexes": {
+ "cost_events_company_receipt_idx": {
+ "name": "cost_events_company_receipt_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_events_provider_request_idx": {
+ "name": "cost_events_provider_request_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "biller",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_request_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_events_company_project_occurred_idx": {
+ "name": "cost_events_company_project_occurred_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "occurred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_events_unpriced_idx": {
+ "name": "cost_events_unpriced_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "occurred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"cost_events\".\"cost_status\" = 'unpriced' and \"cost_events\".\"billing_type\" <> 'subscription_included'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"cost_events_company_occurred_idx": {
"name": "cost_events_company_occurred_idx",
"columns": [
@@ -16483,7 +17731,12 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
- "checkConstraints": {},
+ "checkConstraints": {
+ "cost_events_nonnegative_amounts": {
+ "name": "cost_events_nonnegative_amounts",
+ "value": "\"cost_events\".\"cost_cents\" >= 0 and \"cost_events\".\"input_tokens\" >= 0 and \"cost_events\".\"cached_input_tokens\" >= 0 and \"cost_events\".\"output_tokens\" >= 0"
+ }
+ },
"isRLSEnabled": false
},
"public.decision_archive_notification_outbox": {
@@ -23721,6 +24974,18 @@
"primaryKey": false,
"notNull": false
},
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
"billing_code": {
"name": "billing_code",
"type": "text",
@@ -23796,7 +25061,7 @@
},
"amount_cents": {
"name": "amount_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true
},
@@ -23841,6 +25106,27 @@
}
},
"indexes": {
+ "finance_events_company_receipt_idx": {
+ "name": "finance_events_company_receipt_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"finance_events_company_occurred_idx": {
"name": "finance_events_company_occurred_idx",
"columns": [
@@ -24987,6 +26273,19 @@
"primaryKey": false,
"notNull": true
},
+ "scope_kind": {
+ "name": "scope_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'company'"
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
"invocation_source": {
"name": "invocation_source",
"type": "text",
@@ -25067,6 +26366,44 @@
"primaryKey": false,
"notNull": false
},
+ "cost_accounting_pending": {
+ "name": "cost_accounting_pending",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "cost_accounted_at": {
+ "name": "cost_accounted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_projection_version": {
+ "name": "accounting_projection_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_last_attempt_at": {
+ "name": "accounting_last_attempt_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_last_error": {
+ "name": "accounting_last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_attempt_count": {
+ "name": "accounting_attempt_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
"usage_json": {
"name": "usage_json",
"type": "jsonb",
@@ -25403,6 +26740,28 @@
}
},
"indexes": {
+ "heartbeat_runs_cost_accounting_pending_idx": {
+ "name": "heartbeat_runs_cost_accounting_pending_idx",
+ "columns": [
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"heartbeat_runs\".\"cost_accounting_pending\" = true",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"heartbeat_runs_execution_status_delivery_idx": {
"name": "heartbeat_runs_execution_status_delivery_idx",
"columns": [
@@ -25484,6 +26843,33 @@
"method": "btree",
"with": {}
},
+ "heartbeat_runs_company_issue_created_idx": {
+ "name": "heartbeat_runs_company_issue_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"heartbeat_runs_company_responsible_user_idx": {
"name": "heartbeat_runs_company_responsible_user_idx",
"columns": [
@@ -25722,6 +27108,19 @@
"onDelete": "no action",
"onUpdate": "no action"
},
+ "heartbeat_runs_issue_id_issues_id_fk": {
+ "name": "heartbeat_runs_issue_id_issues_id_fk",
+ "tableFrom": "heartbeat_runs",
+ "tableTo": "issues",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
"heartbeat_runs_wakeup_request_id_agent_wakeup_requests_id_fk": {
"name": "heartbeat_runs_wakeup_request_id_agent_wakeup_requests_id_fk",
"tableFrom": "heartbeat_runs",
@@ -25772,7 +27171,12 @@
}
},
"policies": {},
- "checkConstraints": {},
+ "checkConstraints": {
+ "heartbeat_runs_scope_binding_check": {
+ "name": "heartbeat_runs_scope_binding_check",
+ "value": "(\"heartbeat_runs\".\"scope_kind\" = 'company' AND \"heartbeat_runs\".\"issue_id\" IS NULL)\n OR \"heartbeat_runs\".\"scope_kind\" = 'issue'"
+ }
+ },
"isRLSEnabled": false
},
"public.inbox_dismissals": {
@@ -27215,6 +28619,166 @@
"checkConstraints": {},
"isRLSEnabled": false
},
+ "public.issue_access_grants": {
+ "name": "issue_access_grants",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_type": {
+ "name": "subject_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_id": {
+ "name": "subject_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source": {
+ "name": "source",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "granted_by_user_id": {
+ "name": "granted_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "granted_by_agent_id": {
+ "name": "granted_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "issue_access_grants_subject_active_issue_idx": {
+ "name": "issue_access_grants_subject_active_issue_idx",
+ "columns": [
+ {
+ "expression": "subject_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "revoked_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "issue_access_grants_issue_idx": {
+ "name": "issue_access_grants_issue_idx",
+ "columns": [
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "issue_access_grants_issue_id_issues_id_fk": {
+ "name": "issue_access_grants_issue_id_issues_id_fk",
+ "tableFrom": "issue_access_grants",
+ "tableTo": "issues",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "issue_access_grants_granted_by_agent_id_agents_id_fk": {
+ "name": "issue_access_grants_granted_by_agent_id_agents_id_fk",
+ "tableFrom": "issue_access_grants",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "granted_by_agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "issue_access_grants_subject_type_check": {
+ "name": "issue_access_grants_subject_type_check",
+ "value": "\"issue_access_grants\".\"subject_type\" in ('user', 'agent')"
+ },
+ "issue_access_grants_source_check": {
+ "name": "issue_access_grants_source_check",
+ "value": "\"issue_access_grants\".\"source\" in ('explicit', 'assignment', 'project')"
+ }
+ },
+ "isRLSEnabled": false
+ },
"public.issue_approvals": {
"name": "issue_approvals",
"schema": "",
@@ -32087,6 +33651,25 @@
"primaryKey": false,
"notNull": false
},
+ "visibility": {
+ "name": "visibility",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'open'"
+ },
+ "privacy_root_issue_id": {
+ "name": "privacy_root_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "privacy_parent_issue_id": {
+ "name": "privacy_parent_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
"title": {
"name": "title",
"type": "text",
@@ -32571,6 +34154,48 @@
"method": "btree",
"with": {}
},
+ "issues_company_privacy_parent_idx": {
+ "name": "issues_company_privacy_parent_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "privacy_parent_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "issues_company_privacy_root_idx": {
+ "name": "issues_company_privacy_root_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "privacy_root_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"issues_company_project_idx": {
"name": "issues_company_project_idx",
"columns": [
@@ -33140,6 +34765,32 @@
"onDelete": "no action",
"onUpdate": "no action"
},
+ "issues_privacy_root_issue_id_issues_id_fk": {
+ "name": "issues_privacy_root_issue_id_issues_id_fk",
+ "tableFrom": "issues",
+ "tableTo": "issues",
+ "columnsFrom": [
+ "privacy_root_issue_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "issues_privacy_parent_issue_id_issues_id_fk": {
+ "name": "issues_privacy_parent_issue_id_issues_id_fk",
+ "tableFrom": "issues",
+ "tableTo": "issues",
+ "columnsFrom": [
+ "privacy_parent_issue_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
"issues_assignee_agent_id_agents_id_fk": {
"name": "issues_assignee_agent_id_agents_id_fk",
"tableFrom": "issues",
@@ -33219,6 +34870,10 @@
},
"policies": {},
"checkConstraints": {
+ "issues_visibility_check": {
+ "name": "issues_visibility_check",
+ "value": "\"issues\".\"visibility\" in ('open', 'private')"
+ },
"issues_conversation_identity_check": {
"name": "issues_conversation_identity_check",
"value": "(\n \"issues\".\"conversation_agent_id\" is null and \"issues\".\"conversation_user_id\" is null and \"issues\".\"conversation_state\" is null\n ) or (\n \"issues\".\"conversation_agent_id\" is not null and \"issues\".\"conversation_user_id\" is not null\n and \"issues\".\"assignee_agent_id\" = \"issues\".\"conversation_agent_id\" and \"issues\".\"assignee_agent_id\" is not null\n and \"issues\".\"assignee_user_id\" is null and \"issues\".\"conversation_state\" is not null\n and \"issues\".\"conversation_state\" in ('active', 'waiting')\n and \"issues\".\"status\" not in ('done', 'cancelled')\n )"
@@ -38508,6 +40163,150 @@
"checkConstraints": {},
"isRLSEnabled": false
},
+ "public.project_access_members": {
+ "name": "project_access_members",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_type": {
+ "name": "subject_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_id": {
+ "name": "subject_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "project_access_members_project_subject_uq": {
+ "name": "project_access_members_project_subject_uq",
+ "columns": [
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "project_access_members_subject_lookup_idx": {
+ "name": "project_access_members_subject_lookup_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "project_access_members_company_id_companies_id_fk": {
+ "name": "project_access_members_company_id_companies_id_fk",
+ "tableFrom": "project_access_members",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "project_access_members_project_id_projects_id_fk": {
+ "name": "project_access_members_project_id_projects_id_fk",
+ "tableFrom": "project_access_members",
+ "tableTo": "projects",
+ "columnsFrom": [
+ "project_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "project_access_members_subject_type_check": {
+ "name": "project_access_members_subject_type_check",
+ "value": "\"project_access_members\".\"subject_type\" in ('user', 'agent')"
+ }
+ },
+ "isRLSEnabled": false
+ },
"public.project_goals": {
"name": "project_goals",
"schema": "",
@@ -39137,6 +40936,25 @@
"primaryKey": false,
"notNull": false
},
+ "visibility": {
+ "name": "visibility",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'open'"
+ },
+ "privacy_owner_user_id": {
+ "name": "privacy_owner_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "personal_owner_user_id": {
+ "name": "personal_owner_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
"status": {
"name": "status",
"type": "text",
@@ -39228,6 +41046,28 @@
"concurrently": false,
"method": "btree",
"with": {}
+ },
+ "projects_company_personal_owner_uq": {
+ "name": "projects_company_personal_owner_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "personal_owner_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"projects\".\"personal_owner_user_id\" is not null",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
}
},
"foreignKeys": {
@@ -39274,7 +41114,12 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
- "checkConstraints": {},
+ "checkConstraints": {
+ "projects_visibility_check": {
+ "name": "projects_visibility_check",
+ "value": "\"projects\".\"visibility\" in ('open', 'private')"
+ }
+ },
"isRLSEnabled": false
},
"public.provider_trace_records": {
@@ -42390,7 +44235,7 @@
},
"cost_cents": {
"name": "cost_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true,
"default": 0
diff --git a/packages/db/src/migrations/meta/0314_snapshot.json b/packages/db/src/migrations/meta/0314_snapshot.json
new file mode 100644
index 00000000000..52d8ef6d49a
--- /dev/null
+++ b/packages/db/src/migrations/meta/0314_snapshot.json
@@ -0,0 +1,54905 @@
+{
+ "id": "a1aefefe-8911-4583-9c52-7c658e46e9b4",
+ "prevId": "adf783f2-c391-4fd5-b93a-d85e6d3c60a0",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.accounting_runtime_baselines": {
+ "name": "accounting_runtime_baselines",
+ "schema": "",
+ "columns": {
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cost_cents": {
+ "name": "cost_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "input_tokens": {
+ "name": "input_tokens",
+ "type": "numeric(30, 0)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cached_input_tokens": {
+ "name": "cached_input_tokens",
+ "type": "numeric(30, 0)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "output_tokens": {
+ "name": "output_tokens",
+ "type": "numeric(30, 0)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "accounting_runtime_baselines_company_idx": {
+ "name": "accounting_runtime_baselines_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "accounting_runtime_baselines_agent_id_agents_id_fk": {
+ "name": "accounting_runtime_baselines_agent_id_agents_id_fk",
+ "tableFrom": "accounting_runtime_baselines",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "accounting_runtime_baselines_company_id_companies_id_fk": {
+ "name": "accounting_runtime_baselines_company_id_companies_id_fk",
+ "tableFrom": "accounting_runtime_baselines",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.billing_invoice_lines": {
+ "name": "billing_invoice_lines",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "invoice_id": {
+ "name": "invoice_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "occurred_at": {
+ "name": "occurred_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cost_event_id": {
+ "name": "cost_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_request_id": {
+ "name": "provider_request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "model": {
+ "name": "model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "pricing": {
+ "name": "pricing",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ }
+ },
+ "indexes": {
+ "billing_invoice_lines_identity_idx": {
+ "name": "billing_invoice_lines_identity_idx",
+ "columns": [
+ {
+ "expression": "invoice_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "billing_invoice_lines_company_idx": {
+ "name": "billing_invoice_lines_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "invoice_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "billing_invoice_lines_company_id_companies_id_fk": {
+ "name": "billing_invoice_lines_company_id_companies_id_fk",
+ "tableFrom": "billing_invoice_lines",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "billing_invoice_lines_invoice_id_billing_invoices_id_fk": {
+ "name": "billing_invoice_lines_invoice_id_billing_invoices_id_fk",
+ "tableFrom": "billing_invoice_lines",
+ "columnsFrom": [
+ "invoice_id"
+ ],
+ "tableTo": "billing_invoices",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "billing_invoice_lines_cost_event_id_cost_events_id_fk": {
+ "name": "billing_invoice_lines_cost_event_id_cost_events_id_fk",
+ "tableFrom": "billing_invoice_lines",
+ "columnsFrom": [
+ "cost_event_id"
+ ],
+ "tableTo": "cost_events",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "billing_invoice_lines_amount_check": {
+ "name": "billing_invoice_lines_amount_check",
+ "value": "\"billing_invoice_lines\".\"amount_cents\" >= 0"
+ },
+ "billing_invoice_lines_kind_check": {
+ "name": "billing_invoice_lines_kind_check",
+ "value": "\"billing_invoice_lines\".\"kind\" in ('inference', 'fee', 'credit')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.billing_invoices": {
+ "name": "billing_invoices",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "biller": {
+ "name": "biller",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "currency": {
+ "name": "currency",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "imported_by": {
+ "name": "imported_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "billing_invoices_identity_idx": {
+ "name": "billing_invoices_identity_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "biller",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "billing_invoices_company_id_companies_id_fk": {
+ "name": "billing_invoices_company_id_companies_id_fk",
+ "tableFrom": "billing_invoices",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.budget_reservations": {
+ "name": "budget_reservations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "state": {
+ "name": "state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'held'"
+ },
+ "provider_started_at": {
+ "name": "provider_started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "settled_at": {
+ "name": "settled_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "budget_reservations_run_idx": {
+ "name": "budget_reservations_run_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "budget_reservations_active_idx": {
+ "name": "budget_reservations_active_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "where": "\"budget_reservations\".\"state\" = 'held'",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "budget_reservations_company_id_companies_id_fk": {
+ "name": "budget_reservations_company_id_companies_id_fk",
+ "tableFrom": "budget_reservations",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "budget_reservations_run_id_heartbeat_runs_id_fk": {
+ "name": "budget_reservations_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "budget_reservations",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "budget_reservations_agent_id_agents_id_fk": {
+ "name": "budget_reservations_agent_id_agents_id_fk",
+ "tableFrom": "budget_reservations",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "budget_reservations_state_check": {
+ "name": "budget_reservations_state_check",
+ "value": "\"budget_reservations\".\"state\" in ('held', 'settled', 'released')"
+ },
+ "budget_reservations_amount_check": {
+ "name": "budget_reservations_amount_check",
+ "value": "\"budget_reservations\".\"amount_cents\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.cost_adjustments": {
+ "name": "cost_adjustments",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cost_event_id": {
+ "name": "cost_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "invoice_line_id": {
+ "name": "invoice_line_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_cents": {
+ "name": "previous_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "corrected_cents": {
+ "name": "corrected_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_status": {
+ "name": "previous_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_pricing": {
+ "name": "previous_pricing",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "reason": {
+ "name": "reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_id": {
+ "name": "actor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pricing": {
+ "name": "pricing",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "cost_adjustments_receipt_idx": {
+ "name": "cost_adjustments_receipt_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "cost_adjustments_event_idx": {
+ "name": "cost_adjustments_event_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "cost_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "cost_adjustments_invoice_line_idx": {
+ "name": "cost_adjustments_invoice_line_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "invoice_line_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "cost_adjustments_company_id_companies_id_fk": {
+ "name": "cost_adjustments_company_id_companies_id_fk",
+ "tableFrom": "cost_adjustments",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "cost_adjustments_cost_event_id_cost_events_id_fk": {
+ "name": "cost_adjustments_cost_event_id_cost_events_id_fk",
+ "tableFrom": "cost_adjustments",
+ "columnsFrom": [
+ "cost_event_id"
+ ],
+ "tableTo": "cost_events",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "cost_adjustments_invoice_line_id_billing_invoice_lines_id_fk": {
+ "name": "cost_adjustments_invoice_line_id_billing_invoice_lines_id_fk",
+ "tableFrom": "cost_adjustments",
+ "columnsFrom": [
+ "invoice_line_id"
+ ],
+ "tableTo": "billing_invoice_lines",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "cost_adjustments_amount_check": {
+ "name": "cost_adjustments_amount_check",
+ "value": "\"cost_adjustments\".\"previous_cents\" >= 0 and \"cost_adjustments\".\"corrected_cents\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.provider_billing_snapshots": {
+ "name": "provider_billing_snapshots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope_id": {
+ "name": "scope_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "day": {
+ "name": "day",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revision": {
+ "name": "revision",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "provider_billing_snapshots_identity_idx": {
+ "name": "provider_billing_snapshots_identity_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "account_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scope_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "day",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "provider_billing_snapshots_company_id_companies_id_fk": {
+ "name": "provider_billing_snapshots_company_id_companies_id_fk",
+ "tableFrom": "provider_billing_snapshots",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "provider_billing_snapshots_amount_check": {
+ "name": "provider_billing_snapshots_amount_check",
+ "value": "\"provider_billing_snapshots\".\"amount_cents\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.run_usage_receipts": {
+ "name": "run_usage_receipts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_id": {
+ "name": "source_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sequence": {
+ "name": "sequence",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_json": {
+ "name": "receipt_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "complete": {
+ "name": "complete",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "received_at": {
+ "name": "received_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "run_usage_receipts_source_sequence_idx": {
+ "name": "run_usage_receipts_source_sequence_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sequence",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "run_usage_receipts_run_latest_idx": {
+ "name": "run_usage_receipts_run_latest_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "received_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "run_usage_receipts_company_id_companies_id_fk": {
+ "name": "run_usage_receipts_company_id_companies_id_fk",
+ "tableFrom": "run_usage_receipts",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "run_usage_receipts_run_id_heartbeat_runs_id_fk": {
+ "name": "run_usage_receipts_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "run_usage_receipts",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "run_usage_receipts_positive_sequence": {
+ "name": "run_usage_receipts_positive_sequence",
+ "value": "\"run_usage_receipts\".\"sequence\" > 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.activity_log": {
+ "name": "activity_log",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_type": {
+ "name": "actor_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'system'"
+ },
+ "actor_id": {
+ "name": "actor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "action": {
+ "name": "action",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "responsible_user_id": {
+ "name": "responsible_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "details": {
+ "name": "details",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "activity_log_company_created_idx": {
+ "name": "activity_log_company_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "activity_log_company_agent_created_idx": {
+ "name": "activity_log_company_agent_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "activity_log_company_responsible_user_created_idx": {
+ "name": "activity_log_company_responsible_user_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "responsible_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "activity_log_run_id_idx": {
+ "name": "activity_log_run_id_idx",
+ "columns": [
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "activity_log_entity_type_id_idx": {
+ "name": "activity_log_entity_type_id_idx",
+ "columns": [
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "activity_log_company_id_companies_id_fk": {
+ "name": "activity_log_company_id_companies_id_fk",
+ "tableFrom": "activity_log",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "activity_log_agent_id_agents_id_fk": {
+ "name": "activity_log_agent_id_agents_id_fk",
+ "tableFrom": "activity_log",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "activity_log_run_id_heartbeat_runs_id_fk": {
+ "name": "activity_log_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "activity_log",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.adapter_auth_sessions": {
+ "name": "adapter_auth_sessions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "environment_id": {
+ "name": "environment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ai_connection": {
+ "name": "ai_connection",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "connection_grant_id": {
+ "name": "connection_grant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "connection_method": {
+ "name": "connection_method",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "adapter_type": {
+ "name": "adapter_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "started_by_user_id": {
+ "name": "started_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "public_session_id": {
+ "name": "public_session_id",
+ "type": "varchar(128)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_lease_id": {
+ "name": "provider_lease_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'starting'"
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "promotion_expires_at": {
+ "name": "promotion_expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "bound_at": {
+ "name": "bound_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "finished_at": {
+ "name": "finished_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "failure_reason": {
+ "name": "failure_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "result_claim": {
+ "name": "result_claim",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "adapter_auth_sessions_company_status_idx": {
+ "name": "adapter_auth_sessions_company_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "adapter_auth_sessions_company_owner_adapter_active_uq": {
+ "name": "adapter_auth_sessions_company_owner_adapter_active_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "started_by_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "adapter_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"adapter_auth_sessions\".\"status\" IN ('starting', 'waiting_for_user', 'promoting', 'awaiting_code', 'submitting')",
+ "concurrently": false
+ },
+ "adapter_auth_sessions_public_session_id_uq": {
+ "name": "adapter_auth_sessions_public_session_id_uq",
+ "columns": [
+ {
+ "expression": "public_session_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "adapter_auth_sessions_environment_idx": {
+ "name": "adapter_auth_sessions_environment_idx",
+ "columns": [
+ {
+ "expression": "environment_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "adapter_auth_sessions_expires_idx": {
+ "name": "adapter_auth_sessions_expires_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "adapter_auth_sessions_provider_lease_idx": {
+ "name": "adapter_auth_sessions_provider_lease_idx",
+ "columns": [
+ {
+ "expression": "provider_lease_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "adapter_auth_sessions_company_id_companies_id_fk": {
+ "name": "adapter_auth_sessions_company_id_companies_id_fk",
+ "tableFrom": "adapter_auth_sessions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "adapter_auth_sessions_environment_id_environments_id_fk": {
+ "name": "adapter_auth_sessions_environment_id_environments_id_fk",
+ "tableFrom": "adapter_auth_sessions",
+ "columnsFrom": [
+ "environment_id"
+ ],
+ "tableTo": "environments",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.agent_api_keys": {
+ "name": "agent_api_keys",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "key_hash": {
+ "name": "key_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "responsible_user_id": {
+ "name": "responsible_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scope_config": {
+ "name": "scope_config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_used_at": {
+ "name": "last_used_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "agent_api_keys_key_hash_idx": {
+ "name": "agent_api_keys_key_hash_idx",
+ "columns": [
+ {
+ "expression": "key_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "agent_api_keys_company_agent_idx": {
+ "name": "agent_api_keys_company_agent_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "agent_api_keys_agent_id_agents_id_fk": {
+ "name": "agent_api_keys_agent_id_agents_id_fk",
+ "tableFrom": "agent_api_keys",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "agent_api_keys_company_id_companies_id_fk": {
+ "name": "agent_api_keys_company_id_companies_id_fk",
+ "tableFrom": "agent_api_keys",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.agent_commentary": {
+ "name": "agent_commentary",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "body": {
+ "name": "body",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "payload_hash": {
+ "name": "payload_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "agent_commentary_run_key_uq": {
+ "name": "agent_commentary_run_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "agent_commentary_company_kind_created_idx": {
+ "name": "agent_commentary_company_kind_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "agent_commentary_company_id_companies_id_fk": {
+ "name": "agent_commentary_company_id_companies_id_fk",
+ "tableFrom": "agent_commentary",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "agent_commentary_agent_id_agents_id_fk": {
+ "name": "agent_commentary_agent_id_agents_id_fk",
+ "tableFrom": "agent_commentary",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "agent_commentary_run_id_heartbeat_runs_id_fk": {
+ "name": "agent_commentary_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "agent_commentary",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "agent_commentary_issue_id_issues_id_fk": {
+ "name": "agent_commentary_issue_id_issues_id_fk",
+ "tableFrom": "agent_commentary",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "agent_commentary_kind_check": {
+ "name": "agent_commentary_kind_check",
+ "value": "\"agent_commentary\".\"kind\" in ('complaint', 'suggestion')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.agent_config_revisions": {
+ "name": "agent_config_revisions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source": {
+ "name": "source",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'patch'"
+ },
+ "rolled_back_from_revision_id": {
+ "name": "rolled_back_from_revision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "changed_keys": {
+ "name": "changed_keys",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "before_config": {
+ "name": "before_config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "after_config": {
+ "name": "after_config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "agent_config_revisions_company_agent_created_idx": {
+ "name": "agent_config_revisions_company_agent_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "agent_config_revisions_agent_created_idx": {
+ "name": "agent_config_revisions_agent_created_idx",
+ "columns": [
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "agent_config_revisions_company_id_companies_id_fk": {
+ "name": "agent_config_revisions_company_id_companies_id_fk",
+ "tableFrom": "agent_config_revisions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "agent_config_revisions_agent_id_agents_id_fk": {
+ "name": "agent_config_revisions_agent_id_agents_id_fk",
+ "tableFrom": "agent_config_revisions",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "agent_config_revisions_created_by_agent_id_agents_id_fk": {
+ "name": "agent_config_revisions_created_by_agent_id_agents_id_fk",
+ "tableFrom": "agent_config_revisions",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.agent_identity_keys": {
+ "name": "agent_identity_keys",
+ "schema": "",
+ "columns": {
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "algorithm": {
+ "name": "algorithm",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "key_id": {
+ "name": "key_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "public_key_pem": {
+ "name": "public_key_pem",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "private_key_material": {
+ "name": "private_key_material",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "agent_identity_keys_owner_fk": {
+ "name": "agent_identity_keys_owner_fk",
+ "tableFrom": "agent_identity_keys",
+ "columnsFrom": [
+ "company_id",
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "agent_identity_keys_algorithm_check": {
+ "name": "agent_identity_keys_algorithm_check",
+ "value": "\"agent_identity_keys\".\"algorithm\" = 'Ed25519'"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.agent_instruction_heads": {
+ "name": "agent_instruction_heads",
+ "schema": "",
+ "columns": {
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entry_file": {
+ "name": "entry_file",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revision_id": {
+ "name": "revision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "agent_instruction_heads_company_id_agent_id_entry_file_revision_id_agent_instruction_revisions_company_id_agent_id_entry_file_id_fk": {
+ "name": "agent_instruction_heads_company_id_agent_id_entry_file_revision_id_agent_instruction_revisions_company_id_agent_id_entry_file_id_fk",
+ "tableFrom": "agent_instruction_heads",
+ "columnsFrom": [
+ "company_id",
+ "agent_id",
+ "entry_file",
+ "revision_id"
+ ],
+ "tableTo": "agent_instruction_revisions",
+ "columnsTo": [
+ "company_id",
+ "agent_id",
+ "entry_file",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "agent_instruction_heads_identity_uq": {
+ "name": "agent_instruction_heads_identity_uq",
+ "columns": [
+ "company_id",
+ "agent_id",
+ "entry_file"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.agent_instruction_revisions": {
+ "name": "agent_instruction_revisions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entry_file": {
+ "name": "entry_file",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content_base64": {
+ "name": "content_base64",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content_hash": {
+ "name": "content_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "byte_length": {
+ "name": "byte_length",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parent_revision_id": {
+ "name": "parent_revision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "base_revision_id": {
+ "name": "base_revision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "restored_from_revision_id": {
+ "name": "restored_from_revision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "actor_agent_id": {
+ "name": "actor_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "actor_user_id": {
+ "name": "actor_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "responsible_user_id": {
+ "name": "responsible_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_run_id": {
+ "name": "source_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source": {
+ "name": "source",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "agent_instruction_revisions_history_idx": {
+ "name": "agent_instruction_revisions_history_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entry_file",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "agent_instruction_revisions_company_id_agent_id_agents_company_id_id_fk": {
+ "name": "agent_instruction_revisions_company_id_agent_id_agents_company_id_id_fk",
+ "tableFrom": "agent_instruction_revisions",
+ "columnsFrom": [
+ "company_id",
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "agent_instruction_revisions_identity_uq": {
+ "name": "agent_instruction_revisions_identity_uq",
+ "columns": [
+ "company_id",
+ "agent_id",
+ "entry_file",
+ "id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.agent_instruction_working_copies": {
+ "name": "agent_instruction_working_copies",
+ "schema": "",
+ "columns": {
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "responsible_user_id": {
+ "name": "responsible_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entry_file": {
+ "name": "entry_file",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "base_revision_id": {
+ "name": "base_revision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "base_hash": {
+ "name": "base_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "local_root": {
+ "name": "local_root",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "execution_root": {
+ "name": "execution_root",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "location": {
+ "name": "location",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "state": {
+ "name": "state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'prepared'"
+ },
+ "candidate_base64": {
+ "name": "candidate_base64",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "candidate_hash": {
+ "name": "candidate_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error_code": {
+ "name": "error_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "receipt": {
+ "name": "receipt",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "process_stopped_at": {
+ "name": "process_stopped_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "attempts": {
+ "name": "attempts",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "next_attempt_at": {
+ "name": "next_attempt_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "agent_instruction_copies_pending_idx": {
+ "name": "agent_instruction_copies_pending_idx",
+ "columns": [
+ {
+ "expression": "state",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "next_attempt_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "agent_instruction_copies_agent_idx": {
+ "name": "agent_instruction_copies_agent_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "agent_instruction_working_copies_run_id_heartbeat_runs_id_fk": {
+ "name": "agent_instruction_working_copies_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "agent_instruction_working_copies",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "agent_instruction_working_copies_company_id_agent_id_agents_company_id_id_fk": {
+ "name": "agent_instruction_working_copies_company_id_agent_id_agents_company_id_id_fk",
+ "tableFrom": "agent_instruction_working_copies",
+ "columnsFrom": [
+ "company_id",
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.agent_memberships": {
+ "name": "agent_memberships",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "state": {
+ "name": "state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'joined'"
+ },
+ "starred_at": {
+ "name": "starred_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "agent_memberships_company_user_idx": {
+ "name": "agent_memberships_company_user_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "agent_memberships_company_user_starred_idx": {
+ "name": "agent_memberships_company_user_starred_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "starred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "agent_memberships_agent_idx": {
+ "name": "agent_memberships_agent_idx",
+ "columns": [
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "agent_memberships_company_user_agent_uq": {
+ "name": "agent_memberships_company_user_agent_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "agent_memberships_company_id_companies_id_fk": {
+ "name": "agent_memberships_company_id_companies_id_fk",
+ "tableFrom": "agent_memberships",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "agent_memberships_agent_id_agents_id_fk": {
+ "name": "agent_memberships_agent_id_agents_id_fk",
+ "tableFrom": "agent_memberships",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.agent_runtime_state": {
+ "name": "agent_runtime_state",
+ "schema": "",
+ "columns": {
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "adapter_type": {
+ "name": "adapter_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "session_id": {
+ "name": "session_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "state_json": {
+ "name": "state_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "last_run_id": {
+ "name": "last_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_run_status": {
+ "name": "last_run_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_input_tokens": {
+ "name": "total_input_tokens",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "total_output_tokens": {
+ "name": "total_output_tokens",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "total_cached_input_tokens": {
+ "name": "total_cached_input_tokens",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "total_cost_cents": {
+ "name": "total_cost_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "agent_runtime_state_company_agent_idx": {
+ "name": "agent_runtime_state_company_agent_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "agent_runtime_state_company_updated_idx": {
+ "name": "agent_runtime_state_company_updated_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "agent_runtime_state_agent_id_agents_id_fk": {
+ "name": "agent_runtime_state_agent_id_agents_id_fk",
+ "tableFrom": "agent_runtime_state",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "agent_runtime_state_company_id_companies_id_fk": {
+ "name": "agent_runtime_state_company_id_companies_id_fk",
+ "tableFrom": "agent_runtime_state",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.agent_session_goal_actions": {
+ "name": "agent_session_goal_actions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "session_id": {
+ "name": "session_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "request_id": {
+ "name": "request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "action": {
+ "name": "action",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "payload_json": {
+ "name": "payload_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "result_json": {
+ "name": "result_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "delivered_at": {
+ "name": "delivered_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "agent_session_goal_actions_session_request_uniq": {
+ "name": "agent_session_goal_actions_session_request_uniq",
+ "columns": [
+ {
+ "expression": "session_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "request_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "agent_session_goal_actions_company_status_created_idx": {
+ "name": "agent_session_goal_actions_company_status_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "agent_session_goal_actions_session_created_idx": {
+ "name": "agent_session_goal_actions_session_created_idx",
+ "columns": [
+ {
+ "expression": "session_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "agent_session_goal_actions_company_id_companies_id_fk": {
+ "name": "agent_session_goal_actions_company_id_companies_id_fk",
+ "tableFrom": "agent_session_goal_actions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "agent_session_goal_actions_session_id_agent_task_sessions_id_fk": {
+ "name": "agent_session_goal_actions_session_id_agent_task_sessions_id_fk",
+ "tableFrom": "agent_session_goal_actions",
+ "columnsFrom": [
+ "session_id"
+ ],
+ "tableTo": "agent_task_sessions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.agent_task_sessions": {
+ "name": "agent_task_sessions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "adapter_type": {
+ "name": "adapter_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "task_key": {
+ "name": "task_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "session_params_json": {
+ "name": "session_params_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "session_display_id": {
+ "name": "session_display_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_run_id": {
+ "name": "last_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goal_capability_json": {
+ "name": "goal_capability_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goal_json": {
+ "name": "goal_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goal_status": {
+ "name": "goal_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goal_desired_state": {
+ "name": "goal_desired_state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goal_source_id": {
+ "name": "goal_source_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goal_source_cursor": {
+ "name": "goal_source_cursor",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goal_revision": {
+ "name": "goal_revision",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "goal_observed_at": {
+ "name": "goal_observed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "agent_task_sessions_company_agent_adapter_task_uniq": {
+ "name": "agent_task_sessions_company_agent_adapter_task_uniq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "adapter_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "task_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "agent_task_sessions_company_agent_updated_idx": {
+ "name": "agent_task_sessions_company_agent_updated_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "agent_task_sessions_company_task_updated_idx": {
+ "name": "agent_task_sessions_company_task_updated_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "task_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "agent_task_sessions_company_id_companies_id_fk": {
+ "name": "agent_task_sessions_company_id_companies_id_fk",
+ "tableFrom": "agent_task_sessions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "agent_task_sessions_agent_id_agents_id_fk": {
+ "name": "agent_task_sessions_agent_id_agents_id_fk",
+ "tableFrom": "agent_task_sessions",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "agent_task_sessions_last_run_id_heartbeat_runs_id_fk": {
+ "name": "agent_task_sessions_last_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "agent_task_sessions",
+ "columnsFrom": [
+ "last_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.agent_wakeup_requests": {
+ "name": "agent_wakeup_requests",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source": {
+ "name": "source",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "trigger_detail": {
+ "name": "trigger_detail",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "reason": {
+ "name": "reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "payload": {
+ "name": "payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'queued'"
+ },
+ "coalesced_count": {
+ "name": "coalesced_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "requested_by_actor_type": {
+ "name": "requested_by_actor_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "requested_by_actor_id": {
+ "name": "requested_by_actor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "requested_at": {
+ "name": "requested_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "claimed_at": {
+ "name": "claimed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "finished_at": {
+ "name": "finished_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "agent_wakeup_requests_company_agent_status_idx": {
+ "name": "agent_wakeup_requests_company_agent_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "agent_wakeup_requests_company_requested_idx": {
+ "name": "agent_wakeup_requests_company_requested_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "requested_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "agent_wakeup_requests_agent_requested_idx": {
+ "name": "agent_wakeup_requests_agent_requested_idx",
+ "columns": [
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "requested_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "agent_wakeup_requests_review_path_recovery_idempotency_uq": {
+ "name": "agent_wakeup_requests_review_path_recovery_idempotency_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"agent_wakeup_requests\".\"idempotency_key\" LIKE 'issue_review_path_lost:%' AND \"agent_wakeup_requests\".\"status\" <> 'skipped'",
+ "concurrently": false
+ },
+ "agent_wakeup_requests_disposition_repair_idempotency_uq": {
+ "name": "agent_wakeup_requests_disposition_repair_idempotency_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"agent_wakeup_requests\".\"idempotency_key\" LIKE 'issue_disposition_repair:%' AND \"agent_wakeup_requests\".\"status\" <> 'skipped'",
+ "concurrently": false
+ },
+ "agent_wakeup_requests_question_response_delivery_idempotency_uq": {
+ "name": "agent_wakeup_requests_question_response_delivery_idempotency_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "(\"agent_wakeup_requests\".\"idempotency_key\" LIKE 'question-response:%' OR \"agent_wakeup_requests\".\"idempotency_key\" LIKE 'interaction:%') AND \"agent_wakeup_requests\".\"status\" NOT IN ('skipped', 'failed', 'cancelled')",
+ "concurrently": false
+ },
+ "agent_wakeup_requests_connection_intent_delivery_idempotency_uq": {
+ "name": "agent_wakeup_requests_connection_intent_delivery_idempotency_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"agent_wakeup_requests\".\"idempotency_key\" LIKE 'connection-intent:%' AND \"agent_wakeup_requests\".\"status\" NOT IN ('skipped', 'failed', 'cancelled')",
+ "concurrently": false
+ },
+ "agent_wakeup_requests_tool_action_delivery_uq": {
+ "name": "agent_wakeup_requests_tool_action_delivery_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"agent_wakeup_requests\".\"idempotency_key\" LIKE 'tool-action-response:%' AND \"agent_wakeup_requests\".\"status\" NOT IN ('skipped', 'failed', 'cancelled')",
+ "concurrently": false
+ },
+ "agent_wakeup_requests_chat_completion_uq": {
+ "name": "agent_wakeup_requests_chat_completion_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"agent_wakeup_requests\".\"idempotency_key\" LIKE 'chat-completion:%'",
+ "concurrently": false
+ },
+ "agent_wakeup_requests_company_payload_issue_idx": {
+ "name": "agent_wakeup_requests_company_payload_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "(\"payload\" ->> 'issueId')",
+ "isExpression": true,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "agent_wakeup_requests_company_id_companies_id_fk": {
+ "name": "agent_wakeup_requests_company_id_companies_id_fk",
+ "tableFrom": "agent_wakeup_requests",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "agent_wakeup_requests_agent_id_agents_id_fk": {
+ "name": "agent_wakeup_requests_agent_id_agents_id_fk",
+ "tableFrom": "agent_wakeup_requests",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.agents": {
+ "name": "agents",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'general'"
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "icon": {
+ "name": "icon",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "appearance": {
+ "name": "appearance",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'idle'"
+ },
+ "reports_to": {
+ "name": "reports_to",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "capabilities": {
+ "name": "capabilities",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "adapter_type": {
+ "name": "adapter_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'process'"
+ },
+ "adapter_config": {
+ "name": "adapter_config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "runtime_config": {
+ "name": "runtime_config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "default_environment_id": {
+ "name": "default_environment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "budget_monthly_cents": {
+ "name": "budget_monthly_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "spend_month_utc": {
+ "name": "spend_month_utc",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "spent_monthly_cents": {
+ "name": "spent_monthly_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "pause_reason": {
+ "name": "pause_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "paused_at": {
+ "name": "paused_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error_reason": {
+ "name": "error_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "permissions": {
+ "name": "permissions",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "last_heartbeat_at": {
+ "name": "last_heartbeat_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "agents_company_status_idx": {
+ "name": "agents_company_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "agents_company_reports_to_idx": {
+ "name": "agents_company_reports_to_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "reports_to",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "agents_company_default_environment_idx": {
+ "name": "agents_company_default_environment_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "default_environment_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "agents_company_id_companies_id_fk": {
+ "name": "agents_company_id_companies_id_fk",
+ "tableFrom": "agents",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "agents_reports_to_agents_id_fk": {
+ "name": "agents_reports_to_agents_id_fk",
+ "tableFrom": "agents",
+ "columnsFrom": [
+ "reports_to"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "agents_default_environment_id_environments_id_fk": {
+ "name": "agents_default_environment_id_environments_id_fk",
+ "tableFrom": "agents",
+ "columnsFrom": [
+ "default_environment_id"
+ ],
+ "tableTo": "environments",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "agents_company_id_uq": {
+ "name": "agents_company_id_uq",
+ "columns": [
+ "company_id",
+ "id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.ai_connection_defaults": {
+ "name": "ai_connection_defaults",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "method": {
+ "name": "method",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "grant_id": {
+ "name": "grant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "ai_connection_defaults_owner_method_uq": {
+ "name": "ai_connection_defaults_owner_method_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "method",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_connection_defaults_company_id_companies_id_fk": {
+ "name": "ai_connection_defaults_company_id_companies_id_fk",
+ "tableFrom": "ai_connection_defaults",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_connection_defaults_company_grant_fk": {
+ "name": "ai_connection_defaults_company_grant_fk",
+ "tableFrom": "ai_connection_defaults",
+ "columnsFrom": [
+ "company_id",
+ "grant_id"
+ ],
+ "tableTo": "connection_grants",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "ai_connection_defaults_provider_check": {
+ "name": "ai_connection_defaults_provider_check",
+ "value": "\"ai_connection_defaults\".\"provider\" in ('anthropic','openai','openrouter','xai','google')"
+ },
+ "ai_connection_defaults_method_check": {
+ "name": "ai_connection_defaults_method_check",
+ "value": "\"ai_connection_defaults\".\"method\" in ('subscription','api_key')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.ai_connection_pools": {
+ "name": "ai_connection_pools",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "plugin_key": {
+ "name": "plugin_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "config": {
+ "name": "config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revision": {
+ "name": "revision",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "ai_connection_pools_id_tool_connections_id_fk": {
+ "name": "ai_connection_pools_id_tool_connections_id_fk",
+ "tableFrom": "ai_connection_pools",
+ "columnsFrom": [
+ "id"
+ ],
+ "tableTo": "tool_connections",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_connection_pools_company_id_companies_id_fk": {
+ "name": "ai_connection_pools_company_id_companies_id_fk",
+ "tableFrom": "ai_connection_pools",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_connection_pools_company_connection_fk": {
+ "name": "ai_connection_pools_company_connection_fk",
+ "tableFrom": "ai_connection_pools",
+ "columnsFrom": [
+ "company_id",
+ "id"
+ ],
+ "tableTo": "tool_connections",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "ai_connection_pools_company_id_uq": {
+ "name": "ai_connection_pools_company_id_uq",
+ "columns": [
+ "company_id",
+ "id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.ai_connection_router_cursors": {
+ "name": "ai_connection_router_cursors",
+ "schema": "",
+ "columns": {
+ "pool_id": {
+ "name": "pool_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "last_member_id": {
+ "name": "last_member_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "version": {
+ "name": "version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "ai_connection_router_cursors_pool_id_ai_connection_pools_id_fk": {
+ "name": "ai_connection_router_cursors_pool_id_ai_connection_pools_id_fk",
+ "tableFrom": "ai_connection_router_cursors",
+ "columnsFrom": [
+ "pool_id"
+ ],
+ "tableTo": "ai_connection_pools",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_connection_router_cursors_company_id_companies_id_fk": {
+ "name": "ai_connection_router_cursors_company_id_companies_id_fk",
+ "tableFrom": "ai_connection_router_cursors",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_connection_router_cursors_company_pool_fk": {
+ "name": "ai_connection_router_cursors_company_pool_fk",
+ "tableFrom": "ai_connection_router_cursors",
+ "columnsFrom": [
+ "company_id",
+ "pool_id"
+ ],
+ "tableTo": "ai_connection_pools",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.ai_connection_task_pins": {
+ "name": "ai_connection_task_pins",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pool_id": {
+ "name": "pool_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "task_key": {
+ "name": "task_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "selection": {
+ "name": "selection",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "member": {
+ "name": "member",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "ai_connection_task_pins_affinity_uq": {
+ "name": "ai_connection_task_pins_affinity_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "pool_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "task_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_connection_task_pins_company_id_companies_id_fk": {
+ "name": "ai_connection_task_pins_company_id_companies_id_fk",
+ "tableFrom": "ai_connection_task_pins",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_connection_task_pins_pool_id_ai_connection_pools_id_fk": {
+ "name": "ai_connection_task_pins_pool_id_ai_connection_pools_id_fk",
+ "tableFrom": "ai_connection_task_pins",
+ "columnsFrom": [
+ "pool_id"
+ ],
+ "tableTo": "ai_connection_pools",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_connection_task_pins_agent_id_agents_id_fk": {
+ "name": "ai_connection_task_pins_agent_id_agents_id_fk",
+ "tableFrom": "ai_connection_task_pins",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_connection_task_pins_company_pool_fk": {
+ "name": "ai_connection_task_pins_company_pool_fk",
+ "tableFrom": "ai_connection_task_pins",
+ "columnsFrom": [
+ "company_id",
+ "pool_id"
+ ],
+ "tableTo": "ai_connection_pools",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_connection_task_pins_company_agent_fk": {
+ "name": "ai_connection_task_pins_company_agent_fk",
+ "tableFrom": "ai_connection_task_pins",
+ "columnsFrom": [
+ "company_id",
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.ai_provider_defaults": {
+ "name": "ai_provider_defaults",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "grant_id": {
+ "name": "grant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "ai_provider_defaults_owner_provider_uq": {
+ "name": "ai_provider_defaults_owner_provider_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_provider_defaults_company_id_companies_id_fk": {
+ "name": "ai_provider_defaults_company_id_companies_id_fk",
+ "tableFrom": "ai_provider_defaults",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_provider_defaults_company_grant_fk": {
+ "name": "ai_provider_defaults_company_grant_fk",
+ "tableFrom": "ai_provider_defaults",
+ "columnsFrom": [
+ "company_id",
+ "grant_id"
+ ],
+ "tableTo": "connection_grants",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "ai_provider_defaults_provider_check": {
+ "name": "ai_provider_defaults_provider_check",
+ "value": "\"ai_provider_defaults\".\"provider\" in ('anthropic','openai','openrouter','xai','google')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.announcement_dismissals": {
+ "name": "announcement_dismissals",
+ "schema": "",
+ "columns": {
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "announcement_id": {
+ "name": "announcement_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "dismissed_at": {
+ "name": "dismissed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "announcement_dismissals_user_id_announcement_id_pk": {
+ "name": "announcement_dismissals_user_id_announcement_id_pk",
+ "columns": [
+ "user_id",
+ "announcement_id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.announcement_publications": {
+ "name": "announcement_publications",
+ "schema": "",
+ "columns": {
+ "announcement_id": {
+ "name": "announcement_id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.approval_comments": {
+ "name": "approval_comments",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "approval_id": {
+ "name": "approval_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_agent_id": {
+ "name": "author_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "author_user_id": {
+ "name": "author_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "body": {
+ "name": "body",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "approval_comments_company_idx": {
+ "name": "approval_comments_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "approval_comments_approval_idx": {
+ "name": "approval_comments_approval_idx",
+ "columns": [
+ {
+ "expression": "approval_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "approval_comments_approval_created_idx": {
+ "name": "approval_comments_approval_created_idx",
+ "columns": [
+ {
+ "expression": "approval_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "approval_comments_company_id_companies_id_fk": {
+ "name": "approval_comments_company_id_companies_id_fk",
+ "tableFrom": "approval_comments",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "approval_comments_approval_id_approvals_id_fk": {
+ "name": "approval_comments_approval_id_approvals_id_fk",
+ "tableFrom": "approval_comments",
+ "columnsFrom": [
+ "approval_id"
+ ],
+ "tableTo": "approvals",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "approval_comments_author_agent_id_agents_id_fk": {
+ "name": "approval_comments_author_agent_id_agents_id_fk",
+ "tableFrom": "approval_comments",
+ "columnsFrom": [
+ "author_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.approvals": {
+ "name": "approvals",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "requested_by_agent_id": {
+ "name": "requested_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "requested_by_user_id": {
+ "name": "requested_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "payload": {
+ "name": "payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "decision_note": {
+ "name": "decision_note",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "decided_by_user_id": {
+ "name": "decided_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "decided_at": {
+ "name": "decided_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "approvals_company_status_type_idx": {
+ "name": "approvals_company_status_type_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "approvals_company_id_companies_id_fk": {
+ "name": "approvals_company_id_companies_id_fk",
+ "tableFrom": "approvals",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "approvals_requested_by_agent_id_agents_id_fk": {
+ "name": "approvals_requested_by_agent_id_agents_id_fk",
+ "tableFrom": "approvals",
+ "columnsFrom": [
+ "requested_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.assets": {
+ "name": "assets",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "object_key": {
+ "name": "object_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content_type": {
+ "name": "content_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "byte_size": {
+ "name": "byte_size",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sha256": {
+ "name": "sha256",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "original_filename": {
+ "name": "original_filename",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "assets_company_created_idx": {
+ "name": "assets_company_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "assets_company_provider_idx": {
+ "name": "assets_company_provider_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "assets_company_object_key_uq": {
+ "name": "assets_company_object_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "object_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "assets_company_id_companies_id_fk": {
+ "name": "assets_company_id_companies_id_fk",
+ "tableFrom": "assets",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "assets_created_by_agent_id_agents_id_fk": {
+ "name": "assets_created_by_agent_id_agents_id_fk",
+ "tableFrom": "assets",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.account": {
+ "name": "account",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "issuer": {
+ "name": "issuer",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_id": {
+ "name": "provider_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "access_token": {
+ "name": "access_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_token": {
+ "name": "refresh_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "id_token": {
+ "name": "id_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "access_token_expires_at": {
+ "name": "access_token_expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_token_expires_at": {
+ "name": "refresh_token_expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scope": {
+ "name": "scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "account_issuer_account_id_uq": {
+ "name": "account_issuer_account_id_uq",
+ "columns": [
+ {
+ "expression": "issuer",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "account_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "account_user_id_user_id_fk": {
+ "name": "account_user_id_user_id_fk",
+ "tableFrom": "account",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.session": {
+ "name": "session",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ip_address": {
+ "name": "ip_address",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_agent": {
+ "name": "user_agent",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "session_user_id_user_id_fk": {
+ "name": "session_user_id_user_id_fk",
+ "tableFrom": "session",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.user": {
+ "name": "user",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "email_verified": {
+ "name": "email_verified",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "image": {
+ "name": "image",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.verification": {
+ "name": "verification",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "identifier": {
+ "name": "identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.board_api_keys": {
+ "name": "board_api_keys",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "key_hash": {
+ "name": "key_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "last_used_at": {
+ "name": "last_used_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "board_api_keys_key_hash_idx": {
+ "name": "board_api_keys_key_hash_idx",
+ "columns": [
+ {
+ "expression": "key_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "board_api_keys_user_idx": {
+ "name": "board_api_keys_user_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "board_api_keys_user_id_user_id_fk": {
+ "name": "board_api_keys_user_id_user_id_fk",
+ "tableFrom": "board_api_keys",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.browser_use_browsers": {
+ "name": "browser_use_browsers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "session_id": {
+ "name": "session_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_browser_id": {
+ "name": "provider_browser_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "browser_use_browsers_provider_uq": {
+ "name": "browser_use_browsers_provider_uq",
+ "columns": [
+ {
+ "expression": "provider_browser_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "browser_use_browsers_session_idx": {
+ "name": "browser_use_browsers_session_idx",
+ "columns": [
+ {
+ "expression": "session_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "browser_use_browsers_company_id_companies_id_fk": {
+ "name": "browser_use_browsers_company_id_companies_id_fk",
+ "tableFrom": "browser_use_browsers",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "browser_use_browsers_session_id_browser_use_sessions_id_fk": {
+ "name": "browser_use_browsers_session_id_browser_use_sessions_id_fk",
+ "tableFrom": "browser_use_browsers",
+ "columnsFrom": [
+ "session_id"
+ ],
+ "tableTo": "browser_use_sessions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.browser_use_runs": {
+ "name": "browser_use_runs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "session_id": {
+ "name": "session_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "heartbeat_run_id": {
+ "name": "heartbeat_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "invocation_id": {
+ "name": "invocation_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_run_id": {
+ "name": "provider_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "recovery_cursor": {
+ "name": "recovery_cursor",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'creating'"
+ },
+ "detached_until": {
+ "name": "detached_until",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "event_cursor": {
+ "name": "event_cursor",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "events_drained": {
+ "name": "events_drained",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "accounted_cents": {
+ "name": "accounted_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "progress": {
+ "name": "progress",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "result": {
+ "name": "result",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "browser_use_runs_invocation_uq": {
+ "name": "browser_use_runs_invocation_uq",
+ "columns": [
+ {
+ "expression": "invocation_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "browser_use_runs_provider_uq": {
+ "name": "browser_use_runs_provider_uq",
+ "columns": [
+ {
+ "expression": "provider_run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "browser_use_runs_session_idx": {
+ "name": "browser_use_runs_session_idx",
+ "columns": [
+ {
+ "expression": "session_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "browser_use_runs_company_id_companies_id_fk": {
+ "name": "browser_use_runs_company_id_companies_id_fk",
+ "tableFrom": "browser_use_runs",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "browser_use_runs_session_id_browser_use_sessions_id_fk": {
+ "name": "browser_use_runs_session_id_browser_use_sessions_id_fk",
+ "tableFrom": "browser_use_runs",
+ "columnsFrom": [
+ "session_id"
+ ],
+ "tableTo": "browser_use_sessions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "browser_use_runs_heartbeat_run_id_heartbeat_runs_id_fk": {
+ "name": "browser_use_runs_heartbeat_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "browser_use_runs",
+ "columnsFrom": [
+ "heartbeat_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.browser_use_sessions": {
+ "name": "browser_use_sessions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "grant_id": {
+ "name": "grant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_session_id": {
+ "name": "provider_session_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'starting'"
+ },
+ "idle_deadline": {
+ "name": "idle_deadline",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "stop_requested": {
+ "name": "stop_requested",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lease_token": {
+ "name": "lease_token",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lease_until": {
+ "name": "lease_until",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "next_poll_at": {
+ "name": "next_poll_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "browser_use_sessions_task_idx": {
+ "name": "browser_use_sessions_task_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "browser_use_sessions_provider_uq": {
+ "name": "browser_use_sessions_provider_uq",
+ "columns": [
+ {
+ "expression": "provider_session_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "browser_use_sessions_company_id_companies_id_fk": {
+ "name": "browser_use_sessions_company_id_companies_id_fk",
+ "tableFrom": "browser_use_sessions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "browser_use_sessions_issue_id_issues_id_fk": {
+ "name": "browser_use_sessions_issue_id_issues_id_fk",
+ "tableFrom": "browser_use_sessions",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "browser_use_sessions_agent_id_agents_id_fk": {
+ "name": "browser_use_sessions_agent_id_agents_id_fk",
+ "tableFrom": "browser_use_sessions",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "browser_use_sessions_connection_id_tool_connections_id_fk": {
+ "name": "browser_use_sessions_connection_id_tool_connections_id_fk",
+ "tableFrom": "browser_use_sessions",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "tableTo": "tool_connections",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "browser_use_sessions_grant_id_connection_grants_id_fk": {
+ "name": "browser_use_sessions_grant_id_connection_grants_id_fk",
+ "tableFrom": "browser_use_sessions",
+ "columnsFrom": [
+ "grant_id"
+ ],
+ "tableTo": "connection_grants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.browser_use_settings": {
+ "name": "browser_use_settings",
+ "schema": "",
+ "columns": {
+ "grant_id": {
+ "name": "grant_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "allowed_profile_ids": {
+ "name": "allowed_profile_ids",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "max_cost_usd": {
+ "name": "max_cost_usd",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "browser_use_settings_grant_id_connection_grants_id_fk": {
+ "name": "browser_use_settings_grant_id_connection_grants_id_fk",
+ "tableFrom": "browser_use_settings",
+ "columnsFrom": [
+ "grant_id"
+ ],
+ "tableTo": "connection_grants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "browser_use_settings_company_id_companies_id_fk": {
+ "name": "browser_use_settings_company_id_companies_id_fk",
+ "tableFrom": "browser_use_settings",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.budget_incidents": {
+ "name": "budget_incidents",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "policy_id": {
+ "name": "policy_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope_type": {
+ "name": "scope_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope_id": {
+ "name": "scope_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metric": {
+ "name": "metric",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "window_kind": {
+ "name": "window_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "window_start": {
+ "name": "window_start",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "window_end": {
+ "name": "window_end",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "threshold_type": {
+ "name": "threshold_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "amount_limit": {
+ "name": "amount_limit",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "amount_observed": {
+ "name": "amount_observed",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'open'"
+ },
+ "approval_id": {
+ "name": "approval_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resolved_at": {
+ "name": "resolved_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "budget_incidents_company_status_idx": {
+ "name": "budget_incidents_company_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "budget_incidents_company_scope_idx": {
+ "name": "budget_incidents_company_scope_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scope_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scope_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "budget_incidents_policy_window_threshold_idx": {
+ "name": "budget_incidents_policy_window_threshold_idx",
+ "columns": [
+ {
+ "expression": "policy_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "window_start",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "threshold_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"budget_incidents\".\"status\" = 'open'",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "budget_incidents_company_id_companies_id_fk": {
+ "name": "budget_incidents_company_id_companies_id_fk",
+ "tableFrom": "budget_incidents",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "budget_incidents_policy_id_budget_policies_id_fk": {
+ "name": "budget_incidents_policy_id_budget_policies_id_fk",
+ "tableFrom": "budget_incidents",
+ "columnsFrom": [
+ "policy_id"
+ ],
+ "tableTo": "budget_policies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "budget_incidents_approval_id_approvals_id_fk": {
+ "name": "budget_incidents_approval_id_approvals_id_fk",
+ "tableFrom": "budget_incidents",
+ "columnsFrom": [
+ "approval_id"
+ ],
+ "tableTo": "approvals",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.budget_policies": {
+ "name": "budget_policies",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope_type": {
+ "name": "scope_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope_id": {
+ "name": "scope_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metric": {
+ "name": "metric",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'billed_cents'"
+ },
+ "window_kind": {
+ "name": "window_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "amount": {
+ "name": "amount",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "reservation_cents": {
+ "name": "reservation_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "warn_percent": {
+ "name": "warn_percent",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 80
+ },
+ "hard_stop_enabled": {
+ "name": "hard_stop_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "unpriced_usage_policy": {
+ "name": "unpriced_usage_policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'block'"
+ },
+ "notify_enabled": {
+ "name": "notify_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "enforcement_version": {
+ "name": "enforcement_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "enforcement_delivered_version": {
+ "name": "enforcement_delivered_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_by_user_id": {
+ "name": "updated_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "budget_policies_company_scope_active_idx": {
+ "name": "budget_policies_company_scope_active_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scope_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scope_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "is_active",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "budget_policies_company_window_idx": {
+ "name": "budget_policies_company_window_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "window_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "metric",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "budget_policies_company_scope_metric_unique_idx": {
+ "name": "budget_policies_company_scope_metric_unique_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scope_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scope_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "metric",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "window_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "budget_policies_company_id_companies_id_fk": {
+ "name": "budget_policies_company_id_companies_id_fk",
+ "tableFrom": "budget_policies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "budget_policies_reservation_nonnegative": {
+ "name": "budget_policies_reservation_nonnegative",
+ "value": "\"budget_policies\".\"reservation_cents\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.built_in_managed_resources": {
+ "name": "built_in_managed_resources",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "bundle_key": {
+ "name": "bundle_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_kind": {
+ "name": "resource_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_key": {
+ "name": "resource_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_id": {
+ "name": "resource_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "stock_version": {
+ "name": "stock_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "stock_hash": {
+ "name": "stock_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "defaults_json": {
+ "name": "defaults_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "built_in_managed_resources_company_idx": {
+ "name": "built_in_managed_resources_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "built_in_managed_resources_resource_idx": {
+ "name": "built_in_managed_resources_resource_idx",
+ "columns": [
+ {
+ "expression": "resource_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "built_in_managed_resources_company_bundle_resource_uq": {
+ "name": "built_in_managed_resources_company_bundle_resource_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "bundle_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "built_in_managed_resources_company_id_companies_id_fk": {
+ "name": "built_in_managed_resources_company_id_companies_id_fk",
+ "tableFrom": "built_in_managed_resources",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.case_attachments": {
+ "name": "case_attachments",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "case_id": {
+ "name": "case_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "asset_id": {
+ "name": "asset_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "case_attachments_company_case_idx": {
+ "name": "case_attachments_company_case_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "case_attachments_asset_uq": {
+ "name": "case_attachments_asset_uq",
+ "columns": [
+ {
+ "expression": "asset_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "case_attachments_company_id_companies_id_fk": {
+ "name": "case_attachments_company_id_companies_id_fk",
+ "tableFrom": "case_attachments",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "case_attachments_case_id_cases_id_fk": {
+ "name": "case_attachments_case_id_cases_id_fk",
+ "tableFrom": "case_attachments",
+ "columnsFrom": [
+ "case_id"
+ ],
+ "tableTo": "cases",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "case_attachments_asset_id_assets_id_fk": {
+ "name": "case_attachments_asset_id_assets_id_fk",
+ "tableFrom": "case_attachments",
+ "columnsFrom": [
+ "asset_id"
+ ],
+ "tableTo": "assets",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.case_documents": {
+ "name": "case_documents",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "case_id": {
+ "name": "case_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "case_documents_company_case_key_uq": {
+ "name": "case_documents_company_case_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "case_documents_document_uq": {
+ "name": "case_documents_document_uq",
+ "columns": [
+ {
+ "expression": "document_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "case_documents_company_case_updated_idx": {
+ "name": "case_documents_company_case_updated_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "case_documents_company_id_companies_id_fk": {
+ "name": "case_documents_company_id_companies_id_fk",
+ "tableFrom": "case_documents",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "case_documents_case_id_cases_id_fk": {
+ "name": "case_documents_case_id_cases_id_fk",
+ "tableFrom": "case_documents",
+ "columnsFrom": [
+ "case_id"
+ ],
+ "tableTo": "cases",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "case_documents_document_id_documents_id_fk": {
+ "name": "case_documents_document_id_documents_id_fk",
+ "tableFrom": "case_documents",
+ "columnsFrom": [
+ "document_id"
+ ],
+ "tableTo": "documents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.case_events": {
+ "name": "case_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "case_id": {
+ "name": "case_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_type": {
+ "name": "actor_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_user_id": {
+ "name": "actor_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "actor_agent_id": {
+ "name": "actor_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "payload": {
+ "name": "payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "case_events_case_created_idx": {
+ "name": "case_events_case_created_idx",
+ "columns": [
+ {
+ "expression": "case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "case_events_company_case_idx": {
+ "name": "case_events_company_case_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "case_events_company_id_companies_id_fk": {
+ "name": "case_events_company_id_companies_id_fk",
+ "tableFrom": "case_events",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "case_events_case_id_cases_id_fk": {
+ "name": "case_events_case_id_cases_id_fk",
+ "tableFrom": "case_events",
+ "columnsFrom": [
+ "case_id"
+ ],
+ "tableTo": "cases",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "case_events_actor_agent_id_agents_id_fk": {
+ "name": "case_events_actor_agent_id_agents_id_fk",
+ "tableFrom": "case_events",
+ "columnsFrom": [
+ "actor_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "case_events_kind_check": {
+ "name": "case_events_kind_check",
+ "value": "\"case_events\".\"kind\" in (\n 'created',\n 'updated',\n 'fields_changed',\n 'status_changed',\n 'issue_linked',\n 'issue_unlinked',\n 'document_revised',\n 'child_linked',\n 'attachment_added',\n 'label_added',\n 'label_removed'\n )"
+ },
+ "case_events_actor_type_check": {
+ "name": "case_events_actor_type_check",
+ "value": "\"case_events\".\"actor_type\" in ('user', 'agent', 'system')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.case_issue_links": {
+ "name": "case_issue_links",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "case_id": {
+ "name": "case_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_run_id": {
+ "name": "created_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "case_issue_links_case_issue_uq": {
+ "name": "case_issue_links_case_issue_uq",
+ "columns": [
+ {
+ "expression": "case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "case_issue_links_company_case_idx": {
+ "name": "case_issue_links_company_case_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "case_issue_links_issue_idx": {
+ "name": "case_issue_links_issue_idx",
+ "columns": [
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "case_issue_links_company_id_companies_id_fk": {
+ "name": "case_issue_links_company_id_companies_id_fk",
+ "tableFrom": "case_issue_links",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "case_issue_links_case_id_cases_id_fk": {
+ "name": "case_issue_links_case_id_cases_id_fk",
+ "tableFrom": "case_issue_links",
+ "columnsFrom": [
+ "case_id"
+ ],
+ "tableTo": "cases",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "case_issue_links_issue_id_issues_id_fk": {
+ "name": "case_issue_links_issue_id_issues_id_fk",
+ "tableFrom": "case_issue_links",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "case_issue_links_role_check": {
+ "name": "case_issue_links_role_check",
+ "value": "\"case_issue_links\".\"role\" in ('origin', 'work', 'reference')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.case_labels": {
+ "name": "case_labels",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "case_id": {
+ "name": "case_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "label_id": {
+ "name": "label_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "case_labels_case_label_uq": {
+ "name": "case_labels_case_label_uq",
+ "columns": [
+ {
+ "expression": "case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "label_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "case_labels_company_case_idx": {
+ "name": "case_labels_company_case_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "case_labels_label_idx": {
+ "name": "case_labels_label_idx",
+ "columns": [
+ {
+ "expression": "label_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "case_labels_company_id_companies_id_fk": {
+ "name": "case_labels_company_id_companies_id_fk",
+ "tableFrom": "case_labels",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "case_labels_case_id_cases_id_fk": {
+ "name": "case_labels_case_id_cases_id_fk",
+ "tableFrom": "case_labels",
+ "columnsFrom": [
+ "case_id"
+ ],
+ "tableTo": "cases",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "case_labels_label_id_labels_id_fk": {
+ "name": "case_labels_label_id_labels_id_fk",
+ "tableFrom": "case_labels",
+ "columnsFrom": [
+ "label_id"
+ ],
+ "tableTo": "labels",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.cases": {
+ "name": "cases",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "case_number": {
+ "name": "case_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "identifier": {
+ "name": "identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "case_type": {
+ "name": "case_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "summary": {
+ "name": "summary",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'draft'"
+ },
+ "fields": {
+ "name": "fields",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "parent_case_id": {
+ "name": "parent_case_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "cases_company_case_number_uq": {
+ "name": "cases_company_case_number_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "case_number",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "cases_identifier_uq": {
+ "name": "cases_identifier_uq",
+ "columns": [
+ {
+ "expression": "identifier",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "cases_company_type_key_uq": {
+ "name": "cases_company_type_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "case_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "cases_company_status_idx": {
+ "name": "cases_company_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "cases_company_type_idx": {
+ "name": "cases_company_type_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "case_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "cases_company_project_idx": {
+ "name": "cases_company_project_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "cases_parent_idx": {
+ "name": "cases_parent_idx",
+ "columns": [
+ {
+ "expression": "parent_case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "cases_title_search_idx": {
+ "name": "cases_title_search_idx",
+ "columns": [
+ {
+ "expression": "title",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "gin_trgm_ops"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "gin",
+ "concurrently": false
+ },
+ "cases_identifier_search_idx": {
+ "name": "cases_identifier_search_idx",
+ "columns": [
+ {
+ "expression": "identifier",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "gin_trgm_ops"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "gin",
+ "concurrently": false
+ },
+ "cases_summary_search_idx": {
+ "name": "cases_summary_search_idx",
+ "columns": [
+ {
+ "expression": "summary",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "gin_trgm_ops"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "gin",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "cases_company_id_companies_id_fk": {
+ "name": "cases_company_id_companies_id_fk",
+ "tableFrom": "cases",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "cases_project_id_projects_id_fk": {
+ "name": "cases_project_id_projects_id_fk",
+ "tableFrom": "cases",
+ "columnsFrom": [
+ "project_id"
+ ],
+ "tableTo": "projects",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "cases_parent_case_id_cases_id_fk": {
+ "name": "cases_parent_case_id_cases_id_fk",
+ "tableFrom": "cases",
+ "columnsFrom": [
+ "parent_case_id"
+ ],
+ "tableTo": "cases",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "cases_created_by_agent_id_agents_id_fk": {
+ "name": "cases_created_by_agent_id_agents_id_fk",
+ "tableFrom": "cases",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "cases_status_check": {
+ "name": "cases_status_check",
+ "value": "\"cases\".\"status\" in ('draft', 'in_progress', 'in_review', 'approved', 'done', 'cancelled')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.chat_actions": {
+ "name": "chat_actions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "endpoint_id": {
+ "name": "endpoint_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "delivery_id": {
+ "name": "delivery_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "conversation_id": {
+ "name": "conversation_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "principal_id": {
+ "name": "principal_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_action_id": {
+ "name": "provider_action_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "payload": {
+ "name": "payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'received'"
+ },
+ "result": {
+ "name": "result",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "chat_actions_provider_action_uq": {
+ "name": "chat_actions_provider_action_uq",
+ "columns": [
+ {
+ "expression": "endpoint_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_action_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "chat_actions_company_id_companies_id_fk": {
+ "name": "chat_actions_company_id_companies_id_fk",
+ "tableFrom": "chat_actions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_actions_delivery_id_chat_deliveries_id_fk": {
+ "name": "chat_actions_delivery_id_chat_deliveries_id_fk",
+ "tableFrom": "chat_actions",
+ "columnsFrom": [
+ "delivery_id"
+ ],
+ "tableTo": "chat_deliveries",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "chat_actions_company_delivery_fk": {
+ "name": "chat_actions_company_delivery_fk",
+ "tableFrom": "chat_actions",
+ "columnsFrom": [
+ "company_id",
+ "delivery_id"
+ ],
+ "tableTo": "chat_deliveries",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "chat_actions_company_conversation_fk": {
+ "name": "chat_actions_company_conversation_fk",
+ "tableFrom": "chat_actions",
+ "columnsFrom": [
+ "company_id",
+ "conversation_id"
+ ],
+ "tableTo": "chat_conversations",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "chat_actions_company_principal_fk": {
+ "name": "chat_actions_company_principal_fk",
+ "tableFrom": "chat_actions",
+ "columnsFrom": [
+ "company_id",
+ "principal_id"
+ ],
+ "tableTo": "chat_external_principals",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "chat_actions_company_endpoint_fk": {
+ "name": "chat_actions_company_endpoint_fk",
+ "tableFrom": "chat_actions",
+ "columnsFrom": [
+ "company_id",
+ "endpoint_id"
+ ],
+ "tableTo": "chat_endpoints",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.chat_agent_routes": {
+ "name": "chat_agent_routes",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_endpoint_id": {
+ "name": "source_endpoint_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "destination_endpoint_id": {
+ "name": "destination_endpoint_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "trigger_mode": {
+ "name": "trigger_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'explicit_mention'"
+ },
+ "max_hops": {
+ "name": "max_hops",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "chat_agent_routes_pair_uq": {
+ "name": "chat_agent_routes_pair_uq",
+ "columns": [
+ {
+ "expression": "source_endpoint_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "destination_endpoint_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "chat_agent_routes_company_id_companies_id_fk": {
+ "name": "chat_agent_routes_company_id_companies_id_fk",
+ "tableFrom": "chat_agent_routes",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_agent_routes_company_source_fk": {
+ "name": "chat_agent_routes_company_source_fk",
+ "tableFrom": "chat_agent_routes",
+ "columnsFrom": [
+ "company_id",
+ "source_endpoint_id"
+ ],
+ "tableTo": "chat_endpoints",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_agent_routes_company_destination_fk": {
+ "name": "chat_agent_routes_company_destination_fk",
+ "tableFrom": "chat_agent_routes",
+ "columnsFrom": [
+ "company_id",
+ "destination_endpoint_id"
+ ],
+ "tableTo": "chat_endpoints",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "chat_agent_routes_hops_check": {
+ "name": "chat_agent_routes_hops_check",
+ "value": "\"chat_agent_routes\".\"max_hops\" between 1 and 8"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.chat_conversations": {
+ "name": "chat_conversations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "endpoint_id": {
+ "name": "endpoint_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_id": {
+ "name": "resource_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_conversation_id": {
+ "name": "external_conversation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_thread_id": {
+ "name": "external_thread_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "session_generation": {
+ "name": "session_generation",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "external_label": {
+ "name": "external_label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_url": {
+ "name": "provider_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_direct_message": {
+ "name": "is_direct_message",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "communication_guidance": {
+ "name": "communication_guidance",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "state": {
+ "name": "state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "last_activity_at": {
+ "name": "last_activity_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "chat_conversations_issue_idx": {
+ "name": "chat_conversations_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chat_conversations_thread_uq": {
+ "name": "chat_conversations_thread_uq",
+ "columns": [
+ {
+ "expression": "endpoint_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_conversation_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_thread_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "session_generation",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "chat_conversations_company_id_companies_id_fk": {
+ "name": "chat_conversations_company_id_companies_id_fk",
+ "tableFrom": "chat_conversations",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_conversations_resource_id_chat_endpoint_resources_id_fk": {
+ "name": "chat_conversations_resource_id_chat_endpoint_resources_id_fk",
+ "tableFrom": "chat_conversations",
+ "columnsFrom": [
+ "resource_id"
+ ],
+ "tableTo": "chat_endpoint_resources",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "chat_conversations_issue_id_issues_id_fk": {
+ "name": "chat_conversations_issue_id_issues_id_fk",
+ "tableFrom": "chat_conversations",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "restrict"
+ },
+ "chat_conversations_company_issue_fk": {
+ "name": "chat_conversations_company_issue_fk",
+ "tableFrom": "chat_conversations",
+ "columnsFrom": [
+ "company_id",
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "chat_conversations_company_endpoint_fk": {
+ "name": "chat_conversations_company_endpoint_fk",
+ "tableFrom": "chat_conversations",
+ "columnsFrom": [
+ "company_id",
+ "endpoint_id"
+ ],
+ "tableTo": "chat_endpoints",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_conversations_company_resource_fk": {
+ "name": "chat_conversations_company_resource_fk",
+ "tableFrom": "chat_conversations",
+ "columnsFrom": [
+ "company_id",
+ "resource_id"
+ ],
+ "tableTo": "chat_endpoint_resources",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "chat_conversations_company_id_uq": {
+ "name": "chat_conversations_company_id_uq",
+ "columns": [
+ "company_id",
+ "id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {
+ "chat_conversations_state_check": {
+ "name": "chat_conversations_state_check",
+ "value": "\"chat_conversations\".\"state\" in ('active', 'waiting', 'completed', 'unavailable', 'endpoint_removed')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.chat_deliveries": {
+ "name": "chat_deliveries",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "endpoint_id": {
+ "name": "endpoint_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "conversation_id": {
+ "name": "conversation_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "principal_id": {
+ "name": "principal_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_event_id": {
+ "name": "provider_event_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "deduplication_key": {
+ "name": "deduplication_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "event_kind": {
+ "name": "event_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "normalized_event": {
+ "name": "normalized_event",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "state": {
+ "name": "state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'received'"
+ },
+ "attempts": {
+ "name": "attempts",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "redacted_error": {
+ "name": "redacted_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "next_attempt_at": {
+ "name": "next_attempt_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "received_at": {
+ "name": "received_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "processed_at": {
+ "name": "processed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "chat_deliveries_work_idx": {
+ "name": "chat_deliveries_work_idx",
+ "columns": [
+ {
+ "expression": "state",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "next_attempt_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chat_deliveries_event_uq": {
+ "name": "chat_deliveries_event_uq",
+ "columns": [
+ {
+ "expression": "endpoint_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chat_deliveries_dedupe_uq": {
+ "name": "chat_deliveries_dedupe_uq",
+ "columns": [
+ {
+ "expression": "endpoint_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "deduplication_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "chat_deliveries_company_id_companies_id_fk": {
+ "name": "chat_deliveries_company_id_companies_id_fk",
+ "tableFrom": "chat_deliveries",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_deliveries_conversation_id_chat_conversations_id_fk": {
+ "name": "chat_deliveries_conversation_id_chat_conversations_id_fk",
+ "tableFrom": "chat_deliveries",
+ "columnsFrom": [
+ "conversation_id"
+ ],
+ "tableTo": "chat_conversations",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "chat_deliveries_principal_id_chat_external_principals_id_fk": {
+ "name": "chat_deliveries_principal_id_chat_external_principals_id_fk",
+ "tableFrom": "chat_deliveries",
+ "columnsFrom": [
+ "principal_id"
+ ],
+ "tableTo": "chat_external_principals",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "chat_deliveries_company_endpoint_fk": {
+ "name": "chat_deliveries_company_endpoint_fk",
+ "tableFrom": "chat_deliveries",
+ "columnsFrom": [
+ "company_id",
+ "endpoint_id"
+ ],
+ "tableTo": "chat_endpoints",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_deliveries_company_conversation_fk": {
+ "name": "chat_deliveries_company_conversation_fk",
+ "tableFrom": "chat_deliveries",
+ "columnsFrom": [
+ "company_id",
+ "conversation_id"
+ ],
+ "tableTo": "chat_conversations",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "chat_deliveries_company_principal_fk": {
+ "name": "chat_deliveries_company_principal_fk",
+ "tableFrom": "chat_deliveries",
+ "columnsFrom": [
+ "company_id",
+ "principal_id"
+ ],
+ "tableTo": "chat_external_principals",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "chat_deliveries_company_id_uq": {
+ "name": "chat_deliveries_company_id_uq",
+ "columns": [
+ "company_id",
+ "id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {
+ "chat_deliveries_state_check": {
+ "name": "chat_deliveries_state_check",
+ "value": "\"chat_deliveries\".\"state\" in ('received', 'filtered', 'processing', 'processed', 'retry', 'failed')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.chat_endpoint_leases": {
+ "name": "chat_endpoint_leases",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "endpoint_id": {
+ "name": "endpoint_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lease_key": {
+ "name": "lease_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "chat_endpoint_leases_active_uq": {
+ "name": "chat_endpoint_leases_active_uq",
+ "columns": [
+ {
+ "expression": "endpoint_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lease_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chat_endpoint_leases_expiry_idx": {
+ "name": "chat_endpoint_leases_expiry_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "chat_endpoint_leases_company_id_companies_id_fk": {
+ "name": "chat_endpoint_leases_company_id_companies_id_fk",
+ "tableFrom": "chat_endpoint_leases",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_endpoint_leases_company_endpoint_fk": {
+ "name": "chat_endpoint_leases_company_endpoint_fk",
+ "tableFrom": "chat_endpoint_leases",
+ "columnsFrom": [
+ "company_id",
+ "endpoint_id"
+ ],
+ "tableTo": "chat_endpoints",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.chat_endpoint_resources": {
+ "name": "chat_endpoint_resources",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "endpoint_id": {
+ "name": "endpoint_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_resource_id": {
+ "name": "provider_resource_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parent_provider_resource_id": {
+ "name": "parent_provider_resource_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "label": {
+ "name": "label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "detail": {
+ "name": "detail",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_url": {
+ "name": "provider_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "availability": {
+ "name": "availability",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'available'"
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "chat_endpoint_resources_endpoint_idx": {
+ "name": "chat_endpoint_resources_endpoint_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "endpoint_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chat_endpoint_resources_external_uq": {
+ "name": "chat_endpoint_resources_external_uq",
+ "columns": [
+ {
+ "expression": "endpoint_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_resource_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "chat_endpoint_resources_company_id_companies_id_fk": {
+ "name": "chat_endpoint_resources_company_id_companies_id_fk",
+ "tableFrom": "chat_endpoint_resources",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_endpoint_resources_company_endpoint_fk": {
+ "name": "chat_endpoint_resources_company_endpoint_fk",
+ "tableFrom": "chat_endpoint_resources",
+ "columnsFrom": [
+ "company_id",
+ "endpoint_id"
+ ],
+ "tableTo": "chat_endpoints",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "chat_endpoint_resources_company_id_uq": {
+ "name": "chat_endpoint_resources_company_id_uq",
+ "columns": [
+ "company_id",
+ "id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {
+ "chat_endpoint_resources_availability_check": {
+ "name": "chat_endpoint_resources_availability_check",
+ "value": "\"chat_endpoint_resources\".\"availability\" in ('available', 'unavailable', 'removed')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.chat_endpoints": {
+ "name": "chat_endpoints",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "public_id": {
+ "name": "public_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "publication_mode": {
+ "name": "publication_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'automatic'"
+ },
+ "external_execution_policy": {
+ "name": "external_execution_policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'restricted'"
+ },
+ "assigned_agent_id": {
+ "name": "assigned_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sponsor_user_id": {
+ "name": "sponsor_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'draft'"
+ },
+ "deployment_mode": {
+ "name": "deployment_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'direct'"
+ },
+ "provider_account_id": {
+ "name": "provider_account_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_account_label": {
+ "name": "provider_account_label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "bot_external_id": {
+ "name": "bot_external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "bot_username": {
+ "name": "bot_username",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "bot_display_name": {
+ "name": "bot_display_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "bot_avatar_url": {
+ "name": "bot_avatar_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "communication_instructions": {
+ "name": "communication_instructions",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "allow_direct_messages": {
+ "name": "allow_direct_messages",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "allow_group_chats": {
+ "name": "allow_group_chats",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "allow_unlinked_people": {
+ "name": "allow_unlinked_people",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "concurrency_policy": {
+ "name": "concurrency_policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'queue'"
+ },
+ "capabilities": {
+ "name": "capabilities",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{\"threads\":false,\"directMessages\":false,\"nativeStreaming\":false,\"messageEdits\":false,\"messageDeletes\":false,\"reactions\":false,\"files\":false,\"cards\":false,\"actions\":false,\"modals\":false,\"slashCommands\":false,\"ephemeralMessages\":false,\"proactiveDirectMessages\":false}'::jsonb"
+ },
+ "setup": {
+ "name": "setup",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{\"step\":\"provider_setup\"}'::jsonb"
+ },
+ "health_message": {
+ "name": "health_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_event_at": {
+ "name": "last_event_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_publication_at": {
+ "name": "last_publication_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "activated_at": {
+ "name": "activated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "chat_endpoints_company_idx": {
+ "name": "chat_endpoints_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chat_endpoints_agent_idx": {
+ "name": "chat_endpoints_agent_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "assigned_agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chat_endpoints_status_idx": {
+ "name": "chat_endpoints_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chat_endpoints_public_id_uq": {
+ "name": "chat_endpoints_public_id_uq",
+ "columns": [
+ {
+ "expression": "public_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chat_endpoints_agentmail_inbox_uq": {
+ "name": "chat_endpoints_agentmail_inbox_uq",
+ "columns": [
+ {
+ "expression": "bot_external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"chat_endpoints\".\"provider\" = 'agentmail' and \"chat_endpoints\".\"status\" != 'archived' and \"chat_endpoints\".\"bot_external_id\" is not null",
+ "concurrently": false
+ },
+ "chat_endpoints_connection_uq": {
+ "name": "chat_endpoints_connection_uq",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chat_endpoints_live_bot_external_uq": {
+ "name": "chat_endpoints_live_bot_external_uq",
+ "columns": [
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_account_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "bot_external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"chat_endpoints\".\"status\" in ('verifying', 'active', 'paused', 'attention')\n and \"chat_endpoints\".\"provider_account_id\" is not null\n and \"chat_endpoints\".\"bot_external_id\" is not null",
+ "concurrently": false
+ },
+ "chat_endpoints_photon_number_uq": {
+ "name": "chat_endpoints_photon_number_uq",
+ "columns": [
+ {
+ "expression": "bot_external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"chat_endpoints\".\"provider\" = 'imessage-photon' and \"chat_endpoints\".\"status\" <> 'archived' and \"chat_endpoints\".\"bot_external_id\" is not null",
+ "concurrently": false
+ },
+ "chat_endpoints_live_discord_bot_external_uq": {
+ "name": "chat_endpoints_live_discord_bot_external_uq",
+ "columns": [
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "bot_external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"chat_endpoints\".\"provider\" = 'discord'\n and \"chat_endpoints\".\"status\" in ('verifying', 'active', 'paused', 'attention')\n and \"chat_endpoints\".\"bot_external_id\" is not null",
+ "concurrently": false
+ },
+ "chat_endpoints_live_global_app_bot_external_uq": {
+ "name": "chat_endpoints_live_global_app_bot_external_uq",
+ "columns": [
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "bot_external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"chat_endpoints\".\"provider\" in ('github', 'microsoft-teams')\n and \"chat_endpoints\".\"status\" in ('verifying', 'active', 'paused', 'attention')\n and \"chat_endpoints\".\"bot_external_id\" is not null",
+ "concurrently": false
+ },
+ "chat_endpoints_live_bot_username_uq": {
+ "name": "chat_endpoints_live_bot_username_uq",
+ "columns": [
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_account_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "bot_username",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"chat_endpoints\".\"status\" in ('verifying', 'active', 'paused', 'attention')\n and \"chat_endpoints\".\"provider_account_id\" is not null\n and \"chat_endpoints\".\"bot_username\" is not null",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "chat_endpoints_company_id_companies_id_fk": {
+ "name": "chat_endpoints_company_id_companies_id_fk",
+ "tableFrom": "chat_endpoints",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_endpoints_assigned_agent_id_agents_id_fk": {
+ "name": "chat_endpoints_assigned_agent_id_agents_id_fk",
+ "tableFrom": "chat_endpoints",
+ "columnsFrom": [
+ "assigned_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "restrict"
+ },
+ "chat_endpoints_company_agent_fk": {
+ "name": "chat_endpoints_company_agent_fk",
+ "tableFrom": "chat_endpoints",
+ "columnsFrom": [
+ "company_id",
+ "assigned_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "chat_endpoints_company_connection_fk": {
+ "name": "chat_endpoints_company_connection_fk",
+ "tableFrom": "chat_endpoints",
+ "columnsFrom": [
+ "company_id",
+ "connection_id"
+ ],
+ "tableTo": "tool_connections",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "chat_endpoints_company_id_uq": {
+ "name": "chat_endpoints_company_id_uq",
+ "columns": [
+ "company_id",
+ "id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {
+ "chat_endpoints_publication_mode_check": {
+ "name": "chat_endpoints_publication_mode_check",
+ "value": "\"chat_endpoints\".\"publication_mode\" in ('automatic', 'explicit')"
+ },
+ "chat_endpoints_execution_policy_check": {
+ "name": "chat_endpoints_execution_policy_check",
+ "value": "\"chat_endpoints\".\"external_execution_policy\" in ('restricted', 'agent')"
+ },
+ "chat_endpoints_email_policy_check": {
+ "name": "chat_endpoints_email_policy_check",
+ "value": "\"chat_endpoints\".\"provider\" <> 'agentmail' or (\"chat_endpoints\".\"publication_mode\" = 'explicit' and \"chat_endpoints\".\"external_execution_policy\" = 'agent')"
+ },
+ "chat_endpoints_provider_check": {
+ "name": "chat_endpoints_provider_check",
+ "value": "\"chat_endpoints\".\"provider\" in ('slack', 'github', 'discord', 'microsoft-teams', 'telegram', 'agentmail', 'imessage-photon')"
+ },
+ "chat_endpoints_status_check": {
+ "name": "chat_endpoints_status_check",
+ "value": "\"chat_endpoints\".\"status\" in ('draft', 'verifying', 'active', 'paused', 'attention', 'revoked', 'archived')"
+ },
+ "chat_endpoints_deployment_check": {
+ "name": "chat_endpoints_deployment_check",
+ "value": "\"chat_endpoints\".\"deployment_mode\" in ('direct', 'relay')"
+ },
+ "chat_endpoints_concurrency_check": {
+ "name": "chat_endpoints_concurrency_check",
+ "value": "\"chat_endpoints\".\"concurrency_policy\" in ('burst', 'queue', 'debounce', 'drop', 'concurrent')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.chat_external_principals": {
+ "name": "chat_external_principals",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_account_id": {
+ "name": "provider_account_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'user'"
+ },
+ "display_name": {
+ "name": "display_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "handle": {
+ "name": "handle",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "avatar_url": {
+ "name": "avatar_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_bot": {
+ "name": "is_bot",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "last_seen_at": {
+ "name": "last_seen_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "chat_external_principals_company_idx": {
+ "name": "chat_external_principals_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chat_external_principals_external_uq": {
+ "name": "chat_external_principals_external_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_account_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "chat_external_principals_company_id_companies_id_fk": {
+ "name": "chat_external_principals_company_id_companies_id_fk",
+ "tableFrom": "chat_external_principals",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "chat_external_principals_company_id_uq": {
+ "name": "chat_external_principals_company_id_uq",
+ "columns": [
+ "company_id",
+ "id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {
+ "chat_external_principals_provider_check": {
+ "name": "chat_external_principals_provider_check",
+ "value": "\"chat_external_principals\".\"provider\" in ('slack', 'github', 'discord', 'microsoft-teams', 'telegram', 'agentmail', 'imessage-photon')"
+ },
+ "chat_external_principals_kind_check": {
+ "name": "chat_external_principals_kind_check",
+ "value": "\"chat_external_principals\".\"kind\" in ('user', 'bot', 'app', 'system')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.chat_identity_links": {
+ "name": "chat_identity_links",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "endpoint_id": {
+ "name": "endpoint_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "principal_id": {
+ "name": "principal_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "paperclip_user_id": {
+ "name": "paperclip_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "confirmation_token_hash": {
+ "name": "confirmation_token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "confirmed_at": {
+ "name": "confirmed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "chat_identity_links_user_idx": {
+ "name": "chat_identity_links_user_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "paperclip_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chat_identity_links_endpoint_principal_uq": {
+ "name": "chat_identity_links_endpoint_principal_uq",
+ "columns": [
+ {
+ "expression": "endpoint_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "principal_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "chat_identity_links_company_id_companies_id_fk": {
+ "name": "chat_identity_links_company_id_companies_id_fk",
+ "tableFrom": "chat_identity_links",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_identity_links_company_endpoint_fk": {
+ "name": "chat_identity_links_company_endpoint_fk",
+ "tableFrom": "chat_identity_links",
+ "columnsFrom": [
+ "company_id",
+ "endpoint_id"
+ ],
+ "tableTo": "chat_endpoints",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_identity_links_company_principal_fk": {
+ "name": "chat_identity_links_company_principal_fk",
+ "tableFrom": "chat_identity_links",
+ "columnsFrom": [
+ "company_id",
+ "principal_id"
+ ],
+ "tableTo": "chat_external_principals",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "chat_identity_links_status_check": {
+ "name": "chat_identity_links_status_check",
+ "value": "\"chat_identity_links\".\"status\" in ('pending', 'linked', 'revoked', 'expired')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.chat_message_links": {
+ "name": "chat_message_links",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "endpoint_id": {
+ "name": "endpoint_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "conversation_id": {
+ "name": "conversation_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "delivery_id": {
+ "name": "delivery_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "publication_id": {
+ "name": "publication_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "comment_id": {
+ "name": "comment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_message_id": {
+ "name": "provider_message_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "direction": {
+ "name": "direction",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "chat_message_links_provider_message_uq": {
+ "name": "chat_message_links_provider_message_uq",
+ "columns": [
+ {
+ "expression": "endpoint_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "conversation_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_message_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "chat_message_links_company_id_companies_id_fk": {
+ "name": "chat_message_links_company_id_companies_id_fk",
+ "tableFrom": "chat_message_links",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_message_links_delivery_id_chat_deliveries_id_fk": {
+ "name": "chat_message_links_delivery_id_chat_deliveries_id_fk",
+ "tableFrom": "chat_message_links",
+ "columnsFrom": [
+ "delivery_id"
+ ],
+ "tableTo": "chat_deliveries",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "chat_message_links_publication_id_chat_publications_id_fk": {
+ "name": "chat_message_links_publication_id_chat_publications_id_fk",
+ "tableFrom": "chat_message_links",
+ "columnsFrom": [
+ "publication_id"
+ ],
+ "tableTo": "chat_publications",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "chat_message_links_comment_id_issue_comments_id_fk": {
+ "name": "chat_message_links_comment_id_issue_comments_id_fk",
+ "tableFrom": "chat_message_links",
+ "columnsFrom": [
+ "comment_id"
+ ],
+ "tableTo": "issue_comments",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "chat_message_links_company_endpoint_fk": {
+ "name": "chat_message_links_company_endpoint_fk",
+ "tableFrom": "chat_message_links",
+ "columnsFrom": [
+ "company_id",
+ "endpoint_id"
+ ],
+ "tableTo": "chat_endpoints",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_message_links_company_delivery_fk": {
+ "name": "chat_message_links_company_delivery_fk",
+ "tableFrom": "chat_message_links",
+ "columnsFrom": [
+ "company_id",
+ "delivery_id"
+ ],
+ "tableTo": "chat_deliveries",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "chat_message_links_company_publication_fk": {
+ "name": "chat_message_links_company_publication_fk",
+ "tableFrom": "chat_message_links",
+ "columnsFrom": [
+ "company_id",
+ "publication_id"
+ ],
+ "tableTo": "chat_publications",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "chat_message_links_company_comment_fk": {
+ "name": "chat_message_links_company_comment_fk",
+ "tableFrom": "chat_message_links",
+ "columnsFrom": [
+ "company_id",
+ "comment_id"
+ ],
+ "tableTo": "issue_comments",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "chat_message_links_company_conversation_fk": {
+ "name": "chat_message_links_company_conversation_fk",
+ "tableFrom": "chat_message_links",
+ "columnsFrom": [
+ "company_id",
+ "conversation_id"
+ ],
+ "tableTo": "chat_conversations",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "chat_message_links_direction_check": {
+ "name": "chat_message_links_direction_check",
+ "value": "\"chat_message_links\".\"direction\" in ('inbound', 'outbound')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.chat_publications": {
+ "name": "chat_publications",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "endpoint_id": {
+ "name": "endpoint_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "conversation_id": {
+ "name": "conversation_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "comment_id": {
+ "name": "comment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "payload": {
+ "name": "payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "state": {
+ "name": "state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "provider_message_id": {
+ "name": "provider_message_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_url": {
+ "name": "provider_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "attempts": {
+ "name": "attempts",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "redacted_error": {
+ "name": "redacted_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "next_attempt_at": {
+ "name": "next_attempt_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "published_at": {
+ "name": "published_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "chat_publications_company_id_uq": {
+ "name": "chat_publications_company_id_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chat_publications_work_idx": {
+ "name": "chat_publications_work_idx",
+ "columns": [
+ {
+ "expression": "state",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "next_attempt_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chat_publications_idempotency_uq": {
+ "name": "chat_publications_idempotency_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "chat_publications_company_id_companies_id_fk": {
+ "name": "chat_publications_company_id_companies_id_fk",
+ "tableFrom": "chat_publications",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_publications_issue_id_issues_id_fk": {
+ "name": "chat_publications_issue_id_issues_id_fk",
+ "tableFrom": "chat_publications",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "restrict"
+ },
+ "chat_publications_comment_id_issue_comments_id_fk": {
+ "name": "chat_publications_comment_id_issue_comments_id_fk",
+ "tableFrom": "chat_publications",
+ "columnsFrom": [
+ "comment_id"
+ ],
+ "tableTo": "issue_comments",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "chat_publications_company_issue_fk": {
+ "name": "chat_publications_company_issue_fk",
+ "tableFrom": "chat_publications",
+ "columnsFrom": [
+ "company_id",
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "chat_publications_company_comment_fk": {
+ "name": "chat_publications_company_comment_fk",
+ "tableFrom": "chat_publications",
+ "columnsFrom": [
+ "company_id",
+ "comment_id"
+ ],
+ "tableTo": "issue_comments",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "chat_publications_company_endpoint_fk": {
+ "name": "chat_publications_company_endpoint_fk",
+ "tableFrom": "chat_publications",
+ "columnsFrom": [
+ "company_id",
+ "endpoint_id"
+ ],
+ "tableTo": "chat_endpoints",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_publications_company_conversation_fk": {
+ "name": "chat_publications_company_conversation_fk",
+ "tableFrom": "chat_publications",
+ "columnsFrom": [
+ "company_id",
+ "conversation_id"
+ ],
+ "tableTo": "chat_conversations",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "chat_publications_state_check": {
+ "name": "chat_publications_state_check",
+ "value": "\"chat_publications\".\"state\" in ('pending', 'streaming', 'published', 'retry', 'delivery_unknown', 'failed', 'cancelled', 'awaiting_consent')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.chat_sdk_state": {
+ "name": "chat_sdk_state",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "endpoint_id": {
+ "name": "endpoint_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "state_key": {
+ "name": "state_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "version": {
+ "name": "version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "value": {
+ "name": "value",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "chat_sdk_state_key_uq": {
+ "name": "chat_sdk_state_key_uq",
+ "columns": [
+ {
+ "expression": "endpoint_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "state_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chat_sdk_state_expiry_idx": {
+ "name": "chat_sdk_state_expiry_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "chat_sdk_state_company_id_companies_id_fk": {
+ "name": "chat_sdk_state_company_id_companies_id_fk",
+ "tableFrom": "chat_sdk_state",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_sdk_state_company_endpoint_fk": {
+ "name": "chat_sdk_state_company_endpoint_fk",
+ "tableFrom": "chat_sdk_state",
+ "columnsFrom": [
+ "company_id",
+ "endpoint_id"
+ ],
+ "tableTo": "chat_endpoints",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.chat_completion_deliveries": {
+ "name": "chat_completion_deliveries",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "task_id": {
+ "name": "task_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status_version": {
+ "name": "status_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "attempts": {
+ "name": "attempts",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "next_attempt_at": {
+ "name": "next_attempt_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "target_run_id": {
+ "name": "target_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "response_comment_id": {
+ "name": "response_comment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "chat_completion_deliveries_transition_uq": {
+ "name": "chat_completion_deliveries_transition_uq",
+ "columns": [
+ {
+ "expression": "task_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status_version",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chat_completion_deliveries_pending_idx": {
+ "name": "chat_completion_deliveries_pending_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "next_attempt_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "chat_completion_deliveries_company_id_companies_id_fk": {
+ "name": "chat_completion_deliveries_company_id_companies_id_fk",
+ "tableFrom": "chat_completion_deliveries",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_completion_deliveries_task_id_chat_task_handoffs_task_id_fk": {
+ "name": "chat_completion_deliveries_task_id_chat_task_handoffs_task_id_fk",
+ "tableFrom": "chat_completion_deliveries",
+ "columnsFrom": [
+ "task_id"
+ ],
+ "tableTo": "chat_task_handoffs",
+ "columnsTo": [
+ "task_id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_completion_deliveries_target_run_id_heartbeat_runs_id_fk": {
+ "name": "chat_completion_deliveries_target_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "chat_completion_deliveries",
+ "columnsFrom": [
+ "target_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "chat_completion_deliveries_response_comment_id_issue_comments_id_fk": {
+ "name": "chat_completion_deliveries_response_comment_id_issue_comments_id_fk",
+ "tableFrom": "chat_completion_deliveries",
+ "columnsFrom": [
+ "response_comment_id"
+ ],
+ "tableTo": "issue_comments",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.chat_task_handoffs": {
+ "name": "chat_task_handoffs",
+ "schema": "",
+ "columns": {
+ "task_id": {
+ "name": "task_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "conversation_id": {
+ "name": "conversation_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "session_generation": {
+ "name": "session_generation",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "chat_task_handoffs_source_idx": {
+ "name": "chat_task_handoffs_source_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "conversation_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "chat_task_handoffs_task_id_issues_id_fk": {
+ "name": "chat_task_handoffs_task_id_issues_id_fk",
+ "tableFrom": "chat_task_handoffs",
+ "columnsFrom": [
+ "task_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_task_handoffs_company_id_companies_id_fk": {
+ "name": "chat_task_handoffs_company_id_companies_id_fk",
+ "tableFrom": "chat_task_handoffs",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_task_handoffs_conversation_id_issues_id_fk": {
+ "name": "chat_task_handoffs_conversation_id_issues_id_fk",
+ "tableFrom": "chat_task_handoffs",
+ "columnsFrom": [
+ "conversation_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_task_handoffs_agent_id_agents_id_fk": {
+ "name": "chat_task_handoffs_agent_id_agents_id_fk",
+ "tableFrom": "chat_task_handoffs",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.chat_discord_command_owners": {
+ "name": "chat_discord_command_owners",
+ "schema": "",
+ "columns": {
+ "application_id": {
+ "name": "application_id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "endpoint_id": {
+ "name": "endpoint_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "action_id": {
+ "name": "action_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "chat_discord_command_owners_application_check": {
+ "name": "chat_discord_command_owners_application_check",
+ "value": "\"chat_discord_command_owners\".\"application_id\" ~ '^[1-9][0-9]{16,19}$'"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.chat_github_configurations": {
+ "name": "chat_github_configurations",
+ "schema": "",
+ "columns": {
+ "endpoint_id": {
+ "name": "endpoint_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revision": {
+ "name": "revision",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "configuration": {
+ "name": "configuration",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_by_user_id": {
+ "name": "updated_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "chat_github_configurations_company_id_endpoint_id_chat_endpoints_company_id_id_fk": {
+ "name": "chat_github_configurations_company_id_endpoint_id_chat_endpoints_company_id_id_fk",
+ "tableFrom": "chat_github_configurations",
+ "columnsFrom": [
+ "company_id",
+ "endpoint_id"
+ ],
+ "tableTo": "chat_endpoints",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "chat_github_config_revision_check": {
+ "name": "chat_github_config_revision_check",
+ "value": "\"chat_github_configurations\".\"revision\" > 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.chat_github_registrations": {
+ "name": "chat_github_registrations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "endpoint_id": {
+ "name": "endpoint_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "state_hash": {
+ "name": "state_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "trusted_origin": {
+ "name": "trusted_origin",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "consumed_at": {
+ "name": "consumed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "chat_github_registration_state_uq": {
+ "name": "chat_github_registration_state_uq",
+ "columns": [
+ {
+ "expression": "state_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chat_github_registration_endpoint_idx": {
+ "name": "chat_github_registration_endpoint_idx",
+ "columns": [
+ {
+ "expression": "endpoint_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "chat_github_registrations_company_id_endpoint_id_chat_endpoints_company_id_id_fk": {
+ "name": "chat_github_registrations_company_id_endpoint_id_chat_endpoints_company_id_id_fk",
+ "tableFrom": "chat_github_registrations",
+ "columnsFrom": [
+ "company_id",
+ "endpoint_id"
+ ],
+ "tableTo": "chat_endpoints",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "chat_github_registration_status_check": {
+ "name": "chat_github_registration_status_check",
+ "value": "\"chat_github_registrations\".\"status\" in ('pending', 'exchanging', 'completed', 'failed')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.chat_github_reviews": {
+ "name": "chat_github_reviews",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "endpoint_id": {
+ "name": "endpoint_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "repository_id": {
+ "name": "repository_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "repository": {
+ "name": "repository",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pull_number": {
+ "name": "pull_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "head_sha": {
+ "name": "head_sha",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "delivery_id": {
+ "name": "delivery_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "configuration_revision": {
+ "name": "configuration_revision",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "policy_snapshot": {
+ "name": "policy_snapshot",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "event": {
+ "name": "event",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "state": {
+ "name": "state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'queued'"
+ },
+ "assessment": {
+ "name": "assessment",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "conclusion": {
+ "name": "conclusion",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "check_id": {
+ "name": "check_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "check_url": {
+ "name": "check_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "summary_id": {
+ "name": "summary_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "summary_url": {
+ "name": "summary_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "publication_receipts": {
+ "name": "publication_receipts",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "chat_github_reviews_delivery_uq": {
+ "name": "chat_github_reviews_delivery_uq",
+ "columns": [
+ {
+ "expression": "endpoint_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "delivery_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chat_github_reviews_pull_idx": {
+ "name": "chat_github_reviews_pull_idx",
+ "columns": [
+ {
+ "expression": "endpoint_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "repository_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "pull_number",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chat_github_reviews_task_idx": {
+ "name": "chat_github_reviews_task_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "chat_github_reviews_run_id_heartbeat_runs_id_fk": {
+ "name": "chat_github_reviews_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "chat_github_reviews",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "chat_github_reviews_company_id_endpoint_id_chat_endpoints_company_id_id_fk": {
+ "name": "chat_github_reviews_company_id_endpoint_id_chat_endpoints_company_id_id_fk",
+ "tableFrom": "chat_github_reviews",
+ "columnsFrom": [
+ "company_id",
+ "endpoint_id"
+ ],
+ "tableTo": "chat_endpoints",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_github_reviews_company_id_issue_id_issues_company_id_id_fk": {
+ "name": "chat_github_reviews_company_id_issue_id_issues_company_id_id_fk",
+ "tableFrom": "chat_github_reviews",
+ "columnsFrom": [
+ "company_id",
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "restrict"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "chat_github_reviews_company_id_uq": {
+ "name": "chat_github_reviews_company_id_uq",
+ "columns": [
+ "company_id",
+ "id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {
+ "chat_github_review_pull_number_check": {
+ "name": "chat_github_review_pull_number_check",
+ "value": "\"chat_github_reviews\".\"pull_number\" > 0"
+ },
+ "chat_github_review_state_check": {
+ "name": "chat_github_review_state_check",
+ "value": "\"chat_github_reviews\".\"state\" in ('queued', 'running', 'completed', 'incomplete', 'error', 'superseded', 'manual_required')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.chat_teams_file_transfers": {
+ "name": "chat_teams_file_transfers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "endpoint_id": {
+ "name": "endpoint_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "conversation_id": {
+ "name": "conversation_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "publication_id": {
+ "name": "publication_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "comment_id": {
+ "name": "comment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "attachment_id": {
+ "name": "attachment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "principal_id": {
+ "name": "principal_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "authorized_user_id": {
+ "name": "authorized_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "runtime_generation": {
+ "name": "runtime_generation",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "credential_fingerprint": {
+ "name": "credential_fingerprint",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "conversation_generation": {
+ "name": "conversation_generation",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_digest": {
+ "name": "source_digest",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "authority_digest": {
+ "name": "authority_digest",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "bot_app_id": {
+ "name": "bot_app_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "aad_object_id": {
+ "name": "aad_object_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_conversation_id": {
+ "name": "provider_conversation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_user_id": {
+ "name": "provider_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sha256": {
+ "name": "sha256",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "byte_size": {
+ "name": "byte_size",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "filename": {
+ "name": "filename",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_sha256": {
+ "name": "token_sha256",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "phase": {
+ "name": "phase",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'consent_pending'"
+ },
+ "version": {
+ "name": "version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "attempt_id": {
+ "name": "attempt_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "attempt_expires_at": {
+ "name": "attempt_expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "consent_message_id": {
+ "name": "consent_message_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "file_info_message_id": {
+ "name": "file_info_message_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "response_activity_id": {
+ "name": "response_activity_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "response_digest": {
+ "name": "response_digest",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "private_state": {
+ "name": "private_state",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "reason": {
+ "name": "reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "chat_teams_file_transfers_publication_uq": {
+ "name": "chat_teams_file_transfers_publication_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "publication_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chat_teams_file_transfers_token_uq": {
+ "name": "chat_teams_file_transfers_token_uq",
+ "columns": [
+ {
+ "expression": "endpoint_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "token_sha256",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chat_teams_file_transfers_work_idx": {
+ "name": "chat_teams_file_transfers_work_idx",
+ "columns": [
+ {
+ "expression": "phase",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "attempt_expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "chat_teams_file_transfers_company_id_companies_id_fk": {
+ "name": "chat_teams_file_transfers_company_id_companies_id_fk",
+ "tableFrom": "chat_teams_file_transfers",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_teams_file_transfers_issue_id_issues_id_fk": {
+ "name": "chat_teams_file_transfers_issue_id_issues_id_fk",
+ "tableFrom": "chat_teams_file_transfers",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "restrict"
+ },
+ "chat_teams_file_transfers_company_id_endpoint_id_chat_endpoints_company_id_id_fk": {
+ "name": "chat_teams_file_transfers_company_id_endpoint_id_chat_endpoints_company_id_id_fk",
+ "tableFrom": "chat_teams_file_transfers",
+ "columnsFrom": [
+ "company_id",
+ "endpoint_id"
+ ],
+ "tableTo": "chat_endpoints",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_teams_file_transfers_company_id_publication_id_chat_publications_company_id_id_fk": {
+ "name": "chat_teams_file_transfers_company_id_publication_id_chat_publications_company_id_id_fk",
+ "tableFrom": "chat_teams_file_transfers",
+ "columnsFrom": [
+ "company_id",
+ "publication_id"
+ ],
+ "tableTo": "chat_publications",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_teams_file_transfers_company_id_conversation_id_chat_conversations_company_id_id_fk": {
+ "name": "chat_teams_file_transfers_company_id_conversation_id_chat_conversations_company_id_id_fk",
+ "tableFrom": "chat_teams_file_transfers",
+ "columnsFrom": [
+ "company_id",
+ "conversation_id"
+ ],
+ "tableTo": "chat_conversations",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chat_teams_file_transfers_company_id_principal_id_chat_external_principals_company_id_id_fk": {
+ "name": "chat_teams_file_transfers_company_id_principal_id_chat_external_principals_company_id_id_fk",
+ "tableFrom": "chat_teams_file_transfers",
+ "columnsFrom": [
+ "company_id",
+ "principal_id"
+ ],
+ "tableTo": "chat_external_principals",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "chat_teams_file_transfers_phase_check": {
+ "name": "chat_teams_file_transfers_phase_check",
+ "value": "\"chat_teams_file_transfers\".\"phase\" in ('consent_pending','consent_sending','consent_unknown','awaiting_consent','upload_pending','uploading','upload_unknown','file_info_pending','file_info_sending','file_info_unknown','delivered','declined','expired','cancelled','conflict')"
+ },
+ "chat_teams_file_transfers_bounds_check": {
+ "name": "chat_teams_file_transfers_bounds_check",
+ "value": "\"chat_teams_file_transfers\".\"version\" > 0 and \"chat_teams_file_transfers\".\"runtime_generation\" >= 0 and \"chat_teams_file_transfers\".\"conversation_generation\" > 0 and \"chat_teams_file_transfers\".\"byte_size\" > 0 and \"chat_teams_file_transfers\".\"byte_size\" < 62914560"
+ },
+ "chat_teams_file_transfers_hash_check": {
+ "name": "chat_teams_file_transfers_hash_check",
+ "value": "\"chat_teams_file_transfers\".\"source_digest\" ~ '^[a-f0-9]{64}$' and \"chat_teams_file_transfers\".\"authority_digest\" ~ '^[a-f0-9]{64}$' and \"chat_teams_file_transfers\".\"sha256\" ~ '^[a-f0-9]{64}$' and \"chat_teams_file_transfers\".\"token_sha256\" ~ '^[a-f0-9]{64}$'"
+ },
+ "chat_teams_file_transfers_attempt_check": {
+ "name": "chat_teams_file_transfers_attempt_check",
+ "value": "(\"chat_teams_file_transfers\".\"attempt_id\" is null) = (\"chat_teams_file_transfers\".\"attempt_expires_at\" is null)"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.cli_auth_challenges": {
+ "name": "cli_auth_challenges",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "secret_hash": {
+ "name": "secret_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "command": {
+ "name": "command",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "client_name": {
+ "name": "client_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "requested_access": {
+ "name": "requested_access",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'board'"
+ },
+ "requested_company_id": {
+ "name": "requested_company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "pending_key_hash": {
+ "name": "pending_key_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pending_key_name": {
+ "name": "pending_key_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "approved_by_user_id": {
+ "name": "approved_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "board_api_key_id": {
+ "name": "board_api_key_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "approved_at": {
+ "name": "approved_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cancelled_at": {
+ "name": "cancelled_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "cli_auth_challenges_secret_hash_idx": {
+ "name": "cli_auth_challenges_secret_hash_idx",
+ "columns": [
+ {
+ "expression": "secret_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "cli_auth_challenges_approved_by_idx": {
+ "name": "cli_auth_challenges_approved_by_idx",
+ "columns": [
+ {
+ "expression": "approved_by_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "cli_auth_challenges_requested_company_idx": {
+ "name": "cli_auth_challenges_requested_company_idx",
+ "columns": [
+ {
+ "expression": "requested_company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "cli_auth_challenges_requested_company_id_companies_id_fk": {
+ "name": "cli_auth_challenges_requested_company_id_companies_id_fk",
+ "tableFrom": "cli_auth_challenges",
+ "columnsFrom": [
+ "requested_company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "cli_auth_challenges_approved_by_user_id_user_id_fk": {
+ "name": "cli_auth_challenges_approved_by_user_id_user_id_fk",
+ "tableFrom": "cli_auth_challenges",
+ "columnsFrom": [
+ "approved_by_user_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "cli_auth_challenges_board_api_key_id_board_api_keys_id_fk": {
+ "name": "cli_auth_challenges_board_api_key_id_board_api_keys_id_fk",
+ "tableFrom": "cli_auth_challenges",
+ "columnsFrom": [
+ "board_api_key_id"
+ ],
+ "tableTo": "board_api_keys",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.companies": {
+ "name": "companies",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "pause_reason": {
+ "name": "pause_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "paused_at": {
+ "name": "paused_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_prefix": {
+ "name": "issue_prefix",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'PAP'"
+ },
+ "issue_counter": {
+ "name": "issue_counter",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "budget_monthly_cents": {
+ "name": "budget_monthly_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "spend_month_utc": {
+ "name": "spend_month_utc",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "spent_monthly_cents": {
+ "name": "spent_monthly_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "default_responsible_user_id": {
+ "name": "default_responsible_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "require_board_approval_for_new_agents": {
+ "name": "require_board_approval_for_new_agents",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "interaction_resolver_governance": {
+ "name": "interaction_resolver_governance",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "feedback_data_sharing_enabled": {
+ "name": "feedback_data_sharing_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "feedback_data_sharing_consent_at": {
+ "name": "feedback_data_sharing_consent_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "feedback_data_sharing_consent_by_user_id": {
+ "name": "feedback_data_sharing_consent_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "feedback_data_sharing_terms_version": {
+ "name": "feedback_data_sharing_terms_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "companies_issue_prefix_idx": {
+ "name": "companies_issue_prefix_idx",
+ "columns": [
+ {
+ "expression": "issue_prefix",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.company_logos": {
+ "name": "company_logos",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "asset_id": {
+ "name": "asset_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "company_logos_company_uq": {
+ "name": "company_logos_company_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_logos_asset_uq": {
+ "name": "company_logos_asset_uq",
+ "columns": [
+ {
+ "expression": "asset_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "company_logos_company_id_companies_id_fk": {
+ "name": "company_logos_company_id_companies_id_fk",
+ "tableFrom": "company_logos",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "company_logos_asset_id_assets_id_fk": {
+ "name": "company_logos_asset_id_assets_id_fk",
+ "tableFrom": "company_logos",
+ "columnsFrom": [
+ "asset_id"
+ ],
+ "tableTo": "assets",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.company_memberships": {
+ "name": "company_memberships",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "principal_type": {
+ "name": "principal_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "principal_id": {
+ "name": "principal_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "membership_role": {
+ "name": "membership_role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "company_memberships_company_principal_unique_idx": {
+ "name": "company_memberships_company_principal_unique_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "principal_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "principal_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_memberships_principal_status_idx": {
+ "name": "company_memberships_principal_status_idx",
+ "columns": [
+ {
+ "expression": "principal_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "principal_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_memberships_company_status_idx": {
+ "name": "company_memberships_company_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "company_memberships_company_id_companies_id_fk": {
+ "name": "company_memberships_company_id_companies_id_fk",
+ "tableFrom": "company_memberships",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.company_onboarding_seeds": {
+ "name": "company_onboarding_seeds",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revision": {
+ "name": "revision",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "mission": {
+ "name": "mission",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "agent_name": {
+ "name": "agent_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "agent_role": {
+ "name": "agent_role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "first_task_title": {
+ "name": "first_task_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "first_task_details": {
+ "name": "first_task_details",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goal_id": {
+ "name": "goal_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "applied_at": {
+ "name": "applied_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "company_onboarding_seeds_company_uq": {
+ "name": "company_onboarding_seeds_company_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "company_onboarding_seeds_company_id_companies_id_fk": {
+ "name": "company_onboarding_seeds_company_id_companies_id_fk",
+ "tableFrom": "company_onboarding_seeds",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "company_onboarding_seeds_goal_id_goals_id_fk": {
+ "name": "company_onboarding_seeds_goal_id_goals_id_fk",
+ "tableFrom": "company_onboarding_seeds",
+ "columnsFrom": [
+ "goal_id"
+ ],
+ "tableTo": "goals",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "company_onboarding_seeds_agent_id_agents_id_fk": {
+ "name": "company_onboarding_seeds_agent_id_agents_id_fk",
+ "tableFrom": "company_onboarding_seeds",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "company_onboarding_seeds_issue_id_issues_id_fk": {
+ "name": "company_onboarding_seeds_issue_id_issues_id_fk",
+ "tableFrom": "company_onboarding_seeds",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.company_secret_bindings": {
+ "name": "company_secret_bindings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "secret_id": {
+ "name": "secret_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_type": {
+ "name": "target_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_id": {
+ "name": "target_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "config_path": {
+ "name": "config_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "version_selector": {
+ "name": "version_selector",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'latest'"
+ },
+ "required": {
+ "name": "required",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "label": {
+ "name": "label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "projection_class": {
+ "name": "projection_class",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'unclassified'"
+ },
+ "projection_allowlist_key": {
+ "name": "projection_allowlist_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "company_secret_bindings_company_idx": {
+ "name": "company_secret_bindings_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_secret_bindings_secret_idx": {
+ "name": "company_secret_bindings_secret_idx",
+ "columns": [
+ {
+ "expression": "secret_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_secret_bindings_target_idx": {
+ "name": "company_secret_bindings_target_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_secret_bindings_target_path_uq": {
+ "name": "company_secret_bindings_target_path_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "config_path",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "company_secret_bindings_company_id_companies_id_fk": {
+ "name": "company_secret_bindings_company_id_companies_id_fk",
+ "tableFrom": "company_secret_bindings",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "company_secret_bindings_secret_id_company_secrets_id_fk": {
+ "name": "company_secret_bindings_secret_id_company_secrets_id_fk",
+ "tableFrom": "company_secret_bindings",
+ "columnsFrom": [
+ "secret_id"
+ ],
+ "tableTo": "company_secrets",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.company_secret_proposals": {
+ "name": "company_secret_proposals",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "proposed_name": {
+ "name": "proposed_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "proposed_key": {
+ "name": "proposed_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "proposed_description": {
+ "name": "proposed_description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "justification": {
+ "name": "justification",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value_ciphertext": {
+ "name": "value_ciphertext",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "value_fingerprint_sha256": {
+ "name": "value_fingerprint_sha256",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "value_length": {
+ "name": "value_length",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "secret_id": {
+ "name": "secret_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "secret_proposal_id": {
+ "name": "secret_proposal_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "target_type": {
+ "name": "target_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "target_id": {
+ "name": "target_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "config_path": {
+ "name": "config_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "projection_class": {
+ "name": "projection_class",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'unclassified'"
+ },
+ "binding_target_policy_snapshot": {
+ "name": "binding_target_policy_snapshot",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "proposer_ancestor_ids_snapshot": {
+ "name": "proposer_ancestor_ids_snapshot",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "target_ancestor_ids_snapshot": {
+ "name": "target_ancestor_ids_snapshot",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "proposed_by_agent_id": {
+ "name": "proposed_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "origin_issue_id": {
+ "name": "origin_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "origin_run_id": {
+ "name": "origin_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "interaction_id": {
+ "name": "interaction_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resolved_by_user_id": {
+ "name": "resolved_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resolved_at": {
+ "name": "resolved_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resolution_reason": {
+ "name": "resolution_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_secret_id": {
+ "name": "created_secret_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "applied_binding_config_path": {
+ "name": "applied_binding_config_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ciphertext_scrubbed_at": {
+ "name": "ciphertext_scrubbed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "company_secret_proposals_company_status_idx": {
+ "name": "company_secret_proposals_company_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_secret_proposals_proposer_status_idx": {
+ "name": "company_secret_proposals_proposer_status_idx",
+ "columns": [
+ {
+ "expression": "proposed_by_agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_secret_proposals_expiry_idx": {
+ "name": "company_secret_proposals_expiry_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_secret_proposals_secret_proposal_idx": {
+ "name": "company_secret_proposals_secret_proposal_idx",
+ "columns": [
+ {
+ "expression": "secret_proposal_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_secret_proposals_interaction_idx": {
+ "name": "company_secret_proposals_interaction_idx",
+ "columns": [
+ {
+ "expression": "interaction_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "company_secret_proposals_company_id_companies_id_fk": {
+ "name": "company_secret_proposals_company_id_companies_id_fk",
+ "tableFrom": "company_secret_proposals",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "company_secret_proposals_secret_id_company_secrets_id_fk": {
+ "name": "company_secret_proposals_secret_id_company_secrets_id_fk",
+ "tableFrom": "company_secret_proposals",
+ "columnsFrom": [
+ "secret_id"
+ ],
+ "tableTo": "company_secrets",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "company_secret_proposals_secret_proposal_id_company_secret_proposals_id_fk": {
+ "name": "company_secret_proposals_secret_proposal_id_company_secret_proposals_id_fk",
+ "tableFrom": "company_secret_proposals",
+ "columnsFrom": [
+ "secret_proposal_id"
+ ],
+ "tableTo": "company_secret_proposals",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "company_secret_proposals_target_id_agents_id_fk": {
+ "name": "company_secret_proposals_target_id_agents_id_fk",
+ "tableFrom": "company_secret_proposals",
+ "columnsFrom": [
+ "target_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "company_secret_proposals_proposed_by_agent_id_agents_id_fk": {
+ "name": "company_secret_proposals_proposed_by_agent_id_agents_id_fk",
+ "tableFrom": "company_secret_proposals",
+ "columnsFrom": [
+ "proposed_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "company_secret_proposals_origin_issue_id_issues_id_fk": {
+ "name": "company_secret_proposals_origin_issue_id_issues_id_fk",
+ "tableFrom": "company_secret_proposals",
+ "columnsFrom": [
+ "origin_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "company_secret_proposals_origin_run_id_heartbeat_runs_id_fk": {
+ "name": "company_secret_proposals_origin_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "company_secret_proposals",
+ "columnsFrom": [
+ "origin_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "company_secret_proposals_interaction_id_issue_thread_interactions_id_fk": {
+ "name": "company_secret_proposals_interaction_id_issue_thread_interactions_id_fk",
+ "tableFrom": "company_secret_proposals",
+ "columnsFrom": [
+ "interaction_id"
+ ],
+ "tableTo": "issue_thread_interactions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "company_secret_proposals_created_secret_id_company_secrets_id_fk": {
+ "name": "company_secret_proposals_created_secret_id_company_secrets_id_fk",
+ "tableFrom": "company_secret_proposals",
+ "columnsFrom": [
+ "created_secret_id"
+ ],
+ "tableTo": "company_secrets",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "company_secret_proposals_kind_check": {
+ "name": "company_secret_proposals_kind_check",
+ "value": "\"company_secret_proposals\".\"kind\" in ('secret', 'binding')"
+ },
+ "company_secret_proposals_status_check": {
+ "name": "company_secret_proposals_status_check",
+ "value": "\"company_secret_proposals\".\"status\" in ('pending', 'approved', 'rejected', 'withdrawn', 'expired')"
+ },
+ "company_secret_proposals_projection_check": {
+ "name": "company_secret_proposals_projection_check",
+ "value": "\"company_secret_proposals\".\"projection_class\" = 'unclassified'"
+ },
+ "company_secret_proposals_shape_check": {
+ "name": "company_secret_proposals_shape_check",
+ "value": "(\n \"company_secret_proposals\".\"kind\" = 'secret'\n and \"company_secret_proposals\".\"proposed_name\" is not null\n and \"company_secret_proposals\".\"proposed_key\" is not null\n and \"company_secret_proposals\".\"secret_id\" is null\n and \"company_secret_proposals\".\"secret_proposal_id\" is null\n and \"company_secret_proposals\".\"target_type\" is null\n and \"company_secret_proposals\".\"target_id\" is null\n and \"company_secret_proposals\".\"config_path\" is null\n ) or (\n \"company_secret_proposals\".\"kind\" = 'binding'\n and ((\"company_secret_proposals\".\"secret_id\" is not null)::int + (\"company_secret_proposals\".\"secret_proposal_id\" is not null)::int) = 1\n and \"company_secret_proposals\".\"target_type\" = 'agent'\n and \"company_secret_proposals\".\"target_id\" is not null\n and \"company_secret_proposals\".\"config_path\" is not null\n )"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.company_secret_provider_configs": {
+ "name": "company_secret_provider_configs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "display_name": {
+ "name": "display_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'ready'"
+ },
+ "is_default": {
+ "name": "is_default",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "config": {
+ "name": "config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "health_status": {
+ "name": "health_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "health_checked_at": {
+ "name": "health_checked_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "health_message": {
+ "name": "health_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "health_details": {
+ "name": "health_details",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "disabled_at": {
+ "name": "disabled_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "company_secret_provider_configs_company_idx": {
+ "name": "company_secret_provider_configs_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_secret_provider_configs_company_provider_idx": {
+ "name": "company_secret_provider_configs_company_provider_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_secret_provider_configs_default_uq": {
+ "name": "company_secret_provider_configs_default_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"company_secret_provider_configs\".\"is_default\" = true",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "company_secret_provider_configs_company_id_companies_id_fk": {
+ "name": "company_secret_provider_configs_company_id_companies_id_fk",
+ "tableFrom": "company_secret_provider_configs",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "company_secret_provider_configs_created_by_agent_id_agents_id_fk": {
+ "name": "company_secret_provider_configs_created_by_agent_id_agents_id_fk",
+ "tableFrom": "company_secret_provider_configs",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.company_secret_versions": {
+ "name": "company_secret_versions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "secret_id": {
+ "name": "secret_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "version": {
+ "name": "version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "material": {
+ "name": "material",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value_sha256": {
+ "name": "value_sha256",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_version_ref": {
+ "name": "provider_version_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'current'"
+ },
+ "fingerprint_sha256": {
+ "name": "fingerprint_sha256",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "rotation_job_id": {
+ "name": "rotation_job_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "company_secret_versions_secret_idx": {
+ "name": "company_secret_versions_secret_idx",
+ "columns": [
+ {
+ "expression": "secret_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_secret_versions_value_sha256_idx": {
+ "name": "company_secret_versions_value_sha256_idx",
+ "columns": [
+ {
+ "expression": "value_sha256",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_secret_versions_fingerprint_idx": {
+ "name": "company_secret_versions_fingerprint_idx",
+ "columns": [
+ {
+ "expression": "fingerprint_sha256",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_secret_versions_secret_version_uq": {
+ "name": "company_secret_versions_secret_version_uq",
+ "columns": [
+ {
+ "expression": "secret_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "version",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "company_secret_versions_secret_id_company_secrets_id_fk": {
+ "name": "company_secret_versions_secret_id_company_secrets_id_fk",
+ "tableFrom": "company_secret_versions",
+ "columnsFrom": [
+ "secret_id"
+ ],
+ "tableTo": "company_secrets",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "company_secret_versions_created_by_agent_id_agents_id_fk": {
+ "name": "company_secret_versions_created_by_agent_id_agents_id_fk",
+ "tableFrom": "company_secret_versions",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.company_secrets": {
+ "name": "company_secrets",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope": {
+ "name": "scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'company'"
+ },
+ "owner_user_id": {
+ "name": "owner_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_secret_definition_id": {
+ "name": "user_secret_definition_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'local_encrypted'"
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "managed_mode": {
+ "name": "managed_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'paperclip_managed'"
+ },
+ "external_ref": {
+ "name": "external_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_config_id": {
+ "name": "provider_config_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_metadata": {
+ "name": "provider_metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ai_session_epoch": {
+ "name": "ai_session_epoch",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "latest_version": {
+ "name": "latest_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_resolved_at": {
+ "name": "last_resolved_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_rotated_at": {
+ "name": "last_rotated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "company_secrets_company_idx": {
+ "name": "company_secrets_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_secrets_company_scope_idx": {
+ "name": "company_secrets_company_scope_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scope",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_secrets_company_owner_idx": {
+ "name": "company_secrets_company_owner_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "owner_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_secrets_user_definition_owner_idx": {
+ "name": "company_secrets_user_definition_owner_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_secret_definition_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "owner_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_secrets_company_provider_idx": {
+ "name": "company_secrets_company_provider_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_secrets_provider_config_idx": {
+ "name": "company_secrets_provider_config_idx",
+ "columns": [
+ {
+ "expression": "provider_config_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_secrets_company_name_uq": {
+ "name": "company_secrets_company_name_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"company_secrets\".\"scope\" = 'company' and \"company_secrets\".\"deleted_at\" is null",
+ "concurrently": false
+ },
+ "company_secrets_company_key_uq": {
+ "name": "company_secrets_company_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"company_secrets\".\"scope\" = 'company' and \"company_secrets\".\"deleted_at\" is null",
+ "concurrently": false
+ },
+ "company_secrets_user_definition_owner_uq": {
+ "name": "company_secrets_user_definition_owner_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_secret_definition_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "owner_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"company_secrets\".\"scope\" = 'user' and \"company_secrets\".\"deleted_at\" is null",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "company_secrets_company_id_companies_id_fk": {
+ "name": "company_secrets_company_id_companies_id_fk",
+ "tableFrom": "company_secrets",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "company_secrets_user_secret_definition_id_user_secret_definitions_id_fk": {
+ "name": "company_secrets_user_secret_definition_id_user_secret_definitions_id_fk",
+ "tableFrom": "company_secrets",
+ "columnsFrom": [
+ "user_secret_definition_id"
+ ],
+ "tableTo": "user_secret_definitions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "company_secrets_provider_config_id_company_secret_provider_configs_id_fk": {
+ "name": "company_secrets_provider_config_id_company_secret_provider_configs_id_fk",
+ "tableFrom": "company_secrets",
+ "columnsFrom": [
+ "provider_config_id"
+ ],
+ "tableTo": "company_secret_provider_configs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "company_secrets_created_by_agent_id_agents_id_fk": {
+ "name": "company_secrets_created_by_agent_id_agents_id_fk",
+ "tableFrom": "company_secrets",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "company_secrets_scope_shape_check": {
+ "name": "company_secrets_scope_shape_check",
+ "value": "(\n \"company_secrets\".\"scope\" = 'company'\n and \"company_secrets\".\"owner_user_id\" is null\n and \"company_secrets\".\"user_secret_definition_id\" is null\n ) or (\n \"company_secrets\".\"scope\" = 'user'\n and \"company_secrets\".\"owner_user_id\" is not null\n and \"company_secrets\".\"user_secret_definition_id\" is not null\n )"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.company_skill_policies": {
+ "name": "company_skill_policies",
+ "schema": "",
+ "columns": {
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "schema_version": {
+ "name": "schema_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "revision": {
+ "name": "revision",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "default_effect": {
+ "name": "default_effect",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "rules": {
+ "name": "rules",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "company_skill_policies_company_id_companies_id_fk": {
+ "name": "company_skill_policies_company_id_companies_id_fk",
+ "tableFrom": "company_skill_policies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.company_skill_source_entries": {
+ "name": "company_skill_source_entries",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_id": {
+ "name": "source_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "path": {
+ "name": "path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "inspection": {
+ "name": "inspection",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "skill_id": {
+ "name": "skill_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "selection": {
+ "name": "selection",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'new'"
+ },
+ "present": {
+ "name": "present",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "company_skill_source_entries_source_path_idx": {
+ "name": "company_skill_source_entries_source_path_idx",
+ "columns": [
+ {
+ "expression": "source_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "path",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_skill_source_entries_company_skill_idx": {
+ "name": "company_skill_source_entries_company_skill_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "skill_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "company_skill_source_entries_company_id_companies_id_fk": {
+ "name": "company_skill_source_entries_company_id_companies_id_fk",
+ "tableFrom": "company_skill_source_entries",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "company_skill_source_entries_source_id_company_skill_sources_id_fk": {
+ "name": "company_skill_source_entries_source_id_company_skill_sources_id_fk",
+ "tableFrom": "company_skill_source_entries",
+ "columnsFrom": [
+ "source_id"
+ ],
+ "tableTo": "company_skill_sources",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "company_skill_source_entries_skill_id_company_skills_id_fk": {
+ "name": "company_skill_source_entries_skill_id_company_skills_id_fk",
+ "tableFrom": "company_skill_source_entries",
+ "columnsFrom": [
+ "skill_id"
+ ],
+ "tableTo": "company_skills",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.company_skill_sources": {
+ "name": "company_skill_sources",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "repository_id": {
+ "name": "repository_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "repository_url": {
+ "name": "repository_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "full_name": {
+ "name": "full_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tracking_ref": {
+ "name": "tracking_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "excluded_folders": {
+ "name": "excluded_folders",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "revision": {
+ "name": "revision",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "last_attempt_at": {
+ "name": "last_attempt_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_success_at": {
+ "name": "last_success_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_scan_commit": {
+ "name": "last_scan_commit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lease_token": {
+ "name": "lease_token",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lease_expires_at": {
+ "name": "lease_expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "company_skill_sources_repository_ref_idx": {
+ "name": "company_skill_sources_repository_ref_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "repository_url",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "tracking_ref",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_skill_sources_identity_ref_idx": {
+ "name": "company_skill_sources_identity_ref_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "repository_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "tracking_ref",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "company_skill_sources_company_id_companies_id_fk": {
+ "name": "company_skill_sources_company_id_companies_id_fk",
+ "tableFrom": "company_skill_sources",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "company_skill_sources_connection_id_tool_connections_id_fk": {
+ "name": "company_skill_sources_connection_id_tool_connections_id_fk",
+ "tableFrom": "company_skill_sources",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "tableTo": "tool_connections",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.company_skill_comments": {
+ "name": "company_skill_comments",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "company_skill_id": {
+ "name": "company_skill_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parent_comment_id": {
+ "name": "parent_comment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "author_agent_id": {
+ "name": "author_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "author_user_id": {
+ "name": "author_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "body": {
+ "name": "body",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "company_skill_comments_company_skill_created_idx": {
+ "name": "company_skill_comments_company_skill_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "company_skill_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_skill_comments_parent_idx": {
+ "name": "company_skill_comments_parent_idx",
+ "columns": [
+ {
+ "expression": "parent_comment_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "company_skill_comments_company_id_companies_id_fk": {
+ "name": "company_skill_comments_company_id_companies_id_fk",
+ "tableFrom": "company_skill_comments",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "company_skill_comments_company_skill_id_company_skills_id_fk": {
+ "name": "company_skill_comments_company_skill_id_company_skills_id_fk",
+ "tableFrom": "company_skill_comments",
+ "columnsFrom": [
+ "company_skill_id"
+ ],
+ "tableTo": "company_skills",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "company_skill_comments_parent_comment_id_company_skill_comments_id_fk": {
+ "name": "company_skill_comments_parent_comment_id_company_skill_comments_id_fk",
+ "tableFrom": "company_skill_comments",
+ "columnsFrom": [
+ "parent_comment_id"
+ ],
+ "tableTo": "company_skill_comments",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "company_skill_comments_author_agent_id_agents_id_fk": {
+ "name": "company_skill_comments_author_agent_id_agents_id_fk",
+ "tableFrom": "company_skill_comments",
+ "columnsFrom": [
+ "author_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.company_skill_stars": {
+ "name": "company_skill_stars",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "company_skill_id": {
+ "name": "company_skill_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "company_skill_stars_skill_agent_idx": {
+ "name": "company_skill_stars_skill_agent_idx",
+ "columns": [
+ {
+ "expression": "company_skill_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_skill_stars_skill_user_idx": {
+ "name": "company_skill_stars_skill_user_idx",
+ "columns": [
+ {
+ "expression": "company_skill_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_skill_stars_company_skill_created_idx": {
+ "name": "company_skill_stars_company_skill_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "company_skill_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "company_skill_stars_company_id_companies_id_fk": {
+ "name": "company_skill_stars_company_id_companies_id_fk",
+ "tableFrom": "company_skill_stars",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "company_skill_stars_company_skill_id_company_skills_id_fk": {
+ "name": "company_skill_stars_company_skill_id_company_skills_id_fk",
+ "tableFrom": "company_skill_stars",
+ "columnsFrom": [
+ "company_skill_id"
+ ],
+ "tableTo": "company_skills",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "company_skill_stars_agent_id_agents_id_fk": {
+ "name": "company_skill_stars_agent_id_agents_id_fk",
+ "tableFrom": "company_skill_stars",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.company_skill_test_inputs": {
+ "name": "company_skill_test_inputs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "skill_id": {
+ "name": "skill_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "company_skill_test_inputs_company_skill_name_idx": {
+ "name": "company_skill_test_inputs_company_skill_name_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "skill_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_skill_test_inputs_company_skill_active_idx": {
+ "name": "company_skill_test_inputs_company_skill_active_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "skill_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "deleted_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "company_skill_test_inputs_company_id_companies_id_fk": {
+ "name": "company_skill_test_inputs_company_id_companies_id_fk",
+ "tableFrom": "company_skill_test_inputs",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "company_skill_test_inputs_skill_id_company_skills_id_fk": {
+ "name": "company_skill_test_inputs_skill_id_company_skills_id_fk",
+ "tableFrom": "company_skill_test_inputs",
+ "columnsFrom": [
+ "skill_id"
+ ],
+ "tableTo": "company_skills",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.company_skill_test_run_templates": {
+ "name": "company_skill_test_run_templates",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "body": {
+ "name": "body",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_by_agent_id": {
+ "name": "updated_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_by_user_id": {
+ "name": "updated_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "company_skill_test_run_templates_company_active_idx": {
+ "name": "company_skill_test_run_templates_company_active_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "deleted_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "company_skill_test_run_templates_company_id_companies_id_fk": {
+ "name": "company_skill_test_run_templates_company_id_companies_id_fk",
+ "tableFrom": "company_skill_test_run_templates",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "company_skill_test_run_templates_created_by_agent_id_agents_id_fk": {
+ "name": "company_skill_test_run_templates_created_by_agent_id_agents_id_fk",
+ "tableFrom": "company_skill_test_run_templates",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "company_skill_test_run_templates_updated_by_agent_id_agents_id_fk": {
+ "name": "company_skill_test_run_templates_updated_by_agent_id_agents_id_fk",
+ "tableFrom": "company_skill_test_run_templates",
+ "columnsFrom": [
+ "updated_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.company_skill_test_runs": {
+ "name": "company_skill_test_runs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "skill_id": {
+ "name": "skill_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "input_id": {
+ "name": "input_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "input_snapshot": {
+ "name": "input_snapshot",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "skill_version_id": {
+ "name": "skill_version_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_config_snapshot": {
+ "name": "agent_config_snapshot",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "template_id": {
+ "name": "template_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "template_name": {
+ "name": "template_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "template_body": {
+ "name": "template_body",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rendered_template_body": {
+ "name": "rendered_template_body",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "harness_issue_description": {
+ "name": "harness_issue_description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'queued'"
+ },
+ "output_document_key": {
+ "name": "output_document_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'output'"
+ },
+ "output_snapshot": {
+ "name": "output_snapshot",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "superseded_at": {
+ "name": "superseded_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "harness_issue_expires_at": {
+ "name": "harness_issue_expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "harness_issue_deleted_at": {
+ "name": "harness_issue_deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "company_skill_test_runs_company_skill_created_idx": {
+ "name": "company_skill_test_runs_company_skill_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "skill_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_skill_test_runs_company_issue_idx": {
+ "name": "company_skill_test_runs_company_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_skill_test_runs_company_input_created_idx": {
+ "name": "company_skill_test_runs_company_input_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "input_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_skill_test_runs_company_status_idx": {
+ "name": "company_skill_test_runs_company_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_skill_test_runs_company_harness_expires_idx": {
+ "name": "company_skill_test_runs_company_harness_expires_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "harness_issue_expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "company_skill_test_runs_company_id_companies_id_fk": {
+ "name": "company_skill_test_runs_company_id_companies_id_fk",
+ "tableFrom": "company_skill_test_runs",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "company_skill_test_runs_skill_id_company_skills_id_fk": {
+ "name": "company_skill_test_runs_skill_id_company_skills_id_fk",
+ "tableFrom": "company_skill_test_runs",
+ "columnsFrom": [
+ "skill_id"
+ ],
+ "tableTo": "company_skills",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "company_skill_test_runs_input_id_company_skill_test_inputs_id_fk": {
+ "name": "company_skill_test_runs_input_id_company_skill_test_inputs_id_fk",
+ "tableFrom": "company_skill_test_runs",
+ "columnsFrom": [
+ "input_id"
+ ],
+ "tableTo": "company_skill_test_inputs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "company_skill_test_runs_skill_version_id_company_skill_versions_id_fk": {
+ "name": "company_skill_test_runs_skill_version_id_company_skill_versions_id_fk",
+ "tableFrom": "company_skill_test_runs",
+ "columnsFrom": [
+ "skill_version_id"
+ ],
+ "tableTo": "company_skill_versions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "restrict"
+ },
+ "company_skill_test_runs_agent_id_agents_id_fk": {
+ "name": "company_skill_test_runs_agent_id_agents_id_fk",
+ "tableFrom": "company_skill_test_runs",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "restrict"
+ },
+ "company_skill_test_runs_issue_id_issues_id_fk": {
+ "name": "company_skill_test_runs_issue_id_issues_id_fk",
+ "tableFrom": "company_skill_test_runs",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "restrict"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.company_skill_versions": {
+ "name": "company_skill_versions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "company_skill_id": {
+ "name": "company_skill_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revision_number": {
+ "name": "revision_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "label": {
+ "name": "label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "release_id": {
+ "name": "release_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "release_name": {
+ "name": "release_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "released_at": {
+ "name": "released_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "file_inventory": {
+ "name": "file_inventory",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "author_agent_id": {
+ "name": "author_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "author_user_id": {
+ "name": "author_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "company_skill_versions_skill_revision_idx": {
+ "name": "company_skill_versions_skill_revision_idx",
+ "columns": [
+ {
+ "expression": "company_skill_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "revision_number",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_skill_versions_skill_release_idx": {
+ "name": "company_skill_versions_skill_release_idx",
+ "columns": [
+ {
+ "expression": "company_skill_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "release_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"company_skill_versions\".\"release_id\" is not null",
+ "concurrently": false
+ },
+ "company_skill_versions_company_skill_created_idx": {
+ "name": "company_skill_versions_company_skill_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "company_skill_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "company_skill_versions_company_id_companies_id_fk": {
+ "name": "company_skill_versions_company_id_companies_id_fk",
+ "tableFrom": "company_skill_versions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "company_skill_versions_company_skill_id_company_skills_id_fk": {
+ "name": "company_skill_versions_company_skill_id_company_skills_id_fk",
+ "tableFrom": "company_skill_versions",
+ "columnsFrom": [
+ "company_skill_id"
+ ],
+ "tableTo": "company_skills",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "company_skill_versions_author_agent_id_agents_id_fk": {
+ "name": "company_skill_versions_author_agent_id_agents_id_fk",
+ "tableFrom": "company_skill_versions",
+ "columnsFrom": [
+ "author_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.company_skills": {
+ "name": "company_skills",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "folder_id": {
+ "name": "folder_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "markdown": {
+ "name": "markdown",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_type": {
+ "name": "source_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'local_path'"
+ },
+ "source_locator": {
+ "name": "source_locator",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_ref": {
+ "name": "source_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "trust_level": {
+ "name": "trust_level",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'markdown_only'"
+ },
+ "compatibility": {
+ "name": "compatibility",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'compatible'"
+ },
+ "file_inventory": {
+ "name": "file_inventory",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "icon_url": {
+ "name": "icon_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "color": {
+ "name": "color",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tagline": {
+ "name": "tagline",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "author_name": {
+ "name": "author_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "homepage_url": {
+ "name": "homepage_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "categories": {
+ "name": "categories",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "sharing_scope": {
+ "name": "sharing_scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'company'"
+ },
+ "public_share_token": {
+ "name": "public_share_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "forked_from_skill_id": {
+ "name": "forked_from_skill_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "forked_from_company_id": {
+ "name": "forked_from_company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "star_count": {
+ "name": "star_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "install_count": {
+ "name": "install_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "fork_count": {
+ "name": "fork_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "current_version_id": {
+ "name": "current_version_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "company_skills_company_key_idx": {
+ "name": "company_skills_company_key_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_skills_company_name_idx": {
+ "name": "company_skills_company_name_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_skills_company_folder_idx": {
+ "name": "company_skills_company_folder_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "folder_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_skills_company_categories_idx": {
+ "name": "company_skills_company_categories_idx",
+ "columns": [
+ {
+ "expression": "categories",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "gin",
+ "concurrently": false
+ },
+ "company_skills_company_sharing_scope_idx": {
+ "name": "company_skills_company_sharing_scope_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sharing_scope",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_skills_company_current_version_idx": {
+ "name": "company_skills_company_current_version_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "current_version_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_skills_company_forked_from_idx": {
+ "name": "company_skills_company_forked_from_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "forked_from_skill_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "company_skills_company_id_companies_id_fk": {
+ "name": "company_skills_company_id_companies_id_fk",
+ "tableFrom": "company_skills",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "company_skills_folder_id_folders_id_fk": {
+ "name": "company_skills_folder_id_folders_id_fk",
+ "tableFrom": "company_skills",
+ "columnsFrom": [
+ "folder_id"
+ ],
+ "tableTo": "folders",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "company_skills_forked_from_skill_id_company_skills_id_fk": {
+ "name": "company_skills_forked_from_skill_id_company_skills_id_fk",
+ "tableFrom": "company_skills",
+ "columnsFrom": [
+ "forked_from_skill_id"
+ ],
+ "tableTo": "company_skills",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "company_skills_forked_from_company_id_companies_id_fk": {
+ "name": "company_skills_forked_from_company_id_companies_id_fk",
+ "tableFrom": "company_skills",
+ "columnsFrom": [
+ "forked_from_company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "company_skills_current_version_id_company_skill_versions_id_fk": {
+ "name": "company_skills_current_version_id_company_skill_versions_id_fk",
+ "tableFrom": "company_skills",
+ "columnsFrom": [
+ "current_version_id"
+ ],
+ "tableTo": "company_skill_versions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.company_transfer_runs": {
+ "name": "company_transfer_runs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "direction": {
+ "name": "direction",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "actor_key": {
+ "name": "actor_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "container_ref": {
+ "name": "container_ref",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "manifest_sha256": {
+ "name": "manifest_sha256",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "manifest": {
+ "name": "manifest",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "chunk_count": {
+ "name": "chunk_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "blob_count": {
+ "name": "blob_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "completed_parts": {
+ "name": "completed_parts",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "finished_at": {
+ "name": "finished_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "company_transfer_runs_company_idx": {
+ "name": "company_transfer_runs_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_transfer_runs_idempotency_direction_idx": {
+ "name": "company_transfer_runs_idempotency_direction_idx",
+ "columns": [
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "direction",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_transfer_runs_actor_status_idx": {
+ "name": "company_transfer_runs_actor_status_idx",
+ "columns": [
+ {
+ "expression": "actor_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "company_transfer_runs_company_id_companies_id_fk": {
+ "name": "company_transfer_runs_company_id_companies_id_fk",
+ "tableFrom": "company_transfer_runs",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.company_user_sidebar_preferences": {
+ "name": "company_user_sidebar_preferences",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_order": {
+ "name": "project_order",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "company_user_sidebar_preferences_company_idx": {
+ "name": "company_user_sidebar_preferences_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_user_sidebar_preferences_user_idx": {
+ "name": "company_user_sidebar_preferences_user_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "company_user_sidebar_preferences_company_user_uq": {
+ "name": "company_user_sidebar_preferences_company_user_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "company_user_sidebar_preferences_company_id_companies_id_fk": {
+ "name": "company_user_sidebar_preferences_company_id_companies_id_fk",
+ "tableFrom": "company_user_sidebar_preferences",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.completion_contracts": {
+ "name": "completion_contracts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revision": {
+ "name": "revision",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "schema_version": {
+ "name": "schema_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "policy_version": {
+ "name": "policy_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "risk": {
+ "name": "risk",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "completion_authority": {
+ "name": "completion_authority",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "incomplete_criteria_policy": {
+ "name": "incomplete_criteria_policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "contract_json": {
+ "name": "contract_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "canonical_sha256": {
+ "name": "canonical_sha256",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_actor_type": {
+ "name": "created_by_actor_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_actor_id": {
+ "name": "created_by_actor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "supersedes_contract_id": {
+ "name": "supersedes_contract_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "completion_contracts_issue_revision_uq": {
+ "name": "completion_contracts_issue_revision_uq",
+ "columns": [
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "revision",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "completion_contracts_issue_hash_uq": {
+ "name": "completion_contracts_issue_hash_uq",
+ "columns": [
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "canonical_sha256",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "completion_contracts_company_id_companies_id_fk": {
+ "name": "completion_contracts_company_id_companies_id_fk",
+ "tableFrom": "completion_contracts",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "completion_contracts_issue_company_fk": {
+ "name": "completion_contracts_issue_company_fk",
+ "tableFrom": "completion_contracts",
+ "columnsFrom": [
+ "company_id",
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "completion_contracts_supersedes_owner_fk": {
+ "name": "completion_contracts_supersedes_owner_fk",
+ "tableFrom": "completion_contracts",
+ "columnsFrom": [
+ "company_id",
+ "issue_id",
+ "supersedes_contract_id"
+ ],
+ "tableTo": "completion_contracts",
+ "columnsTo": [
+ "company_id",
+ "issue_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "completion_contracts_company_issue_id_uq": {
+ "name": "completion_contracts_company_issue_id_uq",
+ "columns": [
+ "company_id",
+ "issue_id",
+ "id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.connection_event_deliveries": {
+ "name": "connection_event_deliveries",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_delivery_id": {
+ "name": "provider_delivery_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "event": {
+ "name": "event",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "action": {
+ "name": "action",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "installation_id": {
+ "name": "installation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "repository_id": {
+ "name": "repository_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "normalized_payload": {
+ "name": "normalized_payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'received'"
+ },
+ "attempts": {
+ "name": "attempts",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_created_at": {
+ "name": "provider_created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "processed_at": {
+ "name": "processed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "connection_event_deliveries_company_provider_id_uq": {
+ "name": "connection_event_deliveries_company_provider_id_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_delivery_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "connection_event_deliveries_company_status_idx": {
+ "name": "connection_event_deliveries_company_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "connection_event_deliveries_company_id_companies_id_fk": {
+ "name": "connection_event_deliveries_company_id_companies_id_fk",
+ "tableFrom": "connection_event_deliveries",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.connection_intent_deliveries": {
+ "name": "connection_intent_deliveries",
+ "schema": "",
+ "columns": {
+ "interaction_id": {
+ "name": "interaction_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "next_attempt_at": {
+ "name": "next_attempt_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "delivered_at": {
+ "name": "delivered_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "connection_intent_deliveries_pending_idx": {
+ "name": "connection_intent_deliveries_pending_idx",
+ "columns": [
+ {
+ "expression": "delivered_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "next_attempt_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "connection_intent_deliveries_interaction_id_issue_thread_interactions_id_fk": {
+ "name": "connection_intent_deliveries_interaction_id_issue_thread_interactions_id_fk",
+ "tableFrom": "connection_intent_deliveries",
+ "columnsFrom": [
+ "interaction_id"
+ ],
+ "tableTo": "issue_thread_interactions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "connection_intent_deliveries_company_id_companies_id_fk": {
+ "name": "connection_intent_deliveries_company_id_companies_id_fk",
+ "tableFrom": "connection_intent_deliveries",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.cost_events": {
+ "name": "cost_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goal_id": {
+ "name": "goal_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "heartbeat_run_id": {
+ "name": "heartbeat_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "billing_code": {
+ "name": "billing_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_request_id": {
+ "name": "provider_request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "reported_cost_cents": {
+ "name": "reported_cost_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "pricing_provenance": {
+ "name": "pricing_provenance",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "biller": {
+ "name": "biller",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'unknown'"
+ },
+ "billing_type": {
+ "name": "billing_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'unknown'"
+ },
+ "cost_status": {
+ "name": "cost_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'reported'"
+ },
+ "model": {
+ "name": "model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "input_tokens": {
+ "name": "input_tokens",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "cached_input_tokens": {
+ "name": "cached_input_tokens",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "output_tokens": {
+ "name": "output_tokens",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "cost_cents": {
+ "name": "cost_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "occurred_at": {
+ "name": "occurred_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "cost_events_company_receipt_idx": {
+ "name": "cost_events_company_receipt_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "cost_events_provider_request_idx": {
+ "name": "cost_events_provider_request_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "biller",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_request_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "cost_events_company_project_occurred_idx": {
+ "name": "cost_events_company_project_occurred_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "occurred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "cost_events_unpriced_idx": {
+ "name": "cost_events_unpriced_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "occurred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "where": "\"cost_events\".\"cost_status\" = 'unpriced' and \"cost_events\".\"billing_type\" <> 'subscription_included'",
+ "concurrently": false
+ },
+ "cost_events_company_occurred_idx": {
+ "name": "cost_events_company_occurred_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "occurred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "cost_events_company_agent_occurred_idx": {
+ "name": "cost_events_company_agent_occurred_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "occurred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "cost_events_company_provider_occurred_idx": {
+ "name": "cost_events_company_provider_occurred_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "occurred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "cost_events_company_biller_occurred_idx": {
+ "name": "cost_events_company_biller_occurred_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "biller",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "occurred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "cost_events_company_heartbeat_run_idx": {
+ "name": "cost_events_company_heartbeat_run_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "heartbeat_run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "cost_events_company_id_companies_id_fk": {
+ "name": "cost_events_company_id_companies_id_fk",
+ "tableFrom": "cost_events",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "cost_events_agent_id_agents_id_fk": {
+ "name": "cost_events_agent_id_agents_id_fk",
+ "tableFrom": "cost_events",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "cost_events_issue_id_issues_id_fk": {
+ "name": "cost_events_issue_id_issues_id_fk",
+ "tableFrom": "cost_events",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "cost_events_project_id_projects_id_fk": {
+ "name": "cost_events_project_id_projects_id_fk",
+ "tableFrom": "cost_events",
+ "columnsFrom": [
+ "project_id"
+ ],
+ "tableTo": "projects",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "cost_events_goal_id_goals_id_fk": {
+ "name": "cost_events_goal_id_goals_id_fk",
+ "tableFrom": "cost_events",
+ "columnsFrom": [
+ "goal_id"
+ ],
+ "tableTo": "goals",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "cost_events_heartbeat_run_id_heartbeat_runs_id_fk": {
+ "name": "cost_events_heartbeat_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "cost_events",
+ "columnsFrom": [
+ "heartbeat_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "cost_events_nonnegative_amounts": {
+ "name": "cost_events_nonnegative_amounts",
+ "value": "\"cost_events\".\"cost_cents\" >= 0 and \"cost_events\".\"input_tokens\" >= 0 and \"cost_events\".\"cached_input_tokens\" >= 0 and \"cost_events\".\"output_tokens\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.decision_archive_notification_outbox": {
+ "name": "decision_archive_notification_outbox",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_kind": {
+ "name": "source_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_id": {
+ "name": "source_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "archive_version": {
+ "name": "archive_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "origin_agent_id": {
+ "name": "origin_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "origin_issue_id": {
+ "name": "origin_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "attempt_count": {
+ "name": "attempt_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "last_attempt_at": {
+ "name": "last_attempt_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "delivered_at": {
+ "name": "delivered_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "decision_archive_notification_outbox_uq": {
+ "name": "decision_archive_notification_outbox_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "archive_version",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "origin_agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "decision_archive_notification_outbox_pending_idx": {
+ "name": "decision_archive_notification_outbox_pending_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "decision_archive_notification_outbox_company_id_companies_id_fk": {
+ "name": "decision_archive_notification_outbox_company_id_companies_id_fk",
+ "tableFrom": "decision_archive_notification_outbox",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "decision_archive_notification_outbox_origin_agent_id_agents_id_fk": {
+ "name": "decision_archive_notification_outbox_origin_agent_id_agents_id_fk",
+ "tableFrom": "decision_archive_notification_outbox",
+ "columnsFrom": [
+ "origin_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "decision_archive_notification_outbox_status_check": {
+ "name": "decision_archive_notification_outbox_status_check",
+ "value": "\"decision_archive_notification_outbox\".\"status\" IN ('pending', 'delivering', 'delivered')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.decision_queue_items": {
+ "name": "decision_queue_items",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "queue_id": {
+ "name": "queue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_kind": {
+ "name": "source_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_id": {
+ "name": "source_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "added_by_type": {
+ "name": "added_by_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "added_by_agent_id": {
+ "name": "added_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "added_by_user_id": {
+ "name": "added_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "added_by_run_id": {
+ "name": "added_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "added_by_agent_api_key_id": {
+ "name": "added_by_agent_api_key_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "responsible_user_id": {
+ "name": "responsible_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "decision_queue_items_queue_source_uq": {
+ "name": "decision_queue_items_queue_source_uq",
+ "columns": [
+ {
+ "expression": "queue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "decision_queue_items_company_source_idx": {
+ "name": "decision_queue_items_company_source_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "decision_queue_items_company_id_companies_id_fk": {
+ "name": "decision_queue_items_company_id_companies_id_fk",
+ "tableFrom": "decision_queue_items",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "decision_queue_items_added_by_agent_id_agents_id_fk": {
+ "name": "decision_queue_items_added_by_agent_id_agents_id_fk",
+ "tableFrom": "decision_queue_items",
+ "columnsFrom": [
+ "added_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "decision_queue_items_added_by_run_id_heartbeat_runs_id_fk": {
+ "name": "decision_queue_items_added_by_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "decision_queue_items",
+ "columnsFrom": [
+ "added_by_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "decision_queue_items_added_by_agent_api_key_id_agent_api_keys_id_fk": {
+ "name": "decision_queue_items_added_by_agent_api_key_id_agent_api_keys_id_fk",
+ "tableFrom": "decision_queue_items",
+ "columnsFrom": [
+ "added_by_agent_api_key_id"
+ ],
+ "tableTo": "agent_api_keys",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "decision_queue_items_queue_company_fk": {
+ "name": "decision_queue_items_queue_company_fk",
+ "tableFrom": "decision_queue_items",
+ "columnsFrom": [
+ "queue_id",
+ "company_id"
+ ],
+ "tableTo": "decision_queues",
+ "columnsTo": [
+ "id",
+ "company_id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "decision_queue_items_actor_check": {
+ "name": "decision_queue_items_actor_check",
+ "value": "(\n (\"decision_queue_items\".\"added_by_type\" = 'agent' AND \"decision_queue_items\".\"added_by_agent_id\" IS NOT NULL AND \"decision_queue_items\".\"added_by_user_id\" IS NULL)\n OR (\"decision_queue_items\".\"added_by_type\" = 'user' AND \"decision_queue_items\".\"added_by_agent_id\" IS NULL AND \"decision_queue_items\".\"added_by_user_id\" IS NOT NULL)\n OR (\"decision_queue_items\".\"added_by_type\" = 'system' AND \"decision_queue_items\".\"added_by_agent_id\" IS NULL AND \"decision_queue_items\".\"added_by_user_id\" IS NULL)\n )"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.decision_queues": {
+ "name": "decision_queues",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_type": {
+ "name": "created_by_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_run_id": {
+ "name": "created_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_agent_api_key_id": {
+ "name": "created_by_agent_api_key_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "retention_days": {
+ "name": "retention_days",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "seed_rules": {
+ "name": "seed_rules",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "seed_rules_enabled": {
+ "name": "seed_rules_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "decision_queues_company_key_uq": {
+ "name": "decision_queues_company_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "decision_queues_company_updated_idx": {
+ "name": "decision_queues_company_updated_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "decision_queues_company_id_companies_id_fk": {
+ "name": "decision_queues_company_id_companies_id_fk",
+ "tableFrom": "decision_queues",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "decision_queues_created_by_agent_id_agents_id_fk": {
+ "name": "decision_queues_created_by_agent_id_agents_id_fk",
+ "tableFrom": "decision_queues",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "decision_queues_created_by_run_id_heartbeat_runs_id_fk": {
+ "name": "decision_queues_created_by_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "decision_queues",
+ "columnsFrom": [
+ "created_by_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "decision_queues_created_by_agent_api_key_id_agent_api_keys_id_fk": {
+ "name": "decision_queues_created_by_agent_api_key_id_agent_api_keys_id_fk",
+ "tableFrom": "decision_queues",
+ "columnsFrom": [
+ "created_by_agent_api_key_id"
+ ],
+ "tableTo": "agent_api_keys",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "decision_queues_id_company_uq": {
+ "name": "decision_queues_id_company_uq",
+ "columns": [
+ "id",
+ "company_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {
+ "decision_queues_creator_check": {
+ "name": "decision_queues_creator_check",
+ "value": "(\n (\"decision_queues\".\"created_by_type\" = 'agent' AND \"decision_queues\".\"created_by_agent_id\" IS NOT NULL AND \"decision_queues\".\"created_by_user_id\" IS NULL)\n OR (\"decision_queues\".\"created_by_type\" = 'user' AND \"decision_queues\".\"created_by_agent_id\" IS NULL AND \"decision_queues\".\"created_by_user_id\" IS NOT NULL)\n OR (\"decision_queues\".\"created_by_type\" = 'system' AND \"decision_queues\".\"created_by_agent_id\" IS NULL AND \"decision_queues\".\"created_by_user_id\" IS NULL)\n )"
+ },
+ "decision_queues_retention_days_check": {
+ "name": "decision_queues_retention_days_check",
+ "value": "\"decision_queues\".\"retention_days\" IS NULL OR (\"decision_queues\".\"retention_days\" >= 1 AND \"decision_queues\".\"retention_days\" <= 3650)"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.decision_retention": {
+ "name": "decision_retention",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_kind": {
+ "name": "source_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_id": {
+ "name": "source_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_activity_at": {
+ "name": "source_activity_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "keep": {
+ "name": "keep",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_reason": {
+ "name": "archived_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_by_type": {
+ "name": "archived_by_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_by_agent_id": {
+ "name": "archived_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_by_user_id": {
+ "name": "archived_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_by_run_id": {
+ "name": "archived_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "version": {
+ "name": "version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "archive_version": {
+ "name": "archive_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "decision_retention_company_source_uq": {
+ "name": "decision_retention_company_source_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "decision_retention_company_archived_idx": {
+ "name": "decision_retention_company_archived_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "archived_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "decision_retention_company_id_companies_id_fk": {
+ "name": "decision_retention_company_id_companies_id_fk",
+ "tableFrom": "decision_retention",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "decision_retention_archived_by_agent_id_agents_id_fk": {
+ "name": "decision_retention_archived_by_agent_id_agents_id_fk",
+ "tableFrom": "decision_retention",
+ "columnsFrom": [
+ "archived_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "decision_retention_archived_by_run_id_heartbeat_runs_id_fk": {
+ "name": "decision_retention_archived_by_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "decision_retention",
+ "columnsFrom": [
+ "archived_by_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "decision_retention_archive_actor_check": {
+ "name": "decision_retention_archive_actor_check",
+ "value": "(\n (\"decision_retention\".\"archived_at\" IS NULL AND \"decision_retention\".\"archived_by_type\" IS NULL AND \"decision_retention\".\"archived_by_agent_id\" IS NULL AND \"decision_retention\".\"archived_by_user_id\" IS NULL)\n OR (\"decision_retention\".\"archived_at\" IS NOT NULL AND \"decision_retention\".\"archived_by_type\" = 'system' AND \"decision_retention\".\"archived_by_agent_id\" IS NULL AND \"decision_retention\".\"archived_by_user_id\" IS NULL)\n OR (\"decision_retention\".\"archived_at\" IS NOT NULL AND \"decision_retention\".\"archived_by_type\" = 'agent' AND \"decision_retention\".\"archived_by_agent_id\" IS NOT NULL AND \"decision_retention\".\"archived_by_user_id\" IS NULL)\n OR (\"decision_retention\".\"archived_at\" IS NOT NULL AND \"decision_retention\".\"archived_by_type\" = 'user' AND \"decision_retention\".\"archived_by_agent_id\" IS NULL AND \"decision_retention\".\"archived_by_user_id\" IS NOT NULL)\n )"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.decision_triage": {
+ "name": "decision_triage",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_kind": {
+ "name": "source_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_id": {
+ "name": "source_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "decide_by": {
+ "name": "decide_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "decide_by_date": {
+ "name": "decide_by_date",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "snoozed_until": {
+ "name": "snoozed_until",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "set_by_type": {
+ "name": "set_by_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "set_by_agent_id": {
+ "name": "set_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "set_by_user_id": {
+ "name": "set_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "set_by_run_id": {
+ "name": "set_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "set_by_agent_api_key_id": {
+ "name": "set_by_agent_api_key_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "responsible_user_id": {
+ "name": "responsible_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "version": {
+ "name": "version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "decision_triage_company_source_uq": {
+ "name": "decision_triage_company_source_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "decision_triage_company_decide_by_idx": {
+ "name": "decision_triage_company_decide_by_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "decide_by",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "decision_triage_company_id_companies_id_fk": {
+ "name": "decision_triage_company_id_companies_id_fk",
+ "tableFrom": "decision_triage",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "decision_triage_set_by_agent_id_agents_id_fk": {
+ "name": "decision_triage_set_by_agent_id_agents_id_fk",
+ "tableFrom": "decision_triage",
+ "columnsFrom": [
+ "set_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "decision_triage_set_by_run_id_heartbeat_runs_id_fk": {
+ "name": "decision_triage_set_by_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "decision_triage",
+ "columnsFrom": [
+ "set_by_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "decision_triage_set_by_agent_api_key_id_agent_api_keys_id_fk": {
+ "name": "decision_triage_set_by_agent_api_key_id_agent_api_keys_id_fk",
+ "tableFrom": "decision_triage",
+ "columnsFrom": [
+ "set_by_agent_api_key_id"
+ ],
+ "tableTo": "agent_api_keys",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "decision_triage_actor_check": {
+ "name": "decision_triage_actor_check",
+ "value": "(\n (\"decision_triage\".\"set_by_type\" = 'agent' AND \"decision_triage\".\"set_by_agent_id\" IS NOT NULL AND \"decision_triage\".\"set_by_user_id\" IS NULL)\n OR (\"decision_triage\".\"set_by_type\" = 'user' AND \"decision_triage\".\"set_by_agent_id\" IS NULL AND \"decision_triage\".\"set_by_user_id\" IS NOT NULL)\n )"
+ },
+ "decision_triage_decide_by_check": {
+ "name": "decision_triage_decide_by_check",
+ "value": "(\n (\"decision_triage\".\"decide_by\" IS NULL AND \"decision_triage\".\"decide_by_date\" IS NULL)\n OR (\"decision_triage\".\"decide_by\" IN ('today', 'this_week', 'whenever') AND \"decision_triage\".\"decide_by_date\" IS NULL)\n OR (\"decision_triage\".\"decide_by\" = 'date' AND \"decision_triage\".\"decide_by_date\" IS NOT NULL)\n )"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.decision_triage_events": {
+ "name": "decision_triage_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "queue_id": {
+ "name": "queue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_kind": {
+ "name": "source_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_id": {
+ "name": "source_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "action": {
+ "name": "action",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_type": {
+ "name": "actor_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_agent_id": {
+ "name": "actor_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "actor_user_id": {
+ "name": "actor_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "actor_run_id": {
+ "name": "actor_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "agent_api_key_id": {
+ "name": "agent_api_key_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "responsible_user_id": {
+ "name": "responsible_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "details": {
+ "name": "details",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "decision_triage_events_company_source_created_idx": {
+ "name": "decision_triage_events_company_source_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "decision_triage_events_queue_created_idx": {
+ "name": "decision_triage_events_queue_created_idx",
+ "columns": [
+ {
+ "expression": "queue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "decision_triage_events_company_id_companies_id_fk": {
+ "name": "decision_triage_events_company_id_companies_id_fk",
+ "tableFrom": "decision_triage_events",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "decision_triage_events_queue_id_decision_queues_id_fk": {
+ "name": "decision_triage_events_queue_id_decision_queues_id_fk",
+ "tableFrom": "decision_triage_events",
+ "columnsFrom": [
+ "queue_id"
+ ],
+ "tableTo": "decision_queues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "decision_triage_events_actor_agent_id_agents_id_fk": {
+ "name": "decision_triage_events_actor_agent_id_agents_id_fk",
+ "tableFrom": "decision_triage_events",
+ "columnsFrom": [
+ "actor_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "decision_triage_events_actor_run_id_heartbeat_runs_id_fk": {
+ "name": "decision_triage_events_actor_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "decision_triage_events",
+ "columnsFrom": [
+ "actor_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "decision_triage_events_agent_api_key_id_agent_api_keys_id_fk": {
+ "name": "decision_triage_events_agent_api_key_id_agent_api_keys_id_fk",
+ "tableFrom": "decision_triage_events",
+ "columnsFrom": [
+ "agent_api_key_id"
+ ],
+ "tableTo": "agent_api_keys",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "decision_triage_events_actor_check": {
+ "name": "decision_triage_events_actor_check",
+ "value": "(\n (\"decision_triage_events\".\"actor_type\" = 'agent' AND \"decision_triage_events\".\"actor_agent_id\" IS NOT NULL AND \"decision_triage_events\".\"actor_user_id\" IS NULL)\n OR (\"decision_triage_events\".\"actor_type\" = 'user' AND \"decision_triage_events\".\"actor_agent_id\" IS NULL AND \"decision_triage_events\".\"actor_user_id\" IS NOT NULL)\n OR (\"decision_triage_events\".\"actor_type\" = 'system' AND \"decision_triage_events\".\"actor_agent_id\" IS NULL AND \"decision_triage_events\".\"actor_user_id\" IS NULL)\n )"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.decision_training_examples": {
+ "name": "decision_training_examples",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_kind": {
+ "name": "source_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_id": {
+ "name": "source_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cutoff_at": {
+ "name": "cutoff_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "notes": {
+ "name": "notes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "notes_history": {
+ "name": "notes_history",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "decision_outcome": {
+ "name": "decision_outcome",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "retention_policy": {
+ "name": "retention_policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'scrub_deleted_comments_v1'"
+ },
+ "snapshot": {
+ "name": "snapshot",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "decision_training_examples_company_created_at_idx": {
+ "name": "decision_training_examples_company_created_at_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "decision_training_examples_issue_idx": {
+ "name": "decision_training_examples_issue_idx",
+ "columns": [
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "decision_training_examples_source_author_uq": {
+ "name": "decision_training_examples_source_author_uq",
+ "columns": [
+ {
+ "expression": "source_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_by_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "decision_training_examples_company_id_companies_id_fk": {
+ "name": "decision_training_examples_company_id_companies_id_fk",
+ "tableFrom": "decision_training_examples",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "decision_training_examples_issue_id_issues_id_fk": {
+ "name": "decision_training_examples_issue_id_issues_id_fk",
+ "tableFrom": "decision_training_examples",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.decision_bundles": {
+ "name": "decision_bundles",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "summary": {
+ "name": "summary",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "origin_agent_id": {
+ "name": "origin_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "origin_issue_id": {
+ "name": "origin_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "origin_run_id": {
+ "name": "origin_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "decision_bundles_company_created_at_idx": {
+ "name": "decision_bundles_company_created_at_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "decision_bundles_company_id_companies_id_fk": {
+ "name": "decision_bundles_company_id_companies_id_fk",
+ "tableFrom": "decision_bundles",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "decision_bundles_origin_agent_id_agents_id_fk": {
+ "name": "decision_bundles_origin_agent_id_agents_id_fk",
+ "tableFrom": "decision_bundles",
+ "columnsFrom": [
+ "origin_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "decision_bundles_origin_issue_id_issues_id_fk": {
+ "name": "decision_bundles_origin_issue_id_issues_id_fk",
+ "tableFrom": "decision_bundles",
+ "columnsFrom": [
+ "origin_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "decision_bundles_origin_run_id_heartbeat_runs_id_fk": {
+ "name": "decision_bundles_origin_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "decision_bundles",
+ "columnsFrom": [
+ "origin_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.decision_effect_executions": {
+ "name": "decision_effect_executions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "decision_id": {
+ "name": "decision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "effect_index": {
+ "name": "effect_index",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "effect_type": {
+ "name": "effect_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_issue_id": {
+ "name": "target_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'claimed'"
+ },
+ "result": {
+ "name": "result",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "activity_log_id": {
+ "name": "activity_log_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "executed_at": {
+ "name": "executed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "decision_effect_executions_decision_effect_uq": {
+ "name": "decision_effect_executions_decision_effect_uq",
+ "columns": [
+ {
+ "expression": "decision_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "effect_index",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "decision_effect_executions_target_issue_idx": {
+ "name": "decision_effect_executions_target_issue_idx",
+ "columns": [
+ {
+ "expression": "target_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "decision_effect_executions_decision_id_decisions_id_fk": {
+ "name": "decision_effect_executions_decision_id_decisions_id_fk",
+ "tableFrom": "decision_effect_executions",
+ "columnsFrom": [
+ "decision_id"
+ ],
+ "tableTo": "decisions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "decision_effect_executions_target_issue_id_issues_id_fk": {
+ "name": "decision_effect_executions_target_issue_id_issues_id_fk",
+ "tableFrom": "decision_effect_executions",
+ "columnsFrom": [
+ "target_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "decision_effect_executions_activity_log_id_activity_log_id_fk": {
+ "name": "decision_effect_executions_activity_log_id_activity_log_id_fk",
+ "tableFrom": "decision_effect_executions",
+ "columnsFrom": [
+ "activity_log_id"
+ ],
+ "tableTo": "activity_log",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.decision_target_issues": {
+ "name": "decision_target_issues",
+ "schema": "",
+ "columns": {
+ "decision_id": {
+ "name": "decision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "decision_target_issues_decision_idx": {
+ "name": "decision_target_issues_decision_idx",
+ "columns": [
+ {
+ "expression": "decision_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "decision_target_issues_issue_idx": {
+ "name": "decision_target_issues_issue_idx",
+ "columns": [
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "decision_target_issues_decision_id_decisions_id_fk": {
+ "name": "decision_target_issues_decision_id_decisions_id_fk",
+ "tableFrom": "decision_target_issues",
+ "columnsFrom": [
+ "decision_id"
+ ],
+ "tableTo": "decisions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "decision_target_issues_issue_id_issues_id_fk": {
+ "name": "decision_target_issues_issue_id_issues_id_fk",
+ "tableFrom": "decision_target_issues",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "decision_target_issues_company_id_companies_id_fk": {
+ "name": "decision_target_issues_company_id_companies_id_fk",
+ "tableFrom": "decision_target_issues",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "decision_target_issues_decision_id_issue_id_pk": {
+ "name": "decision_target_issues_decision_id_issue_id_pk",
+ "columns": [
+ "decision_id",
+ "issue_id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.decisions": {
+ "name": "decisions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "bundle_id": {
+ "name": "bundle_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "origin_agent_id": {
+ "name": "origin_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "origin_issue_id": {
+ "name": "origin_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "origin_run_id": {
+ "name": "origin_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "rule_key": {
+ "name": "rule_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "body": {
+ "name": "body",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "options": {
+ "name": "options",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "inputs": {
+ "name": "inputs",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'open'"
+ },
+ "execution_status": {
+ "name": "execution_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "chosen_option_id": {
+ "name": "chosen_option_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "input_values": {
+ "name": "input_values",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "decided_by_user_id": {
+ "name": "decided_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "decided_at": {
+ "name": "decided_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "signed_spec": {
+ "name": "signed_spec",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_snapshots": {
+ "name": "target_snapshots",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "continuation_policy": {
+ "name": "continuation_policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'none'"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "decisions_company_status_expires_at_idx": {
+ "name": "decisions_company_status_expires_at_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "decisions_bundle_idx": {
+ "name": "decisions_bundle_idx",
+ "columns": [
+ {
+ "expression": "bundle_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "decisions_origin_issue_idx": {
+ "name": "decisions_origin_issue_idx",
+ "columns": [
+ {
+ "expression": "origin_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "decisions_company_idempotency_uq": {
+ "name": "decisions_company_idempotency_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"decisions\".\"idempotency_key\" IS NOT NULL",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "decisions_company_id_companies_id_fk": {
+ "name": "decisions_company_id_companies_id_fk",
+ "tableFrom": "decisions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "decisions_bundle_id_decision_bundles_id_fk": {
+ "name": "decisions_bundle_id_decision_bundles_id_fk",
+ "tableFrom": "decisions",
+ "columnsFrom": [
+ "bundle_id"
+ ],
+ "tableTo": "decision_bundles",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "decisions_origin_agent_id_agents_id_fk": {
+ "name": "decisions_origin_agent_id_agents_id_fk",
+ "tableFrom": "decisions",
+ "columnsFrom": [
+ "origin_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "decisions_origin_issue_id_issues_id_fk": {
+ "name": "decisions_origin_issue_id_issues_id_fk",
+ "tableFrom": "decisions",
+ "columnsFrom": [
+ "origin_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "decisions_origin_run_id_heartbeat_runs_id_fk": {
+ "name": "decisions_origin_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "decisions",
+ "columnsFrom": [
+ "origin_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.document_annotation_anchor_snapshots": {
+ "name": "document_annotation_anchor_snapshots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "thread_id": {
+ "name": "thread_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "from_revision_id": {
+ "name": "from_revision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "from_revision_number": {
+ "name": "from_revision_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "to_revision_id": {
+ "name": "to_revision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "to_revision_number": {
+ "name": "to_revision_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_anchor": {
+ "name": "previous_anchor",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "next_anchor": {
+ "name": "next_anchor",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "anchor_state": {
+ "name": "anchor_state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "anchor_confidence": {
+ "name": "anchor_confidence",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "failure_reason": {
+ "name": "failure_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "document_annotation_anchor_snapshots_company_thread_created_at_idx": {
+ "name": "document_annotation_anchor_snapshots_company_thread_created_at_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "thread_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "document_annotation_anchor_snapshots_company_document_revision_idx": {
+ "name": "document_annotation_anchor_snapshots_company_document_revision_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "document_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "to_revision_number",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "document_annotation_anchor_snapshots_company_id_companies_id_fk": {
+ "name": "document_annotation_anchor_snapshots_company_id_companies_id_fk",
+ "tableFrom": "document_annotation_anchor_snapshots",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "document_annotation_anchor_snapshots_thread_id_document_annotation_threads_id_fk": {
+ "name": "document_annotation_anchor_snapshots_thread_id_document_annotation_threads_id_fk",
+ "tableFrom": "document_annotation_anchor_snapshots",
+ "columnsFrom": [
+ "thread_id"
+ ],
+ "tableTo": "document_annotation_threads",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "document_annotation_anchor_snapshots_document_id_documents_id_fk": {
+ "name": "document_annotation_anchor_snapshots_document_id_documents_id_fk",
+ "tableFrom": "document_annotation_anchor_snapshots",
+ "columnsFrom": [
+ "document_id"
+ ],
+ "tableTo": "documents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "document_annotation_anchor_snapshots_from_revision_id_document_revisions_id_fk": {
+ "name": "document_annotation_anchor_snapshots_from_revision_id_document_revisions_id_fk",
+ "tableFrom": "document_annotation_anchor_snapshots",
+ "columnsFrom": [
+ "from_revision_id"
+ ],
+ "tableTo": "document_revisions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "document_annotation_anchor_snapshots_to_revision_id_document_revisions_id_fk": {
+ "name": "document_annotation_anchor_snapshots_to_revision_id_document_revisions_id_fk",
+ "tableFrom": "document_annotation_anchor_snapshots",
+ "columnsFrom": [
+ "to_revision_id"
+ ],
+ "tableTo": "document_revisions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.document_annotation_comments": {
+ "name": "document_annotation_comments",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "thread_id": {
+ "name": "thread_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "routine_id": {
+ "name": "routine_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "case_id": {
+ "name": "case_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "body": {
+ "name": "body",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_type": {
+ "name": "author_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_agent_id": {
+ "name": "author_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "author_user_id": {
+ "name": "author_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_run_id": {
+ "name": "created_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_comment_id": {
+ "name": "issue_comment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_trust": {
+ "name": "source_trust",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "document_annotation_comments_company_thread_created_at_idx": {
+ "name": "document_annotation_comments_company_thread_created_at_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "thread_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "document_annotation_comments_company_issue_created_at_idx": {
+ "name": "document_annotation_comments_company_issue_created_at_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "document_annotation_comments_company_routine_created_at_idx": {
+ "name": "document_annotation_comments_company_routine_created_at_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "routine_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "document_annotation_comments_company_case_created_at_idx": {
+ "name": "document_annotation_comments_company_case_created_at_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "document_annotation_comments_company_document_created_at_idx": {
+ "name": "document_annotation_comments_company_document_created_at_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "document_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "document_annotation_comments_issue_comment_idx": {
+ "name": "document_annotation_comments_issue_comment_idx",
+ "columns": [
+ {
+ "expression": "issue_comment_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "document_annotation_comments_body_search_idx": {
+ "name": "document_annotation_comments_body_search_idx",
+ "columns": [
+ {
+ "expression": "body",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "gin_trgm_ops"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "gin",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "document_annotation_comments_company_id_companies_id_fk": {
+ "name": "document_annotation_comments_company_id_companies_id_fk",
+ "tableFrom": "document_annotation_comments",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "document_annotation_comments_thread_id_document_annotation_threads_id_fk": {
+ "name": "document_annotation_comments_thread_id_document_annotation_threads_id_fk",
+ "tableFrom": "document_annotation_comments",
+ "columnsFrom": [
+ "thread_id"
+ ],
+ "tableTo": "document_annotation_threads",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "document_annotation_comments_issue_id_issues_id_fk": {
+ "name": "document_annotation_comments_issue_id_issues_id_fk",
+ "tableFrom": "document_annotation_comments",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "document_annotation_comments_routine_id_routines_id_fk": {
+ "name": "document_annotation_comments_routine_id_routines_id_fk",
+ "tableFrom": "document_annotation_comments",
+ "columnsFrom": [
+ "routine_id"
+ ],
+ "tableTo": "routines",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "document_annotation_comments_case_id_cases_id_fk": {
+ "name": "document_annotation_comments_case_id_cases_id_fk",
+ "tableFrom": "document_annotation_comments",
+ "columnsFrom": [
+ "case_id"
+ ],
+ "tableTo": "cases",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "document_annotation_comments_document_id_documents_id_fk": {
+ "name": "document_annotation_comments_document_id_documents_id_fk",
+ "tableFrom": "document_annotation_comments",
+ "columnsFrom": [
+ "document_id"
+ ],
+ "tableTo": "documents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "document_annotation_comments_author_agent_id_agents_id_fk": {
+ "name": "document_annotation_comments_author_agent_id_agents_id_fk",
+ "tableFrom": "document_annotation_comments",
+ "columnsFrom": [
+ "author_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "document_annotation_comments_created_by_run_id_heartbeat_runs_id_fk": {
+ "name": "document_annotation_comments_created_by_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "document_annotation_comments",
+ "columnsFrom": [
+ "created_by_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "document_annotation_comments_issue_comment_id_issue_comments_id_fk": {
+ "name": "document_annotation_comments_issue_comment_id_issue_comments_id_fk",
+ "tableFrom": "document_annotation_comments",
+ "columnsFrom": [
+ "issue_comment_id"
+ ],
+ "tableTo": "issue_comments",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "document_annotation_comments_exactly_one_owner_chk": {
+ "name": "document_annotation_comments_exactly_one_owner_chk",
+ "value": "num_nonnulls(\"document_annotation_comments\".\"issue_id\", \"document_annotation_comments\".\"routine_id\", \"document_annotation_comments\".\"case_id\") = 1"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.document_annotation_threads": {
+ "name": "document_annotation_threads",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "routine_id": {
+ "name": "routine_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "case_id": {
+ "name": "case_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_key": {
+ "name": "document_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'open'"
+ },
+ "anchor_state": {
+ "name": "anchor_state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "original_revision_id": {
+ "name": "original_revision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "original_revision_number": {
+ "name": "original_revision_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "current_revision_id": {
+ "name": "current_revision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "current_revision_number": {
+ "name": "current_revision_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "selected_text": {
+ "name": "selected_text",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "prefix_text": {
+ "name": "prefix_text",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "suffix_text": {
+ "name": "suffix_text",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "normalized_start": {
+ "name": "normalized_start",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "normalized_end": {
+ "name": "normalized_end",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "markdown_start": {
+ "name": "markdown_start",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "markdown_end": {
+ "name": "markdown_end",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "anchor_confidence": {
+ "name": "anchor_confidence",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'exact'"
+ },
+ "anchor_selector": {
+ "name": "anchor_selector",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resolved_by_agent_id": {
+ "name": "resolved_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resolved_by_user_id": {
+ "name": "resolved_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resolved_at": {
+ "name": "resolved_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "document_annotation_threads_company_document_status_idx": {
+ "name": "document_annotation_threads_company_document_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "document_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "document_annotation_threads_company_issue_status_idx": {
+ "name": "document_annotation_threads_company_issue_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "document_annotation_threads_company_routine_status_idx": {
+ "name": "document_annotation_threads_company_routine_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "routine_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "document_annotation_threads_company_case_status_idx": {
+ "name": "document_annotation_threads_company_case_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "document_annotation_threads_company_current_revision_open_idx": {
+ "name": "document_annotation_threads_company_current_revision_open_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "document_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "current_revision_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "document_annotation_threads_company_anchor_state_idx": {
+ "name": "document_annotation_threads_company_anchor_state_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "anchor_state",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "document_annotation_threads_company_id_companies_id_fk": {
+ "name": "document_annotation_threads_company_id_companies_id_fk",
+ "tableFrom": "document_annotation_threads",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "document_annotation_threads_issue_id_issues_id_fk": {
+ "name": "document_annotation_threads_issue_id_issues_id_fk",
+ "tableFrom": "document_annotation_threads",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "document_annotation_threads_routine_id_routines_id_fk": {
+ "name": "document_annotation_threads_routine_id_routines_id_fk",
+ "tableFrom": "document_annotation_threads",
+ "columnsFrom": [
+ "routine_id"
+ ],
+ "tableTo": "routines",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "document_annotation_threads_case_id_cases_id_fk": {
+ "name": "document_annotation_threads_case_id_cases_id_fk",
+ "tableFrom": "document_annotation_threads",
+ "columnsFrom": [
+ "case_id"
+ ],
+ "tableTo": "cases",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "document_annotation_threads_document_id_documents_id_fk": {
+ "name": "document_annotation_threads_document_id_documents_id_fk",
+ "tableFrom": "document_annotation_threads",
+ "columnsFrom": [
+ "document_id"
+ ],
+ "tableTo": "documents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "document_annotation_threads_original_revision_id_document_revisions_id_fk": {
+ "name": "document_annotation_threads_original_revision_id_document_revisions_id_fk",
+ "tableFrom": "document_annotation_threads",
+ "columnsFrom": [
+ "original_revision_id"
+ ],
+ "tableTo": "document_revisions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "document_annotation_threads_current_revision_id_document_revisions_id_fk": {
+ "name": "document_annotation_threads_current_revision_id_document_revisions_id_fk",
+ "tableFrom": "document_annotation_threads",
+ "columnsFrom": [
+ "current_revision_id"
+ ],
+ "tableTo": "document_revisions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "document_annotation_threads_created_by_agent_id_agents_id_fk": {
+ "name": "document_annotation_threads_created_by_agent_id_agents_id_fk",
+ "tableFrom": "document_annotation_threads",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "document_annotation_threads_resolved_by_agent_id_agents_id_fk": {
+ "name": "document_annotation_threads_resolved_by_agent_id_agents_id_fk",
+ "tableFrom": "document_annotation_threads",
+ "columnsFrom": [
+ "resolved_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "document_annotation_threads_exactly_one_owner_chk": {
+ "name": "document_annotation_threads_exactly_one_owner_chk",
+ "value": "num_nonnulls(\"document_annotation_threads\".\"issue_id\", \"document_annotation_threads\".\"routine_id\", \"document_annotation_threads\".\"case_id\") = 1"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.document_memberships": {
+ "name": "document_memberships",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "starred_at": {
+ "name": "starred_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "document_memberships_company_user_starred_idx": {
+ "name": "document_memberships_company_user_starred_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "starred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "document_memberships_company_user_document_uq": {
+ "name": "document_memberships_company_user_document_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "document_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "document_memberships_company_id_companies_id_fk": {
+ "name": "document_memberships_company_id_companies_id_fk",
+ "tableFrom": "document_memberships",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "document_memberships_document_id_documents_id_fk": {
+ "name": "document_memberships_document_id_documents_id_fk",
+ "tableFrom": "document_memberships",
+ "columnsFrom": [
+ "document_id"
+ ],
+ "tableTo": "documents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.document_revisions": {
+ "name": "document_revisions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revision_number": {
+ "name": "revision_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "format": {
+ "name": "format",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'markdown'"
+ },
+ "body": {
+ "name": "body",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "change_summary": {
+ "name": "change_summary",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_run_id": {
+ "name": "created_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "document_revisions_document_revision_uq": {
+ "name": "document_revisions_document_revision_uq",
+ "columns": [
+ {
+ "expression": "document_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "revision_number",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "document_revisions_company_document_created_idx": {
+ "name": "document_revisions_company_document_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "document_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "document_revisions_company_id_companies_id_fk": {
+ "name": "document_revisions_company_id_companies_id_fk",
+ "tableFrom": "document_revisions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "document_revisions_document_id_documents_id_fk": {
+ "name": "document_revisions_document_id_documents_id_fk",
+ "tableFrom": "document_revisions",
+ "columnsFrom": [
+ "document_id"
+ ],
+ "tableTo": "documents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "document_revisions_created_by_agent_id_agents_id_fk": {
+ "name": "document_revisions_created_by_agent_id_agents_id_fk",
+ "tableFrom": "document_revisions",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "document_revisions_created_by_run_id_heartbeat_runs_id_fk": {
+ "name": "document_revisions_created_by_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "document_revisions",
+ "columnsFrom": [
+ "created_by_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.documents": {
+ "name": "documents",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "format": {
+ "name": "format",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'markdown'"
+ },
+ "latest_body": {
+ "name": "latest_body",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "latest_revision_id": {
+ "name": "latest_revision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "latest_revision_number": {
+ "name": "latest_revision_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_by_agent_id": {
+ "name": "updated_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_by_user_id": {
+ "name": "updated_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "locked_at": {
+ "name": "locked_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "locked_by_agent_id": {
+ "name": "locked_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "locked_by_user_id": {
+ "name": "locked_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_trust": {
+ "name": "source_trust",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "documents_company_updated_idx": {
+ "name": "documents_company_updated_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "documents_company_created_idx": {
+ "name": "documents_company_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "documents_title_search_idx": {
+ "name": "documents_title_search_idx",
+ "columns": [
+ {
+ "expression": "title",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "gin_trgm_ops"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "gin",
+ "concurrently": false
+ },
+ "documents_latest_body_search_idx": {
+ "name": "documents_latest_body_search_idx",
+ "columns": [
+ {
+ "expression": "latest_body",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "gin_trgm_ops"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "gin",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "documents_company_id_companies_id_fk": {
+ "name": "documents_company_id_companies_id_fk",
+ "tableFrom": "documents",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "documents_created_by_agent_id_agents_id_fk": {
+ "name": "documents_created_by_agent_id_agents_id_fk",
+ "tableFrom": "documents",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "documents_updated_by_agent_id_agents_id_fk": {
+ "name": "documents_updated_by_agent_id_agents_id_fk",
+ "tableFrom": "documents",
+ "columnsFrom": [
+ "updated_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "documents_locked_by_agent_id_agents_id_fk": {
+ "name": "documents_locked_by_agent_id_agents_id_fk",
+ "tableFrom": "documents",
+ "columnsFrom": [
+ "locked_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.email_endpoints": {
+ "name": "email_endpoints",
+ "schema": "",
+ "columns": {
+ "endpoint_id": {
+ "name": "endpoint_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receive_mode": {
+ "name": "receive_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "webhook_id": {
+ "name": "webhook_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "owned_api_key_id": {
+ "name": "owned_api_key_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "activation_at": {
+ "name": "activation_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_checkpoint": {
+ "name": "sync_checkpoint",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_sync_at": {
+ "name": "last_sync_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "email_endpoints_company_id_endpoint_id_chat_endpoints_company_id_id_fk": {
+ "name": "email_endpoints_company_id_endpoint_id_chat_endpoints_company_id_id_fk",
+ "tableFrom": "email_endpoints",
+ "columnsFrom": [
+ "company_id",
+ "endpoint_id"
+ ],
+ "tableTo": "chat_endpoints",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "email_endpoints_receive_mode_check": {
+ "name": "email_endpoints_receive_mode_check",
+ "value": "\"email_endpoints\".\"receive_mode\" in ('websocket', 'webhook')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.email_messages": {
+ "name": "email_messages",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "endpoint_id": {
+ "name": "endpoint_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "conversation_id": {
+ "name": "conversation_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_message_id": {
+ "name": "provider_message_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "envelope": {
+ "name": "envelope",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "text": {
+ "name": "text",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "full_text": {
+ "name": "full_text",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "direction": {
+ "name": "direction",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "automatic": {
+ "name": "automatic",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "attachment_ids": {
+ "name": "attachment_ids",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "timestamp": {
+ "name": "timestamp",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "email_messages_provider_uq": {
+ "name": "email_messages_provider_uq",
+ "columns": [
+ {
+ "expression": "endpoint_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_message_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "email_messages_conversation_idx": {
+ "name": "email_messages_conversation_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "conversation_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "timestamp",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "email_messages_company_id_endpoint_id_chat_endpoints_company_id_id_fk": {
+ "name": "email_messages_company_id_endpoint_id_chat_endpoints_company_id_id_fk",
+ "tableFrom": "email_messages",
+ "columnsFrom": [
+ "company_id",
+ "endpoint_id"
+ ],
+ "tableTo": "chat_endpoints",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "email_messages_company_id_conversation_id_chat_conversations_company_id_id_fk": {
+ "name": "email_messages_company_id_conversation_id_chat_conversations_company_id_id_fk",
+ "tableFrom": "email_messages",
+ "columnsFrom": [
+ "company_id",
+ "conversation_id"
+ ],
+ "tableTo": "chat_conversations",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "email_messages_direction_check": {
+ "name": "email_messages_direction_check",
+ "value": "\"email_messages\".\"direction\" in ('inbound', 'outbound')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.email_sends": {
+ "name": "email_sends",
+ "schema": "",
+ "columns": {
+ "publication_id": {
+ "name": "publication_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "endpoint_id": {
+ "name": "endpoint_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "request": {
+ "name": "request",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor": {
+ "name": "actor",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "digest": {
+ "name": "digest",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "outcome": {
+ "name": "outcome",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'queued'"
+ },
+ "first_attempt_at": {
+ "name": "first_attempt_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "email_sends_pending_idx": {
+ "name": "email_sends_pending_idx",
+ "columns": [
+ {
+ "expression": "endpoint_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "outcome",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "where": "\"email_sends\".\"outcome\" in ('queued', 'uncertain')",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "email_sends_company_id_endpoint_id_chat_endpoints_company_id_id_fk": {
+ "name": "email_sends_company_id_endpoint_id_chat_endpoints_company_id_id_fk",
+ "tableFrom": "email_sends",
+ "columnsFrom": [
+ "company_id",
+ "endpoint_id"
+ ],
+ "tableTo": "chat_endpoints",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "email_sends_company_id_publication_id_chat_publications_company_id_id_fk": {
+ "name": "email_sends_company_id_publication_id_chat_publications_company_id_id_fk",
+ "tableFrom": "email_sends",
+ "columnsFrom": [
+ "company_id",
+ "publication_id"
+ ],
+ "tableTo": "chat_publications",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "email_sends_outcome_check": {
+ "name": "email_sends_outcome_check",
+ "value": "\"email_sends\".\"outcome\" in ('queued', 'sent', 'delivered', 'failed', 'uncertain')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.environment_custom_image_setup_sessions": {
+ "name": "environment_custom_image_setup_sessions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "environment_id": {
+ "name": "environment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "template_id": {
+ "name": "template_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "promoted_template_id": {
+ "name": "promoted_template_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_lease_id": {
+ "name": "provider_lease_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "environment_lease_id": {
+ "name": "environment_lease_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'starting'"
+ },
+ "started_by_user_id": {
+ "name": "started_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "started_by_agent_id": {
+ "name": "started_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "base_template_ref": {
+ "name": "base_template_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "finished_at": {
+ "name": "finished_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "failure_reason": {
+ "name": "failure_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "connection_summary": {
+ "name": "connection_summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "connection_secret_ref": {
+ "name": "connection_secret_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "environment_custom_image_setup_sessions_environment_status_idx": {
+ "name": "environment_custom_image_setup_sessions_environment_status_idx",
+ "columns": [
+ {
+ "expression": "environment_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "environment_custom_image_setup_sessions_environment_active_uq": {
+ "name": "environment_custom_image_setup_sessions_environment_active_uq",
+ "columns": [
+ {
+ "expression": "environment_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"environment_custom_image_setup_sessions\".\"status\" IN ('starting', 'waiting_for_user', 'capturing')",
+ "concurrently": false
+ },
+ "environment_custom_image_setup_sessions_template_idx": {
+ "name": "environment_custom_image_setup_sessions_template_idx",
+ "columns": [
+ {
+ "expression": "template_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "environment_custom_image_setup_sessions_promoted_template_idx": {
+ "name": "environment_custom_image_setup_sessions_promoted_template_idx",
+ "columns": [
+ {
+ "expression": "promoted_template_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "environment_custom_image_setup_sessions_expires_idx": {
+ "name": "environment_custom_image_setup_sessions_expires_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "environment_custom_image_setup_sessions_provider_lease_idx": {
+ "name": "environment_custom_image_setup_sessions_provider_lease_idx",
+ "columns": [
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_lease_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "environment_custom_image_setup_sessions_environment_id_environments_id_fk": {
+ "name": "environment_custom_image_setup_sessions_environment_id_environments_id_fk",
+ "tableFrom": "environment_custom_image_setup_sessions",
+ "columnsFrom": [
+ "environment_id"
+ ],
+ "tableTo": "environments",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "environment_custom_image_setup_sessions_template_id_environment_custom_image_templates_id_fk": {
+ "name": "environment_custom_image_setup_sessions_template_id_environment_custom_image_templates_id_fk",
+ "tableFrom": "environment_custom_image_setup_sessions",
+ "columnsFrom": [
+ "template_id"
+ ],
+ "tableTo": "environment_custom_image_templates",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "environment_custom_image_setup_sessions_promoted_template_id_environment_custom_image_templates_id_fk": {
+ "name": "environment_custom_image_setup_sessions_promoted_template_id_environment_custom_image_templates_id_fk",
+ "tableFrom": "environment_custom_image_setup_sessions",
+ "columnsFrom": [
+ "promoted_template_id"
+ ],
+ "tableTo": "environment_custom_image_templates",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "environment_custom_image_setup_sessions_environment_lease_id_environment_leases_id_fk": {
+ "name": "environment_custom_image_setup_sessions_environment_lease_id_environment_leases_id_fk",
+ "tableFrom": "environment_custom_image_setup_sessions",
+ "columnsFrom": [
+ "environment_lease_id"
+ ],
+ "tableTo": "environment_leases",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "environment_custom_image_setup_sessions_started_by_agent_id_agents_id_fk": {
+ "name": "environment_custom_image_setup_sessions_started_by_agent_id_agents_id_fk",
+ "tableFrom": "environment_custom_image_setup_sessions",
+ "columnsFrom": [
+ "started_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.environment_custom_image_templates": {
+ "name": "environment_custom_image_templates",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "environment_id": {
+ "name": "environment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "template_kind": {
+ "name": "template_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'unknown'"
+ },
+ "template_ref": {
+ "name": "template_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_template_ref": {
+ "name": "source_template_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_environment_config_fingerprint": {
+ "name": "source_environment_config_fingerprint",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "captured_at": {
+ "name": "captured_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_used_at": {
+ "name": "last_used_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "superseded_by_template_id": {
+ "name": "superseded_by_template_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "environment_custom_image_templates_environment_status_idx": {
+ "name": "environment_custom_image_templates_environment_status_idx",
+ "columns": [
+ {
+ "expression": "environment_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "environment_custom_image_templates_environment_provider_status_idx": {
+ "name": "environment_custom_image_templates_environment_provider_status_idx",
+ "columns": [
+ {
+ "expression": "environment_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "environment_custom_image_templates_environment_active_uq": {
+ "name": "environment_custom_image_templates_environment_active_uq",
+ "columns": [
+ {
+ "expression": "environment_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"environment_custom_image_templates\".\"status\" = 'active'",
+ "concurrently": false
+ },
+ "environment_custom_image_templates_superseded_by_idx": {
+ "name": "environment_custom_image_templates_superseded_by_idx",
+ "columns": [
+ {
+ "expression": "superseded_by_template_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "environment_custom_image_templates_last_used_idx": {
+ "name": "environment_custom_image_templates_last_used_idx",
+ "columns": [
+ {
+ "expression": "last_used_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "environment_custom_image_templates_environment_id_environments_id_fk": {
+ "name": "environment_custom_image_templates_environment_id_environments_id_fk",
+ "tableFrom": "environment_custom_image_templates",
+ "columnsFrom": [
+ "environment_id"
+ ],
+ "tableTo": "environments",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "environment_custom_image_templates_created_by_agent_id_agents_id_fk": {
+ "name": "environment_custom_image_templates_created_by_agent_id_agents_id_fk",
+ "tableFrom": "environment_custom_image_templates",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "environment_custom_image_templates_superseded_by_template_id_environment_custom_image_templates_id_fk": {
+ "name": "environment_custom_image_templates_superseded_by_template_id_environment_custom_image_templates_id_fk",
+ "tableFrom": "environment_custom_image_templates",
+ "columnsFrom": [
+ "superseded_by_template_id"
+ ],
+ "tableTo": "environment_custom_image_templates",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.environment_leases": {
+ "name": "environment_leases",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "environment_id": {
+ "name": "environment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "execution_workspace_id": {
+ "name": "execution_workspace_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "heartbeat_run_id": {
+ "name": "heartbeat_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "lease_policy": {
+ "name": "lease_policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'ephemeral'"
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_lease_id": {
+ "name": "provider_lease_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "acquired_at": {
+ "name": "acquired_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "last_used_at": {
+ "name": "last_used_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "released_at": {
+ "name": "released_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "failure_reason": {
+ "name": "failure_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cleanup_status": {
+ "name": "cleanup_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "environment_leases_company_environment_status_idx": {
+ "name": "environment_leases_company_environment_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "environment_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "environment_leases_company_execution_workspace_idx": {
+ "name": "environment_leases_company_execution_workspace_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "execution_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "environment_leases_company_issue_idx": {
+ "name": "environment_leases_company_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "environment_leases_heartbeat_run_idx": {
+ "name": "environment_leases_heartbeat_run_idx",
+ "columns": [
+ {
+ "expression": "heartbeat_run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "environment_leases_company_last_used_idx": {
+ "name": "environment_leases_company_last_used_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "last_used_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "environment_leases_provider_lease_idx": {
+ "name": "environment_leases_provider_lease_idx",
+ "columns": [
+ {
+ "expression": "provider_lease_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "environment_leases_company_id_companies_id_fk": {
+ "name": "environment_leases_company_id_companies_id_fk",
+ "tableFrom": "environment_leases",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "environment_leases_environment_id_environments_id_fk": {
+ "name": "environment_leases_environment_id_environments_id_fk",
+ "tableFrom": "environment_leases",
+ "columnsFrom": [
+ "environment_id"
+ ],
+ "tableTo": "environments",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "environment_leases_execution_workspace_id_execution_workspaces_id_fk": {
+ "name": "environment_leases_execution_workspace_id_execution_workspaces_id_fk",
+ "tableFrom": "environment_leases",
+ "columnsFrom": [
+ "execution_workspace_id"
+ ],
+ "tableTo": "execution_workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "environment_leases_issue_id_issues_id_fk": {
+ "name": "environment_leases_issue_id_issues_id_fk",
+ "tableFrom": "environment_leases",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "environment_leases_heartbeat_run_id_heartbeat_runs_id_fk": {
+ "name": "environment_leases_heartbeat_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "environment_leases",
+ "columnsFrom": [
+ "heartbeat_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.environments": {
+ "name": "environments",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "driver": {
+ "name": "driver",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'local'"
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "config": {
+ "name": "config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "env_vars": {
+ "name": "env_vars",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "environments_status_idx": {
+ "name": "environments_status_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "environments_local_driver_idx": {
+ "name": "environments_local_driver_idx",
+ "columns": [
+ {
+ "expression": "driver",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"environments\".\"driver\" = 'local'",
+ "concurrently": false
+ },
+ "environments_managed_sandbox_idx": {
+ "name": "environments_managed_sandbox_idx",
+ "columns": [
+ {
+ "expression": "driver",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"environments\".\"driver\" = 'sandbox' AND (\"environments\".\"metadata\" ->> 'managedByPaperclip')::boolean = true",
+ "concurrently": false
+ },
+ "environments_name_idx": {
+ "name": "environments_name_idx",
+ "columns": [
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.execution_workspace_runtime_leases": {
+ "name": "execution_workspace_runtime_leases",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "execution_workspace_id": {
+ "name": "execution_workspace_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "owner_key": {
+ "name": "owner_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "owner_issue_id": {
+ "name": "owner_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "owner_run_id": {
+ "name": "owner_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "owner_agent_id": {
+ "name": "owner_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_action": {
+ "name": "last_action",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "claimed_at": {
+ "name": "claimed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "renewed_at": {
+ "name": "renewed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "execution_workspace_runtime_leases_company_workspace_idx": {
+ "name": "execution_workspace_runtime_leases_company_workspace_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "execution_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "execution_workspace_runtime_leases_company_owner_idx": {
+ "name": "execution_workspace_runtime_leases_company_owner_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "owner_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "execution_workspace_runtime_leases_expires_at_idx": {
+ "name": "execution_workspace_runtime_leases_expires_at_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "execution_workspace_runtime_leases_company_id_companies_id_fk": {
+ "name": "execution_workspace_runtime_leases_company_id_companies_id_fk",
+ "tableFrom": "execution_workspace_runtime_leases",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "execution_workspace_runtime_leases_execution_workspace_id_execution_workspaces_id_fk": {
+ "name": "execution_workspace_runtime_leases_execution_workspace_id_execution_workspaces_id_fk",
+ "tableFrom": "execution_workspace_runtime_leases",
+ "columnsFrom": [
+ "execution_workspace_id"
+ ],
+ "tableTo": "execution_workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "execution_workspace_runtime_leases_owner_issue_id_issues_id_fk": {
+ "name": "execution_workspace_runtime_leases_owner_issue_id_issues_id_fk",
+ "tableFrom": "execution_workspace_runtime_leases",
+ "columnsFrom": [
+ "owner_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "execution_workspace_runtime_leases_owner_run_id_heartbeat_runs_id_fk": {
+ "name": "execution_workspace_runtime_leases_owner_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "execution_workspace_runtime_leases",
+ "columnsFrom": [
+ "owner_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "execution_workspace_runtime_leases_owner_agent_id_agents_id_fk": {
+ "name": "execution_workspace_runtime_leases_owner_agent_id_agents_id_fk",
+ "tableFrom": "execution_workspace_runtime_leases",
+ "columnsFrom": [
+ "owner_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "execution_workspace_runtime_leases_execution_workspace_id_unique": {
+ "name": "execution_workspace_runtime_leases_execution_workspace_id_unique",
+ "columns": [
+ "execution_workspace_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.execution_workspaces": {
+ "name": "execution_workspaces",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_workspace_id": {
+ "name": "project_workspace_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_issue_id": {
+ "name": "source_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "mode": {
+ "name": "mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "strategy_type": {
+ "name": "strategy_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "cwd": {
+ "name": "cwd",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "repo_url": {
+ "name": "repo_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "base_ref": {
+ "name": "base_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "branch_name": {
+ "name": "branch_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_type": {
+ "name": "provider_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'local_fs'"
+ },
+ "provider_ref": {
+ "name": "provider_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "derived_from_execution_workspace_id": {
+ "name": "derived_from_execution_workspace_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_used_at": {
+ "name": "last_used_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "opened_at": {
+ "name": "opened_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "closed_at": {
+ "name": "closed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cleanup_eligible_at": {
+ "name": "cleanup_eligible_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cleanup_reason": {
+ "name": "cleanup_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "execution_workspaces_company_project_status_idx": {
+ "name": "execution_workspaces_company_project_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "execution_workspaces_company_project_workspace_status_idx": {
+ "name": "execution_workspaces_company_project_workspace_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "execution_workspaces_company_source_issue_idx": {
+ "name": "execution_workspaces_company_source_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "execution_workspaces_company_last_used_idx": {
+ "name": "execution_workspaces_company_last_used_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "last_used_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "execution_workspaces_company_branch_idx": {
+ "name": "execution_workspaces_company_branch_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "branch_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "execution_workspaces_company_id_companies_id_fk": {
+ "name": "execution_workspaces_company_id_companies_id_fk",
+ "tableFrom": "execution_workspaces",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "execution_workspaces_project_id_projects_id_fk": {
+ "name": "execution_workspaces_project_id_projects_id_fk",
+ "tableFrom": "execution_workspaces",
+ "columnsFrom": [
+ "project_id"
+ ],
+ "tableTo": "projects",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "execution_workspaces_project_workspace_id_project_workspaces_id_fk": {
+ "name": "execution_workspaces_project_workspace_id_project_workspaces_id_fk",
+ "tableFrom": "execution_workspaces",
+ "columnsFrom": [
+ "project_workspace_id"
+ ],
+ "tableTo": "project_workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "execution_workspaces_source_issue_id_issues_id_fk": {
+ "name": "execution_workspaces_source_issue_id_issues_id_fk",
+ "tableFrom": "execution_workspaces",
+ "columnsFrom": [
+ "source_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "execution_workspaces_derived_from_execution_workspace_id_execution_workspaces_id_fk": {
+ "name": "execution_workspaces_derived_from_execution_workspace_id_execution_workspaces_id_fk",
+ "tableFrom": "execution_workspaces",
+ "columnsFrom": [
+ "derived_from_execution_workspace_id"
+ ],
+ "tableTo": "execution_workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.external_object_mentions": {
+ "name": "external_object_mentions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_issue_id": {
+ "name": "source_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_kind": {
+ "name": "source_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_record_id": {
+ "name": "source_record_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "document_key": {
+ "name": "document_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "property_key": {
+ "name": "property_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "matched_text_redacted": {
+ "name": "matched_text_redacted",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sanitized_display_url": {
+ "name": "sanitized_display_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "canonical_identity_hash": {
+ "name": "canonical_identity_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "canonical_identity": {
+ "name": "canonical_identity",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "object_id": {
+ "name": "object_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_key": {
+ "name": "provider_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "detector_key": {
+ "name": "detector_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "object_type": {
+ "name": "object_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "confidence": {
+ "name": "confidence",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'exact'"
+ },
+ "created_by_plugin_id": {
+ "name": "created_by_plugin_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "external_object_mentions_company_source_issue_idx": {
+ "name": "external_object_mentions_company_source_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "external_object_mentions_company_object_idx": {
+ "name": "external_object_mentions_company_object_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "object_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "external_object_mentions_company_provider_idx": {
+ "name": "external_object_mentions_company_provider_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "object_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "external_object_mentions_company_source_record_uq": {
+ "name": "external_object_mentions_company_source_record_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_record_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "document_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "property_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "canonical_identity_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"external_object_mentions\".\"source_record_id\" is not null and \"external_object_mentions\".\"canonical_identity_hash\" is not null",
+ "concurrently": false
+ },
+ "external_object_mentions_company_source_null_record_uq": {
+ "name": "external_object_mentions_company_source_null_record_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "document_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "property_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "canonical_identity_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"external_object_mentions\".\"source_record_id\" is null and \"external_object_mentions\".\"canonical_identity_hash\" is not null",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "external_object_mentions_company_id_companies_id_fk": {
+ "name": "external_object_mentions_company_id_companies_id_fk",
+ "tableFrom": "external_object_mentions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "external_object_mentions_source_issue_id_issues_id_fk": {
+ "name": "external_object_mentions_source_issue_id_issues_id_fk",
+ "tableFrom": "external_object_mentions",
+ "columnsFrom": [
+ "source_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "external_object_mentions_object_id_external_objects_id_fk": {
+ "name": "external_object_mentions_object_id_external_objects_id_fk",
+ "tableFrom": "external_object_mentions",
+ "columnsFrom": [
+ "object_id"
+ ],
+ "tableTo": "external_objects",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "external_object_mentions_created_by_plugin_id_plugins_id_fk": {
+ "name": "external_object_mentions_created_by_plugin_id_plugins_id_fk",
+ "tableFrom": "external_object_mentions",
+ "columnsFrom": [
+ "created_by_plugin_id"
+ ],
+ "tableTo": "plugins",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.external_objects": {
+ "name": "external_objects",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_key": {
+ "name": "provider_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "plugin_id": {
+ "name": "plugin_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "object_type": {
+ "name": "object_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sanitized_canonical_url": {
+ "name": "sanitized_canonical_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "canonical_identity_hash": {
+ "name": "canonical_identity_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "display_key": {
+ "name": "display_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "icon_key": {
+ "name": "icon_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "display_title": {
+ "name": "display_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status_key": {
+ "name": "status_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status_label": {
+ "name": "status_label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status_icon_key": {
+ "name": "status_icon_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status_category": {
+ "name": "status_category",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'unknown'"
+ },
+ "status_tone": {
+ "name": "status_tone",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'neutral'"
+ },
+ "liveness": {
+ "name": "liveness",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'unknown'"
+ },
+ "is_terminal": {
+ "name": "is_terminal",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "data": {
+ "name": "data",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "remote_version": {
+ "name": "remote_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "etag": {
+ "name": "etag",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_resolved_at": {
+ "name": "last_resolved_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_changed_at": {
+ "name": "last_changed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error_at": {
+ "name": "last_error_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "next_refresh_at": {
+ "name": "next_refresh_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_started_at": {
+ "name": "refresh_started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_token": {
+ "name": "refresh_token",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error_code": {
+ "name": "last_error_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error_message": {
+ "name": "last_error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "external_objects_company_provider_object_idx": {
+ "name": "external_objects_company_provider_object_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "object_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "external_objects_company_provider_status_idx": {
+ "name": "external_objects_company_provider_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status_category",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "external_objects_company_refresh_idx": {
+ "name": "external_objects_company_refresh_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "next_refresh_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "external_objects_company_external_id_uq": {
+ "name": "external_objects_company_external_id_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "object_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "external_objects_company_identity_uq": {
+ "name": "external_objects_company_identity_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "object_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "canonical_identity_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "external_objects_company_id_companies_id_fk": {
+ "name": "external_objects_company_id_companies_id_fk",
+ "tableFrom": "external_objects",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "external_objects_plugin_id_plugins_id_fk": {
+ "name": "external_objects_plugin_id_plugins_id_fk",
+ "tableFrom": "external_objects",
+ "columnsFrom": [
+ "plugin_id"
+ ],
+ "tableTo": "plugins",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.feedback_exports": {
+ "name": "feedback_exports",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "feedback_vote_id": {
+ "name": "feedback_vote_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "author_user_id": {
+ "name": "author_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_type": {
+ "name": "target_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_id": {
+ "name": "target_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "vote": {
+ "name": "vote",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'local_only'"
+ },
+ "destination": {
+ "name": "destination",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "export_id": {
+ "name": "export_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "consent_version": {
+ "name": "consent_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "schema_version": {
+ "name": "schema_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'paperclip-feedback-envelope-v2'"
+ },
+ "bundle_version": {
+ "name": "bundle_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'paperclip-feedback-bundle-v2'"
+ },
+ "payload_version": {
+ "name": "payload_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'paperclip-feedback-v1'"
+ },
+ "payload_digest": {
+ "name": "payload_digest",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "payload_snapshot": {
+ "name": "payload_snapshot",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "target_summary": {
+ "name": "target_summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "redaction_summary": {
+ "name": "redaction_summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "attempt_count": {
+ "name": "attempt_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "last_attempted_at": {
+ "name": "last_attempted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "exported_at": {
+ "name": "exported_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "failure_reason": {
+ "name": "failure_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "feedback_exports_feedback_vote_idx": {
+ "name": "feedback_exports_feedback_vote_idx",
+ "columns": [
+ {
+ "expression": "feedback_vote_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "feedback_exports_company_created_idx": {
+ "name": "feedback_exports_company_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "feedback_exports_company_status_idx": {
+ "name": "feedback_exports_company_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "feedback_exports_company_issue_idx": {
+ "name": "feedback_exports_company_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "feedback_exports_company_project_idx": {
+ "name": "feedback_exports_company_project_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "feedback_exports_company_author_idx": {
+ "name": "feedback_exports_company_author_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "author_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "feedback_exports_company_id_companies_id_fk": {
+ "name": "feedback_exports_company_id_companies_id_fk",
+ "tableFrom": "feedback_exports",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "feedback_exports_feedback_vote_id_feedback_votes_id_fk": {
+ "name": "feedback_exports_feedback_vote_id_feedback_votes_id_fk",
+ "tableFrom": "feedback_exports",
+ "columnsFrom": [
+ "feedback_vote_id"
+ ],
+ "tableTo": "feedback_votes",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "feedback_exports_issue_id_issues_id_fk": {
+ "name": "feedback_exports_issue_id_issues_id_fk",
+ "tableFrom": "feedback_exports",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "feedback_exports_project_id_projects_id_fk": {
+ "name": "feedback_exports_project_id_projects_id_fk",
+ "tableFrom": "feedback_exports",
+ "columnsFrom": [
+ "project_id"
+ ],
+ "tableTo": "projects",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.feedback_votes": {
+ "name": "feedback_votes",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_type": {
+ "name": "target_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_id": {
+ "name": "target_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_user_id": {
+ "name": "author_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "vote": {
+ "name": "vote",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "reason": {
+ "name": "reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "shared_with_labs": {
+ "name": "shared_with_labs",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "shared_at": {
+ "name": "shared_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "consent_version": {
+ "name": "consent_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "redaction_summary": {
+ "name": "redaction_summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "feedback_votes_company_issue_idx": {
+ "name": "feedback_votes_company_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "feedback_votes_issue_target_idx": {
+ "name": "feedback_votes_issue_target_idx",
+ "columns": [
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "feedback_votes_author_idx": {
+ "name": "feedback_votes_author_idx",
+ "columns": [
+ {
+ "expression": "author_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "feedback_votes_company_target_author_idx": {
+ "name": "feedback_votes_company_target_author_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "author_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "feedback_votes_company_id_companies_id_fk": {
+ "name": "feedback_votes_company_id_companies_id_fk",
+ "tableFrom": "feedback_votes",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "feedback_votes_issue_id_issues_id_fk": {
+ "name": "feedback_votes_issue_id_issues_id_fk",
+ "tableFrom": "feedback_votes",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.finance_events": {
+ "name": "finance_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goal_id": {
+ "name": "goal_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "heartbeat_run_id": {
+ "name": "heartbeat_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cost_event_id": {
+ "name": "cost_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "billing_code": {
+ "name": "billing_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "event_kind": {
+ "name": "event_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "direction": {
+ "name": "direction",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'debit'"
+ },
+ "biller": {
+ "name": "biller",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "execution_adapter_type": {
+ "name": "execution_adapter_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "pricing_tier": {
+ "name": "pricing_tier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "region": {
+ "name": "region",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "model": {
+ "name": "model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "quantity": {
+ "name": "quantity",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "unit": {
+ "name": "unit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "currency": {
+ "name": "currency",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'USD'"
+ },
+ "estimated": {
+ "name": "estimated",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "external_invoice_id": {
+ "name": "external_invoice_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata_json": {
+ "name": "metadata_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "occurred_at": {
+ "name": "occurred_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "finance_events_company_receipt_idx": {
+ "name": "finance_events_company_receipt_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "finance_events_company_occurred_idx": {
+ "name": "finance_events_company_occurred_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "occurred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "finance_events_company_biller_occurred_idx": {
+ "name": "finance_events_company_biller_occurred_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "biller",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "occurred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "finance_events_company_kind_occurred_idx": {
+ "name": "finance_events_company_kind_occurred_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "event_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "occurred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "finance_events_company_direction_occurred_idx": {
+ "name": "finance_events_company_direction_occurred_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "direction",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "occurred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "finance_events_company_heartbeat_run_idx": {
+ "name": "finance_events_company_heartbeat_run_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "heartbeat_run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "finance_events_company_cost_event_idx": {
+ "name": "finance_events_company_cost_event_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "cost_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "finance_events_company_id_companies_id_fk": {
+ "name": "finance_events_company_id_companies_id_fk",
+ "tableFrom": "finance_events",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "finance_events_agent_id_agents_id_fk": {
+ "name": "finance_events_agent_id_agents_id_fk",
+ "tableFrom": "finance_events",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "finance_events_issue_id_issues_id_fk": {
+ "name": "finance_events_issue_id_issues_id_fk",
+ "tableFrom": "finance_events",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "finance_events_project_id_projects_id_fk": {
+ "name": "finance_events_project_id_projects_id_fk",
+ "tableFrom": "finance_events",
+ "columnsFrom": [
+ "project_id"
+ ],
+ "tableTo": "projects",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "finance_events_goal_id_goals_id_fk": {
+ "name": "finance_events_goal_id_goals_id_fk",
+ "tableFrom": "finance_events",
+ "columnsFrom": [
+ "goal_id"
+ ],
+ "tableTo": "goals",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "finance_events_heartbeat_run_id_heartbeat_runs_id_fk": {
+ "name": "finance_events_heartbeat_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "finance_events",
+ "columnsFrom": [
+ "heartbeat_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "finance_events_cost_event_id_cost_events_id_fk": {
+ "name": "finance_events_cost_event_id_cost_events_id_fk",
+ "tableFrom": "finance_events",
+ "columnsFrom": [
+ "cost_event_id"
+ ],
+ "tableTo": "cost_events",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.folders": {
+ "name": "folders",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parent_id": {
+ "name": "parent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "system_key": {
+ "name": "system_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "color": {
+ "name": "color",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "position": {
+ "name": "position",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "folders_company_kind_position_idx": {
+ "name": "folders_company_kind_position_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "position",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "folders_company_kind_root_slug_uq": {
+ "name": "folders_company_kind_root_slug_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "slug",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"folders\".\"parent_id\" is null",
+ "concurrently": false
+ },
+ "folders_company_kind_parent_slug_uq": {
+ "name": "folders_company_kind_parent_slug_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "parent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "slug",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"folders\".\"parent_id\" is not null",
+ "concurrently": false
+ },
+ "folders_company_kind_system_key_uq": {
+ "name": "folders_company_kind_system_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "system_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"folders\".\"system_key\" is not null",
+ "concurrently": false
+ },
+ "folders_company_kind_parent_position_idx": {
+ "name": "folders_company_kind_parent_position_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "parent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "position",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "folders_company_id_companies_id_fk": {
+ "name": "folders_company_id_companies_id_fk",
+ "tableFrom": "folders",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "folders_parent_id_folders_id_fk": {
+ "name": "folders_parent_id_folders_id_fk",
+ "tableFrom": "folders",
+ "columnsFrom": [
+ "parent_id"
+ ],
+ "tableTo": "folders",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "restrict"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.goals": {
+ "name": "goals",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "level": {
+ "name": "level",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'task'"
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'planned'"
+ },
+ "parent_id": {
+ "name": "parent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "owner_agent_id": {
+ "name": "owner_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "goals_company_idx": {
+ "name": "goals_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "goals_company_id_companies_id_fk": {
+ "name": "goals_company_id_companies_id_fk",
+ "tableFrom": "goals",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "goals_parent_id_goals_id_fk": {
+ "name": "goals_parent_id_goals_id_fk",
+ "tableFrom": "goals",
+ "columnsFrom": [
+ "parent_id"
+ ],
+ "tableTo": "goals",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "goals_owner_agent_id_agents_id_fk": {
+ "name": "goals_owner_agent_id_agents_id_fk",
+ "tableFrom": "goals",
+ "columnsFrom": [
+ "owner_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.heartbeat_run_events": {
+ "name": "heartbeat_run_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "seq": {
+ "name": "seq",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "event_type": {
+ "name": "event_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "stream": {
+ "name": "stream",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "level": {
+ "name": "level",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "color": {
+ "name": "color",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "message": {
+ "name": "message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "payload": {
+ "name": "payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_instance_id": {
+ "name": "source_instance_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_event_id": {
+ "name": "source_event_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_seq": {
+ "name": "source_seq",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_payload_sha256": {
+ "name": "source_payload_sha256",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "protocol_schema_version": {
+ "name": "protocol_schema_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "heartbeat_run_events_run_seq_uq": {
+ "name": "heartbeat_run_events_run_seq_uq",
+ "columns": [
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "seq",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "heartbeat_run_events_run_source_event_uq": {
+ "name": "heartbeat_run_events_run_source_event_uq",
+ "columns": [
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"heartbeat_run_events\".\"source_event_id\" is not null",
+ "concurrently": false
+ },
+ "heartbeat_run_events_run_source_seq_uq": {
+ "name": "heartbeat_run_events_run_source_seq_uq",
+ "columns": [
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_instance_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_seq",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"heartbeat_run_events\".\"source_instance_id\" is not null and \"heartbeat_run_events\".\"source_seq\" is not null",
+ "concurrently": false
+ },
+ "heartbeat_run_events_company_run_idx": {
+ "name": "heartbeat_run_events_company_run_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "heartbeat_run_events_company_created_idx": {
+ "name": "heartbeat_run_events_company_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "heartbeat_run_events_company_id_companies_id_fk": {
+ "name": "heartbeat_run_events_company_id_companies_id_fk",
+ "tableFrom": "heartbeat_run_events",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "heartbeat_run_events_run_id_heartbeat_runs_id_fk": {
+ "name": "heartbeat_run_events_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "heartbeat_run_events",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "heartbeat_run_events_agent_id_agents_id_fk": {
+ "name": "heartbeat_run_events_agent_id_agents_id_fk",
+ "tableFrom": "heartbeat_run_events",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.heartbeat_run_watchdog_decisions": {
+ "name": "heartbeat_run_watchdog_decisions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "evaluation_issue_id": {
+ "name": "evaluation_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "decision": {
+ "name": "decision",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "snoozed_until": {
+ "name": "snoozed_until",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "reason": {
+ "name": "reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_run_id": {
+ "name": "created_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "heartbeat_run_watchdog_decisions_company_run_created_idx": {
+ "name": "heartbeat_run_watchdog_decisions_company_run_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "heartbeat_run_watchdog_decisions_company_run_snooze_idx": {
+ "name": "heartbeat_run_watchdog_decisions_company_run_snooze_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "snoozed_until",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "heartbeat_run_watchdog_decisions_company_id_companies_id_fk": {
+ "name": "heartbeat_run_watchdog_decisions_company_id_companies_id_fk",
+ "tableFrom": "heartbeat_run_watchdog_decisions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "heartbeat_run_watchdog_decisions_run_id_heartbeat_runs_id_fk": {
+ "name": "heartbeat_run_watchdog_decisions_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "heartbeat_run_watchdog_decisions",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "heartbeat_run_watchdog_decisions_evaluation_issue_id_issues_id_fk": {
+ "name": "heartbeat_run_watchdog_decisions_evaluation_issue_id_issues_id_fk",
+ "tableFrom": "heartbeat_run_watchdog_decisions",
+ "columnsFrom": [
+ "evaluation_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "heartbeat_run_watchdog_decisions_created_by_agent_id_agents_id_fk": {
+ "name": "heartbeat_run_watchdog_decisions_created_by_agent_id_agents_id_fk",
+ "tableFrom": "heartbeat_run_watchdog_decisions",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "heartbeat_run_watchdog_decisions_created_by_run_id_heartbeat_runs_id_fk": {
+ "name": "heartbeat_run_watchdog_decisions_created_by_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "heartbeat_run_watchdog_decisions",
+ "columnsFrom": [
+ "created_by_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.heartbeat_runs": {
+ "name": "heartbeat_runs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope_kind": {
+ "name": "scope_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'company'"
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "invocation_source": {
+ "name": "invocation_source",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'on_demand'"
+ },
+ "trigger_detail": {
+ "name": "trigger_detail",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'queued'"
+ },
+ "responsible_user_id": {
+ "name": "responsible_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "active_identity_context_id": {
+ "name": "active_identity_context_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "finished_at": {
+ "name": "finished_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "execution_control_deadline_at": {
+ "name": "execution_control_deadline_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "execution_status_delivery_id": {
+ "name": "execution_status_delivery_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "wakeup_request_id": {
+ "name": "wakeup_request_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "exit_code": {
+ "name": "exit_code",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "signal": {
+ "name": "signal",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cost_accounting_pending": {
+ "name": "cost_accounting_pending",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "cost_accounted_at": {
+ "name": "cost_accounted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_projection_version": {
+ "name": "accounting_projection_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_last_attempt_at": {
+ "name": "accounting_last_attempt_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_last_error": {
+ "name": "accounting_last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_attempt_count": {
+ "name": "accounting_attempt_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "usage_json": {
+ "name": "usage_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "result_json": {
+ "name": "result_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "runtime_mode": {
+ "name": "runtime_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'legacy'"
+ },
+ "runtime_mode_resolver_version": {
+ "name": "runtime_mode_resolver_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "runtime_mode_reason": {
+ "name": "runtime_mode_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "runtime_mode_resolved_at": {
+ "name": "runtime_mode_resolved_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "runner_profile_json": {
+ "name": "runner_profile_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "runner_instance_id": {
+ "name": "runner_instance_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "native_session_id": {
+ "name": "native_session_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "native_issue_id": {
+ "name": "native_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "driver_kind": {
+ "name": "driver_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "driver_version": {
+ "name": "driver_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completion_contract_id": {
+ "name": "completion_contract_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completion_contract_sha256": {
+ "name": "completion_contract_sha256",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "next_event_seq": {
+ "name": "next_event_seq",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "native_phase": {
+ "name": "native_phase",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "native_phase_updated_at": {
+ "name": "native_phase_updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "session_id_before": {
+ "name": "session_id_before",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "session_id_after": {
+ "name": "session_id_after",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "log_store": {
+ "name": "log_store",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "log_ref": {
+ "name": "log_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "log_bytes": {
+ "name": "log_bytes",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "log_sha256": {
+ "name": "log_sha256",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "log_compressed": {
+ "name": "log_compressed",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "stdout_excerpt": {
+ "name": "stdout_excerpt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "stderr_excerpt": {
+ "name": "stderr_excerpt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error_code": {
+ "name": "error_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "external_run_id": {
+ "name": "external_run_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "controller_boot_id": {
+ "name": "controller_boot_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "controller_lease_expires_at": {
+ "name": "controller_lease_expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "execution_stage": {
+ "name": "execution_stage",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "process_pid": {
+ "name": "process_pid",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "process_group_id": {
+ "name": "process_group_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "process_started_at": {
+ "name": "process_started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_output_at": {
+ "name": "last_output_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_output_seq": {
+ "name": "last_output_seq",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "last_output_stream": {
+ "name": "last_output_stream",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_output_bytes": {
+ "name": "last_output_bytes",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "retry_of_run_id": {
+ "name": "retry_of_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "process_loss_retry_count": {
+ "name": "process_loss_retry_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "scheduled_retry_at": {
+ "name": "scheduled_retry_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scheduled_retry_attempt": {
+ "name": "scheduled_retry_attempt",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "scheduled_retry_reason": {
+ "name": "scheduled_retry_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_comment_status": {
+ "name": "issue_comment_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'not_applicable'"
+ },
+ "issue_comment_satisfied_by_comment_id": {
+ "name": "issue_comment_satisfied_by_comment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_comment_retry_queued_at": {
+ "name": "issue_comment_retry_queued_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "liveness_state": {
+ "name": "liveness_state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "liveness_reason": {
+ "name": "liveness_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "continuation_attempt": {
+ "name": "continuation_attempt",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "last_useful_action_at": {
+ "name": "last_useful_action_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "next_action": {
+ "name": "next_action",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "context_snapshot": {
+ "name": "context_snapshot",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "heartbeat_runs_cost_accounting_pending_idx": {
+ "name": "heartbeat_runs_cost_accounting_pending_idx",
+ "columns": [
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "where": "\"heartbeat_runs\".\"cost_accounting_pending\" = true",
+ "concurrently": false
+ },
+ "heartbeat_runs_execution_status_delivery_idx": {
+ "name": "heartbeat_runs_execution_status_delivery_idx",
+ "columns": [
+ {
+ "expression": "execution_status_delivery_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "where": "\"heartbeat_runs\".\"execution_status_delivery_id\" is not null",
+ "concurrently": false
+ },
+ "heartbeat_runs_execution_control_deadline_idx": {
+ "name": "heartbeat_runs_execution_control_deadline_idx",
+ "columns": [
+ {
+ "expression": "execution_control_deadline_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "where": "\"heartbeat_runs\".\"execution_control_deadline_at\" is not null",
+ "concurrently": false
+ },
+ "heartbeat_runs_native_replacement_predecessor_uq": {
+ "name": "heartbeat_runs_native_replacement_predecessor_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "retry_of_run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"heartbeat_runs\".\"scheduled_retry_reason\" = 'native_safe_replacement'",
+ "concurrently": false
+ },
+ "heartbeat_runs_company_agent_started_idx": {
+ "name": "heartbeat_runs_company_agent_started_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "heartbeat_runs_company_issue_created_idx": {
+ "name": "heartbeat_runs_company_issue_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "heartbeat_runs_company_responsible_user_idx": {
+ "name": "heartbeat_runs_company_responsible_user_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "responsible_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "heartbeat_runs_company_liveness_idx": {
+ "name": "heartbeat_runs_company_liveness_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "liveness_state",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "heartbeat_runs_company_status_last_output_idx": {
+ "name": "heartbeat_runs_company_status_last_output_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "last_output_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "heartbeat_runs_company_status_process_started_idx": {
+ "name": "heartbeat_runs_company_status_process_started_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "process_started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "heartbeat_runs_company_created_at_desc_idx": {
+ "name": "heartbeat_runs_company_created_at_desc_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": false,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "heartbeat_runs_company_ctx_issue_created_idx": {
+ "name": "heartbeat_runs_company_ctx_issue_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "(\"context_snapshot\" ->> 'issueId')",
+ "isExpression": true,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": false,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "heartbeat_runs_company_ctx_task_created_idx": {
+ "name": "heartbeat_runs_company_ctx_task_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "(\"context_snapshot\" ->> 'taskId')",
+ "isExpression": true,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": false,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "heartbeat_runs_company_ctx_taskkey_created_idx": {
+ "name": "heartbeat_runs_company_ctx_taskkey_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "(\"context_snapshot\" ->> 'taskKey')",
+ "isExpression": true,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": false,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "heartbeat_runs_company_id_companies_id_fk": {
+ "name": "heartbeat_runs_company_id_companies_id_fk",
+ "tableFrom": "heartbeat_runs",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "heartbeat_runs_agent_id_agents_id_fk": {
+ "name": "heartbeat_runs_agent_id_agents_id_fk",
+ "tableFrom": "heartbeat_runs",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "heartbeat_runs_issue_id_issues_id_fk": {
+ "name": "heartbeat_runs_issue_id_issues_id_fk",
+ "tableFrom": "heartbeat_runs",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "heartbeat_runs_wakeup_request_id_agent_wakeup_requests_id_fk": {
+ "name": "heartbeat_runs_wakeup_request_id_agent_wakeup_requests_id_fk",
+ "tableFrom": "heartbeat_runs",
+ "columnsFrom": [
+ "wakeup_request_id"
+ ],
+ "tableTo": "agent_wakeup_requests",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "heartbeat_runs_retry_of_run_id_heartbeat_runs_id_fk": {
+ "name": "heartbeat_runs_retry_of_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "heartbeat_runs",
+ "columnsFrom": [
+ "retry_of_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "heartbeat_runs_company_native_issue_id_uq": {
+ "name": "heartbeat_runs_company_native_issue_id_uq",
+ "columns": [
+ "company_id",
+ "native_issue_id",
+ "id"
+ ],
+ "nullsNotDistinct": false
+ },
+ "heartbeat_runs_company_native_issue_contract_id_uq": {
+ "name": "heartbeat_runs_company_native_issue_contract_id_uq",
+ "columns": [
+ "company_id",
+ "native_issue_id",
+ "id",
+ "completion_contract_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {
+ "heartbeat_runs_scope_binding_check": {
+ "name": "heartbeat_runs_scope_binding_check",
+ "value": "(\"heartbeat_runs\".\"scope_kind\" = 'company' AND \"heartbeat_runs\".\"issue_id\" IS NULL)\n OR \"heartbeat_runs\".\"scope_kind\" = 'issue'"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.inbox_dismissals": {
+ "name": "inbox_dismissals",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "item_key": {
+ "name": "item_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'dismiss'"
+ },
+ "dismissed_at": {
+ "name": "dismissed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "snoozed_until": {
+ "name": "snoozed_until",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "inbox_dismissals_company_user_idx": {
+ "name": "inbox_dismissals_company_user_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "inbox_dismissals_company_item_idx": {
+ "name": "inbox_dismissals_company_item_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "item_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "inbox_dismissals_company_user_item_idx": {
+ "name": "inbox_dismissals_company_user_item_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "item_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "inbox_dismissals_company_id_companies_id_fk": {
+ "name": "inbox_dismissals_company_id_companies_id_fk",
+ "tableFrom": "inbox_dismissals",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.connection_grant_delegations": {
+ "name": "connection_grant_delegations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "grant_id": {
+ "name": "grant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "connection_grant_delegations_company_agent_idx": {
+ "name": "connection_grant_delegations_company_agent_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "connection_grant_delegations_grant_agent_uq": {
+ "name": "connection_grant_delegations_grant_agent_uq",
+ "columns": [
+ {
+ "expression": "grant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "connection_grant_delegations_company_id_companies_id_fk": {
+ "name": "connection_grant_delegations_company_id_companies_id_fk",
+ "tableFrom": "connection_grant_delegations",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "connection_grant_delegations_agent_id_agents_id_fk": {
+ "name": "connection_grant_delegations_agent_id_agents_id_fk",
+ "tableFrom": "connection_grant_delegations",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "connection_grant_delegations_company_grant_fk": {
+ "name": "connection_grant_delegations_company_grant_fk",
+ "tableFrom": "connection_grant_delegations",
+ "columnsFrom": [
+ "company_id",
+ "grant_id"
+ ],
+ "tableTo": "connection_grants",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.connection_grant_members": {
+ "name": "connection_grant_members",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "grant_id": {
+ "name": "grant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_type": {
+ "name": "subject_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_id": {
+ "name": "subject_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "connection_grant_members_company_subject_idx": {
+ "name": "connection_grant_members_company_subject_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "connection_grant_members_grant_subject_uq": {
+ "name": "connection_grant_members_grant_subject_uq",
+ "columns": [
+ {
+ "expression": "grant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "connection_grant_members_company_id_companies_id_fk": {
+ "name": "connection_grant_members_company_id_companies_id_fk",
+ "tableFrom": "connection_grant_members",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "connection_grant_members_company_grant_fk": {
+ "name": "connection_grant_members_company_grant_fk",
+ "tableFrom": "connection_grant_members",
+ "columnsFrom": [
+ "company_id",
+ "grant_id"
+ ],
+ "tableTo": "connection_grants",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "connection_grant_members_subject_type_check": {
+ "name": "connection_grant_members_subject_type_check",
+ "value": "\"connection_grant_members\".\"subject_type\" in ('user')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.connection_grants": {
+ "name": "connection_grants",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_user_id": {
+ "name": "subject_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "subject_agent_id": {
+ "name": "subject_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_tenant": {
+ "name": "provider_tenant",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "credential_secret_refs": {
+ "name": "credential_secret_refs",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "external_credential": {
+ "name": "external_credential",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "is_default": {
+ "name": "is_default",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revoked_by_agent_id": {
+ "name": "revoked_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revoked_by_user_id": {
+ "name": "revoked_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_used_at": {
+ "name": "last_used_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "connection_grants_company_connection_idx": {
+ "name": "connection_grants_company_connection_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "connection_grants_subject_user_idx": {
+ "name": "connection_grants_subject_user_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "connection_grants_subject_agent_idx": {
+ "name": "connection_grants_subject_agent_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "connection_grants_user_uq": {
+ "name": "connection_grants_user_uq",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "connection_grants_agent_uq": {
+ "name": "connection_grants_agent_uq",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "connection_grants_default_uq": {
+ "name": "connection_grants_default_uq",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"connection_grants\".\"is_default\" = true and \"connection_grants\".\"kind\" = 'organization'",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "connection_grants_company_id_companies_id_fk": {
+ "name": "connection_grants_company_id_companies_id_fk",
+ "tableFrom": "connection_grants",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "connection_grants_subject_agent_id_agents_id_fk": {
+ "name": "connection_grants_subject_agent_id_agents_id_fk",
+ "tableFrom": "connection_grants",
+ "columnsFrom": [
+ "subject_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "connection_grants_created_by_agent_id_agents_id_fk": {
+ "name": "connection_grants_created_by_agent_id_agents_id_fk",
+ "tableFrom": "connection_grants",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "connection_grants_revoked_by_agent_id_agents_id_fk": {
+ "name": "connection_grants_revoked_by_agent_id_agents_id_fk",
+ "tableFrom": "connection_grants",
+ "columnsFrom": [
+ "revoked_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "connection_grants_company_connection_fk": {
+ "name": "connection_grants_company_connection_fk",
+ "tableFrom": "connection_grants",
+ "columnsFrom": [
+ "company_id",
+ "connection_id"
+ ],
+ "tableTo": "tool_connections",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "connection_grants_company_id_uq": {
+ "name": "connection_grants_company_id_uq",
+ "columns": [
+ "company_id",
+ "id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {
+ "connection_grants_kind_check": {
+ "name": "connection_grants_kind_check",
+ "value": "\"connection_grants\".\"kind\" in ('organization', 'user', 'agent')"
+ },
+ "connection_grants_status_check": {
+ "name": "connection_grants_status_check",
+ "value": "\"connection_grants\".\"status\" in ('active', 'revoked', 'expired', 'needs_reauthorization')"
+ },
+ "connection_grants_credential_source_one_of_check": {
+ "name": "connection_grants_credential_source_one_of_check",
+ "value": "\"connection_grants\".\"external_credential\" is null or jsonb_array_length(\"connection_grants\".\"credential_secret_refs\") = 0"
+ },
+ "connection_grants_subject_check": {
+ "name": "connection_grants_subject_check",
+ "value": "(\"connection_grants\".\"kind\" = 'user' and \"connection_grants\".\"subject_user_id\" is not null and \"connection_grants\".\"subject_agent_id\" is null) or (\"connection_grants\".\"kind\" = 'agent' and \"connection_grants\".\"subject_agent_id\" is not null and \"connection_grants\".\"subject_user_id\" is null) or (\"connection_grants\".\"kind\" = 'organization' and \"connection_grants\".\"subject_user_id\" is null and \"connection_grants\".\"subject_agent_id\" is null)"
+ },
+ "connection_grants_default_check": {
+ "name": "connection_grants_default_check",
+ "value": "\"connection_grants\".\"is_default\" = false or \"connection_grants\".\"kind\" = 'organization'"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.connection_token_issuances": {
+ "name": "connection_token_issuances",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "application_id": {
+ "name": "application_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "responsible_user_id": {
+ "name": "responsible_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "path": {
+ "name": "path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "requested_scope": {
+ "name": "requested_scope",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "issued_scope": {
+ "name": "issued_scope",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "ttl_seconds": {
+ "name": "ttl_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "outcome": {
+ "name": "outcome",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "error_code": {
+ "name": "error_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "connection_token_issuances_company_created_idx": {
+ "name": "connection_token_issuances_company_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "connection_token_issuances_connection_created_idx": {
+ "name": "connection_token_issuances_connection_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "connection_token_issuances_agent_connection_idx": {
+ "name": "connection_token_issuances_agent_connection_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "connection_token_issuances_run_idx": {
+ "name": "connection_token_issuances_run_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "connection_token_issuances_company_id_companies_id_fk": {
+ "name": "connection_token_issuances_company_id_companies_id_fk",
+ "tableFrom": "connection_token_issuances",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "connection_token_issuances_application_id_tool_applications_id_fk": {
+ "name": "connection_token_issuances_application_id_tool_applications_id_fk",
+ "tableFrom": "connection_token_issuances",
+ "columnsFrom": [
+ "application_id"
+ ],
+ "tableTo": "tool_applications",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "connection_token_issuances_connection_id_tool_connections_id_fk": {
+ "name": "connection_token_issuances_connection_id_tool_connections_id_fk",
+ "tableFrom": "connection_token_issuances",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "tableTo": "tool_connections",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "connection_token_issuances_agent_id_agents_id_fk": {
+ "name": "connection_token_issuances_agent_id_agents_id_fk",
+ "tableFrom": "connection_token_issuances",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "connection_token_issuances_run_id_heartbeat_runs_id_fk": {
+ "name": "connection_token_issuances_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "connection_token_issuances",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "connection_token_issuances_issue_id_issues_id_fk": {
+ "name": "connection_token_issuances_issue_id_issues_id_fk",
+ "tableFrom": "connection_token_issuances",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "connection_token_issuances_project_id_projects_id_fk": {
+ "name": "connection_token_issuances_project_id_projects_id_fk",
+ "tableFrom": "connection_token_issuances",
+ "columnsFrom": [
+ "project_id"
+ ],
+ "tableTo": "projects",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.instance_settings": {
+ "name": "instance_settings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "singleton_key": {
+ "name": "singleton_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'default'"
+ },
+ "default_environment_id": {
+ "name": "default_environment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "general": {
+ "name": "general",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "experimental": {
+ "name": "experimental",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "instance_settings_singleton_key_idx": {
+ "name": "instance_settings_singleton_key_idx",
+ "columns": [
+ {
+ "expression": "singleton_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "instance_settings_default_environment_id_environments_id_fk": {
+ "name": "instance_settings_default_environment_id_environments_id_fk",
+ "tableFrom": "instance_settings",
+ "columnsFrom": [
+ "default_environment_id"
+ ],
+ "tableTo": "environments",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.instance_user_roles": {
+ "name": "instance_user_roles",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'instance_admin'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "instance_user_roles_user_role_unique_idx": {
+ "name": "instance_user_roles_user_role_unique_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "role",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "instance_user_roles_role_idx": {
+ "name": "instance_user_roles_role_idx",
+ "columns": [
+ {
+ "expression": "role",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.invites": {
+ "name": "invites",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "invite_type": {
+ "name": "invite_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'company_join'"
+ },
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "allowed_join_types": {
+ "name": "allowed_join_types",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'both'"
+ },
+ "defaults_payload": {
+ "name": "defaults_payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "invited_by_user_id": {
+ "name": "invited_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accepted_at": {
+ "name": "accepted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "invites_token_hash_unique_idx": {
+ "name": "invites_token_hash_unique_idx",
+ "columns": [
+ {
+ "expression": "token_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "invites_company_invite_state_idx": {
+ "name": "invites_company_invite_state_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "invite_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "revoked_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "invites_company_id_companies_id_fk": {
+ "name": "invites_company_id_companies_id_fk",
+ "tableFrom": "invites",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.issue_access_grants": {
+ "name": "issue_access_grants",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_type": {
+ "name": "subject_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_id": {
+ "name": "subject_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source": {
+ "name": "source",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "granted_by_user_id": {
+ "name": "granted_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "granted_by_agent_id": {
+ "name": "granted_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "issue_access_grants_subject_active_issue_idx": {
+ "name": "issue_access_grants_subject_active_issue_idx",
+ "columns": [
+ {
+ "expression": "subject_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "revoked_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_access_grants_issue_idx": {
+ "name": "issue_access_grants_issue_idx",
+ "columns": [
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "issue_access_grants_issue_id_issues_id_fk": {
+ "name": "issue_access_grants_issue_id_issues_id_fk",
+ "tableFrom": "issue_access_grants",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_access_grants_granted_by_agent_id_agents_id_fk": {
+ "name": "issue_access_grants_granted_by_agent_id_agents_id_fk",
+ "tableFrom": "issue_access_grants",
+ "columnsFrom": [
+ "granted_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "issue_access_grants_subject_type_check": {
+ "name": "issue_access_grants_subject_type_check",
+ "value": "\"issue_access_grants\".\"subject_type\" in ('user', 'agent')"
+ },
+ "issue_access_grants_source_check": {
+ "name": "issue_access_grants_source_check",
+ "value": "\"issue_access_grants\".\"source\" in ('explicit', 'assignment', 'project')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.issue_approvals": {
+ "name": "issue_approvals",
+ "schema": "",
+ "columns": {
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "approval_id": {
+ "name": "approval_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "linked_by_agent_id": {
+ "name": "linked_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "linked_by_user_id": {
+ "name": "linked_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "issue_approvals_issue_idx": {
+ "name": "issue_approvals_issue_idx",
+ "columns": [
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_approvals_approval_idx": {
+ "name": "issue_approvals_approval_idx",
+ "columns": [
+ {
+ "expression": "approval_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_approvals_company_idx": {
+ "name": "issue_approvals_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "issue_approvals_company_id_companies_id_fk": {
+ "name": "issue_approvals_company_id_companies_id_fk",
+ "tableFrom": "issue_approvals",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issue_approvals_issue_id_issues_id_fk": {
+ "name": "issue_approvals_issue_id_issues_id_fk",
+ "tableFrom": "issue_approvals",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_approvals_approval_id_approvals_id_fk": {
+ "name": "issue_approvals_approval_id_approvals_id_fk",
+ "tableFrom": "issue_approvals",
+ "columnsFrom": [
+ "approval_id"
+ ],
+ "tableTo": "approvals",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_approvals_linked_by_agent_id_agents_id_fk": {
+ "name": "issue_approvals_linked_by_agent_id_agents_id_fk",
+ "tableFrom": "issue_approvals",
+ "columnsFrom": [
+ "linked_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {
+ "issue_approvals_pk": {
+ "name": "issue_approvals_pk",
+ "columns": [
+ "issue_id",
+ "approval_id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.issue_attachments": {
+ "name": "issue_attachments",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "asset_id": {
+ "name": "asset_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_comment_id": {
+ "name": "issue_comment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "originating_run_id": {
+ "name": "originating_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "issue_attachments_company_issue_idx": {
+ "name": "issue_attachments_company_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_attachments_issue_comment_idx": {
+ "name": "issue_attachments_issue_comment_idx",
+ "columns": [
+ {
+ "expression": "issue_comment_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_attachments_originating_run_idx": {
+ "name": "issue_attachments_originating_run_idx",
+ "columns": [
+ {
+ "expression": "originating_run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_attachments_asset_uq": {
+ "name": "issue_attachments_asset_uq",
+ "columns": [
+ {
+ "expression": "asset_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "issue_attachments_company_id_companies_id_fk": {
+ "name": "issue_attachments_company_id_companies_id_fk",
+ "tableFrom": "issue_attachments",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issue_attachments_issue_id_issues_id_fk": {
+ "name": "issue_attachments_issue_id_issues_id_fk",
+ "tableFrom": "issue_attachments",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_attachments_asset_id_assets_id_fk": {
+ "name": "issue_attachments_asset_id_assets_id_fk",
+ "tableFrom": "issue_attachments",
+ "columnsFrom": [
+ "asset_id"
+ ],
+ "tableTo": "assets",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_attachments_issue_comment_id_issue_comments_id_fk": {
+ "name": "issue_attachments_issue_comment_id_issue_comments_id_fk",
+ "tableFrom": "issue_attachments",
+ "columnsFrom": [
+ "issue_comment_id"
+ ],
+ "tableTo": "issue_comments",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_attachments_originating_run_id_heartbeat_runs_id_fk": {
+ "name": "issue_attachments_originating_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "issue_attachments",
+ "columnsFrom": [
+ "originating_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.issue_comments": {
+ "name": "issue_comments",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_agent_id": {
+ "name": "author_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "author_user_id": {
+ "name": "author_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "on_behalf_of_user_id": {
+ "name": "on_behalf_of_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "author_type": {
+ "name": "author_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_run_id": {
+ "name": "created_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "derived_author_agent_id": {
+ "name": "derived_author_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "derived_created_by_run_id": {
+ "name": "derived_created_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "derived_author_source": {
+ "name": "derived_author_source",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "client_request_id": {
+ "name": "client_request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "conversation_session_generation": {
+ "name": "conversation_session_generation",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "body": {
+ "name": "body",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "presentation": {
+ "name": "presentation",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_by_type": {
+ "name": "deleted_by_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_by_agent_id": {
+ "name": "deleted_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_by_user_id": {
+ "name": "deleted_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_by_run_id": {
+ "name": "deleted_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_trust": {
+ "name": "source_trust",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "issue_comments_issue_idx": {
+ "name": "issue_comments_issue_idx",
+ "columns": [
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_comments_company_idx": {
+ "name": "issue_comments_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_comments_company_issue_created_at_idx": {
+ "name": "issue_comments_company_issue_created_at_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_comments_company_author_issue_created_at_idx": {
+ "name": "issue_comments_company_author_issue_created_at_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "author_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_comments_body_search_idx": {
+ "name": "issue_comments_body_search_idx",
+ "columns": [
+ {
+ "expression": "body",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "gin_trgm_ops"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "gin",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "issue_comments_company_id_companies_id_fk": {
+ "name": "issue_comments_company_id_companies_id_fk",
+ "tableFrom": "issue_comments",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issue_comments_issue_id_issues_id_fk": {
+ "name": "issue_comments_issue_id_issues_id_fk",
+ "tableFrom": "issue_comments",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_comments_author_agent_id_agents_id_fk": {
+ "name": "issue_comments_author_agent_id_agents_id_fk",
+ "tableFrom": "issue_comments",
+ "columnsFrom": [
+ "author_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issue_comments_on_behalf_of_user_id_user_id_fk": {
+ "name": "issue_comments_on_behalf_of_user_id_user_id_fk",
+ "tableFrom": "issue_comments",
+ "columnsFrom": [
+ "on_behalf_of_user_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_comments_created_by_run_id_heartbeat_runs_id_fk": {
+ "name": "issue_comments_created_by_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "issue_comments",
+ "columnsFrom": [
+ "created_by_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_comments_derived_author_agent_id_agents_id_fk": {
+ "name": "issue_comments_derived_author_agent_id_agents_id_fk",
+ "tableFrom": "issue_comments",
+ "columnsFrom": [
+ "derived_author_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_comments_derived_created_by_run_id_heartbeat_runs_id_fk": {
+ "name": "issue_comments_derived_created_by_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "issue_comments",
+ "columnsFrom": [
+ "derived_created_by_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_comments_deleted_by_agent_id_agents_id_fk": {
+ "name": "issue_comments_deleted_by_agent_id_agents_id_fk",
+ "tableFrom": "issue_comments",
+ "columnsFrom": [
+ "deleted_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_comments_deleted_by_run_id_heartbeat_runs_id_fk": {
+ "name": "issue_comments_deleted_by_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "issue_comments",
+ "columnsFrom": [
+ "deleted_by_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "issue_comments_client_request_uq": {
+ "name": "issue_comments_client_request_uq",
+ "columns": [
+ "issue_id",
+ "author_user_id",
+ "client_request_id"
+ ],
+ "nullsNotDistinct": false
+ },
+ "issue_comments_company_id_uq": {
+ "name": "issue_comments_company_id_uq",
+ "columns": [
+ "company_id",
+ "id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.issue_create_idempotency_keys": {
+ "name": "issue_create_idempotency_keys",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "issue_create_idempotency_keys_company_key_uq": {
+ "name": "issue_create_idempotency_keys_company_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_create_idempotency_keys_issue_idx": {
+ "name": "issue_create_idempotency_keys_issue_idx",
+ "columns": [
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_create_idempotency_keys_company_created_at_idx": {
+ "name": "issue_create_idempotency_keys_company_created_at_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "issue_create_idempotency_keys_company_id_companies_id_fk": {
+ "name": "issue_create_idempotency_keys_company_id_companies_id_fk",
+ "tableFrom": "issue_create_idempotency_keys",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_create_idempotency_keys_issue_id_issues_id_fk": {
+ "name": "issue_create_idempotency_keys_issue_id_issues_id_fk",
+ "tableFrom": "issue_create_idempotency_keys",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.issue_documents": {
+ "name": "issue_documents",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "issue_documents_company_issue_key_uq": {
+ "name": "issue_documents_company_issue_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_documents_document_uq": {
+ "name": "issue_documents_document_uq",
+ "columns": [
+ {
+ "expression": "document_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_documents_company_issue_updated_idx": {
+ "name": "issue_documents_company_issue_updated_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "issue_documents_company_id_companies_id_fk": {
+ "name": "issue_documents_company_id_companies_id_fk",
+ "tableFrom": "issue_documents",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issue_documents_issue_id_issues_id_fk": {
+ "name": "issue_documents_issue_id_issues_id_fk",
+ "tableFrom": "issue_documents",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_documents_document_id_documents_id_fk": {
+ "name": "issue_documents_document_id_documents_id_fk",
+ "tableFrom": "issue_documents",
+ "columnsFrom": [
+ "document_id"
+ ],
+ "tableTo": "documents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.issue_execution_decisions": {
+ "name": "issue_execution_decisions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "stage_id": {
+ "name": "stage_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "stage_type": {
+ "name": "stage_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_agent_id": {
+ "name": "actor_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "actor_user_id": {
+ "name": "actor_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "outcome": {
+ "name": "outcome",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "body": {
+ "name": "body",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_run_id": {
+ "name": "created_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "issue_execution_decisions_company_issue_idx": {
+ "name": "issue_execution_decisions_company_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_execution_decisions_stage_idx": {
+ "name": "issue_execution_decisions_stage_idx",
+ "columns": [
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "stage_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "issue_execution_decisions_company_id_companies_id_fk": {
+ "name": "issue_execution_decisions_company_id_companies_id_fk",
+ "tableFrom": "issue_execution_decisions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issue_execution_decisions_issue_id_issues_id_fk": {
+ "name": "issue_execution_decisions_issue_id_issues_id_fk",
+ "tableFrom": "issue_execution_decisions",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_execution_decisions_actor_agent_id_agents_id_fk": {
+ "name": "issue_execution_decisions_actor_agent_id_agents_id_fk",
+ "tableFrom": "issue_execution_decisions",
+ "columnsFrom": [
+ "actor_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issue_execution_decisions_created_by_run_id_heartbeat_runs_id_fk": {
+ "name": "issue_execution_decisions_created_by_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "issue_execution_decisions",
+ "columnsFrom": [
+ "created_by_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.issue_inbox_archives": {
+ "name": "issue_inbox_archives",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "archived_by_actor_type": {
+ "name": "archived_by_actor_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'user'"
+ },
+ "archived_by_agent_id": {
+ "name": "archived_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_by_run_id": {
+ "name": "archived_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "issue_inbox_archives_company_issue_idx": {
+ "name": "issue_inbox_archives_company_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_inbox_archives_company_user_idx": {
+ "name": "issue_inbox_archives_company_user_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_inbox_archives_company_issue_user_idx": {
+ "name": "issue_inbox_archives_company_issue_user_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "issue_inbox_archives_company_id_companies_id_fk": {
+ "name": "issue_inbox_archives_company_id_companies_id_fk",
+ "tableFrom": "issue_inbox_archives",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issue_inbox_archives_issue_id_issues_id_fk": {
+ "name": "issue_inbox_archives_issue_id_issues_id_fk",
+ "tableFrom": "issue_inbox_archives",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_inbox_archives_archived_by_agent_id_agents_id_fk": {
+ "name": "issue_inbox_archives_archived_by_agent_id_agents_id_fk",
+ "tableFrom": "issue_inbox_archives",
+ "columnsFrom": [
+ "archived_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_inbox_archives_archived_by_run_id_heartbeat_runs_id_fk": {
+ "name": "issue_inbox_archives_archived_by_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "issue_inbox_archives",
+ "columnsFrom": [
+ "archived_by_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "issue_inbox_archives_archived_by_actor_type_check": {
+ "name": "issue_inbox_archives_archived_by_actor_type_check",
+ "value": "\"issue_inbox_archives\".\"archived_by_actor_type\" in ('user', 'agent')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.issue_labels": {
+ "name": "issue_labels",
+ "schema": "",
+ "columns": {
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "label_id": {
+ "name": "label_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "issue_labels_issue_idx": {
+ "name": "issue_labels_issue_idx",
+ "columns": [
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_labels_label_idx": {
+ "name": "issue_labels_label_idx",
+ "columns": [
+ {
+ "expression": "label_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_labels_company_idx": {
+ "name": "issue_labels_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "issue_labels_issue_id_issues_id_fk": {
+ "name": "issue_labels_issue_id_issues_id_fk",
+ "tableFrom": "issue_labels",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_labels_label_id_labels_id_fk": {
+ "name": "issue_labels_label_id_labels_id_fk",
+ "tableFrom": "issue_labels",
+ "columnsFrom": [
+ "label_id"
+ ],
+ "tableTo": "labels",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_labels_company_id_companies_id_fk": {
+ "name": "issue_labels_company_id_companies_id_fk",
+ "tableFrom": "issue_labels",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {
+ "issue_labels_pk": {
+ "name": "issue_labels_pk",
+ "columns": [
+ "issue_id",
+ "label_id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.issue_plan_decompositions": {
+ "name": "issue_plan_decompositions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_issue_id": {
+ "name": "source_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "accepted_plan_revision_id": {
+ "name": "accepted_plan_revision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "accepted_interaction_id": {
+ "name": "accepted_interaction_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'in_flight'"
+ },
+ "request_fingerprint": {
+ "name": "request_fingerprint",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "requested_child_count": {
+ "name": "requested_child_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "requested_children": {
+ "name": "requested_children",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "child_issue_ids": {
+ "name": "child_issue_ids",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "owner_agent_id": {
+ "name": "owner_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "owner_user_id": {
+ "name": "owner_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "owner_run_id": {
+ "name": "owner_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "issue_plan_decompositions_company_source_status_idx": {
+ "name": "issue_plan_decompositions_company_source_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_plan_decompositions_active_owner_idx": {
+ "name": "issue_plan_decompositions_active_owner_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "owner_agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "where": "\"issue_plan_decompositions\".\"status\" = 'in_flight'",
+ "concurrently": false
+ },
+ "issue_plan_decompositions_source_revision_uq": {
+ "name": "issue_plan_decompositions_source_revision_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "accepted_plan_revision_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "issue_plan_decompositions_company_id_companies_id_fk": {
+ "name": "issue_plan_decompositions_company_id_companies_id_fk",
+ "tableFrom": "issue_plan_decompositions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issue_plan_decompositions_source_issue_id_issues_id_fk": {
+ "name": "issue_plan_decompositions_source_issue_id_issues_id_fk",
+ "tableFrom": "issue_plan_decompositions",
+ "columnsFrom": [
+ "source_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_plan_decompositions_accepted_plan_revision_id_document_revisions_id_fk": {
+ "name": "issue_plan_decompositions_accepted_plan_revision_id_document_revisions_id_fk",
+ "tableFrom": "issue_plan_decompositions",
+ "columnsFrom": [
+ "accepted_plan_revision_id"
+ ],
+ "tableTo": "document_revisions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_plan_decompositions_accepted_interaction_id_issue_thread_interactions_id_fk": {
+ "name": "issue_plan_decompositions_accepted_interaction_id_issue_thread_interactions_id_fk",
+ "tableFrom": "issue_plan_decompositions",
+ "columnsFrom": [
+ "accepted_interaction_id"
+ ],
+ "tableTo": "issue_thread_interactions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_plan_decompositions_owner_agent_id_agents_id_fk": {
+ "name": "issue_plan_decompositions_owner_agent_id_agents_id_fk",
+ "tableFrom": "issue_plan_decompositions",
+ "columnsFrom": [
+ "owner_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_plan_decompositions_owner_run_id_heartbeat_runs_id_fk": {
+ "name": "issue_plan_decompositions_owner_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "issue_plan_decompositions",
+ "columnsFrom": [
+ "owner_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.issue_question_response_deliveries": {
+ "name": "issue_question_response_deliveries",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "interaction_id": {
+ "name": "interaction_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_run_id": {
+ "name": "source_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "target_run_id": {
+ "name": "target_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "target_turn_id": {
+ "name": "target_turn_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "correlation_id": {
+ "name": "correlation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "payload_sha256": {
+ "name": "payload_sha256",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "delivery_mode": {
+ "name": "delivery_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "attempt_count": {
+ "name": "attempt_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "error_count": {
+ "name": "error_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "last_attempt_at": {
+ "name": "last_attempt_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "acknowledged_at": {
+ "name": "acknowledged_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error_code": {
+ "name": "last_error_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "issue_question_response_deliveries_interaction_uq": {
+ "name": "issue_question_response_deliveries_interaction_uq",
+ "columns": [
+ {
+ "expression": "interaction_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_question_response_deliveries_correlation_uq": {
+ "name": "issue_question_response_deliveries_correlation_uq",
+ "columns": [
+ {
+ "expression": "correlation_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_question_response_deliveries_pending_idx": {
+ "name": "issue_question_response_deliveries_pending_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_question_response_deliveries_company_issue_idx": {
+ "name": "issue_question_response_deliveries_company_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "issue_question_response_deliveries_company_id_companies_id_fk": {
+ "name": "issue_question_response_deliveries_company_id_companies_id_fk",
+ "tableFrom": "issue_question_response_deliveries",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_question_response_deliveries_issue_id_issues_id_fk": {
+ "name": "issue_question_response_deliveries_issue_id_issues_id_fk",
+ "tableFrom": "issue_question_response_deliveries",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_question_response_deliveries_interaction_id_issue_thread_interactions_id_fk": {
+ "name": "issue_question_response_deliveries_interaction_id_issue_thread_interactions_id_fk",
+ "tableFrom": "issue_question_response_deliveries",
+ "columnsFrom": [
+ "interaction_id"
+ ],
+ "tableTo": "issue_thread_interactions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_question_response_deliveries_source_run_id_heartbeat_runs_id_fk": {
+ "name": "issue_question_response_deliveries_source_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "issue_question_response_deliveries",
+ "columnsFrom": [
+ "source_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_question_response_deliveries_target_run_id_heartbeat_runs_id_fk": {
+ "name": "issue_question_response_deliveries_target_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "issue_question_response_deliveries",
+ "columnsFrom": [
+ "target_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "issue_question_response_deliveries_status_check": {
+ "name": "issue_question_response_deliveries_status_check",
+ "value": "\"issue_question_response_deliveries\".\"status\" IN ('pending', 'delivering', 'delivered', 'fallback_queued', 'failed')"
+ },
+ "issue_question_response_deliveries_mode_check": {
+ "name": "issue_question_response_deliveries_mode_check",
+ "value": "\"issue_question_response_deliveries\".\"delivery_mode\" IS NULL OR \"issue_question_response_deliveries\".\"delivery_mode\" IN ('steered', 'coalesced', 'wake_fallback')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.issue_read_states": {
+ "name": "issue_read_states",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "last_read_at": {
+ "name": "last_read_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "issue_read_states_company_issue_idx": {
+ "name": "issue_read_states_company_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_read_states_company_user_idx": {
+ "name": "issue_read_states_company_user_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_read_states_company_issue_user_idx": {
+ "name": "issue_read_states_company_issue_user_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "issue_read_states_company_id_companies_id_fk": {
+ "name": "issue_read_states_company_id_companies_id_fk",
+ "tableFrom": "issue_read_states",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issue_read_states_issue_id_issues_id_fk": {
+ "name": "issue_read_states_issue_id_issues_id_fk",
+ "tableFrom": "issue_read_states",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.issue_recovery_actions": {
+ "name": "issue_recovery_actions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_issue_id": {
+ "name": "source_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "recovery_issue_id": {
+ "name": "recovery_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "owner_type": {
+ "name": "owner_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'agent'"
+ },
+ "owner_agent_id": {
+ "name": "owner_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "owner_user_id": {
+ "name": "owner_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "previous_owner_agent_id": {
+ "name": "previous_owner_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "return_owner_agent_id": {
+ "name": "return_owner_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cause": {
+ "name": "cause",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "fingerprint": {
+ "name": "fingerprint",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "evidence": {
+ "name": "evidence",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "next_action": {
+ "name": "next_action",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "wake_policy": {
+ "name": "wake_policy",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "monitor_policy": {
+ "name": "monitor_policy",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "attempt_count": {
+ "name": "attempt_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "max_attempts": {
+ "name": "max_attempts",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "timeout_at": {
+ "name": "timeout_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_attempt_at": {
+ "name": "last_attempt_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "outcome": {
+ "name": "outcome",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resolution_note": {
+ "name": "resolution_note",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resolved_at": {
+ "name": "resolved_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "issue_recovery_actions_company_source_status_idx": {
+ "name": "issue_recovery_actions_company_source_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_recovery_actions_company_owner_status_idx": {
+ "name": "issue_recovery_actions_company_owner_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "owner_agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_recovery_actions_company_recovery_issue_idx": {
+ "name": "issue_recovery_actions_company_recovery_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "recovery_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_recovery_actions_active_source_uq": {
+ "name": "issue_recovery_actions_active_source_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"issue_recovery_actions\".\"status\" in ('active', 'escalated')",
+ "concurrently": false
+ },
+ "issue_recovery_actions_active_fingerprint_uq": {
+ "name": "issue_recovery_actions_active_fingerprint_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "cause",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "fingerprint",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"issue_recovery_actions\".\"status\" in ('active', 'escalated')",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "issue_recovery_actions_company_id_companies_id_fk": {
+ "name": "issue_recovery_actions_company_id_companies_id_fk",
+ "tableFrom": "issue_recovery_actions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issue_recovery_actions_source_issue_id_issues_id_fk": {
+ "name": "issue_recovery_actions_source_issue_id_issues_id_fk",
+ "tableFrom": "issue_recovery_actions",
+ "columnsFrom": [
+ "source_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_recovery_actions_recovery_issue_id_issues_id_fk": {
+ "name": "issue_recovery_actions_recovery_issue_id_issues_id_fk",
+ "tableFrom": "issue_recovery_actions",
+ "columnsFrom": [
+ "recovery_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_recovery_actions_owner_agent_id_agents_id_fk": {
+ "name": "issue_recovery_actions_owner_agent_id_agents_id_fk",
+ "tableFrom": "issue_recovery_actions",
+ "columnsFrom": [
+ "owner_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_recovery_actions_previous_owner_agent_id_agents_id_fk": {
+ "name": "issue_recovery_actions_previous_owner_agent_id_agents_id_fk",
+ "tableFrom": "issue_recovery_actions",
+ "columnsFrom": [
+ "previous_owner_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_recovery_actions_return_owner_agent_id_agents_id_fk": {
+ "name": "issue_recovery_actions_return_owner_agent_id_agents_id_fk",
+ "tableFrom": "issue_recovery_actions",
+ "columnsFrom": [
+ "return_owner_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.issue_reference_mentions": {
+ "name": "issue_reference_mentions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_issue_id": {
+ "name": "source_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_issue_id": {
+ "name": "target_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_kind": {
+ "name": "source_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_record_id": {
+ "name": "source_record_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "document_key": {
+ "name": "document_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "matched_text": {
+ "name": "matched_text",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "issue_reference_mentions_company_source_issue_idx": {
+ "name": "issue_reference_mentions_company_source_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_reference_mentions_company_target_issue_idx": {
+ "name": "issue_reference_mentions_company_target_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_reference_mentions_company_issue_pair_idx": {
+ "name": "issue_reference_mentions_company_issue_pair_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_reference_mentions_company_source_mention_record_uq": {
+ "name": "issue_reference_mentions_company_source_mention_record_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_record_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"issue_reference_mentions\".\"source_record_id\" is not null",
+ "concurrently": false
+ },
+ "issue_reference_mentions_company_source_mention_null_record_uq": {
+ "name": "issue_reference_mentions_company_source_mention_null_record_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"issue_reference_mentions\".\"source_record_id\" is null",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "issue_reference_mentions_company_id_companies_id_fk": {
+ "name": "issue_reference_mentions_company_id_companies_id_fk",
+ "tableFrom": "issue_reference_mentions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issue_reference_mentions_source_issue_id_issues_id_fk": {
+ "name": "issue_reference_mentions_source_issue_id_issues_id_fk",
+ "tableFrom": "issue_reference_mentions",
+ "columnsFrom": [
+ "source_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_reference_mentions_target_issue_id_issues_id_fk": {
+ "name": "issue_reference_mentions_target_issue_id_issues_id_fk",
+ "tableFrom": "issue_reference_mentions",
+ "columnsFrom": [
+ "target_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.issue_relations": {
+ "name": "issue_relations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "related_issue_id": {
+ "name": "related_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "issue_relations_company_issue_idx": {
+ "name": "issue_relations_company_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_relations_company_related_issue_idx": {
+ "name": "issue_relations_company_related_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "related_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_relations_company_type_idx": {
+ "name": "issue_relations_company_type_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_relations_company_edge_uq": {
+ "name": "issue_relations_company_edge_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "related_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "issue_relations_company_id_companies_id_fk": {
+ "name": "issue_relations_company_id_companies_id_fk",
+ "tableFrom": "issue_relations",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issue_relations_issue_id_issues_id_fk": {
+ "name": "issue_relations_issue_id_issues_id_fk",
+ "tableFrom": "issue_relations",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_relations_related_issue_id_issues_id_fk": {
+ "name": "issue_relations_related_issue_id_issues_id_fk",
+ "tableFrom": "issue_relations",
+ "columnsFrom": [
+ "related_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_relations_created_by_agent_id_agents_id_fk": {
+ "name": "issue_relations_created_by_agent_id_agents_id_fk",
+ "tableFrom": "issue_relations",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.issue_thread_interactions": {
+ "name": "issue_thread_interactions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "continuation_policy": {
+ "name": "continuation_policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'wake_assignee'"
+ },
+ "requested_resolver_policy": {
+ "name": "requested_resolver_policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'anyone'"
+ },
+ "effective_resolver_policy": {
+ "name": "effective_resolver_policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'anyone'"
+ },
+ "resolver_policy_provenance": {
+ "name": "resolver_policy_provenance",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'inherited'"
+ },
+ "effective_resolver_policy_source": {
+ "name": "effective_resolver_policy_source",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'requested'"
+ },
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "origin_comment_ids": {
+ "name": "origin_comment_ids",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "source_comment_id": {
+ "name": "source_comment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_identity_context_id": {
+ "name": "source_identity_context_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_run_id": {
+ "name": "source_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "summary": {
+ "name": "summary",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "addressee_agent_id": {
+ "name": "addressee_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "addressee_user_id": {
+ "name": "addressee_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resolved_by_agent_id": {
+ "name": "resolved_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resolved_by_run_id": {
+ "name": "resolved_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resolved_by_user_id": {
+ "name": "resolved_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "payload": {
+ "name": "payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "result": {
+ "name": "result",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resolved_at": {
+ "name": "resolved_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "issue_thread_interactions_issue_idx": {
+ "name": "issue_thread_interactions_issue_idx",
+ "columns": [
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_thread_interactions_company_issue_created_at_idx": {
+ "name": "issue_thread_interactions_company_issue_created_at_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_thread_interactions_company_issue_status_idx": {
+ "name": "issue_thread_interactions_company_issue_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_thread_interactions_company_issue_idempotency_uq": {
+ "name": "issue_thread_interactions_company_issue_idempotency_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"issue_thread_interactions\".\"idempotency_key\" IS NOT NULL",
+ "concurrently": false
+ },
+ "issue_thread_interactions_source_comment_idx": {
+ "name": "issue_thread_interactions_source_comment_idx",
+ "columns": [
+ {
+ "expression": "source_comment_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_thread_interactions_addressee_agent_idx": {
+ "name": "issue_thread_interactions_addressee_agent_idx",
+ "columns": [
+ {
+ "expression": "addressee_agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_thread_interactions_addressee_user_idx": {
+ "name": "issue_thread_interactions_addressee_user_idx",
+ "columns": [
+ {
+ "expression": "addressee_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "issue_thread_interactions_company_id_companies_id_fk": {
+ "name": "issue_thread_interactions_company_id_companies_id_fk",
+ "tableFrom": "issue_thread_interactions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issue_thread_interactions_issue_id_issues_id_fk": {
+ "name": "issue_thread_interactions_issue_id_issues_id_fk",
+ "tableFrom": "issue_thread_interactions",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_thread_interactions_source_comment_id_issue_comments_id_fk": {
+ "name": "issue_thread_interactions_source_comment_id_issue_comments_id_fk",
+ "tableFrom": "issue_thread_interactions",
+ "columnsFrom": [
+ "source_comment_id"
+ ],
+ "tableTo": "issue_comments",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_thread_interactions_source_run_id_heartbeat_runs_id_fk": {
+ "name": "issue_thread_interactions_source_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "issue_thread_interactions",
+ "columnsFrom": [
+ "source_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_thread_interactions_created_by_agent_id_agents_id_fk": {
+ "name": "issue_thread_interactions_created_by_agent_id_agents_id_fk",
+ "tableFrom": "issue_thread_interactions",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issue_thread_interactions_addressee_agent_id_agents_id_fk": {
+ "name": "issue_thread_interactions_addressee_agent_id_agents_id_fk",
+ "tableFrom": "issue_thread_interactions",
+ "columnsFrom": [
+ "addressee_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_thread_interactions_resolved_by_agent_id_agents_id_fk": {
+ "name": "issue_thread_interactions_resolved_by_agent_id_agents_id_fk",
+ "tableFrom": "issue_thread_interactions",
+ "columnsFrom": [
+ "resolved_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issue_thread_interactions_resolved_by_run_id_heartbeat_runs_id_fk": {
+ "name": "issue_thread_interactions_resolved_by_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "issue_thread_interactions",
+ "columnsFrom": [
+ "resolved_by_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.issue_tree_hold_members": {
+ "name": "issue_tree_hold_members",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "hold_id": {
+ "name": "hold_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parent_issue_id": {
+ "name": "parent_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "depth": {
+ "name": "depth",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "issue_identifier": {
+ "name": "issue_identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_title": {
+ "name": "issue_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_status": {
+ "name": "issue_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "assignee_agent_id": {
+ "name": "assignee_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "assignee_user_id": {
+ "name": "assignee_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "active_run_id": {
+ "name": "active_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "active_run_status": {
+ "name": "active_run_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "skipped": {
+ "name": "skipped",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "skip_reason": {
+ "name": "skip_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "issue_tree_hold_members_hold_issue_uq": {
+ "name": "issue_tree_hold_members_hold_issue_uq",
+ "columns": [
+ {
+ "expression": "hold_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_tree_hold_members_company_issue_idx": {
+ "name": "issue_tree_hold_members_company_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_tree_hold_members_hold_depth_idx": {
+ "name": "issue_tree_hold_members_hold_depth_idx",
+ "columns": [
+ {
+ "expression": "hold_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "depth",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "issue_tree_hold_members_company_id_companies_id_fk": {
+ "name": "issue_tree_hold_members_company_id_companies_id_fk",
+ "tableFrom": "issue_tree_hold_members",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issue_tree_hold_members_hold_id_issue_tree_holds_id_fk": {
+ "name": "issue_tree_hold_members_hold_id_issue_tree_holds_id_fk",
+ "tableFrom": "issue_tree_hold_members",
+ "columnsFrom": [
+ "hold_id"
+ ],
+ "tableTo": "issue_tree_holds",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_tree_hold_members_issue_id_issues_id_fk": {
+ "name": "issue_tree_hold_members_issue_id_issues_id_fk",
+ "tableFrom": "issue_tree_hold_members",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_tree_hold_members_parent_issue_id_issues_id_fk": {
+ "name": "issue_tree_hold_members_parent_issue_id_issues_id_fk",
+ "tableFrom": "issue_tree_hold_members",
+ "columnsFrom": [
+ "parent_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_tree_hold_members_assignee_agent_id_agents_id_fk": {
+ "name": "issue_tree_hold_members_assignee_agent_id_agents_id_fk",
+ "tableFrom": "issue_tree_hold_members",
+ "columnsFrom": [
+ "assignee_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_tree_hold_members_active_run_id_heartbeat_runs_id_fk": {
+ "name": "issue_tree_hold_members_active_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "issue_tree_hold_members",
+ "columnsFrom": [
+ "active_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.issue_tree_holds": {
+ "name": "issue_tree_holds",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "root_issue_id": {
+ "name": "root_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "mode": {
+ "name": "mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "reason": {
+ "name": "reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "release_policy": {
+ "name": "release_policy",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_actor_type": {
+ "name": "created_by_actor_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'system'"
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_run_id": {
+ "name": "created_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "released_at": {
+ "name": "released_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "released_by_actor_type": {
+ "name": "released_by_actor_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "released_by_agent_id": {
+ "name": "released_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "released_by_user_id": {
+ "name": "released_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "released_by_run_id": {
+ "name": "released_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "release_reason": {
+ "name": "release_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "release_metadata": {
+ "name": "release_metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "issue_tree_holds_company_root_status_idx": {
+ "name": "issue_tree_holds_company_root_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "root_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_tree_holds_company_status_mode_idx": {
+ "name": "issue_tree_holds_company_status_mode_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "mode",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "issue_tree_holds_company_id_companies_id_fk": {
+ "name": "issue_tree_holds_company_id_companies_id_fk",
+ "tableFrom": "issue_tree_holds",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issue_tree_holds_root_issue_id_issues_id_fk": {
+ "name": "issue_tree_holds_root_issue_id_issues_id_fk",
+ "tableFrom": "issue_tree_holds",
+ "columnsFrom": [
+ "root_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_tree_holds_created_by_agent_id_agents_id_fk": {
+ "name": "issue_tree_holds_created_by_agent_id_agents_id_fk",
+ "tableFrom": "issue_tree_holds",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_tree_holds_created_by_run_id_heartbeat_runs_id_fk": {
+ "name": "issue_tree_holds_created_by_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "issue_tree_holds",
+ "columnsFrom": [
+ "created_by_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_tree_holds_released_by_agent_id_agents_id_fk": {
+ "name": "issue_tree_holds_released_by_agent_id_agents_id_fk",
+ "tableFrom": "issue_tree_holds",
+ "columnsFrom": [
+ "released_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_tree_holds_released_by_run_id_heartbeat_runs_id_fk": {
+ "name": "issue_tree_holds_released_by_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "issue_tree_holds",
+ "columnsFrom": [
+ "released_by_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.issue_watchdogs": {
+ "name": "issue_watchdogs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "watchdog_agent_id": {
+ "name": "watchdog_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "instructions": {
+ "name": "instructions",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "watchdog_issue_id": {
+ "name": "watchdog_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_observed_fingerprint": {
+ "name": "last_observed_fingerprint",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_reviewed_fingerprint": {
+ "name": "last_reviewed_fingerprint",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_observed_stop_snapshot": {
+ "name": "last_observed_stop_snapshot",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_reviewed_stop_snapshot": {
+ "name": "last_reviewed_stop_snapshot",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_triggered_at": {
+ "name": "last_triggered_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_completed_at": {
+ "name": "last_completed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "trigger_count": {
+ "name": "trigger_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_run_id": {
+ "name": "created_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_by_agent_id": {
+ "name": "updated_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_by_user_id": {
+ "name": "updated_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_by_run_id": {
+ "name": "updated_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "issue_watchdogs_company_issue_uq": {
+ "name": "issue_watchdogs_company_issue_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_watchdogs_company_status_idx": {
+ "name": "issue_watchdogs_company_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_watchdogs_company_agent_idx": {
+ "name": "issue_watchdogs_company_agent_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "watchdog_agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_watchdogs_company_watchdog_issue_uq": {
+ "name": "issue_watchdogs_company_watchdog_issue_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "watchdog_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"issue_watchdogs\".\"watchdog_issue_id\" is not null",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "issue_watchdogs_company_id_companies_id_fk": {
+ "name": "issue_watchdogs_company_id_companies_id_fk",
+ "tableFrom": "issue_watchdogs",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_watchdogs_issue_id_issues_id_fk": {
+ "name": "issue_watchdogs_issue_id_issues_id_fk",
+ "tableFrom": "issue_watchdogs",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_watchdogs_watchdog_agent_id_agents_id_fk": {
+ "name": "issue_watchdogs_watchdog_agent_id_agents_id_fk",
+ "tableFrom": "issue_watchdogs",
+ "columnsFrom": [
+ "watchdog_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issue_watchdogs_watchdog_issue_id_issues_id_fk": {
+ "name": "issue_watchdogs_watchdog_issue_id_issues_id_fk",
+ "tableFrom": "issue_watchdogs",
+ "columnsFrom": [
+ "watchdog_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_watchdogs_created_by_agent_id_agents_id_fk": {
+ "name": "issue_watchdogs_created_by_agent_id_agents_id_fk",
+ "tableFrom": "issue_watchdogs",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_watchdogs_created_by_run_id_heartbeat_runs_id_fk": {
+ "name": "issue_watchdogs_created_by_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "issue_watchdogs",
+ "columnsFrom": [
+ "created_by_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_watchdogs_updated_by_agent_id_agents_id_fk": {
+ "name": "issue_watchdogs_updated_by_agent_id_agents_id_fk",
+ "tableFrom": "issue_watchdogs",
+ "columnsFrom": [
+ "updated_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_watchdogs_updated_by_run_id_heartbeat_runs_id_fk": {
+ "name": "issue_watchdogs_updated_by_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "issue_watchdogs",
+ "columnsFrom": [
+ "updated_by_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.issue_work_products": {
+ "name": "issue_work_products",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "execution_workspace_id": {
+ "name": "execution_workspace_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "runtime_service_id": {
+ "name": "runtime_service_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "url": {
+ "name": "url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "review_state": {
+ "name": "review_state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'none'"
+ },
+ "is_primary": {
+ "name": "is_primary",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "health_status": {
+ "name": "health_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'unknown'"
+ },
+ "summary": {
+ "name": "summary",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_trust": {
+ "name": "source_trust",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_run_id": {
+ "name": "created_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "issue_work_products_company_issue_type_idx": {
+ "name": "issue_work_products_company_issue_type_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_work_products_company_execution_workspace_type_idx": {
+ "name": "issue_work_products_company_execution_workspace_type_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "execution_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_work_products_company_provider_external_id_idx": {
+ "name": "issue_work_products_company_provider_external_id_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issue_work_products_company_updated_idx": {
+ "name": "issue_work_products_company_updated_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "issue_work_products_company_id_companies_id_fk": {
+ "name": "issue_work_products_company_id_companies_id_fk",
+ "tableFrom": "issue_work_products",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issue_work_products_project_id_projects_id_fk": {
+ "name": "issue_work_products_project_id_projects_id_fk",
+ "tableFrom": "issue_work_products",
+ "columnsFrom": [
+ "project_id"
+ ],
+ "tableTo": "projects",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_work_products_issue_id_issues_id_fk": {
+ "name": "issue_work_products_issue_id_issues_id_fk",
+ "tableFrom": "issue_work_products",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "issue_work_products_execution_workspace_id_execution_workspaces_id_fk": {
+ "name": "issue_work_products_execution_workspace_id_execution_workspaces_id_fk",
+ "tableFrom": "issue_work_products",
+ "columnsFrom": [
+ "execution_workspace_id"
+ ],
+ "tableTo": "execution_workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_work_products_runtime_service_id_workspace_runtime_services_id_fk": {
+ "name": "issue_work_products_runtime_service_id_workspace_runtime_services_id_fk",
+ "tableFrom": "issue_work_products",
+ "columnsFrom": [
+ "runtime_service_id"
+ ],
+ "tableTo": "workspace_runtime_services",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issue_work_products_created_by_run_id_heartbeat_runs_id_fk": {
+ "name": "issue_work_products_created_by_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "issue_work_products",
+ "columnsFrom": [
+ "created_by_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.issues": {
+ "name": "issues",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "conversation_agent_id": {
+ "name": "conversation_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "conversation_user_id": {
+ "name": "conversation_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "conversation_state": {
+ "name": "conversation_state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "conversation_session_generation": {
+ "name": "conversation_session_generation",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "conversation_boundary_comment_id": {
+ "name": "conversation_boundary_comment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "project_workspace_id": {
+ "name": "project_workspace_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goal_id": {
+ "name": "goal_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "parent_id": {
+ "name": "parent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "visibility": {
+ "name": "visibility",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'open'"
+ },
+ "privacy_root_issue_id": {
+ "name": "privacy_root_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "privacy_parent_issue_id": {
+ "name": "privacy_parent_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title_needs_generation": {
+ "name": "title_needs_generation",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'backlog'"
+ },
+ "status_version": {
+ "name": "status_version",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "last_status_decision_id": {
+ "name": "last_status_decision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "work_mode": {
+ "name": "work_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'standard'"
+ },
+ "harness_kind": {
+ "name": "harness_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "priority": {
+ "name": "priority",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'medium'"
+ },
+ "review_policy": {
+ "name": "review_policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "assignee_agent_id": {
+ "name": "assignee_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "assignee_user_id": {
+ "name": "assignee_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "checkout_run_id": {
+ "name": "checkout_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "execution_run_id": {
+ "name": "execution_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "execution_agent_name_key": {
+ "name": "execution_agent_name_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "execution_locked_at": {
+ "name": "execution_locked_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "responsible_user_id": {
+ "name": "responsible_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_number": {
+ "name": "issue_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "identifier": {
+ "name": "identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "origin_kind": {
+ "name": "origin_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'manual'"
+ },
+ "origin_id": {
+ "name": "origin_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "origin_run_id": {
+ "name": "origin_run_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "origin_identity_context_id": {
+ "name": "origin_identity_context_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "continuation_identity_context_id": {
+ "name": "continuation_identity_context_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "origin_fingerprint": {
+ "name": "origin_fingerprint",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'default'"
+ },
+ "request_depth": {
+ "name": "request_depth",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "billing_code": {
+ "name": "billing_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "assignee_adapter_overrides": {
+ "name": "assignee_adapter_overrides",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "execution_policy": {
+ "name": "execution_policy",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "execution_state": {
+ "name": "execution_state",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "monitor_next_check_at": {
+ "name": "monitor_next_check_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "monitor_wake_requested_at": {
+ "name": "monitor_wake_requested_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "monitor_last_triggered_at": {
+ "name": "monitor_last_triggered_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "monitor_attempt_count": {
+ "name": "monitor_attempt_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "monitor_notes": {
+ "name": "monitor_notes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "monitor_scheduled_by": {
+ "name": "monitor_scheduled_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "execution_workspace_id": {
+ "name": "execution_workspace_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "execution_workspace_preference": {
+ "name": "execution_workspace_preference",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "execution_workspace_settings": {
+ "name": "execution_workspace_settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_trust": {
+ "name": "source_trust",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "unblock_descriptor": {
+ "name": "unblock_descriptor",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "blocked_transition_at": {
+ "name": "blocked_transition_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "blocked_owner_notified_at": {
+ "name": "blocked_owner_notified_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cancelled_at": {
+ "name": "cancelled_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "hidden_at": {
+ "name": "hidden_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "issues_conversation_identity_idx": {
+ "name": "issues_conversation_identity_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "conversation_agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "conversation_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issues_company_status_idx": {
+ "name": "issues_company_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issues_company_harness_kind_idx": {
+ "name": "issues_company_harness_kind_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "harness_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issues_company_assignee_status_idx": {
+ "name": "issues_company_assignee_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "assignee_agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issues_company_assignee_user_status_idx": {
+ "name": "issues_company_assignee_user_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "assignee_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issues_company_responsible_user_idx": {
+ "name": "issues_company_responsible_user_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "responsible_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issues_company_parent_idx": {
+ "name": "issues_company_parent_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "parent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issues_company_privacy_parent_idx": {
+ "name": "issues_company_privacy_parent_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "privacy_parent_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issues_company_privacy_root_idx": {
+ "name": "issues_company_privacy_root_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "privacy_root_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issues_company_project_idx": {
+ "name": "issues_company_project_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issues_company_origin_idx": {
+ "name": "issues_company_origin_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "origin_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "origin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issues_company_project_workspace_idx": {
+ "name": "issues_company_project_workspace_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issues_company_execution_workspace_idx": {
+ "name": "issues_company_execution_workspace_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "execution_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issues_company_monitor_due_idx": {
+ "name": "issues_company_monitor_due_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "monitor_next_check_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issues_company_updated_idx": {
+ "name": "issues_company_updated_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issues_company_created_idx": {
+ "name": "issues_company_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issues_open_normalized_title_created_idx": {
+ "name": "issues_open_normalized_title_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "parent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lower(regexp_replace(btrim(\"title\"), '\\s+', ' ', 'g'))",
+ "isExpression": true,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "where": "\"issues\".\"hidden_at\" is null and \"issues\".\"status\" not in ('done', 'cancelled')",
+ "concurrently": false
+ },
+ "issues_company_priority_idx": {
+ "name": "issues_company_priority_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "priority",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issues_identifier_idx": {
+ "name": "issues_identifier_idx",
+ "columns": [
+ {
+ "expression": "identifier",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "issues_title_search_idx": {
+ "name": "issues_title_search_idx",
+ "columns": [
+ {
+ "expression": "title",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "gin_trgm_ops"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "gin",
+ "concurrently": false
+ },
+ "issues_identifier_search_idx": {
+ "name": "issues_identifier_search_idx",
+ "columns": [
+ {
+ "expression": "identifier",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "gin_trgm_ops"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "gin",
+ "concurrently": false
+ },
+ "issues_description_search_idx": {
+ "name": "issues_description_search_idx",
+ "columns": [
+ {
+ "expression": "description",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "gin_trgm_ops"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "gin",
+ "concurrently": false
+ },
+ "issues_open_routine_execution_uq": {
+ "name": "issues_open_routine_execution_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "origin_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "origin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "origin_fingerprint",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"issues\".\"origin_kind\" = 'routine_execution'\n and \"issues\".\"origin_id\" is not null\n and \"issues\".\"hidden_at\" is null\n and \"issues\".\"execution_run_id\" is not null\n and \"issues\".\"status\" in ('backlog', 'todo', 'in_progress', 'in_review', 'blocked')",
+ "concurrently": false
+ },
+ "issues_active_liveness_recovery_incident_uq": {
+ "name": "issues_active_liveness_recovery_incident_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "origin_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "origin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"issues\".\"origin_kind\" = 'harness_liveness_escalation'\n and \"issues\".\"origin_id\" is not null\n and \"issues\".\"hidden_at\" is null\n and \"issues\".\"status\" not in ('done', 'cancelled')",
+ "concurrently": false
+ },
+ "issues_active_liveness_recovery_leaf_uq": {
+ "name": "issues_active_liveness_recovery_leaf_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "origin_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "origin_fingerprint",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"issues\".\"origin_kind\" = 'harness_liveness_escalation'\n and \"issues\".\"origin_fingerprint\" <> 'default'\n and \"issues\".\"hidden_at\" is null\n and \"issues\".\"status\" not in ('done', 'cancelled')",
+ "concurrently": false
+ },
+ "issues_active_stale_run_evaluation_uq": {
+ "name": "issues_active_stale_run_evaluation_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "origin_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "origin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"issues\".\"origin_kind\" = 'stale_active_run_evaluation'\n and \"issues\".\"origin_id\" is not null\n and \"issues\".\"hidden_at\" is null\n and \"issues\".\"status\" not in ('done', 'cancelled')",
+ "concurrently": false
+ },
+ "issues_active_task_watchdog_uq": {
+ "name": "issues_active_task_watchdog_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "origin_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "origin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"issues\".\"origin_kind\" = 'task_watchdog'\n and \"issues\".\"origin_id\" is not null\n and \"issues\".\"hidden_at\" is null\n and \"issues\".\"status\" not in ('done', 'cancelled')",
+ "concurrently": false
+ },
+ "issues_active_productivity_review_uq": {
+ "name": "issues_active_productivity_review_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "origin_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "origin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"issues\".\"origin_kind\" = 'issue_productivity_review'\n and \"issues\".\"origin_id\" is not null\n and \"issues\".\"hidden_at\" is null\n and \"issues\".\"status\" not in ('done', 'cancelled')",
+ "concurrently": false
+ },
+ "issues_active_stranded_issue_recovery_uq": {
+ "name": "issues_active_stranded_issue_recovery_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "origin_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "origin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"issues\".\"origin_kind\" = 'stranded_issue_recovery'\n and \"issues\".\"origin_id\" is not null\n and \"issues\".\"hidden_at\" is null\n and \"issues\".\"status\" not in ('done', 'cancelled')",
+ "concurrently": false
+ },
+ "issues_onboarding_first_task_uq": {
+ "name": "issues_onboarding_first_task_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"issues\".\"origin_kind\" = 'onboarding_first_task'",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "issues_company_id_companies_id_fk": {
+ "name": "issues_company_id_companies_id_fk",
+ "tableFrom": "issues",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issues_conversation_agent_id_agents_id_fk": {
+ "name": "issues_conversation_agent_id_agents_id_fk",
+ "tableFrom": "issues",
+ "columnsFrom": [
+ "conversation_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issues_project_id_projects_id_fk": {
+ "name": "issues_project_id_projects_id_fk",
+ "tableFrom": "issues",
+ "columnsFrom": [
+ "project_id"
+ ],
+ "tableTo": "projects",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issues_project_workspace_id_project_workspaces_id_fk": {
+ "name": "issues_project_workspace_id_project_workspaces_id_fk",
+ "tableFrom": "issues",
+ "columnsFrom": [
+ "project_workspace_id"
+ ],
+ "tableTo": "project_workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issues_goal_id_goals_id_fk": {
+ "name": "issues_goal_id_goals_id_fk",
+ "tableFrom": "issues",
+ "columnsFrom": [
+ "goal_id"
+ ],
+ "tableTo": "goals",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issues_parent_id_issues_id_fk": {
+ "name": "issues_parent_id_issues_id_fk",
+ "tableFrom": "issues",
+ "columnsFrom": [
+ "parent_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issues_privacy_root_issue_id_issues_id_fk": {
+ "name": "issues_privacy_root_issue_id_issues_id_fk",
+ "tableFrom": "issues",
+ "columnsFrom": [
+ "privacy_root_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issues_privacy_parent_issue_id_issues_id_fk": {
+ "name": "issues_privacy_parent_issue_id_issues_id_fk",
+ "tableFrom": "issues",
+ "columnsFrom": [
+ "privacy_parent_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issues_assignee_agent_id_agents_id_fk": {
+ "name": "issues_assignee_agent_id_agents_id_fk",
+ "tableFrom": "issues",
+ "columnsFrom": [
+ "assignee_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issues_checkout_run_id_heartbeat_runs_id_fk": {
+ "name": "issues_checkout_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "issues",
+ "columnsFrom": [
+ "checkout_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issues_execution_run_id_heartbeat_runs_id_fk": {
+ "name": "issues_execution_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "issues",
+ "columnsFrom": [
+ "execution_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "issues_created_by_agent_id_agents_id_fk": {
+ "name": "issues_created_by_agent_id_agents_id_fk",
+ "tableFrom": "issues",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "issues_execution_workspace_id_execution_workspaces_id_fk": {
+ "name": "issues_execution_workspace_id_execution_workspaces_id_fk",
+ "tableFrom": "issues",
+ "columnsFrom": [
+ "execution_workspace_id"
+ ],
+ "tableTo": "execution_workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "issues_company_id_uq": {
+ "name": "issues_company_id_uq",
+ "columns": [
+ "company_id",
+ "id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {
+ "issues_visibility_check": {
+ "name": "issues_visibility_check",
+ "value": "\"issues\".\"visibility\" in ('open', 'private')"
+ },
+ "issues_conversation_identity_check": {
+ "name": "issues_conversation_identity_check",
+ "value": "(\n \"issues\".\"conversation_agent_id\" is null and \"issues\".\"conversation_user_id\" is null and \"issues\".\"conversation_state\" is null\n ) or (\n \"issues\".\"conversation_agent_id\" is not null and \"issues\".\"conversation_user_id\" is not null\n and \"issues\".\"assignee_agent_id\" = \"issues\".\"conversation_agent_id\" and \"issues\".\"assignee_agent_id\" is not null\n and \"issues\".\"assignee_user_id\" is null and \"issues\".\"conversation_state\" is not null\n and \"issues\".\"conversation_state\" in ('active', 'waiting')\n and \"issues\".\"status\" not in ('done', 'cancelled')\n )"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.join_requests": {
+ "name": "join_requests",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "invite_id": {
+ "name": "invite_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "request_type": {
+ "name": "request_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending_approval'"
+ },
+ "request_ip": {
+ "name": "request_ip",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "requesting_user_id": {
+ "name": "requesting_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "request_email_snapshot": {
+ "name": "request_email_snapshot",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "agent_name": {
+ "name": "agent_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "adapter_type": {
+ "name": "adapter_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "capabilities": {
+ "name": "capabilities",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "agent_defaults_payload": {
+ "name": "agent_defaults_payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "claim_secret_hash": {
+ "name": "claim_secret_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "claim_secret_expires_at": {
+ "name": "claim_secret_expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "claim_secret_consumed_at": {
+ "name": "claim_secret_consumed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_agent_id": {
+ "name": "created_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "approved_by_user_id": {
+ "name": "approved_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "approved_at": {
+ "name": "approved_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rejected_by_user_id": {
+ "name": "rejected_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rejected_at": {
+ "name": "rejected_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "join_requests_invite_unique_idx": {
+ "name": "join_requests_invite_unique_idx",
+ "columns": [
+ {
+ "expression": "invite_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "join_requests_company_status_type_created_idx": {
+ "name": "join_requests_company_status_type_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "request_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "join_requests_pending_human_user_uq": {
+ "name": "join_requests_pending_human_user_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "requesting_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"join_requests\".\"request_type\" = 'human' AND \"join_requests\".\"status\" = 'pending_approval' AND \"join_requests\".\"requesting_user_id\" IS NOT NULL",
+ "concurrently": false
+ },
+ "join_requests_pending_human_email_uq": {
+ "name": "join_requests_pending_human_email_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lower(\"request_email_snapshot\")",
+ "isExpression": true,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"join_requests\".\"request_type\" = 'human' AND \"join_requests\".\"status\" = 'pending_approval' AND \"join_requests\".\"request_email_snapshot\" IS NOT NULL",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "join_requests_invite_id_invites_id_fk": {
+ "name": "join_requests_invite_id_invites_id_fk",
+ "tableFrom": "join_requests",
+ "columnsFrom": [
+ "invite_id"
+ ],
+ "tableTo": "invites",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "join_requests_company_id_companies_id_fk": {
+ "name": "join_requests_company_id_companies_id_fk",
+ "tableFrom": "join_requests",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "join_requests_created_agent_id_agents_id_fk": {
+ "name": "join_requests_created_agent_id_agents_id_fk",
+ "tableFrom": "join_requests",
+ "columnsFrom": [
+ "created_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.labels": {
+ "name": "labels",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "color": {
+ "name": "color",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "labels_company_idx": {
+ "name": "labels_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "labels_company_name_idx": {
+ "name": "labels_company_name_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "labels_company_id_companies_id_fk": {
+ "name": "labels_company_id_companies_id_fk",
+ "tableFrom": "labels",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.managed_agent_profiles": {
+ "name": "managed_agent_profiles",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "profile_key": {
+ "name": "profile_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "display_name": {
+ "name": "display_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "service": {
+ "name": "service",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'anthropic_managed_agents'"
+ },
+ "anthropic_agent_id": {
+ "name": "anthropic_agent_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_version": {
+ "name": "agent_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "environment_id": {
+ "name": "environment_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "beta_version": {
+ "name": "beta_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'managed-agents-2026-04-01'"
+ },
+ "default_model": {
+ "name": "default_model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'claude-sonnet-5'"
+ },
+ "default_max_list_cost_cents": {
+ "name": "default_max_list_cost_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 100
+ },
+ "api_key_secret_id": {
+ "name": "api_key_secret_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "retention_acknowledged": {
+ "name": "retention_acknowledged",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "qualification": {
+ "name": "qualification",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "qualified_at": {
+ "name": "qualified_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "qualified_revision": {
+ "name": "qualified_revision",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "managed_agent_profiles_company_idx": {
+ "name": "managed_agent_profiles_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "managed_agent_profiles_company_key_uq": {
+ "name": "managed_agent_profiles_company_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "profile_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "managed_agent_profiles_company_resource_uq": {
+ "name": "managed_agent_profiles_company_resource_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "anthropic_agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_version",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "environment_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "managed_agent_profiles_company_id_companies_id_fk": {
+ "name": "managed_agent_profiles_company_id_companies_id_fk",
+ "tableFrom": "managed_agent_profiles",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "managed_agent_profiles_api_key_secret_id_company_secrets_id_fk": {
+ "name": "managed_agent_profiles_api_key_secret_id_company_secrets_id_fk",
+ "tableFrom": "managed_agent_profiles",
+ "columnsFrom": [
+ "api_key_secret_id"
+ ],
+ "tableTo": "company_secrets",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "restrict"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "managed_agent_profiles_service_check": {
+ "name": "managed_agent_profiles_service_check",
+ "value": "\"managed_agent_profiles\".\"service\" = 'anthropic_managed_agents'"
+ },
+ "managed_agent_profiles_beta_check": {
+ "name": "managed_agent_profiles_beta_check",
+ "value": "\"managed_agent_profiles\".\"beta_version\" = 'managed-agents-2026-04-01'"
+ },
+ "managed_agent_profiles_positive_budget_check": {
+ "name": "managed_agent_profiles_positive_budget_check",
+ "value": "\"managed_agent_profiles\".\"default_max_list_cost_cents\" > 0"
+ },
+ "managed_agent_profiles_qualified_revision_check": {
+ "name": "managed_agent_profiles_qualified_revision_check",
+ "value": "(\"managed_agent_profiles\".\"qualified_at\" IS NULL AND \"managed_agent_profiles\".\"qualified_revision\" IS NULL) OR (\"managed_agent_profiles\".\"qualified_at\" IS NOT NULL AND \"managed_agent_profiles\".\"qualification\" <> '{}'::jsonb AND \"managed_agent_profiles\".\"qualified_revision\" ~ '^sha256:[0-9a-f]{64}$')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.native_run_finalizations": {
+ "name": "native_run_finalizations",
+ "schema": "",
+ "columns": {
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "phase": {
+ "name": "phase",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "attempt": {
+ "name": "attempt",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "lease_owner": {
+ "name": "lease_owner",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lease_expires_at": {
+ "name": "lease_expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "controller_boot_id": {
+ "name": "controller_boot_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "controller_pid": {
+ "name": "controller_pid",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "controller_process_started_at": {
+ "name": "controller_process_started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "controller_generation": {
+ "name": "controller_generation",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "recovery_state": {
+ "name": "recovery_state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "recovery_request_id": {
+ "name": "recovery_request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "recovery_history": {
+ "name": "recovery_history",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "result_id": {
+ "name": "result_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "assessment_id": {
+ "name": "assessment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "decision_id": {
+ "name": "decision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "failure_code": {
+ "name": "failure_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "failure_detail": {
+ "name": "failure_detail",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "control_deadline_at": {
+ "name": "control_deadline_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "next_attempt_at": {
+ "name": "next_attempt_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "native_run_finalizations_control_deadline_idx": {
+ "name": "native_run_finalizations_control_deadline_idx",
+ "columns": [
+ {
+ "expression": "control_deadline_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "where": "\"native_run_finalizations\".\"control_deadline_at\" is not null",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "native_run_finalizations_company_id_companies_id_fk": {
+ "name": "native_run_finalizations_company_id_companies_id_fk",
+ "tableFrom": "native_run_finalizations",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "native_run_finalizations_issue_company_fk": {
+ "name": "native_run_finalizations_issue_company_fk",
+ "tableFrom": "native_run_finalizations",
+ "columnsFrom": [
+ "company_id",
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "native_run_finalizations_run_owner_fk": {
+ "name": "native_run_finalizations_run_owner_fk",
+ "tableFrom": "native_run_finalizations",
+ "columnsFrom": [
+ "company_id",
+ "issue_id",
+ "run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "company_id",
+ "native_issue_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "native_run_finalizations_result_owner_fk": {
+ "name": "native_run_finalizations_result_owner_fk",
+ "tableFrom": "native_run_finalizations",
+ "columnsFrom": [
+ "company_id",
+ "issue_id",
+ "run_id",
+ "result_id"
+ ],
+ "tableTo": "native_run_results",
+ "columnsTo": [
+ "company_id",
+ "issue_id",
+ "run_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "native_run_finalizations_assessment_owner_fk": {
+ "name": "native_run_finalizations_assessment_owner_fk",
+ "tableFrom": "native_run_finalizations",
+ "columnsFrom": [
+ "company_id",
+ "issue_id",
+ "run_id",
+ "assessment_id"
+ ],
+ "tableTo": "work_assessments",
+ "columnsTo": [
+ "company_id",
+ "issue_id",
+ "run_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "native_run_finalizations_decision_owner_fk": {
+ "name": "native_run_finalizations_decision_owner_fk",
+ "tableFrom": "native_run_finalizations",
+ "columnsFrom": [
+ "company_id",
+ "issue_id",
+ "run_id",
+ "assessment_id",
+ "decision_id"
+ ],
+ "tableTo": "status_decisions",
+ "columnsTo": [
+ "company_id",
+ "issue_id",
+ "run_id",
+ "assessment_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "native_run_finalizations_assessment_requires_result_check": {
+ "name": "native_run_finalizations_assessment_requires_result_check",
+ "value": "\"native_run_finalizations\".\"assessment_id\" is null or \"native_run_finalizations\".\"result_id\" is not null"
+ },
+ "native_run_finalizations_decision_requires_assessment_check": {
+ "name": "native_run_finalizations_decision_requires_assessment_check",
+ "value": "\"native_run_finalizations\".\"decision_id\" is null or \"native_run_finalizations\".\"assessment_id\" is not null"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.native_run_results": {
+ "name": "native_run_results",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "turn_id": {
+ "name": "turn_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completion_contract_id": {
+ "name": "completion_contract_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "caller_result_id": {
+ "name": "caller_result_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "caller_dedupe_key": {
+ "name": "caller_dedupe_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "server_fingerprint": {
+ "name": "server_fingerprint",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "schema_status": {
+ "name": "schema_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "rejection_code": {
+ "name": "rejection_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "result_json": {
+ "name": "result_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "canonical_sha256": {
+ "name": "canonical_sha256",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "native_run_results_run_fingerprint_uq": {
+ "name": "native_run_results_run_fingerprint_uq",
+ "columns": [
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "server_fingerprint",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "native_run_results_run_caller_result_uq": {
+ "name": "native_run_results_run_caller_result_uq",
+ "columns": [
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "caller_result_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "native_run_results_run_caller_dedupe_uq": {
+ "name": "native_run_results_run_caller_dedupe_uq",
+ "columns": [
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "caller_dedupe_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "native_run_results_company_id_companies_id_fk": {
+ "name": "native_run_results_company_id_companies_id_fk",
+ "tableFrom": "native_run_results",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "native_run_results_issue_company_fk": {
+ "name": "native_run_results_issue_company_fk",
+ "tableFrom": "native_run_results",
+ "columnsFrom": [
+ "company_id",
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "native_run_results_run_contract_owner_fk": {
+ "name": "native_run_results_run_contract_owner_fk",
+ "tableFrom": "native_run_results",
+ "columnsFrom": [
+ "company_id",
+ "issue_id",
+ "run_id",
+ "completion_contract_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "company_id",
+ "native_issue_id",
+ "id",
+ "completion_contract_id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "native_run_results_completion_contract_owner_fk": {
+ "name": "native_run_results_completion_contract_owner_fk",
+ "tableFrom": "native_run_results",
+ "columnsFrom": [
+ "company_id",
+ "issue_id",
+ "completion_contract_id"
+ ],
+ "tableTo": "completion_contracts",
+ "columnsTo": [
+ "company_id",
+ "issue_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "native_run_results_company_issue_run_id_uq": {
+ "name": "native_run_results_company_issue_run_id_uq",
+ "columns": [
+ "company_id",
+ "issue_id",
+ "run_id",
+ "id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.pipeline_automation_executions": {
+ "name": "pipeline_automation_executions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "case_id": {
+ "name": "case_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "automation_id": {
+ "name": "automation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "triggering_event_id": {
+ "name": "triggering_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "routine_id": {
+ "name": "routine_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "execution_issue_id": {
+ "name": "execution_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "retry_of_execution_id": {
+ "name": "retry_of_execution_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "generation": {
+ "name": "generation",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "pipeline_automation_executions_idempotency_uq": {
+ "name": "pipeline_automation_executions_idempotency_uq",
+ "columns": [
+ {
+ "expression": "case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "automation_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "triggering_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_automation_executions_company_case_idx": {
+ "name": "pipeline_automation_executions_company_case_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_automation_executions_routine_idx": {
+ "name": "pipeline_automation_executions_routine_idx",
+ "columns": [
+ {
+ "expression": "routine_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_automation_executions_execution_issue_idx": {
+ "name": "pipeline_automation_executions_execution_issue_idx",
+ "columns": [
+ {
+ "expression": "execution_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_automation_executions_retry_of_execution_idx": {
+ "name": "pipeline_automation_executions_retry_of_execution_idx",
+ "columns": [
+ {
+ "expression": "retry_of_execution_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "pipeline_automation_executions_company_id_companies_id_fk": {
+ "name": "pipeline_automation_executions_company_id_companies_id_fk",
+ "tableFrom": "pipeline_automation_executions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "pipeline_automation_executions_case_id_pipeline_cases_id_fk": {
+ "name": "pipeline_automation_executions_case_id_pipeline_cases_id_fk",
+ "tableFrom": "pipeline_automation_executions",
+ "columnsFrom": [
+ "case_id"
+ ],
+ "tableTo": "pipeline_cases",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "pipeline_automation_executions_routine_id_routines_id_fk": {
+ "name": "pipeline_automation_executions_routine_id_routines_id_fk",
+ "tableFrom": "pipeline_automation_executions",
+ "columnsFrom": [
+ "routine_id"
+ ],
+ "tableTo": "routines",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "pipeline_automation_executions_execution_issue_id_issues_id_fk": {
+ "name": "pipeline_automation_executions_execution_issue_id_issues_id_fk",
+ "tableFrom": "pipeline_automation_executions",
+ "columnsFrom": [
+ "execution_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "pipeline_automation_executions_status_check": {
+ "name": "pipeline_automation_executions_status_check",
+ "value": "\"pipeline_automation_executions\".\"status\" in ('succeeded', 'failed')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.pipeline_case_blockers": {
+ "name": "pipeline_case_blockers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "case_id": {
+ "name": "case_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "blocked_by_case_id": {
+ "name": "blocked_by_case_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "pipeline_case_blockers_case_blocked_by_uq": {
+ "name": "pipeline_case_blockers_case_blocked_by_uq",
+ "columns": [
+ {
+ "expression": "case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "blocked_by_case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_case_blockers_blocked_by_idx": {
+ "name": "pipeline_case_blockers_blocked_by_idx",
+ "columns": [
+ {
+ "expression": "blocked_by_case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_case_blockers_company_case_idx": {
+ "name": "pipeline_case_blockers_company_case_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "pipeline_case_blockers_company_id_companies_id_fk": {
+ "name": "pipeline_case_blockers_company_id_companies_id_fk",
+ "tableFrom": "pipeline_case_blockers",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "pipeline_case_blockers_case_id_pipeline_cases_id_fk": {
+ "name": "pipeline_case_blockers_case_id_pipeline_cases_id_fk",
+ "tableFrom": "pipeline_case_blockers",
+ "columnsFrom": [
+ "case_id"
+ ],
+ "tableTo": "pipeline_cases",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "pipeline_case_blockers_blocked_by_case_id_pipeline_cases_id_fk": {
+ "name": "pipeline_case_blockers_blocked_by_case_id_pipeline_cases_id_fk",
+ "tableFrom": "pipeline_case_blockers",
+ "columnsFrom": [
+ "blocked_by_case_id"
+ ],
+ "tableTo": "pipeline_cases",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "pipeline_case_blockers_no_self_block_check": {
+ "name": "pipeline_case_blockers_no_self_block_check",
+ "value": "\"pipeline_case_blockers\".\"case_id\" <> \"pipeline_case_blockers\".\"blocked_by_case_id\""
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.pipeline_case_documents": {
+ "name": "pipeline_case_documents",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "case_id": {
+ "name": "case_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "pipeline_case_documents_company_case_key_uq": {
+ "name": "pipeline_case_documents_company_case_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_case_documents_document_uq": {
+ "name": "pipeline_case_documents_document_uq",
+ "columns": [
+ {
+ "expression": "document_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_case_documents_company_case_updated_idx": {
+ "name": "pipeline_case_documents_company_case_updated_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "pipeline_case_documents_company_id_companies_id_fk": {
+ "name": "pipeline_case_documents_company_id_companies_id_fk",
+ "tableFrom": "pipeline_case_documents",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "pipeline_case_documents_case_id_pipeline_cases_id_fk": {
+ "name": "pipeline_case_documents_case_id_pipeline_cases_id_fk",
+ "tableFrom": "pipeline_case_documents",
+ "columnsFrom": [
+ "case_id"
+ ],
+ "tableTo": "pipeline_cases",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "pipeline_case_documents_document_id_documents_id_fk": {
+ "name": "pipeline_case_documents_document_id_documents_id_fk",
+ "tableFrom": "pipeline_case_documents",
+ "columnsFrom": [
+ "document_id"
+ ],
+ "tableTo": "documents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.pipeline_case_events": {
+ "name": "pipeline_case_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "case_id": {
+ "name": "case_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_type": {
+ "name": "actor_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_user_id": {
+ "name": "actor_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "actor_agent_id": {
+ "name": "actor_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "from_stage_id": {
+ "name": "from_stage_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "to_stage_id": {
+ "name": "to_stage_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "payload": {
+ "name": "payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "pipeline_case_events_case_created_idx": {
+ "name": "pipeline_case_events_case_created_idx",
+ "columns": [
+ {
+ "expression": "case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_case_events_company_case_idx": {
+ "name": "pipeline_case_events_company_case_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "pipeline_case_events_company_id_companies_id_fk": {
+ "name": "pipeline_case_events_company_id_companies_id_fk",
+ "tableFrom": "pipeline_case_events",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "pipeline_case_events_case_id_pipeline_cases_id_fk": {
+ "name": "pipeline_case_events_case_id_pipeline_cases_id_fk",
+ "tableFrom": "pipeline_case_events",
+ "columnsFrom": [
+ "case_id"
+ ],
+ "tableTo": "pipeline_cases",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "pipeline_case_events_actor_agent_id_agents_id_fk": {
+ "name": "pipeline_case_events_actor_agent_id_agents_id_fk",
+ "tableFrom": "pipeline_case_events",
+ "columnsFrom": [
+ "actor_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "pipeline_case_events_from_stage_id_pipeline_stages_id_fk": {
+ "name": "pipeline_case_events_from_stage_id_pipeline_stages_id_fk",
+ "tableFrom": "pipeline_case_events",
+ "columnsFrom": [
+ "from_stage_id"
+ ],
+ "tableTo": "pipeline_stages",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "pipeline_case_events_to_stage_id_pipeline_stages_id_fk": {
+ "name": "pipeline_case_events_to_stage_id_pipeline_stages_id_fk",
+ "tableFrom": "pipeline_case_events",
+ "columnsFrom": [
+ "to_stage_id"
+ ],
+ "tableTo": "pipeline_stages",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "pipeline_case_events_type_check": {
+ "name": "pipeline_case_events_type_check",
+ "value": "\"pipeline_case_events\".\"type\" in (\n 'ingested',\n 'updated',\n 'claimed',\n 'lease_released',\n 'lease_expired',\n 'transitioned',\n 'transition_forced',\n 'transition_suggested',\n 'suggestion_resolved',\n 'review_decided',\n 'conversation_opened',\n 'issue_linked',\n 'issue_unlinked',\n 'automation_executed',\n 'automation_failed',\n 'automation_retry_requested',\n 'automation_effects_retired',\n 'automation_retry_dispatched',\n 'blockers_set',\n 'blockers_resolved',\n 'children_terminal',\n 'upstream_drift',\n 'drift_acknowledged'\n )"
+ },
+ "pipeline_case_events_actor_type_check": {
+ "name": "pipeline_case_events_actor_type_check",
+ "value": "\"pipeline_case_events\".\"actor_type\" in ('user', 'agent', 'system')"
+ },
+ "pipeline_case_events_agent_run_check": {
+ "name": "pipeline_case_events_agent_run_check",
+ "value": "\"pipeline_case_events\".\"actor_type\" <> 'agent' or \"pipeline_case_events\".\"run_id\" is not null"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.pipeline_case_issue_links": {
+ "name": "pipeline_case_issue_links",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "case_id": {
+ "name": "case_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_run_id": {
+ "name": "created_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "automation_attempt_id": {
+ "name": "automation_attempt_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "retired_at": {
+ "name": "retired_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "retired_by_attempt_id": {
+ "name": "retired_by_attempt_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "retired_reason": {
+ "name": "retired_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "pipeline_case_issue_links_case_issue_uq": {
+ "name": "pipeline_case_issue_links_case_issue_uq",
+ "columns": [
+ {
+ "expression": "case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_case_issue_links_issue_idx": {
+ "name": "pipeline_case_issue_links_issue_idx",
+ "columns": [
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_case_issue_links_company_case_idx": {
+ "name": "pipeline_case_issue_links_company_case_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_case_issue_links_automation_attempt_idx": {
+ "name": "pipeline_case_issue_links_automation_attempt_idx",
+ "columns": [
+ {
+ "expression": "automation_attempt_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "pipeline_case_issue_links_company_id_companies_id_fk": {
+ "name": "pipeline_case_issue_links_company_id_companies_id_fk",
+ "tableFrom": "pipeline_case_issue_links",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "pipeline_case_issue_links_case_id_pipeline_cases_id_fk": {
+ "name": "pipeline_case_issue_links_case_id_pipeline_cases_id_fk",
+ "tableFrom": "pipeline_case_issue_links",
+ "columnsFrom": [
+ "case_id"
+ ],
+ "tableTo": "pipeline_cases",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "pipeline_case_issue_links_issue_id_issues_id_fk": {
+ "name": "pipeline_case_issue_links_issue_id_issues_id_fk",
+ "tableFrom": "pipeline_case_issue_links",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "pipeline_case_issue_links_role_check": {
+ "name": "pipeline_case_issue_links_role_check",
+ "value": "\"pipeline_case_issue_links\".\"role\" in ('origin', 'conversation', 'work', 'automation')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.pipeline_cases": {
+ "name": "pipeline_cases",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pipeline_id": {
+ "name": "pipeline_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "stage_id": {
+ "name": "stage_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "case_key": {
+ "name": "case_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "summary": {
+ "name": "summary",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "fields": {
+ "name": "fields",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "workspace_ref": {
+ "name": "workspace_ref",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "parent_case_id": {
+ "name": "parent_case_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "parent_case_version": {
+ "name": "parent_case_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "request_key": {
+ "name": "request_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "automation_attempt_id": {
+ "name": "automation_attempt_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "version": {
+ "name": "version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "pending_suggestion": {
+ "name": "pending_suggestion",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lease_owner_type": {
+ "name": "lease_owner_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lease_agent_id": {
+ "name": "lease_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lease_user_id": {
+ "name": "lease_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lease_token": {
+ "name": "lease_token",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lease_expires_at": {
+ "name": "lease_expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "terminal_kind": {
+ "name": "terminal_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "terminal_at": {
+ "name": "terminal_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "retired_at": {
+ "name": "retired_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "retired_by_attempt_id": {
+ "name": "retired_by_attempt_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "retired_reason": {
+ "name": "retired_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "hidden_from_board_at": {
+ "name": "hidden_from_board_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "child_count": {
+ "name": "child_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "terminal_child_count": {
+ "name": "terminal_child_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "origin_run_id": {
+ "name": "origin_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "pipeline_cases_pipeline_case_key_uq": {
+ "name": "pipeline_cases_pipeline_case_key_uq",
+ "columns": [
+ {
+ "expression": "pipeline_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "case_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_cases_parent_request_key_uq": {
+ "name": "pipeline_cases_parent_request_key_uq",
+ "columns": [
+ {
+ "expression": "parent_case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "request_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"pipeline_cases\".\"request_key\" is not null and \"pipeline_cases\".\"retired_at\" is null",
+ "concurrently": false
+ },
+ "pipeline_cases_company_idx": {
+ "name": "pipeline_cases_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_cases_pipeline_stage_idx": {
+ "name": "pipeline_cases_pipeline_stage_idx",
+ "columns": [
+ {
+ "expression": "pipeline_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "stage_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_cases_parent_idx": {
+ "name": "pipeline_cases_parent_idx",
+ "columns": [
+ {
+ "expression": "parent_case_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_cases_automation_attempt_idx": {
+ "name": "pipeline_cases_automation_attempt_idx",
+ "columns": [
+ {
+ "expression": "automation_attempt_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_cases_retired_idx": {
+ "name": "pipeline_cases_retired_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "retired_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_cases_lease_expires_idx": {
+ "name": "pipeline_cases_lease_expires_idx",
+ "columns": [
+ {
+ "expression": "lease_expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "where": "\"pipeline_cases\".\"lease_expires_at\" is not null",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "pipeline_cases_company_id_companies_id_fk": {
+ "name": "pipeline_cases_company_id_companies_id_fk",
+ "tableFrom": "pipeline_cases",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "pipeline_cases_pipeline_id_pipelines_id_fk": {
+ "name": "pipeline_cases_pipeline_id_pipelines_id_fk",
+ "tableFrom": "pipeline_cases",
+ "columnsFrom": [
+ "pipeline_id"
+ ],
+ "tableTo": "pipelines",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "pipeline_cases_stage_id_pipeline_stages_id_fk": {
+ "name": "pipeline_cases_stage_id_pipeline_stages_id_fk",
+ "tableFrom": "pipeline_cases",
+ "columnsFrom": [
+ "stage_id"
+ ],
+ "tableTo": "pipeline_stages",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "pipeline_cases_parent_case_id_pipeline_cases_id_fk": {
+ "name": "pipeline_cases_parent_case_id_pipeline_cases_id_fk",
+ "tableFrom": "pipeline_cases",
+ "columnsFrom": [
+ "parent_case_id"
+ ],
+ "tableTo": "pipeline_cases",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "pipeline_cases_lease_agent_id_agents_id_fk": {
+ "name": "pipeline_cases_lease_agent_id_agents_id_fk",
+ "tableFrom": "pipeline_cases",
+ "columnsFrom": [
+ "lease_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "pipeline_cases_created_by_agent_id_agents_id_fk": {
+ "name": "pipeline_cases_created_by_agent_id_agents_id_fk",
+ "tableFrom": "pipeline_cases",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "pipeline_cases_terminal_kind_check": {
+ "name": "pipeline_cases_terminal_kind_check",
+ "value": "\"pipeline_cases\".\"terminal_kind\" is null or \"pipeline_cases\".\"terminal_kind\" in ('done', 'cancelled')"
+ },
+ "pipeline_cases_lease_owner_type_check": {
+ "name": "pipeline_cases_lease_owner_type_check",
+ "value": "\"pipeline_cases\".\"lease_owner_type\" is null or \"pipeline_cases\".\"lease_owner_type\" in ('user', 'agent')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.pipeline_documents": {
+ "name": "pipeline_documents",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pipeline_id": {
+ "name": "pipeline_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "pipeline_documents_company_pipeline_key_uq": {
+ "name": "pipeline_documents_company_pipeline_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "pipeline_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_documents_document_uq": {
+ "name": "pipeline_documents_document_uq",
+ "columns": [
+ {
+ "expression": "document_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_documents_company_pipeline_updated_idx": {
+ "name": "pipeline_documents_company_pipeline_updated_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "pipeline_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "pipeline_documents_company_id_companies_id_fk": {
+ "name": "pipeline_documents_company_id_companies_id_fk",
+ "tableFrom": "pipeline_documents",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "pipeline_documents_pipeline_id_pipelines_id_fk": {
+ "name": "pipeline_documents_pipeline_id_pipelines_id_fk",
+ "tableFrom": "pipeline_documents",
+ "columnsFrom": [
+ "pipeline_id"
+ ],
+ "tableTo": "pipelines",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "pipeline_documents_document_id_documents_id_fk": {
+ "name": "pipeline_documents_document_id_documents_id_fk",
+ "tableFrom": "pipeline_documents",
+ "columnsFrom": [
+ "document_id"
+ ],
+ "tableTo": "documents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.pipeline_stages": {
+ "name": "pipeline_stages",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "pipeline_id": {
+ "name": "pipeline_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "position": {
+ "name": "position",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "config": {
+ "name": "config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "pipeline_stages_pipeline_key_uq": {
+ "name": "pipeline_stages_pipeline_key_uq",
+ "columns": [
+ {
+ "expression": "pipeline_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_stages_pipeline_position_idx": {
+ "name": "pipeline_stages_pipeline_position_idx",
+ "columns": [
+ {
+ "expression": "pipeline_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "position",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "pipeline_stages_pipeline_id_pipelines_id_fk": {
+ "name": "pipeline_stages_pipeline_id_pipelines_id_fk",
+ "tableFrom": "pipeline_stages",
+ "columnsFrom": [
+ "pipeline_id"
+ ],
+ "tableTo": "pipelines",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "pipeline_stages_kind_check": {
+ "name": "pipeline_stages_kind_check",
+ "value": "\"pipeline_stages\".\"kind\" in ('working', 'review', 'done', 'cancelled')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.pipeline_transitions": {
+ "name": "pipeline_transitions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "pipeline_id": {
+ "name": "pipeline_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "from_stage_id": {
+ "name": "from_stage_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "to_stage_id": {
+ "name": "to_stage_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "label": {
+ "name": "label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "pipeline_transitions_pipeline_edge_uq": {
+ "name": "pipeline_transitions_pipeline_edge_uq",
+ "columns": [
+ {
+ "expression": "pipeline_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "from_stage_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "to_stage_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_transitions_pipeline_from_idx": {
+ "name": "pipeline_transitions_pipeline_from_idx",
+ "columns": [
+ {
+ "expression": "pipeline_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "from_stage_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipeline_transitions_pipeline_to_idx": {
+ "name": "pipeline_transitions_pipeline_to_idx",
+ "columns": [
+ {
+ "expression": "pipeline_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "to_stage_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "pipeline_transitions_pipeline_id_pipelines_id_fk": {
+ "name": "pipeline_transitions_pipeline_id_pipelines_id_fk",
+ "tableFrom": "pipeline_transitions",
+ "columnsFrom": [
+ "pipeline_id"
+ ],
+ "tableTo": "pipelines",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "pipeline_transitions_from_stage_id_pipeline_stages_id_fk": {
+ "name": "pipeline_transitions_from_stage_id_pipeline_stages_id_fk",
+ "tableFrom": "pipeline_transitions",
+ "columnsFrom": [
+ "from_stage_id"
+ ],
+ "tableTo": "pipeline_stages",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "pipeline_transitions_to_stage_id_pipeline_stages_id_fk": {
+ "name": "pipeline_transitions_to_stage_id_pipeline_stages_id_fk",
+ "tableFrom": "pipeline_transitions",
+ "columnsFrom": [
+ "to_stage_id"
+ ],
+ "tableTo": "pipeline_stages",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.pipelines": {
+ "name": "pipelines",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enforce_transitions": {
+ "name": "enforce_transitions",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "pipelines_company_key_uq": {
+ "name": "pipelines_company_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipelines_company_idx": {
+ "name": "pipelines_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "pipelines_company_project_idx": {
+ "name": "pipelines_company_project_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "pipelines_company_id_companies_id_fk": {
+ "name": "pipelines_company_id_companies_id_fk",
+ "tableFrom": "pipelines",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "pipelines_project_id_projects_id_fk": {
+ "name": "pipelines_project_id_projects_id_fk",
+ "tableFrom": "pipelines",
+ "columnsFrom": [
+ "project_id"
+ ],
+ "tableTo": "projects",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "pipelines_created_by_agent_id_agents_id_fk": {
+ "name": "pipelines_created_by_agent_id_agents_id_fk",
+ "tableFrom": "pipelines",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.plugin_company_settings": {
+ "name": "plugin_company_settings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "plugin_id": {
+ "name": "plugin_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "settings_json": {
+ "name": "settings_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "plugin_company_settings_company_idx": {
+ "name": "plugin_company_settings_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_company_settings_plugin_idx": {
+ "name": "plugin_company_settings_plugin_idx",
+ "columns": [
+ {
+ "expression": "plugin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_company_settings_company_plugin_uq": {
+ "name": "plugin_company_settings_company_plugin_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "plugin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "plugin_company_settings_company_id_companies_id_fk": {
+ "name": "plugin_company_settings_company_id_companies_id_fk",
+ "tableFrom": "plugin_company_settings",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "plugin_company_settings_plugin_id_plugins_id_fk": {
+ "name": "plugin_company_settings_plugin_id_plugins_id_fk",
+ "tableFrom": "plugin_company_settings",
+ "columnsFrom": [
+ "plugin_id"
+ ],
+ "tableTo": "plugins",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.plugin_config": {
+ "name": "plugin_config",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "plugin_id": {
+ "name": "plugin_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "config_json": {
+ "name": "config_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "plugin_config_plugin_company_idx": {
+ "name": "plugin_config_plugin_company_idx",
+ "columns": [
+ {
+ "expression": "plugin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "plugin_config_plugin_id_plugins_id_fk": {
+ "name": "plugin_config_plugin_id_plugins_id_fk",
+ "tableFrom": "plugin_config",
+ "columnsFrom": [
+ "plugin_id"
+ ],
+ "tableTo": "plugins",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "plugin_config_company_id_companies_id_fk": {
+ "name": "plugin_config_company_id_companies_id_fk",
+ "tableFrom": "plugin_config",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.plugin_database_namespaces": {
+ "name": "plugin_database_namespaces",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "plugin_id": {
+ "name": "plugin_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "plugin_key": {
+ "name": "plugin_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "namespace_name": {
+ "name": "namespace_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "namespace_mode": {
+ "name": "namespace_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'schema'"
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "plugin_database_namespaces_plugin_idx": {
+ "name": "plugin_database_namespaces_plugin_idx",
+ "columns": [
+ {
+ "expression": "plugin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_database_namespaces_namespace_idx": {
+ "name": "plugin_database_namespaces_namespace_idx",
+ "columns": [
+ {
+ "expression": "namespace_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_database_namespaces_status_idx": {
+ "name": "plugin_database_namespaces_status_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "plugin_database_namespaces_plugin_id_plugins_id_fk": {
+ "name": "plugin_database_namespaces_plugin_id_plugins_id_fk",
+ "tableFrom": "plugin_database_namespaces",
+ "columnsFrom": [
+ "plugin_id"
+ ],
+ "tableTo": "plugins",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.plugin_entities": {
+ "name": "plugin_entities",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "plugin_id": {
+ "name": "plugin_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope_kind": {
+ "name": "scope_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope_id": {
+ "name": "scope_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "data": {
+ "name": "data",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "plugin_entities_plugin_idx": {
+ "name": "plugin_entities_plugin_idx",
+ "columns": [
+ {
+ "expression": "plugin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_entities_company_idx": {
+ "name": "plugin_entities_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_entities_type_idx": {
+ "name": "plugin_entities_type_idx",
+ "columns": [
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_entities_scope_idx": {
+ "name": "plugin_entities_scope_idx",
+ "columns": [
+ {
+ "expression": "scope_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scope_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "plugin_entities_plugin_id_plugins_id_fk": {
+ "name": "plugin_entities_plugin_id_plugins_id_fk",
+ "tableFrom": "plugin_entities",
+ "columnsFrom": [
+ "plugin_id"
+ ],
+ "tableTo": "plugins",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "plugin_entities_company_id_companies_id_fk": {
+ "name": "plugin_entities_company_id_companies_id_fk",
+ "tableFrom": "plugin_entities",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "plugin_entities_external_idx": {
+ "name": "plugin_entities_external_idx",
+ "columns": [
+ "company_id",
+ "plugin_id",
+ "entity_type",
+ "external_id"
+ ],
+ "nullsNotDistinct": true
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.plugin_job_runs": {
+ "name": "plugin_job_runs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "job_id": {
+ "name": "job_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "plugin_id": {
+ "name": "plugin_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "trigger": {
+ "name": "trigger",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "duration_ms": {
+ "name": "duration_ms",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "logs": {
+ "name": "logs",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "finished_at": {
+ "name": "finished_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "plugin_job_runs_job_idx": {
+ "name": "plugin_job_runs_job_idx",
+ "columns": [
+ {
+ "expression": "job_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_job_runs_plugin_idx": {
+ "name": "plugin_job_runs_plugin_idx",
+ "columns": [
+ {
+ "expression": "plugin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_job_runs_company_idx": {
+ "name": "plugin_job_runs_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_job_runs_status_idx": {
+ "name": "plugin_job_runs_status_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "plugin_job_runs_job_id_plugin_jobs_id_fk": {
+ "name": "plugin_job_runs_job_id_plugin_jobs_id_fk",
+ "tableFrom": "plugin_job_runs",
+ "columnsFrom": [
+ "job_id"
+ ],
+ "tableTo": "plugin_jobs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "plugin_job_runs_plugin_id_plugins_id_fk": {
+ "name": "plugin_job_runs_plugin_id_plugins_id_fk",
+ "tableFrom": "plugin_job_runs",
+ "columnsFrom": [
+ "plugin_id"
+ ],
+ "tableTo": "plugins",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "plugin_job_runs_company_id_companies_id_fk": {
+ "name": "plugin_job_runs_company_id_companies_id_fk",
+ "tableFrom": "plugin_job_runs",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.plugin_jobs": {
+ "name": "plugin_jobs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "plugin_id": {
+ "name": "plugin_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "job_key": {
+ "name": "job_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "schedule": {
+ "name": "schedule",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "last_run_at": {
+ "name": "last_run_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "next_run_at": {
+ "name": "next_run_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "plugin_jobs_plugin_idx": {
+ "name": "plugin_jobs_plugin_idx",
+ "columns": [
+ {
+ "expression": "plugin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_jobs_next_run_idx": {
+ "name": "plugin_jobs_next_run_idx",
+ "columns": [
+ {
+ "expression": "next_run_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_jobs_unique_idx": {
+ "name": "plugin_jobs_unique_idx",
+ "columns": [
+ {
+ "expression": "plugin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "job_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "plugin_jobs_plugin_id_plugins_id_fk": {
+ "name": "plugin_jobs_plugin_id_plugins_id_fk",
+ "tableFrom": "plugin_jobs",
+ "columnsFrom": [
+ "plugin_id"
+ ],
+ "tableTo": "plugins",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.plugin_lifecycle_acknowledgments": {
+ "name": "plugin_lifecycle_acknowledgments",
+ "schema": "",
+ "columns": {
+ "plugin_id": {
+ "name": "plugin_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "event_id": {
+ "name": "event_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "acknowledged_at": {
+ "name": "acknowledged_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "plugin_lifecycle_acknowledgments_event_idx": {
+ "name": "plugin_lifecycle_acknowledgments_event_idx",
+ "columns": [
+ {
+ "expression": "event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "plugin_lifecycle_acknowledgments_plugin_id_plugins_id_fk": {
+ "name": "plugin_lifecycle_acknowledgments_plugin_id_plugins_id_fk",
+ "tableFrom": "plugin_lifecycle_acknowledgments",
+ "columnsFrom": [
+ "plugin_id"
+ ],
+ "tableTo": "plugins",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "plugin_lifecycle_acknowledgments_event_id_resource_lifecycle_events_id_fk": {
+ "name": "plugin_lifecycle_acknowledgments_event_id_resource_lifecycle_events_id_fk",
+ "tableFrom": "plugin_lifecycle_acknowledgments",
+ "columnsFrom": [
+ "event_id"
+ ],
+ "tableTo": "resource_lifecycle_events",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {
+ "plugin_lifecycle_acknowledgments_plugin_id_event_id_pk": {
+ "name": "plugin_lifecycle_acknowledgments_plugin_id_event_id_pk",
+ "columns": [
+ "plugin_id",
+ "event_id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.plugin_logs": {
+ "name": "plugin_logs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "plugin_id": {
+ "name": "plugin_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "level": {
+ "name": "level",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'info'"
+ },
+ "message": {
+ "name": "message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "meta": {
+ "name": "meta",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "plugin_logs_plugin_time_idx": {
+ "name": "plugin_logs_plugin_time_idx",
+ "columns": [
+ {
+ "expression": "plugin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_logs_company_idx": {
+ "name": "plugin_logs_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_logs_level_idx": {
+ "name": "plugin_logs_level_idx",
+ "columns": [
+ {
+ "expression": "level",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "plugin_logs_plugin_id_plugins_id_fk": {
+ "name": "plugin_logs_plugin_id_plugins_id_fk",
+ "tableFrom": "plugin_logs",
+ "columnsFrom": [
+ "plugin_id"
+ ],
+ "tableTo": "plugins",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "plugin_logs_company_id_companies_id_fk": {
+ "name": "plugin_logs_company_id_companies_id_fk",
+ "tableFrom": "plugin_logs",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.plugin_managed_resources": {
+ "name": "plugin_managed_resources",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "plugin_id": {
+ "name": "plugin_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "plugin_key": {
+ "name": "plugin_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_kind": {
+ "name": "resource_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_key": {
+ "name": "resource_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_id": {
+ "name": "resource_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "defaults_json": {
+ "name": "defaults_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "plugin_managed_resources_company_idx": {
+ "name": "plugin_managed_resources_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_managed_resources_plugin_idx": {
+ "name": "plugin_managed_resources_plugin_idx",
+ "columns": [
+ {
+ "expression": "plugin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_managed_resources_resource_idx": {
+ "name": "plugin_managed_resources_resource_idx",
+ "columns": [
+ {
+ "expression": "resource_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_managed_resources_company_plugin_resource_uq": {
+ "name": "plugin_managed_resources_company_plugin_resource_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "plugin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "plugin_managed_resources_company_id_companies_id_fk": {
+ "name": "plugin_managed_resources_company_id_companies_id_fk",
+ "tableFrom": "plugin_managed_resources",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "plugin_managed_resources_plugin_id_plugins_id_fk": {
+ "name": "plugin_managed_resources_plugin_id_plugins_id_fk",
+ "tableFrom": "plugin_managed_resources",
+ "columnsFrom": [
+ "plugin_id"
+ ],
+ "tableTo": "plugins",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.plugin_migrations": {
+ "name": "plugin_migrations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "plugin_id": {
+ "name": "plugin_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "plugin_key": {
+ "name": "plugin_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "namespace_name": {
+ "name": "namespace_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "migration_key": {
+ "name": "migration_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "checksum": {
+ "name": "checksum",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "plugin_version": {
+ "name": "plugin_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "applied_at": {
+ "name": "applied_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "plugin_migrations_plugin_key_idx": {
+ "name": "plugin_migrations_plugin_key_idx",
+ "columns": [
+ {
+ "expression": "plugin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "migration_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_migrations_plugin_idx": {
+ "name": "plugin_migrations_plugin_idx",
+ "columns": [
+ {
+ "expression": "plugin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_migrations_status_idx": {
+ "name": "plugin_migrations_status_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "plugin_migrations_plugin_id_plugins_id_fk": {
+ "name": "plugin_migrations_plugin_id_plugins_id_fk",
+ "tableFrom": "plugin_migrations",
+ "columnsFrom": [
+ "plugin_id"
+ ],
+ "tableTo": "plugins",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.plugin_state": {
+ "name": "plugin_state",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "plugin_id": {
+ "name": "plugin_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope_kind": {
+ "name": "scope_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope_id": {
+ "name": "scope_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "namespace": {
+ "name": "namespace",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'default'"
+ },
+ "state_key": {
+ "name": "state_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value_json": {
+ "name": "value_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "plugin_state_plugin_scope_idx": {
+ "name": "plugin_state_plugin_scope_idx",
+ "columns": [
+ {
+ "expression": "plugin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scope_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "plugin_state_plugin_id_plugins_id_fk": {
+ "name": "plugin_state_plugin_id_plugins_id_fk",
+ "tableFrom": "plugin_state",
+ "columnsFrom": [
+ "plugin_id"
+ ],
+ "tableTo": "plugins",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "plugin_state_unique_entry_idx": {
+ "name": "plugin_state_unique_entry_idx",
+ "columns": [
+ "plugin_id",
+ "scope_kind",
+ "scope_id",
+ "namespace",
+ "state_key"
+ ],
+ "nullsNotDistinct": true
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.plugin_webhook_deliveries": {
+ "name": "plugin_webhook_deliveries",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "plugin_id": {
+ "name": "plugin_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "webhook_key": {
+ "name": "webhook_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "duration_ms": {
+ "name": "duration_ms",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "payload": {
+ "name": "payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "headers": {
+ "name": "headers",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "finished_at": {
+ "name": "finished_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "plugin_webhook_deliveries_plugin_idx": {
+ "name": "plugin_webhook_deliveries_plugin_idx",
+ "columns": [
+ {
+ "expression": "plugin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_webhook_deliveries_company_idx": {
+ "name": "plugin_webhook_deliveries_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_webhook_deliveries_status_idx": {
+ "name": "plugin_webhook_deliveries_status_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugin_webhook_deliveries_key_idx": {
+ "name": "plugin_webhook_deliveries_key_idx",
+ "columns": [
+ {
+ "expression": "webhook_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "plugin_webhook_deliveries_plugin_id_plugins_id_fk": {
+ "name": "plugin_webhook_deliveries_plugin_id_plugins_id_fk",
+ "tableFrom": "plugin_webhook_deliveries",
+ "columnsFrom": [
+ "plugin_id"
+ ],
+ "tableTo": "plugins",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "plugin_webhook_deliveries_company_id_companies_id_fk": {
+ "name": "plugin_webhook_deliveries_company_id_companies_id_fk",
+ "tableFrom": "plugin_webhook_deliveries",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.plugins": {
+ "name": "plugins",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "plugin_key": {
+ "name": "plugin_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "package_name": {
+ "name": "package_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "version": {
+ "name": "version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "api_version": {
+ "name": "api_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "categories": {
+ "name": "categories",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "manifest_json": {
+ "name": "manifest_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'installed'"
+ },
+ "install_order": {
+ "name": "install_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "package_path": {
+ "name": "package_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "installed_at": {
+ "name": "installed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "plugins_plugin_key_idx": {
+ "name": "plugins_plugin_key_idx",
+ "columns": [
+ {
+ "expression": "plugin_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "plugins_status_idx": {
+ "name": "plugins_status_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.principal_permission_grants": {
+ "name": "principal_permission_grants",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "principal_type": {
+ "name": "principal_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "principal_id": {
+ "name": "principal_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "permission_key": {
+ "name": "permission_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope": {
+ "name": "scope",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "granted_by_user_id": {
+ "name": "granted_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "principal_permission_grants_unique_idx": {
+ "name": "principal_permission_grants_unique_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "principal_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "principal_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "permission_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "principal_permission_grants_company_permission_idx": {
+ "name": "principal_permission_grants_company_permission_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "permission_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "principal_permission_grants_company_id_companies_id_fk": {
+ "name": "principal_permission_grants_company_id_companies_id_fk",
+ "tableFrom": "principal_permission_grants",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.project_access_members": {
+ "name": "project_access_members",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_type": {
+ "name": "subject_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_id": {
+ "name": "subject_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "project_access_members_project_subject_uq": {
+ "name": "project_access_members_project_subject_uq",
+ "columns": [
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "project_access_members_subject_lookup_idx": {
+ "name": "project_access_members_subject_lookup_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "project_access_members_company_id_companies_id_fk": {
+ "name": "project_access_members_company_id_companies_id_fk",
+ "tableFrom": "project_access_members",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "project_access_members_project_id_projects_id_fk": {
+ "name": "project_access_members_project_id_projects_id_fk",
+ "tableFrom": "project_access_members",
+ "columnsFrom": [
+ "project_id"
+ ],
+ "tableTo": "projects",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "project_access_members_subject_type_check": {
+ "name": "project_access_members_subject_type_check",
+ "value": "\"project_access_members\".\"subject_type\" in ('user', 'agent')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.project_goals": {
+ "name": "project_goals",
+ "schema": "",
+ "columns": {
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "goal_id": {
+ "name": "goal_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "project_goals_project_idx": {
+ "name": "project_goals_project_idx",
+ "columns": [
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "project_goals_goal_idx": {
+ "name": "project_goals_goal_idx",
+ "columns": [
+ {
+ "expression": "goal_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "project_goals_company_idx": {
+ "name": "project_goals_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "project_goals_project_id_projects_id_fk": {
+ "name": "project_goals_project_id_projects_id_fk",
+ "tableFrom": "project_goals",
+ "columnsFrom": [
+ "project_id"
+ ],
+ "tableTo": "projects",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "project_goals_goal_id_goals_id_fk": {
+ "name": "project_goals_goal_id_goals_id_fk",
+ "tableFrom": "project_goals",
+ "columnsFrom": [
+ "goal_id"
+ ],
+ "tableTo": "goals",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "project_goals_company_id_companies_id_fk": {
+ "name": "project_goals_company_id_companies_id_fk",
+ "tableFrom": "project_goals",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "project_goals_project_id_goal_id_pk": {
+ "name": "project_goals_project_id_goal_id_pk",
+ "columns": [
+ "project_id",
+ "goal_id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.project_memberships": {
+ "name": "project_memberships",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "state": {
+ "name": "state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'joined'"
+ },
+ "starred_at": {
+ "name": "starred_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "project_memberships_company_user_idx": {
+ "name": "project_memberships_company_user_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "project_memberships_company_user_starred_idx": {
+ "name": "project_memberships_company_user_starred_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "starred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "project_memberships_project_idx": {
+ "name": "project_memberships_project_idx",
+ "columns": [
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "project_memberships_company_user_project_uq": {
+ "name": "project_memberships_company_user_project_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "project_memberships_company_id_companies_id_fk": {
+ "name": "project_memberships_company_id_companies_id_fk",
+ "tableFrom": "project_memberships",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "project_memberships_project_id_projects_id_fk": {
+ "name": "project_memberships_project_id_projects_id_fk",
+ "tableFrom": "project_memberships",
+ "columnsFrom": [
+ "project_id"
+ ],
+ "tableTo": "projects",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.project_workspaces": {
+ "name": "project_workspaces",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_type": {
+ "name": "source_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'local_path'"
+ },
+ "cwd": {
+ "name": "cwd",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "repo_url": {
+ "name": "repo_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "repo_ref": {
+ "name": "repo_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "default_ref": {
+ "name": "default_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "visibility": {
+ "name": "visibility",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'default'"
+ },
+ "setup_command": {
+ "name": "setup_command",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cleanup_command": {
+ "name": "cleanup_command",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "remote_provider": {
+ "name": "remote_provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "remote_workspace_ref": {
+ "name": "remote_workspace_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "shared_workspace_key": {
+ "name": "shared_workspace_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_primary": {
+ "name": "is_primary",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "project_workspaces_company_project_idx": {
+ "name": "project_workspaces_company_project_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "project_workspaces_project_primary_idx": {
+ "name": "project_workspaces_project_primary_idx",
+ "columns": [
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "is_primary",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "project_workspaces_project_source_type_idx": {
+ "name": "project_workspaces_project_source_type_idx",
+ "columns": [
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "project_workspaces_company_shared_key_idx": {
+ "name": "project_workspaces_company_shared_key_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "shared_workspace_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "project_workspaces_project_remote_ref_idx": {
+ "name": "project_workspaces_project_remote_ref_idx",
+ "columns": [
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "remote_provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "remote_workspace_ref",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "project_workspaces_company_id_companies_id_fk": {
+ "name": "project_workspaces_company_id_companies_id_fk",
+ "tableFrom": "project_workspaces",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "project_workspaces_project_id_projects_id_fk": {
+ "name": "project_workspaces_project_id_projects_id_fk",
+ "tableFrom": "project_workspaces",
+ "columnsFrom": [
+ "project_id"
+ ],
+ "tableTo": "projects",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.projects": {
+ "name": "projects",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "goal_id": {
+ "name": "goal_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "visibility": {
+ "name": "visibility",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'open'"
+ },
+ "privacy_owner_user_id": {
+ "name": "privacy_owner_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "personal_owner_user_id": {
+ "name": "personal_owner_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'backlog'"
+ },
+ "lead_agent_id": {
+ "name": "lead_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "target_date": {
+ "name": "target_date",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "color": {
+ "name": "color",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "icon": {
+ "name": "icon",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "env": {
+ "name": "env",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "pause_reason": {
+ "name": "pause_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "paused_at": {
+ "name": "paused_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "execution_workspace_policy": {
+ "name": "execution_workspace_policy",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "projects_company_idx": {
+ "name": "projects_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "projects_company_personal_owner_uq": {
+ "name": "projects_company_personal_owner_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "personal_owner_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"projects\".\"personal_owner_user_id\" is not null",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "projects_company_id_companies_id_fk": {
+ "name": "projects_company_id_companies_id_fk",
+ "tableFrom": "projects",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "projects_goal_id_goals_id_fk": {
+ "name": "projects_goal_id_goals_id_fk",
+ "tableFrom": "projects",
+ "columnsFrom": [
+ "goal_id"
+ ],
+ "tableTo": "goals",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "projects_lead_agent_id_agents_id_fk": {
+ "name": "projects_lead_agent_id_agents_id_fk",
+ "tableFrom": "projects",
+ "columnsFrom": [
+ "lead_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "projects_visibility_check": {
+ "name": "projects_visibility_check",
+ "value": "\"projects\".\"visibility\" in ('open', 'private')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.provider_trace_records": {
+ "name": "provider_trace_records",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'capturing'"
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "trace_ref": {
+ "name": "trace_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "frame_count": {
+ "name": "frame_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "byte_count": {
+ "name": "byte_count",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "digest": {
+ "name": "digest",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "reason": {
+ "name": "reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "requested_by": {
+ "name": "requested_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "provider_trace_records_run_unique": {
+ "name": "provider_trace_records_run_unique",
+ "columns": [
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "provider_trace_records_expiry_idx": {
+ "name": "provider_trace_records_expiry_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "provider_trace_records_company_created_idx": {
+ "name": "provider_trace_records_company_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "provider_trace_records_company_id_companies_id_fk": {
+ "name": "provider_trace_records_company_id_companies_id_fk",
+ "tableFrom": "provider_trace_records",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "provider_trace_records_run_id_heartbeat_runs_id_fk": {
+ "name": "provider_trace_records_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "provider_trace_records",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.remote_agent_profiles": {
+ "name": "remote_agent_profiles",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "profile_key": {
+ "name": "profile_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "display_name": {
+ "name": "display_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "service": {
+ "name": "service",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "configuration": {
+ "name": "configuration",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "retention_acknowledged": {
+ "name": "retention_acknowledged",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "qualification": {
+ "name": "qualification",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "qualified_at": {
+ "name": "qualified_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "qualified_revision": {
+ "name": "qualified_revision",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "remote_agent_profiles_company_idx": {
+ "name": "remote_agent_profiles_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "remote_agent_profiles_company_key_uq": {
+ "name": "remote_agent_profiles_company_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "profile_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "remote_agent_profiles_company_id_companies_id_fk": {
+ "name": "remote_agent_profiles_company_id_companies_id_fk",
+ "tableFrom": "remote_agent_profiles",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "remote_agent_profiles_service_check": {
+ "name": "remote_agent_profiles_service_check",
+ "value": "\"remote_agent_profiles\".\"service\" = 'aws_bedrock_agentcore_harness'"
+ },
+ "remote_agent_profiles_qualified_revision_check": {
+ "name": "remote_agent_profiles_qualified_revision_check",
+ "value": "(\"remote_agent_profiles\".\"qualified_at\" IS NULL AND \"remote_agent_profiles\".\"qualified_revision\" IS NULL) OR (\"remote_agent_profiles\".\"qualified_at\" IS NOT NULL AND \"remote_agent_profiles\".\"qualification\" <> '{}'::jsonb AND \"remote_agent_profiles\".\"qualified_revision\" ~ '^sha256:[0-9a-f]{64}$')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.resource_lifecycle_events": {
+ "name": "resource_lifecycle_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigint",
+ "primaryKey": true,
+ "notNull": true,
+ "identity": {
+ "name": "resource_lifecycle_events_id_seq",
+ "increment": "1",
+ "minValue": "1",
+ "maxValue": "9223372036854775807",
+ "startWith": "1",
+ "cache": "1",
+ "cycle": false,
+ "schema": "public",
+ "type": "always"
+ }
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_type": {
+ "name": "resource_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_id": {
+ "name": "resource_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "action": {
+ "name": "action",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "resource_lifecycle_events_creation_idx": {
+ "name": "resource_lifecycle_events_creation_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"resource_lifecycle_events\".\"action\" = 'create'",
+ "concurrently": false
+ },
+ "resource_lifecycle_events_company_idx": {
+ "name": "resource_lifecycle_events_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "resource_lifecycle_events_resource_order_idx": {
+ "name": "resource_lifecycle_events_resource_order_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "resource_lifecycle_events_company_id_companies_id_fk": {
+ "name": "resource_lifecycle_events_company_id_companies_id_fk",
+ "tableFrom": "resource_lifecycle_events",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "resource_lifecycle_events_resource_type_check": {
+ "name": "resource_lifecycle_events_resource_type_check",
+ "value": "\"resource_lifecycle_events\".\"resource_type\" IN ('agent', 'project')"
+ },
+ "resource_lifecycle_events_action_check": {
+ "name": "resource_lifecycle_events_action_check",
+ "value": "\"resource_lifecycle_events\".\"action\" = 'create' OR (\"resource_lifecycle_events\".\"resource_type\" = 'project' AND \"resource_lifecycle_events\".\"action\" IN ('update', 'archive')) OR (\"resource_lifecycle_events\".\"resource_type\" = 'agent' AND \"resource_lifecycle_events\".\"action\" IN ('pause', 'resume', 'terminate'))"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.routine_documents": {
+ "name": "routine_documents",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "routine_id": {
+ "name": "routine_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "routine_documents_company_routine_key_uq": {
+ "name": "routine_documents_company_routine_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "routine_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "routine_documents_document_uq": {
+ "name": "routine_documents_document_uq",
+ "columns": [
+ {
+ "expression": "document_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "routine_documents_company_routine_updated_idx": {
+ "name": "routine_documents_company_routine_updated_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "routine_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "routine_documents_company_id_companies_id_fk": {
+ "name": "routine_documents_company_id_companies_id_fk",
+ "tableFrom": "routine_documents",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "routine_documents_routine_id_routines_id_fk": {
+ "name": "routine_documents_routine_id_routines_id_fk",
+ "tableFrom": "routine_documents",
+ "columnsFrom": [
+ "routine_id"
+ ],
+ "tableTo": "routines",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "routine_documents_document_id_documents_id_fk": {
+ "name": "routine_documents_document_id_documents_id_fk",
+ "tableFrom": "routine_documents",
+ "columnsFrom": [
+ "document_id"
+ ],
+ "tableTo": "documents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.routine_revisions": {
+ "name": "routine_revisions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "routine_id": {
+ "name": "routine_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revision_number": {
+ "name": "revision_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "snapshot": {
+ "name": "snapshot",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "change_summary": {
+ "name": "change_summary",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "restored_from_revision_id": {
+ "name": "restored_from_revision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_run_id": {
+ "name": "created_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "responsible_user_id": {
+ "name": "responsible_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "routine_revisions_routine_revision_uq": {
+ "name": "routine_revisions_routine_revision_uq",
+ "columns": [
+ {
+ "expression": "routine_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "revision_number",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "routine_revisions_company_routine_created_idx": {
+ "name": "routine_revisions_company_routine_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "routine_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "routine_revisions_company_responsible_user_idx": {
+ "name": "routine_revisions_company_responsible_user_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "responsible_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "routine_revisions_company_id_companies_id_fk": {
+ "name": "routine_revisions_company_id_companies_id_fk",
+ "tableFrom": "routine_revisions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "routine_revisions_routine_id_routines_id_fk": {
+ "name": "routine_revisions_routine_id_routines_id_fk",
+ "tableFrom": "routine_revisions",
+ "columnsFrom": [
+ "routine_id"
+ ],
+ "tableTo": "routines",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "routine_revisions_restored_from_revision_id_routine_revisions_id_fk": {
+ "name": "routine_revisions_restored_from_revision_id_routine_revisions_id_fk",
+ "tableFrom": "routine_revisions",
+ "columnsFrom": [
+ "restored_from_revision_id"
+ ],
+ "tableTo": "routine_revisions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "routine_revisions_created_by_agent_id_agents_id_fk": {
+ "name": "routine_revisions_created_by_agent_id_agents_id_fk",
+ "tableFrom": "routine_revisions",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "routine_revisions_created_by_run_id_heartbeat_runs_id_fk": {
+ "name": "routine_revisions_created_by_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "routine_revisions",
+ "columnsFrom": [
+ "created_by_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.routine_runs": {
+ "name": "routine_runs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "routine_id": {
+ "name": "routine_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "trigger_id": {
+ "name": "trigger_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source": {
+ "name": "source",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'received'"
+ },
+ "triggered_at": {
+ "name": "triggered_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "routine_revision_id": {
+ "name": "routine_revision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "responsible_user_id": {
+ "name": "responsible_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "trigger_payload": {
+ "name": "trigger_payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "dispatch_fingerprint": {
+ "name": "dispatch_fingerprint",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "linked_issue_id": {
+ "name": "linked_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "coalesced_into_run_id": {
+ "name": "coalesced_into_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "failure_reason": {
+ "name": "failure_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "routine_runs_company_routine_idx": {
+ "name": "routine_runs_company_routine_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "routine_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "routine_runs_revision_idx": {
+ "name": "routine_runs_revision_idx",
+ "columns": [
+ {
+ "expression": "routine_revision_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "routine_runs_company_responsible_user_idx": {
+ "name": "routine_runs_company_responsible_user_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "responsible_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "routine_runs_trigger_idx": {
+ "name": "routine_runs_trigger_idx",
+ "columns": [
+ {
+ "expression": "trigger_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "routine_runs_dispatch_fingerprint_idx": {
+ "name": "routine_runs_dispatch_fingerprint_idx",
+ "columns": [
+ {
+ "expression": "routine_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "dispatch_fingerprint",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "routine_runs_linked_issue_idx": {
+ "name": "routine_runs_linked_issue_idx",
+ "columns": [
+ {
+ "expression": "linked_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "routine_runs_trigger_idempotency_idx": {
+ "name": "routine_runs_trigger_idempotency_idx",
+ "columns": [
+ {
+ "expression": "trigger_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "routine_runs_company_id_companies_id_fk": {
+ "name": "routine_runs_company_id_companies_id_fk",
+ "tableFrom": "routine_runs",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "routine_runs_routine_id_routines_id_fk": {
+ "name": "routine_runs_routine_id_routines_id_fk",
+ "tableFrom": "routine_runs",
+ "columnsFrom": [
+ "routine_id"
+ ],
+ "tableTo": "routines",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "routine_runs_trigger_id_routine_triggers_id_fk": {
+ "name": "routine_runs_trigger_id_routine_triggers_id_fk",
+ "tableFrom": "routine_runs",
+ "columnsFrom": [
+ "trigger_id"
+ ],
+ "tableTo": "routine_triggers",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "routine_runs_routine_revision_id_routine_revisions_id_fk": {
+ "name": "routine_runs_routine_revision_id_routine_revisions_id_fk",
+ "tableFrom": "routine_runs",
+ "columnsFrom": [
+ "routine_revision_id"
+ ],
+ "tableTo": "routine_revisions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "routine_runs_linked_issue_id_issues_id_fk": {
+ "name": "routine_runs_linked_issue_id_issues_id_fk",
+ "tableFrom": "routine_runs",
+ "columnsFrom": [
+ "linked_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.routine_triggers": {
+ "name": "routine_triggers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "routine_id": {
+ "name": "routine_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "label": {
+ "name": "label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "setup_pending": {
+ "name": "setup_pending",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "last_webhook_delivery": {
+ "name": "last_webhook_delivery",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cron_expression": {
+ "name": "cron_expression",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "timezone": {
+ "name": "timezone",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "next_run_at": {
+ "name": "next_run_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_fired_at": {
+ "name": "last_fired_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "public_id": {
+ "name": "public_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "secret_id": {
+ "name": "secret_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "signing_mode": {
+ "name": "signing_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "replay_window_sec": {
+ "name": "replay_window_sec",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_rotated_at": {
+ "name": "last_rotated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_result": {
+ "name": "last_result",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_by_agent_id": {
+ "name": "updated_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_by_user_id": {
+ "name": "updated_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "routine_triggers_company_routine_idx": {
+ "name": "routine_triggers_company_routine_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "routine_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "routine_triggers_company_kind_idx": {
+ "name": "routine_triggers_company_kind_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "routine_triggers_next_run_idx": {
+ "name": "routine_triggers_next_run_idx",
+ "columns": [
+ {
+ "expression": "next_run_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "routine_triggers_public_id_idx": {
+ "name": "routine_triggers_public_id_idx",
+ "columns": [
+ {
+ "expression": "public_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "routine_triggers_public_id_uq": {
+ "name": "routine_triggers_public_id_uq",
+ "columns": [
+ {
+ "expression": "public_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "routine_triggers_company_id_companies_id_fk": {
+ "name": "routine_triggers_company_id_companies_id_fk",
+ "tableFrom": "routine_triggers",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "routine_triggers_routine_id_routines_id_fk": {
+ "name": "routine_triggers_routine_id_routines_id_fk",
+ "tableFrom": "routine_triggers",
+ "columnsFrom": [
+ "routine_id"
+ ],
+ "tableTo": "routines",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "routine_triggers_secret_id_company_secrets_id_fk": {
+ "name": "routine_triggers_secret_id_company_secrets_id_fk",
+ "tableFrom": "routine_triggers",
+ "columnsFrom": [
+ "secret_id"
+ ],
+ "tableTo": "company_secrets",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "routine_triggers_created_by_agent_id_agents_id_fk": {
+ "name": "routine_triggers_created_by_agent_id_agents_id_fk",
+ "tableFrom": "routine_triggers",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "routine_triggers_updated_by_agent_id_agents_id_fk": {
+ "name": "routine_triggers_updated_by_agent_id_agents_id_fk",
+ "tableFrom": "routine_triggers",
+ "columnsFrom": [
+ "updated_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.routine_webhook_test_receipts": {
+ "name": "routine_webhook_test_receipts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "trigger_id": {
+ "name": "trigger_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "delivery_key_hash": {
+ "name": "delivery_key_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "received_at": {
+ "name": "received_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "routine_webhook_test_receipts_delivery_uq": {
+ "name": "routine_webhook_test_receipts_delivery_uq",
+ "columns": [
+ {
+ "expression": "trigger_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "delivery_key_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "routine_webhook_test_receipts_company_id_companies_id_fk": {
+ "name": "routine_webhook_test_receipts_company_id_companies_id_fk",
+ "tableFrom": "routine_webhook_test_receipts",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "routine_webhook_test_receipts_trigger_id_routine_triggers_id_fk": {
+ "name": "routine_webhook_test_receipts_trigger_id_routine_triggers_id_fk",
+ "tableFrom": "routine_webhook_test_receipts",
+ "columnsFrom": [
+ "trigger_id"
+ ],
+ "tableTo": "routine_triggers",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.routines": {
+ "name": "routines",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "folder_id": {
+ "name": "folder_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goal_id": {
+ "name": "goal_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "parent_issue_id": {
+ "name": "parent_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "assignee_agent_id": {
+ "name": "assignee_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "priority": {
+ "name": "priority",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'medium'"
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "concurrency_policy": {
+ "name": "concurrency_policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'coalesce_if_active'"
+ },
+ "catch_up_policy": {
+ "name": "catch_up_policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'skip_missed'"
+ },
+ "activity_gate_policy": {
+ "name": "activity_gate_policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'always'"
+ },
+ "activity_gate_scope": {
+ "name": "activity_gate_scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'company'"
+ },
+ "origin_kind": {
+ "name": "origin_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'manual'"
+ },
+ "origin_id": {
+ "name": "origin_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "variables": {
+ "name": "variables",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "env": {
+ "name": "env",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "latest_revision_id": {
+ "name": "latest_revision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "latest_revision_number": {
+ "name": "latest_revision_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "responsible_user_id": {
+ "name": "responsible_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_by_agent_id": {
+ "name": "updated_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_by_user_id": {
+ "name": "updated_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_triggered_at": {
+ "name": "last_triggered_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_enqueued_at": {
+ "name": "last_enqueued_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "routines_company_status_idx": {
+ "name": "routines_company_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "routines_company_assignee_idx": {
+ "name": "routines_company_assignee_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "assignee_agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "routines_company_project_idx": {
+ "name": "routines_company_project_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "routines_company_folder_idx": {
+ "name": "routines_company_folder_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "folder_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "routines_company_responsible_user_idx": {
+ "name": "routines_company_responsible_user_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "responsible_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "routines_company_origin_idx": {
+ "name": "routines_company_origin_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "origin_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "origin_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "routines_company_id_companies_id_fk": {
+ "name": "routines_company_id_companies_id_fk",
+ "tableFrom": "routines",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "routines_project_id_projects_id_fk": {
+ "name": "routines_project_id_projects_id_fk",
+ "tableFrom": "routines",
+ "columnsFrom": [
+ "project_id"
+ ],
+ "tableTo": "projects",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "routines_folder_id_folders_id_fk": {
+ "name": "routines_folder_id_folders_id_fk",
+ "tableFrom": "routines",
+ "columnsFrom": [
+ "folder_id"
+ ],
+ "tableTo": "folders",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "routines_goal_id_goals_id_fk": {
+ "name": "routines_goal_id_goals_id_fk",
+ "tableFrom": "routines",
+ "columnsFrom": [
+ "goal_id"
+ ],
+ "tableTo": "goals",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "routines_parent_issue_id_issues_id_fk": {
+ "name": "routines_parent_issue_id_issues_id_fk",
+ "tableFrom": "routines",
+ "columnsFrom": [
+ "parent_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "routines_assignee_agent_id_agents_id_fk": {
+ "name": "routines_assignee_agent_id_agents_id_fk",
+ "tableFrom": "routines",
+ "columnsFrom": [
+ "assignee_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "routines_created_by_agent_id_agents_id_fk": {
+ "name": "routines_created_by_agent_id_agents_id_fk",
+ "tableFrom": "routines",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "routines_updated_by_agent_id_agents_id_fk": {
+ "name": "routines_updated_by_agent_id_agents_id_fk",
+ "tableFrom": "routines",
+ "columnsFrom": [
+ "updated_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.run_identity_contexts": {
+ "name": "run_identity_contexts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revision": {
+ "name": "revision",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "responsible_user_id": {
+ "name": "responsible_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "message_id": {
+ "name": "message_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "parent_context_id": {
+ "name": "parent_context_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cause": {
+ "name": "cause",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "correlation_id": {
+ "name": "correlation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'accepted'"
+ },
+ "accepted_at": {
+ "name": "accepted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "github": {
+ "name": "github",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "run_identity_contexts_run_revision_idx": {
+ "name": "run_identity_contexts_run_revision_idx",
+ "columns": [
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "revision",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "run_identity_contexts_run_correlation_idx": {
+ "name": "run_identity_contexts_run_correlation_idx",
+ "columns": [
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "correlation_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "run_identity_contexts_company_run_idx": {
+ "name": "run_identity_contexts_company_run_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "run_identity_contexts_company_id_companies_id_fk": {
+ "name": "run_identity_contexts_company_id_companies_id_fk",
+ "tableFrom": "run_identity_contexts",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.runner_api_response_reservations": {
+ "name": "runner_api_response_reservations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "asset_id": {
+ "name": "asset_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "reserved_bytes": {
+ "name": "reserved_bytes",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "runner_api_response_reservations_company_idx": {
+ "name": "runner_api_response_reservations_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "runner_api_response_reservations_company_id_companies_id_fk": {
+ "name": "runner_api_response_reservations_company_id_companies_id_fk",
+ "tableFrom": "runner_api_response_reservations",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "runner_api_response_reservations_run_id_heartbeat_runs_id_fk": {
+ "name": "runner_api_response_reservations_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "runner_api_response_reservations",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "runner_api_response_reservations_asset_id_assets_id_fk": {
+ "name": "runner_api_response_reservations_asset_id_assets_id_fk",
+ "tableFrom": "runner_api_response_reservations",
+ "columnsFrom": [
+ "asset_id"
+ ],
+ "tableTo": "assets",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.secret_access_events": {
+ "name": "secret_access_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "secret_id": {
+ "name": "secret_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_secret_definition_id": {
+ "name": "user_secret_definition_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "secret_scope": {
+ "name": "secret_scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'company'"
+ },
+ "version": {
+ "name": "version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "responsible_user_id": {
+ "name": "responsible_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "credential_owner_user_id": {
+ "name": "credential_owner_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "credential_subject_type": {
+ "name": "credential_subject_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "credential_subject_id": {
+ "name": "credential_subject_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "actor_type": {
+ "name": "actor_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_id": {
+ "name": "actor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "consumer_type": {
+ "name": "consumer_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "consumer_id": {
+ "name": "consumer_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "config_path": {
+ "name": "config_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "heartbeat_run_id": {
+ "name": "heartbeat_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "plugin_id": {
+ "name": "plugin_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "outcome": {
+ "name": "outcome",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "error_code": {
+ "name": "error_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "secret_access_events_company_created_idx": {
+ "name": "secret_access_events_company_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "secret_access_events_secret_created_idx": {
+ "name": "secret_access_events_secret_created_idx",
+ "columns": [
+ {
+ "expression": "secret_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "secret_access_events_user_definition_created_idx": {
+ "name": "secret_access_events_user_definition_created_idx",
+ "columns": [
+ {
+ "expression": "user_secret_definition_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "secret_access_events_company_credential_owner_idx": {
+ "name": "secret_access_events_company_credential_owner_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "credential_owner_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "secret_access_events_consumer_idx": {
+ "name": "secret_access_events_consumer_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "consumer_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "consumer_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "secret_access_events_run_idx": {
+ "name": "secret_access_events_run_idx",
+ "columns": [
+ {
+ "expression": "heartbeat_run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "secret_access_events_company_id_companies_id_fk": {
+ "name": "secret_access_events_company_id_companies_id_fk",
+ "tableFrom": "secret_access_events",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "secret_access_events_secret_id_company_secrets_id_fk": {
+ "name": "secret_access_events_secret_id_company_secrets_id_fk",
+ "tableFrom": "secret_access_events",
+ "columnsFrom": [
+ "secret_id"
+ ],
+ "tableTo": "company_secrets",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "secret_access_events_user_secret_definition_id_user_secret_definitions_id_fk": {
+ "name": "secret_access_events_user_secret_definition_id_user_secret_definitions_id_fk",
+ "tableFrom": "secret_access_events",
+ "columnsFrom": [
+ "user_secret_definition_id"
+ ],
+ "tableTo": "user_secret_definitions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "secret_access_events_issue_id_issues_id_fk": {
+ "name": "secret_access_events_issue_id_issues_id_fk",
+ "tableFrom": "secret_access_events",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "secret_access_events_heartbeat_run_id_heartbeat_runs_id_fk": {
+ "name": "secret_access_events_heartbeat_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "secret_access_events",
+ "columnsFrom": [
+ "heartbeat_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "secret_access_events_plugin_id_plugins_id_fk": {
+ "name": "secret_access_events_plugin_id_plugins_id_fk",
+ "tableFrom": "secret_access_events",
+ "columnsFrom": [
+ "plugin_id"
+ ],
+ "tableTo": "plugins",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.smoke_run_steps": {
+ "name": "smoke_run_steps",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "path": {
+ "name": "path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scenario_step": {
+ "name": "scenario_step",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "detail": {
+ "name": "detail",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "screenshot_artifact_ref": {
+ "name": "screenshot_artifact_ref",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "duration_ms": {
+ "name": "duration_ms",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "smoke_run_steps_company_run_idx": {
+ "name": "smoke_run_steps_company_run_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "smoke_run_steps_company_path_idx": {
+ "name": "smoke_run_steps_company_path_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "path",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "smoke_run_steps_company_id_companies_id_fk": {
+ "name": "smoke_run_steps_company_id_companies_id_fk",
+ "tableFrom": "smoke_run_steps",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "smoke_run_steps_run_id_smoke_runs_id_fk": {
+ "name": "smoke_run_steps_run_id_smoke_runs_id_fk",
+ "tableFrom": "smoke_run_steps",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "tableTo": "smoke_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.smoke_runs": {
+ "name": "smoke_runs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "trigger": {
+ "name": "trigger",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'running'"
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "finished_at": {
+ "name": "finished_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "summary": {
+ "name": "summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "smoke_runs_company_started_idx": {
+ "name": "smoke_runs_company_started_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "smoke_runs_company_status_idx": {
+ "name": "smoke_runs_company_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "smoke_runs_company_id_companies_id_fk": {
+ "name": "smoke_runs_company_id_companies_id_fk",
+ "tableFrom": "smoke_runs",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.status_card_updates": {
+ "name": "status_card_updates",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "card_id": {
+ "name": "card_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "trigger": {
+ "name": "trigger",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "generation_issue_id": {
+ "name": "generation_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "changes": {
+ "name": "changes",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "input_tokens": {
+ "name": "input_tokens",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "output_tokens": {
+ "name": "output_tokens",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "cost_cents": {
+ "name": "cost_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "model": {
+ "name": "model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "query_version": {
+ "name": "query_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "change_summary": {
+ "name": "change_summary",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "finished_at": {
+ "name": "finished_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "status_card_updates_card_started_idx": {
+ "name": "status_card_updates_card_started_idx",
+ "columns": [
+ {
+ "expression": "card_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "status_card_updates_generation_issue_idx": {
+ "name": "status_card_updates_generation_issue_idx",
+ "columns": [
+ {
+ "expression": "generation_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "status_card_updates_card_id_status_cards_id_fk": {
+ "name": "status_card_updates_card_id_status_cards_id_fk",
+ "tableFrom": "status_card_updates",
+ "columnsFrom": [
+ "card_id"
+ ],
+ "tableTo": "status_cards",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "status_card_updates_generation_issue_id_issues_id_fk": {
+ "name": "status_card_updates_generation_issue_id_issues_id_fk",
+ "tableFrom": "status_card_updates",
+ "columnsFrom": [
+ "generation_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "status_card_updates_run_id_heartbeat_runs_id_fk": {
+ "name": "status_card_updates_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "status_card_updates",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.status_cards": {
+ "name": "status_cards",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "title_pinned": {
+ "name": "title_pinned",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "interest_prompt": {
+ "name": "interest_prompt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "queries": {
+ "name": "queries",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "query_version": {
+ "name": "query_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "query_compiled_at": {
+ "name": "query_compiled_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "query_compiled_by_agent_id": {
+ "name": "query_compiled_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_policy": {
+ "name": "refresh_policy",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "state": {
+ "name": "state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'compiling'"
+ },
+ "pending_change_count": {
+ "name": "pending_change_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "pending_change_hash": {
+ "name": "pending_change_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_change_at": {
+ "name": "last_change_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "fingerprint": {
+ "name": "fingerprint",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "fingerprint_at": {
+ "name": "fingerprint_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "mentioned_issue_ids": {
+ "name": "mentioned_issue_ids",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_update_run_kind": {
+ "name": "last_update_run_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_generated_at": {
+ "name": "last_generated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_model": {
+ "name": "last_model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "generating_issue_id": {
+ "name": "generating_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "failure_reason": {
+ "name": "failure_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "next_eval_at": {
+ "name": "next_eval_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_by_user_id": {
+ "name": "archived_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_by_agent_id": {
+ "name": "archived_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "status_cards_company_archived_idx": {
+ "name": "status_cards_company_archived_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "archived_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "status_cards_company_next_eval_idx": {
+ "name": "status_cards_company_next_eval_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "next_eval_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "status_cards_company_id_companies_id_fk": {
+ "name": "status_cards_company_id_companies_id_fk",
+ "tableFrom": "status_cards",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "status_cards_created_by_agent_id_agents_id_fk": {
+ "name": "status_cards_created_by_agent_id_agents_id_fk",
+ "tableFrom": "status_cards",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "status_cards_query_compiled_by_agent_id_agents_id_fk": {
+ "name": "status_cards_query_compiled_by_agent_id_agents_id_fk",
+ "tableFrom": "status_cards",
+ "columnsFrom": [
+ "query_compiled_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "status_cards_agent_id_agents_id_fk": {
+ "name": "status_cards_agent_id_agents_id_fk",
+ "tableFrom": "status_cards",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "status_cards_document_id_documents_id_fk": {
+ "name": "status_cards_document_id_documents_id_fk",
+ "tableFrom": "status_cards",
+ "columnsFrom": [
+ "document_id"
+ ],
+ "tableTo": "documents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "status_cards_generating_issue_id_issues_id_fk": {
+ "name": "status_cards_generating_issue_id_issues_id_fk",
+ "tableFrom": "status_cards",
+ "columnsFrom": [
+ "generating_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "status_cards_archived_by_agent_id_agents_id_fk": {
+ "name": "status_cards_archived_by_agent_id_agents_id_fk",
+ "tableFrom": "status_cards",
+ "columnsFrom": [
+ "archived_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.status_decision_effects": {
+ "name": "status_decision_effects",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "decision_id": {
+ "name": "decision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ordinal": {
+ "name": "ordinal",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "effect_kind": {
+ "name": "effect_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_type": {
+ "name": "target_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_id": {
+ "name": "target_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "payload": {
+ "name": "payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "delivery_state": {
+ "name": "delivery_state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "attempt_count": {
+ "name": "attempt_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "next_attempt_at": {
+ "name": "next_attempt_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "delivered_at": {
+ "name": "delivered_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "status_decision_effects_decision_ordinal_uq": {
+ "name": "status_decision_effects_decision_ordinal_uq",
+ "columns": [
+ {
+ "expression": "decision_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "ordinal",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "status_decision_effects_company_idempotency_uq": {
+ "name": "status_decision_effects_company_idempotency_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "status_decision_effects_company_id_companies_id_fk": {
+ "name": "status_decision_effects_company_id_companies_id_fk",
+ "tableFrom": "status_decision_effects",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "status_decision_effects_issue_company_fk": {
+ "name": "status_decision_effects_issue_company_fk",
+ "tableFrom": "status_decision_effects",
+ "columnsFrom": [
+ "company_id",
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "status_decision_effects_decision_owner_fk": {
+ "name": "status_decision_effects_decision_owner_fk",
+ "tableFrom": "status_decision_effects",
+ "columnsFrom": [
+ "company_id",
+ "issue_id",
+ "decision_id"
+ ],
+ "tableTo": "status_decisions",
+ "columnsTo": [
+ "company_id",
+ "issue_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.status_decisions": {
+ "name": "status_decisions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "assessment_id": {
+ "name": "assessment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "decision_version": {
+ "name": "decision_version",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "policy_version": {
+ "name": "policy_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "from_status": {
+ "name": "from_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "to_status": {
+ "name": "to_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "reason_code": {
+ "name": "reason_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "decision_json": {
+ "name": "decision_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "decision_digest": {
+ "name": "decision_digest",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "application_state": {
+ "name": "application_state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'proposed'"
+ },
+ "supersedes_decision_id": {
+ "name": "supersedes_decision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "applied_at": {
+ "name": "applied_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "status_decisions_company_issue_version_uq": {
+ "name": "status_decisions_company_issue_version_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "decision_version",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "status_decisions_company_assessment_uq": {
+ "name": "status_decisions_company_assessment_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "assessment_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "status_decisions_company_issue_digest_uq": {
+ "name": "status_decisions_company_issue_digest_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "decision_digest",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "status_decisions_company_id_companies_id_fk": {
+ "name": "status_decisions_company_id_companies_id_fk",
+ "tableFrom": "status_decisions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "status_decisions_issue_company_fk": {
+ "name": "status_decisions_issue_company_fk",
+ "tableFrom": "status_decisions",
+ "columnsFrom": [
+ "company_id",
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "status_decisions_assessment_owner_fk": {
+ "name": "status_decisions_assessment_owner_fk",
+ "tableFrom": "status_decisions",
+ "columnsFrom": [
+ "company_id",
+ "issue_id",
+ "run_id",
+ "assessment_id"
+ ],
+ "tableTo": "work_assessments",
+ "columnsTo": [
+ "company_id",
+ "issue_id",
+ "run_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "status_decisions_supersedes_owner_fk": {
+ "name": "status_decisions_supersedes_owner_fk",
+ "tableFrom": "status_decisions",
+ "columnsFrom": [
+ "company_id",
+ "issue_id",
+ "supersedes_decision_id"
+ ],
+ "tableTo": "status_decisions",
+ "columnsTo": [
+ "company_id",
+ "issue_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "status_decisions_company_issue_id_uq": {
+ "name": "status_decisions_company_issue_id_uq",
+ "columns": [
+ "company_id",
+ "issue_id",
+ "id"
+ ],
+ "nullsNotDistinct": false
+ },
+ "status_decisions_company_issue_run_assessment_id_uq": {
+ "name": "status_decisions_company_issue_run_assessment_id_uq",
+ "columns": [
+ "company_id",
+ "issue_id",
+ "run_id",
+ "assessment_id",
+ "id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.summary_slots": {
+ "name": "summary_slots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope_kind": {
+ "name": "scope_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope_id": {
+ "name": "scope_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "slot_key": {
+ "name": "slot_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'idle'"
+ },
+ "failure_reason": {
+ "name": "failure_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "generating_issue_id": {
+ "name": "generating_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_generated_at": {
+ "name": "last_generated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_generated_by_agent_id": {
+ "name": "last_generated_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_model": {
+ "name": "last_model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "summary_slots_document_uq": {
+ "name": "summary_slots_document_uq",
+ "columns": [
+ {
+ "expression": "document_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "summary_slots_company_scope_idx": {
+ "name": "summary_slots_company_scope_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scope_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scope_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "summary_slots_company_generating_issue_idx": {
+ "name": "summary_slots_company_generating_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "generating_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "summary_slots_company_updated_idx": {
+ "name": "summary_slots_company_updated_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "summary_slots_company_id_companies_id_fk": {
+ "name": "summary_slots_company_id_companies_id_fk",
+ "tableFrom": "summary_slots",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "summary_slots_document_id_documents_id_fk": {
+ "name": "summary_slots_document_id_documents_id_fk",
+ "tableFrom": "summary_slots",
+ "columnsFrom": [
+ "document_id"
+ ],
+ "tableTo": "documents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "summary_slots_generating_issue_id_issues_id_fk": {
+ "name": "summary_slots_generating_issue_id_issues_id_fk",
+ "tableFrom": "summary_slots",
+ "columnsFrom": [
+ "generating_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "summary_slots_last_generated_by_agent_id_agents_id_fk": {
+ "name": "summary_slots_last_generated_by_agent_id_agents_id_fk",
+ "tableFrom": "summary_slots",
+ "columnsFrom": [
+ "last_generated_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "summary_slots_company_scope_slot_uq": {
+ "name": "summary_slots_company_scope_slot_uq",
+ "columns": [
+ "company_id",
+ "scope_kind",
+ "scope_id",
+ "slot_key"
+ ],
+ "nullsNotDistinct": true
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_access_audit_events": {
+ "name": "tool_access_audit_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "gateway_id": {
+ "name": "gateway_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gateway_token_id": {
+ "name": "gateway_token_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gateway_public_id": {
+ "name": "gateway_public_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "client_name": {
+ "name": "client_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "correlation_id": {
+ "name": "correlation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "catalog_entry_id": {
+ "name": "catalog_entry_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "actor_type": {
+ "name": "actor_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'system'"
+ },
+ "actor_id": {
+ "name": "actor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "action": {
+ "name": "action",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "outcome": {
+ "name": "outcome",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "reason_code": {
+ "name": "reason_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "details": {
+ "name": "details",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_access_audit_company_created_idx": {
+ "name": "tool_access_audit_company_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_access_audit_connection_idx": {
+ "name": "tool_access_audit_connection_idx",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_access_audit_gateway_idx": {
+ "name": "tool_access_audit_gateway_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "gateway_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_access_audit_events_company_id_companies_id_fk": {
+ "name": "tool_access_audit_events_company_id_companies_id_fk",
+ "tableFrom": "tool_access_audit_events",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_access_audit_events_gateway_id_tool_mcp_gateways_id_fk": {
+ "name": "tool_access_audit_events_gateway_id_tool_mcp_gateways_id_fk",
+ "tableFrom": "tool_access_audit_events",
+ "columnsFrom": [
+ "gateway_id"
+ ],
+ "tableTo": "tool_mcp_gateways",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_access_audit_events_gateway_token_id_tool_mcp_gateway_tokens_id_fk": {
+ "name": "tool_access_audit_events_gateway_token_id_tool_mcp_gateway_tokens_id_fk",
+ "tableFrom": "tool_access_audit_events",
+ "columnsFrom": [
+ "gateway_token_id"
+ ],
+ "tableTo": "tool_mcp_gateway_tokens",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_access_audit_events_connection_id_tool_connections_id_fk": {
+ "name": "tool_access_audit_events_connection_id_tool_connections_id_fk",
+ "tableFrom": "tool_access_audit_events",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "tableTo": "tool_connections",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_access_audit_events_catalog_entry_id_tool_catalog_entries_id_fk": {
+ "name": "tool_access_audit_events_catalog_entry_id_tool_catalog_entries_id_fk",
+ "tableFrom": "tool_access_audit_events",
+ "columnsFrom": [
+ "catalog_entry_id"
+ ],
+ "tableTo": "tool_catalog_entries",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_action_deliveries": {
+ "name": "tool_action_deliveries",
+ "schema": "",
+ "columns": {
+ "action_request_id": {
+ "name": "action_request_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "interaction_id": {
+ "name": "interaction_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "delivered_at": {
+ "name": "delivered_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_action_deliveries_pending_idx": {
+ "name": "tool_action_deliveries_pending_idx",
+ "columns": [
+ {
+ "expression": "delivered_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_action_deliveries_action_request_id_tool_action_requests_id_fk": {
+ "name": "tool_action_deliveries_action_request_id_tool_action_requests_id_fk",
+ "tableFrom": "tool_action_deliveries",
+ "columnsFrom": [
+ "action_request_id"
+ ],
+ "tableTo": "tool_action_requests",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_action_deliveries_company_id_companies_id_fk": {
+ "name": "tool_action_deliveries_company_id_companies_id_fk",
+ "tableFrom": "tool_action_deliveries",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_action_deliveries_issue_id_issues_id_fk": {
+ "name": "tool_action_deliveries_issue_id_issues_id_fk",
+ "tableFrom": "tool_action_deliveries",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_action_deliveries_interaction_id_issue_thread_interactions_id_fk": {
+ "name": "tool_action_deliveries_interaction_id_issue_thread_interactions_id_fk",
+ "tableFrom": "tool_action_deliveries",
+ "columnsFrom": [
+ "interaction_id"
+ ],
+ "tableTo": "issue_thread_interactions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_action_requests": {
+ "name": "tool_action_requests",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "invocation_id": {
+ "name": "invocation_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "interaction_id": {
+ "name": "interaction_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "approval_id": {
+ "name": "approval_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "canonical_arguments_hash": {
+ "name": "canonical_arguments_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "canonical_arguments_summary": {
+ "name": "canonical_arguments_summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "signed_arguments": {
+ "name": "signed_arguments",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "preview_markdown": {
+ "name": "preview_markdown",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "requested_by_agent_id": {
+ "name": "requested_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "requested_by_user_id": {
+ "name": "requested_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resolved_by_agent_id": {
+ "name": "resolved_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resolved_by_user_id": {
+ "name": "resolved_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "decided_by_agent_id": {
+ "name": "decided_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "decided_by_user_id": {
+ "name": "decided_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "decided_at": {
+ "name": "decided_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resolved_at": {
+ "name": "resolved_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_action_requests_company_status_idx": {
+ "name": "tool_action_requests_company_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_action_requests_invocation_idx": {
+ "name": "tool_action_requests_invocation_idx",
+ "columns": [
+ {
+ "expression": "invocation_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_action_requests_issue_idx": {
+ "name": "tool_action_requests_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_action_requests_company_id_companies_id_fk": {
+ "name": "tool_action_requests_company_id_companies_id_fk",
+ "tableFrom": "tool_action_requests",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_action_requests_invocation_id_tool_invocations_id_fk": {
+ "name": "tool_action_requests_invocation_id_tool_invocations_id_fk",
+ "tableFrom": "tool_action_requests",
+ "columnsFrom": [
+ "invocation_id"
+ ],
+ "tableTo": "tool_invocations",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_action_requests_issue_id_issues_id_fk": {
+ "name": "tool_action_requests_issue_id_issues_id_fk",
+ "tableFrom": "tool_action_requests",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_action_requests_interaction_id_issue_thread_interactions_id_fk": {
+ "name": "tool_action_requests_interaction_id_issue_thread_interactions_id_fk",
+ "tableFrom": "tool_action_requests",
+ "columnsFrom": [
+ "interaction_id"
+ ],
+ "tableTo": "issue_thread_interactions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_action_requests_approval_id_approvals_id_fk": {
+ "name": "tool_action_requests_approval_id_approvals_id_fk",
+ "tableFrom": "tool_action_requests",
+ "columnsFrom": [
+ "approval_id"
+ ],
+ "tableTo": "approvals",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_action_requests_requested_by_agent_id_agents_id_fk": {
+ "name": "tool_action_requests_requested_by_agent_id_agents_id_fk",
+ "tableFrom": "tool_action_requests",
+ "columnsFrom": [
+ "requested_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_action_requests_resolved_by_agent_id_agents_id_fk": {
+ "name": "tool_action_requests_resolved_by_agent_id_agents_id_fk",
+ "tableFrom": "tool_action_requests",
+ "columnsFrom": [
+ "resolved_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_action_requests_decided_by_agent_id_agents_id_fk": {
+ "name": "tool_action_requests_decided_by_agent_id_agents_id_fk",
+ "tableFrom": "tool_action_requests",
+ "columnsFrom": [
+ "decided_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_applications": {
+ "name": "tool_applications",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "application_key": {
+ "name": "application_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "plugin_id": {
+ "name": "plugin_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "owner_agent_id": {
+ "name": "owner_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "owner_user_id": {
+ "name": "owner_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_applications_company_idx": {
+ "name": "tool_applications_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_applications_company_status_idx": {
+ "name": "tool_applications_company_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_applications_company_name_uq": {
+ "name": "tool_applications_company_name_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_applications_company_key_uq": {
+ "name": "tool_applications_company_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "application_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_applications_company_id_companies_id_fk": {
+ "name": "tool_applications_company_id_companies_id_fk",
+ "tableFrom": "tool_applications",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_applications_plugin_id_plugins_id_fk": {
+ "name": "tool_applications_plugin_id_plugins_id_fk",
+ "tableFrom": "tool_applications",
+ "columnsFrom": [
+ "plugin_id"
+ ],
+ "tableTo": "plugins",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_applications_owner_agent_id_agents_id_fk": {
+ "name": "tool_applications_owner_agent_id_agents_id_fk",
+ "tableFrom": "tool_applications",
+ "columnsFrom": [
+ "owner_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_call_events": {
+ "name": "tool_call_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "event_type": {
+ "name": "event_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_type": {
+ "name": "actor_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'system'"
+ },
+ "actor_id": {
+ "name": "actor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gateway_id": {
+ "name": "gateway_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gateway_token_id": {
+ "name": "gateway_token_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gateway_public_id": {
+ "name": "gateway_public_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "client_subject_type": {
+ "name": "client_subject_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "client_subject_id": {
+ "name": "client_subject_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "client_name": {
+ "name": "client_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "mcp_session_id": {
+ "name": "mcp_session_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "correlation_id": {
+ "name": "correlation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "application_id": {
+ "name": "application_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "catalog_entry_id": {
+ "name": "catalog_entry_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "invocation_id": {
+ "name": "invocation_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "action_request_id": {
+ "name": "action_request_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "runtime_slot_id": {
+ "name": "runtime_slot_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tool_name": {
+ "name": "tool_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "decision": {
+ "name": "decision",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "matched_policy_ids": {
+ "name": "matched_policy_ids",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "reason_code": {
+ "name": "reason_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "policy_explanation": {
+ "name": "policy_explanation",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "credential_scope_summary": {
+ "name": "credential_scope_summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "header_policy_summary": {
+ "name": "header_policy_summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "outcome": {
+ "name": "outcome",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "latency_ms": {
+ "name": "latency_ms",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "arguments_summary": {
+ "name": "arguments_summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "request_hash": {
+ "name": "request_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "request_summary": {
+ "name": "request_summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "result_hash": {
+ "name": "result_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "result_summary": {
+ "name": "result_summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "result_size_bytes": {
+ "name": "result_size_bytes",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "redaction_plan": {
+ "name": "redaction_plan",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rate_limit_state": {
+ "name": "rate_limit_state",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error_code": {
+ "name": "error_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_call_events_company_created_idx": {
+ "name": "tool_call_events_company_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_call_events_run_idx": {
+ "name": "tool_call_events_run_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_call_events_issue_idx": {
+ "name": "tool_call_events_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_call_events_invocation_idx": {
+ "name": "tool_call_events_invocation_idx",
+ "columns": [
+ {
+ "expression": "invocation_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_call_events_gateway_idx": {
+ "name": "tool_call_events_gateway_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "gateway_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_call_events_company_id_companies_id_fk": {
+ "name": "tool_call_events_company_id_companies_id_fk",
+ "tableFrom": "tool_call_events",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_call_events_agent_id_agents_id_fk": {
+ "name": "tool_call_events_agent_id_agents_id_fk",
+ "tableFrom": "tool_call_events",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_call_events_run_id_heartbeat_runs_id_fk": {
+ "name": "tool_call_events_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "tool_call_events",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_call_events_issue_id_issues_id_fk": {
+ "name": "tool_call_events_issue_id_issues_id_fk",
+ "tableFrom": "tool_call_events",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_call_events_gateway_id_tool_mcp_gateways_id_fk": {
+ "name": "tool_call_events_gateway_id_tool_mcp_gateways_id_fk",
+ "tableFrom": "tool_call_events",
+ "columnsFrom": [
+ "gateway_id"
+ ],
+ "tableTo": "tool_mcp_gateways",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_call_events_gateway_token_id_tool_mcp_gateway_tokens_id_fk": {
+ "name": "tool_call_events_gateway_token_id_tool_mcp_gateway_tokens_id_fk",
+ "tableFrom": "tool_call_events",
+ "columnsFrom": [
+ "gateway_token_id"
+ ],
+ "tableTo": "tool_mcp_gateway_tokens",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_call_events_application_id_tool_applications_id_fk": {
+ "name": "tool_call_events_application_id_tool_applications_id_fk",
+ "tableFrom": "tool_call_events",
+ "columnsFrom": [
+ "application_id"
+ ],
+ "tableTo": "tool_applications",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_call_events_connection_id_tool_connections_id_fk": {
+ "name": "tool_call_events_connection_id_tool_connections_id_fk",
+ "tableFrom": "tool_call_events",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "tableTo": "tool_connections",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_call_events_catalog_entry_id_tool_catalog_entries_id_fk": {
+ "name": "tool_call_events_catalog_entry_id_tool_catalog_entries_id_fk",
+ "tableFrom": "tool_call_events",
+ "columnsFrom": [
+ "catalog_entry_id"
+ ],
+ "tableTo": "tool_catalog_entries",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_call_events_invocation_id_tool_invocations_id_fk": {
+ "name": "tool_call_events_invocation_id_tool_invocations_id_fk",
+ "tableFrom": "tool_call_events",
+ "columnsFrom": [
+ "invocation_id"
+ ],
+ "tableTo": "tool_invocations",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_call_events_action_request_id_tool_action_requests_id_fk": {
+ "name": "tool_call_events_action_request_id_tool_action_requests_id_fk",
+ "tableFrom": "tool_call_events",
+ "columnsFrom": [
+ "action_request_id"
+ ],
+ "tableTo": "tool_action_requests",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_call_events_runtime_slot_id_tool_runtime_slots_id_fk": {
+ "name": "tool_call_events_runtime_slot_id_tool_runtime_slots_id_fk",
+ "tableFrom": "tool_call_events",
+ "columnsFrom": [
+ "runtime_slot_id"
+ ],
+ "tableTo": "tool_runtime_slots",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_catalog_entries": {
+ "name": "tool_catalog_entries",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "application_id": {
+ "name": "application_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entry_kind": {
+ "name": "entry_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'tool'"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tool_name": {
+ "name": "tool_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "input_schema": {
+ "name": "input_schema",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "output_schema": {
+ "name": "output_schema",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "annotations": {
+ "name": "annotations",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "risk_level": {
+ "name": "risk_level",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'read'"
+ },
+ "is_read_only": {
+ "name": "is_read_only",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "is_write": {
+ "name": "is_write",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "is_destructive": {
+ "name": "is_destructive",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "version": {
+ "name": "version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "version_hash": {
+ "name": "version_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "schema_hash": {
+ "name": "schema_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "first_seen_at": {
+ "name": "first_seen_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "last_seen_at": {
+ "name": "last_seen_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "reviewed_at": {
+ "name": "reviewed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "reviewed_by_agent_id": {
+ "name": "reviewed_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "reviewed_by_user_id": {
+ "name": "reviewed_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "quarantined_at": {
+ "name": "quarantined_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "quarantine_reason": {
+ "name": "quarantine_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_catalog_entries_company_idx": {
+ "name": "tool_catalog_entries_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_catalog_entries_application_idx": {
+ "name": "tool_catalog_entries_application_idx",
+ "columns": [
+ {
+ "expression": "application_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_catalog_entries_connection_idx": {
+ "name": "tool_catalog_entries_connection_idx",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_catalog_entries_company_status_idx": {
+ "name": "tool_catalog_entries_company_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_catalog_entries_connection_name_uq": {
+ "name": "tool_catalog_entries_connection_name_uq",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_catalog_entries_company_id_companies_id_fk": {
+ "name": "tool_catalog_entries_company_id_companies_id_fk",
+ "tableFrom": "tool_catalog_entries",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_catalog_entries_application_id_tool_applications_id_fk": {
+ "name": "tool_catalog_entries_application_id_tool_applications_id_fk",
+ "tableFrom": "tool_catalog_entries",
+ "columnsFrom": [
+ "application_id"
+ ],
+ "tableTo": "tool_applications",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_catalog_entries_connection_id_tool_connections_id_fk": {
+ "name": "tool_catalog_entries_connection_id_tool_connections_id_fk",
+ "tableFrom": "tool_catalog_entries",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "tableTo": "tool_connections",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_catalog_entries_reviewed_by_agent_id_agents_id_fk": {
+ "name": "tool_catalog_entries_reviewed_by_agent_id_agents_id_fk",
+ "tableFrom": "tool_catalog_entries",
+ "columnsFrom": [
+ "reviewed_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_connection_app_snapshots": {
+ "name": "tool_connection_app_snapshots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "credential_key": {
+ "name": "credential_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "toolkit": {
+ "name": "toolkit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "accounts": {
+ "name": "accounts",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "checked_at": {
+ "name": "checked_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "error_at": {
+ "name": "error_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "tool_connection_app_snapshots_owner_toolkit_uq": {
+ "name": "tool_connection_app_snapshots_owner_toolkit_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "toolkit",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_connection_app_snapshots_company_id_companies_id_fk": {
+ "name": "tool_connection_app_snapshots_company_id_companies_id_fk",
+ "tableFrom": "tool_connection_app_snapshots",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_connection_app_snapshots_company_connection_fk": {
+ "name": "tool_connection_app_snapshots_company_connection_fk",
+ "tableFrom": "tool_connection_app_snapshots",
+ "columnsFrom": [
+ "company_id",
+ "connection_id"
+ ],
+ "tableTo": "tool_connections",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_connection_app_syncs": {
+ "name": "tool_connection_app_syncs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "credential_key": {
+ "name": "credential_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lease_id": {
+ "name": "lease_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "checked": {
+ "name": "checked",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "total": {
+ "name": "total",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "failed": {
+ "name": "failed",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "last_completed_at": {
+ "name": "last_completed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_connection_app_syncs_owner_key_uq": {
+ "name": "tool_connection_app_syncs_owner_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "credential_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_connection_app_syncs_company_id_companies_id_fk": {
+ "name": "tool_connection_app_syncs_company_id_companies_id_fk",
+ "tableFrom": "tool_connection_app_syncs",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_connection_app_syncs_company_connection_fk": {
+ "name": "tool_connection_app_syncs_company_connection_fk",
+ "tableFrom": "tool_connection_app_syncs",
+ "columnsFrom": [
+ "company_id",
+ "connection_id"
+ ],
+ "tableTo": "tool_connections",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_connection_installs": {
+ "name": "tool_connection_installs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_type": {
+ "name": "target_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_id": {
+ "name": "target_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_connection_installs_company_target_idx": {
+ "name": "tool_connection_installs_company_target_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_connection_installs_connection_idx": {
+ "name": "tool_connection_installs_connection_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_connection_installs_target_uq": {
+ "name": "tool_connection_installs_target_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_connection_installs_company_id_companies_id_fk": {
+ "name": "tool_connection_installs_company_id_companies_id_fk",
+ "tableFrom": "tool_connection_installs",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_connection_installs_connection_id_tool_connections_id_fk": {
+ "name": "tool_connection_installs_connection_id_tool_connections_id_fk",
+ "tableFrom": "tool_connection_installs",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "tableTo": "tool_connections",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_connection_installs_created_by_agent_id_agents_id_fk": {
+ "name": "tool_connection_installs_created_by_agent_id_agents_id_fk",
+ "tableFrom": "tool_connection_installs",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "tool_connection_installs_target_type_check": {
+ "name": "tool_connection_installs_target_type_check",
+ "value": "\"tool_connection_installs\".\"target_type\" in ('company', 'agent')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.tool_connections": {
+ "name": "tool_connections",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "application_id": {
+ "name": "application_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "uid": {
+ "name": "uid",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "connection_kind": {
+ "name": "connection_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'managed'"
+ },
+ "connection_purpose": {
+ "name": "connection_purpose",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'tool'"
+ },
+ "ownership": {
+ "name": "ownership",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'customer'"
+ },
+ "transport": {
+ "name": "transport",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "auth_kind": {
+ "name": "auth_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'none'"
+ },
+ "credential_source": {
+ "name": "credential_source",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'paperclip_vault'"
+ },
+ "external_credential": {
+ "name": "external_credential",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "credential_policy": {
+ "name": "credential_policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'shared'"
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'draft'"
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "agent_instructions": {
+ "name": "agent_instructions",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "config": {
+ "name": "config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "transport_config": {
+ "name": "transport_config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "credential_refs": {
+ "name": "credential_refs",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "credential_secret_refs": {
+ "name": "credential_secret_refs",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "health_status": {
+ "name": "health_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'unchecked'"
+ },
+ "health_message": {
+ "name": "health_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "health_checked_at": {
+ "name": "health_checked_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_health_at": {
+ "name": "last_health_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_catalog_refresh_at": {
+ "name": "last_catalog_refresh_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_connections_company_idx": {
+ "name": "tool_connections_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_connections_application_idx": {
+ "name": "tool_connections_application_idx",
+ "columns": [
+ {
+ "expression": "application_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_connections_company_enabled_idx": {
+ "name": "tool_connections_company_enabled_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "enabled",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_connections_company_uid_uq": {
+ "name": "tool_connections_company_uid_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "uid",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_connections_company_id_companies_id_fk": {
+ "name": "tool_connections_company_id_companies_id_fk",
+ "tableFrom": "tool_connections",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_connections_application_id_tool_applications_id_fk": {
+ "name": "tool_connections_application_id_tool_applications_id_fk",
+ "tableFrom": "tool_connections",
+ "columnsFrom": [
+ "application_id"
+ ],
+ "tableTo": "tool_applications",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "tool_connections_created_by_agent_id_agents_id_fk": {
+ "name": "tool_connections_created_by_agent_id_agents_id_fk",
+ "tableFrom": "tool_connections",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "tool_connections_company_id_uq": {
+ "name": "tool_connections_company_id_uq",
+ "columns": [
+ "company_id",
+ "id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {
+ "tool_connections_ownership_check": {
+ "name": "tool_connections_ownership_check",
+ "value": "\"tool_connections\".\"ownership\" in ('platform_shared', 'platform_provisioned', 'customer', 'dcr')"
+ },
+ "tool_connections_transport_check": {
+ "name": "tool_connections_transport_check",
+ "value": "\"tool_connections\".\"transport\" in ('mcp_remote', 'rest_api', 'local_stdio', 'chat_sdk', 'runtime_auth')"
+ },
+ "tool_connections_purpose_check": {
+ "name": "tool_connections_purpose_check",
+ "value": "\"tool_connections\".\"connection_purpose\" in ('tool', 'channel', 'ai')"
+ },
+ "tool_connections_channel_transport_check": {
+ "name": "tool_connections_channel_transport_check",
+ "value": "(\n (\"tool_connections\".\"connection_purpose\" = 'tool' and \"tool_connections\".\"transport\" not in ('chat_sdk', 'runtime_auth'))\n or\n (\"tool_connections\".\"connection_purpose\" = 'channel' and (\"tool_connections\".\"transport\" = 'chat_sdk' or (\"tool_connections\".\"transport\" = 'rest_api' and \"tool_connections\".\"config\"->>'provider' = 'agentmail')))\n or\n (\"tool_connections\".\"connection_purpose\" = 'ai' and \"tool_connections\".\"transport\" = 'runtime_auth')\n )"
+ },
+ "tool_connections_auth_kind_check": {
+ "name": "tool_connections_auth_kind_check",
+ "value": "\"tool_connections\".\"auth_kind\" in ('oauth', 'api_key', 'none')"
+ },
+ "tool_connections_credential_source_check": {
+ "name": "tool_connections_credential_source_check",
+ "value": "\"tool_connections\".\"credential_source\" in ('paperclip_vault', 'vercel_connect')"
+ },
+ "tool_connections_credential_source_one_of_check": {
+ "name": "tool_connections_credential_source_one_of_check",
+ "value": "(\n (\"tool_connections\".\"credential_source\" = 'paperclip_vault' and \"tool_connections\".\"external_credential\" is null)\n or\n (\"tool_connections\".\"credential_source\" = 'vercel_connect' and \"tool_connections\".\"external_credential\" is not null and jsonb_array_length(\"tool_connections\".\"credential_refs\") = 0 and jsonb_array_length(\"tool_connections\".\"credential_secret_refs\") = 0)\n )"
+ },
+ "tool_connections_credential_policy_check": {
+ "name": "tool_connections_credential_policy_check",
+ "value": "\"tool_connections\".\"credential_policy\" in ('shared', 'per_user', 'per_user_with_fallback', 'per_agent')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.tool_gateway_rate_limit_counters": {
+ "name": "tool_gateway_rate_limit_counters",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "counter_key": {
+ "name": "counter_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "window_start_at": {
+ "name": "window_start_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "window_ms": {
+ "name": "window_ms",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "limit": {
+ "name": "limit",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "count": {
+ "name": "count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "reset_at": {
+ "name": "reset_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_gateway_rate_limit_counters_company_idx": {
+ "name": "tool_gateway_rate_limit_counters_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_gateway_rate_limit_counters_window_uq": {
+ "name": "tool_gateway_rate_limit_counters_window_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "counter_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "window_start_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_gateway_rate_limit_counters_company_id_companies_id_fk": {
+ "name": "tool_gateway_rate_limit_counters_company_id_companies_id_fk",
+ "tableFrom": "tool_gateway_rate_limit_counters",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_gateway_sessions": {
+ "name": "tool_gateway_sessions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gateway_id": {
+ "name": "gateway_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gateway_token_id": {
+ "name": "gateway_token_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gateway_public_id": {
+ "name": "gateway_public_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "client_subject_type": {
+ "name": "client_subject_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "client_subject_id": {
+ "name": "client_subject_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "client_name": {
+ "name": "client_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "mcp_session_id": {
+ "name": "mcp_session_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "correlation_id": {
+ "name": "correlation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "last_used_at": {
+ "name": "last_used_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_gateway_sessions_token_hash_uq": {
+ "name": "tool_gateway_sessions_token_hash_uq",
+ "columns": [
+ {
+ "expression": "token_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_gateway_sessions_company_agent_idx": {
+ "name": "tool_gateway_sessions_company_agent_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_gateway_sessions_company_expires_idx": {
+ "name": "tool_gateway_sessions_company_expires_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_gateway_sessions_run_idx": {
+ "name": "tool_gateway_sessions_run_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_gateway_sessions_issue_idx": {
+ "name": "tool_gateway_sessions_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_gateway_sessions_gateway_idx": {
+ "name": "tool_gateway_sessions_gateway_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "gateway_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_gateway_sessions_company_id_companies_id_fk": {
+ "name": "tool_gateway_sessions_company_id_companies_id_fk",
+ "tableFrom": "tool_gateway_sessions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_gateway_sessions_agent_id_agents_id_fk": {
+ "name": "tool_gateway_sessions_agent_id_agents_id_fk",
+ "tableFrom": "tool_gateway_sessions",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_gateway_sessions_run_id_heartbeat_runs_id_fk": {
+ "name": "tool_gateway_sessions_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "tool_gateway_sessions",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_gateway_sessions_issue_id_issues_id_fk": {
+ "name": "tool_gateway_sessions_issue_id_issues_id_fk",
+ "tableFrom": "tool_gateway_sessions",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_gateway_sessions_project_id_projects_id_fk": {
+ "name": "tool_gateway_sessions_project_id_projects_id_fk",
+ "tableFrom": "tool_gateway_sessions",
+ "columnsFrom": [
+ "project_id"
+ ],
+ "tableTo": "projects",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_gateway_sessions_gateway_id_tool_mcp_gateways_id_fk": {
+ "name": "tool_gateway_sessions_gateway_id_tool_mcp_gateways_id_fk",
+ "tableFrom": "tool_gateway_sessions",
+ "columnsFrom": [
+ "gateway_id"
+ ],
+ "tableTo": "tool_mcp_gateways",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_gateway_sessions_gateway_token_id_tool_mcp_gateway_tokens_id_fk": {
+ "name": "tool_gateway_sessions_gateway_token_id_tool_mcp_gateway_tokens_id_fk",
+ "tableFrom": "tool_gateway_sessions",
+ "columnsFrom": [
+ "gateway_token_id"
+ ],
+ "tableTo": "tool_mcp_gateway_tokens",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_invocations": {
+ "name": "tool_invocations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "actor_type": {
+ "name": "actor_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'system'"
+ },
+ "actor_id": {
+ "name": "actor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gateway_id": {
+ "name": "gateway_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gateway_token_id": {
+ "name": "gateway_token_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gateway_public_id": {
+ "name": "gateway_public_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "client_subject_type": {
+ "name": "client_subject_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "client_subject_id": {
+ "name": "client_subject_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "client_name": {
+ "name": "client_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "mcp_session_id": {
+ "name": "mcp_session_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "correlation_id": {
+ "name": "correlation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "application_id": {
+ "name": "application_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "catalog_entry_id": {
+ "name": "catalog_entry_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "catalog_version_hash": {
+ "name": "catalog_version_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "catalog_schema_hash": {
+ "name": "catalog_schema_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_type": {
+ "name": "provider_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "application_key": {
+ "name": "application_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "upstream_tool_name": {
+ "name": "upstream_tool_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "risk_level": {
+ "name": "risk_level",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tool_name": {
+ "name": "tool_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "arguments_hash": {
+ "name": "arguments_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "arguments_summary": {
+ "name": "arguments_summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "policy_decision": {
+ "name": "policy_decision",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "matched_policy_ids": {
+ "name": "matched_policy_ids",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "policy_explanation": {
+ "name": "policy_explanation",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "credential_scope_summary": {
+ "name": "credential_scope_summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "header_policy_summary": {
+ "name": "header_policy_summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "approval_state": {
+ "name": "approval_state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'not_required'"
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "upstream_request_id": {
+ "name": "upstream_request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "result_hash": {
+ "name": "result_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "result_summary": {
+ "name": "result_summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "result_size_bytes": {
+ "name": "result_size_bytes",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "result_artifact_id": {
+ "name": "result_artifact_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error_code": {
+ "name": "error_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_invocations_company_created_idx": {
+ "name": "tool_invocations_company_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_invocations_run_idx": {
+ "name": "tool_invocations_run_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_invocations_issue_idx": {
+ "name": "tool_invocations_issue_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_invocations_gateway_idx": {
+ "name": "tool_invocations_gateway_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "gateway_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_invocations_company_idempotency_uq": {
+ "name": "tool_invocations_company_idempotency_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_invocations_company_id_companies_id_fk": {
+ "name": "tool_invocations_company_id_companies_id_fk",
+ "tableFrom": "tool_invocations",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_invocations_agent_id_agents_id_fk": {
+ "name": "tool_invocations_agent_id_agents_id_fk",
+ "tableFrom": "tool_invocations",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_invocations_issue_id_issues_id_fk": {
+ "name": "tool_invocations_issue_id_issues_id_fk",
+ "tableFrom": "tool_invocations",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_invocations_run_id_heartbeat_runs_id_fk": {
+ "name": "tool_invocations_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "tool_invocations",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_invocations_gateway_id_tool_mcp_gateways_id_fk": {
+ "name": "tool_invocations_gateway_id_tool_mcp_gateways_id_fk",
+ "tableFrom": "tool_invocations",
+ "columnsFrom": [
+ "gateway_id"
+ ],
+ "tableTo": "tool_mcp_gateways",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_invocations_gateway_token_id_tool_mcp_gateway_tokens_id_fk": {
+ "name": "tool_invocations_gateway_token_id_tool_mcp_gateway_tokens_id_fk",
+ "tableFrom": "tool_invocations",
+ "columnsFrom": [
+ "gateway_token_id"
+ ],
+ "tableTo": "tool_mcp_gateway_tokens",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_invocations_application_id_tool_applications_id_fk": {
+ "name": "tool_invocations_application_id_tool_applications_id_fk",
+ "tableFrom": "tool_invocations",
+ "columnsFrom": [
+ "application_id"
+ ],
+ "tableTo": "tool_applications",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_invocations_connection_id_tool_connections_id_fk": {
+ "name": "tool_invocations_connection_id_tool_connections_id_fk",
+ "tableFrom": "tool_invocations",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "tableTo": "tool_connections",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_invocations_catalog_entry_id_tool_catalog_entries_id_fk": {
+ "name": "tool_invocations_catalog_entry_id_tool_catalog_entries_id_fk",
+ "tableFrom": "tool_invocations",
+ "columnsFrom": [
+ "catalog_entry_id"
+ ],
+ "tableTo": "tool_catalog_entries",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_mcp_gateway_tokens": {
+ "name": "tool_mcp_gateway_tokens",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "gateway_id": {
+ "name": "gateway_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_prefix": {
+ "name": "token_prefix",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "subject_type": {
+ "name": "subject_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'gateway_client'"
+ },
+ "subject_id": {
+ "name": "subject_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "client_label": {
+ "name": "client_label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "owner_note": {
+ "name": "owner_note",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "allowed_actions": {
+ "name": "allowed_actions",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[\"tools/list\",\"tools/call\"]'::jsonb"
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expiry_override_reason": {
+ "name": "expiry_override_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expiry_override_by_user_id": {
+ "name": "expiry_override_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expiry_override_by_agent_id": {
+ "name": "expiry_override_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expiry_override_at": {
+ "name": "expiry_override_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_used_at": {
+ "name": "last_used_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_mcp_gateway_tokens_token_hash_uq": {
+ "name": "tool_mcp_gateway_tokens_token_hash_uq",
+ "columns": [
+ {
+ "expression": "token_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_mcp_gateway_tokens_expiry_idx": {
+ "name": "tool_mcp_gateway_tokens_expiry_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_mcp_gateway_tokens_gateway_idx": {
+ "name": "tool_mcp_gateway_tokens_gateway_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "gateway_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_mcp_gateway_tokens_subject_idx": {
+ "name": "tool_mcp_gateway_tokens_subject_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_mcp_gateway_tokens_company_expires_idx": {
+ "name": "tool_mcp_gateway_tokens_company_expires_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_mcp_gateway_tokens_company_id_companies_id_fk": {
+ "name": "tool_mcp_gateway_tokens_company_id_companies_id_fk",
+ "tableFrom": "tool_mcp_gateway_tokens",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_mcp_gateway_tokens_gateway_id_tool_mcp_gateways_id_fk": {
+ "name": "tool_mcp_gateway_tokens_gateway_id_tool_mcp_gateways_id_fk",
+ "tableFrom": "tool_mcp_gateway_tokens",
+ "columnsFrom": [
+ "gateway_id"
+ ],
+ "tableTo": "tool_mcp_gateways",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_mcp_gateway_tokens_expiry_override_by_agent_id_agents_id_fk": {
+ "name": "tool_mcp_gateway_tokens_expiry_override_by_agent_id_agents_id_fk",
+ "tableFrom": "tool_mcp_gateway_tokens",
+ "columnsFrom": [
+ "expiry_override_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_mcp_gateway_tokens_created_by_agent_id_agents_id_fk": {
+ "name": "tool_mcp_gateway_tokens_created_by_agent_id_agents_id_fk",
+ "tableFrom": "tool_mcp_gateway_tokens",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_mcp_gateways": {
+ "name": "tool_mcp_gateways",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "gateway_public_id": {
+ "name": "gateway_public_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'gw_' || replace(gen_random_uuid()::text, '-', '')"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "display_slug": {
+ "name": "display_slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "profile_id": {
+ "name": "profile_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "default_profile_mode": {
+ "name": "default_profile_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'gateway_only'"
+ },
+ "context_scope_type": {
+ "name": "context_scope_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'none'"
+ },
+ "context_scope_id": {
+ "name": "context_scope_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "approval_issue_id": {
+ "name": "approval_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "auth_config": {
+ "name": "auth_config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{\"version\":1,\"bearer\":{\"enabled\":true,\"tokenPrefix\":\"pcgw\",\"defaultTtlSeconds\":7776000,\"requireFiniteExpiry\":true,\"longLivedTokenRequiresOverride\":true},\"oauth\":{\"enabled\":false,\"reservedFor\":\"v1_5\",\"dynamicClientRegistration\":false,\"authorizationCodePkce\":false}}'::jsonb"
+ },
+ "header_policy": {
+ "name": "header_policy",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{\"version\":1,\"callerPassthrough\":{\"enabled\":false,\"allowedHeaders\":[]},\"staticHeaders\":[],\"generatedMetadata\":{\"enabled\":false,\"allowedHeaders\":[]},\"responseHeaders\":{\"forwardMcpRequiredHeaders\":true,\"forwardSafeCacheHeaders\":true}}'::jsonb"
+ },
+ "metadata_policy": {
+ "name": "metadata_policy",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{\"version\":1,\"forwardCompanyId\":false,\"forwardGatewayId\":false,\"forwardProjectId\":false,\"forwardIssueId\":false,\"forwardAgentId\":false,\"forwardRunId\":false,\"forwardCorrelationId\":true}'::jsonb"
+ },
+ "on_demand_tools_config": {
+ "name": "on_demand_tools_config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{\"enabled\":false,\"searchToolName\":\"search_tools\",\"runToolName\":\"run_tool\"}'::jsonb"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_mcp_gateways_company_idx": {
+ "name": "tool_mcp_gateways_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_mcp_gateways_company_status_idx": {
+ "name": "tool_mcp_gateways_company_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_mcp_gateways_profile_idx": {
+ "name": "tool_mcp_gateways_profile_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "profile_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_mcp_gateways_public_id_uq": {
+ "name": "tool_mcp_gateways_public_id_uq",
+ "columns": [
+ {
+ "expression": "gateway_public_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_mcp_gateways_company_slug_uq": {
+ "name": "tool_mcp_gateways_company_slug_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "slug",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_mcp_gateways_company_name_uq": {
+ "name": "tool_mcp_gateways_company_name_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_mcp_gateways_company_id_companies_id_fk": {
+ "name": "tool_mcp_gateways_company_id_companies_id_fk",
+ "tableFrom": "tool_mcp_gateways",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_mcp_gateways_profile_id_tool_profiles_id_fk": {
+ "name": "tool_mcp_gateways_profile_id_tool_profiles_id_fk",
+ "tableFrom": "tool_mcp_gateways",
+ "columnsFrom": [
+ "profile_id"
+ ],
+ "tableTo": "tool_profiles",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "restrict"
+ },
+ "tool_mcp_gateways_agent_id_agents_id_fk": {
+ "name": "tool_mcp_gateways_agent_id_agents_id_fk",
+ "tableFrom": "tool_mcp_gateways",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_mcp_gateways_project_id_projects_id_fk": {
+ "name": "tool_mcp_gateways_project_id_projects_id_fk",
+ "tableFrom": "tool_mcp_gateways",
+ "columnsFrom": [
+ "project_id"
+ ],
+ "tableTo": "projects",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_mcp_gateways_issue_id_issues_id_fk": {
+ "name": "tool_mcp_gateways_issue_id_issues_id_fk",
+ "tableFrom": "tool_mcp_gateways",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_mcp_gateways_approval_issue_id_issues_id_fk": {
+ "name": "tool_mcp_gateways_approval_issue_id_issues_id_fk",
+ "tableFrom": "tool_mcp_gateways",
+ "columnsFrom": [
+ "approval_issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_mcp_gateways_created_by_agent_id_agents_id_fk": {
+ "name": "tool_mcp_gateways_created_by_agent_id_agents_id_fk",
+ "tableFrom": "tool_mcp_gateways",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_oauth_states": {
+ "name": "tool_oauth_states",
+ "schema": "",
+ "columns": {
+ "state": {
+ "name": "state",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "code_verifier": {
+ "name": "code_verifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_actor_type": {
+ "name": "created_by_actor_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_actor_id": {
+ "name": "created_by_actor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_session_id": {
+ "name": "created_by_session_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "subject_user_id": {
+ "name": "subject_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "subject_agent_id": {
+ "name": "subject_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "requested_scopes": {
+ "name": "requested_scopes",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "return_to": {
+ "name": "return_to",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "interaction_id": {
+ "name": "interaction_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_oauth_states_company_idx": {
+ "name": "tool_oauth_states_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_oauth_states_connection_idx": {
+ "name": "tool_oauth_states_connection_idx",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_oauth_states_actor_idx": {
+ "name": "tool_oauth_states_actor_idx",
+ "columns": [
+ {
+ "expression": "created_by_actor_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_by_actor_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_oauth_states_subject_agent_idx": {
+ "name": "tool_oauth_states_subject_agent_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_oauth_states_expires_at_idx": {
+ "name": "tool_oauth_states_expires_at_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_oauth_states_company_id_companies_id_fk": {
+ "name": "tool_oauth_states_company_id_companies_id_fk",
+ "tableFrom": "tool_oauth_states",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_oauth_states_connection_id_tool_connections_id_fk": {
+ "name": "tool_oauth_states_connection_id_tool_connections_id_fk",
+ "tableFrom": "tool_oauth_states",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "tableTo": "tool_connections",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_oauth_states_subject_agent_id_agents_id_fk": {
+ "name": "tool_oauth_states_subject_agent_id_agents_id_fk",
+ "tableFrom": "tool_oauth_states",
+ "columnsFrom": [
+ "subject_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_policies": {
+ "name": "tool_policies",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "policy_type": {
+ "name": "policy_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "priority": {
+ "name": "priority",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 100
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "selectors": {
+ "name": "selectors",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "conditions": {
+ "name": "conditions",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "config": {
+ "name": "config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_policies_company_enabled_idx": {
+ "name": "tool_policies_company_enabled_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "enabled",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_policies_company_type_idx": {
+ "name": "tool_policies_company_type_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "policy_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_policies_company_name_uq": {
+ "name": "tool_policies_company_name_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_policies_company_id_companies_id_fk": {
+ "name": "tool_policies_company_id_companies_id_fk",
+ "tableFrom": "tool_policies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_policies_created_by_agent_id_agents_id_fk": {
+ "name": "tool_policies_created_by_agent_id_agents_id_fk",
+ "tableFrom": "tool_policies",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_profile_bindings": {
+ "name": "tool_profile_bindings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "profile_id": {
+ "name": "profile_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_type": {
+ "name": "target_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_id": {
+ "name": "target_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "priority": {
+ "name": "priority",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 100
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_profile_bindings_company_target_idx": {
+ "name": "tool_profile_bindings_company_target_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_profile_bindings_target_profile_uq": {
+ "name": "tool_profile_bindings_target_profile_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "profile_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_profile_bindings_company_id_companies_id_fk": {
+ "name": "tool_profile_bindings_company_id_companies_id_fk",
+ "tableFrom": "tool_profile_bindings",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_profile_bindings_profile_id_tool_profiles_id_fk": {
+ "name": "tool_profile_bindings_profile_id_tool_profiles_id_fk",
+ "tableFrom": "tool_profile_bindings",
+ "columnsFrom": [
+ "profile_id"
+ ],
+ "tableTo": "tool_profiles",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_profile_bindings_created_by_agent_id_agents_id_fk": {
+ "name": "tool_profile_bindings_created_by_agent_id_agents_id_fk",
+ "tableFrom": "tool_profile_bindings",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_profile_entries": {
+ "name": "tool_profile_entries",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "profile_id": {
+ "name": "profile_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "selector_type": {
+ "name": "selector_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "effect": {
+ "name": "effect",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'include'"
+ },
+ "application_id": {
+ "name": "application_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "catalog_entry_id": {
+ "name": "catalog_entry_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tool_name": {
+ "name": "tool_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "risk_level": {
+ "name": "risk_level",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "conditions": {
+ "name": "conditions",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_profile_entries_company_profile_idx": {
+ "name": "tool_profile_entries_company_profile_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "profile_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_profile_entries_application_idx": {
+ "name": "tool_profile_entries_application_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "application_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_profile_entries_connection_idx": {
+ "name": "tool_profile_entries_connection_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_profile_entries_catalog_entry_idx": {
+ "name": "tool_profile_entries_catalog_entry_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "catalog_entry_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_profile_entries_company_id_companies_id_fk": {
+ "name": "tool_profile_entries_company_id_companies_id_fk",
+ "tableFrom": "tool_profile_entries",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_profile_entries_profile_id_tool_profiles_id_fk": {
+ "name": "tool_profile_entries_profile_id_tool_profiles_id_fk",
+ "tableFrom": "tool_profile_entries",
+ "columnsFrom": [
+ "profile_id"
+ ],
+ "tableTo": "tool_profiles",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_profile_entries_application_id_tool_applications_id_fk": {
+ "name": "tool_profile_entries_application_id_tool_applications_id_fk",
+ "tableFrom": "tool_profile_entries",
+ "columnsFrom": [
+ "application_id"
+ ],
+ "tableTo": "tool_applications",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_profile_entries_connection_id_tool_connections_id_fk": {
+ "name": "tool_profile_entries_connection_id_tool_connections_id_fk",
+ "tableFrom": "tool_profile_entries",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "tableTo": "tool_connections",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_profile_entries_catalog_entry_id_tool_catalog_entries_id_fk": {
+ "name": "tool_profile_entries_catalog_entry_id_tool_catalog_entries_id_fk",
+ "tableFrom": "tool_profile_entries",
+ "columnsFrom": [
+ "catalog_entry_id"
+ ],
+ "tableTo": "tool_catalog_entries",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_profiles": {
+ "name": "tool_profiles",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "profile_key": {
+ "name": "profile_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "default_action": {
+ "name": "default_action",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'deny'"
+ },
+ "new_tools_reviewed_at": {
+ "name": "new_tools_reviewed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_profiles_company_status_idx": {
+ "name": "tool_profiles_company_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_profiles_company_key_uq": {
+ "name": "tool_profiles_company_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "profile_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_profiles_company_name_uq": {
+ "name": "tool_profiles_company_name_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_profiles_company_id_companies_id_fk": {
+ "name": "tool_profiles_company_id_companies_id_fk",
+ "tableFrom": "tool_profiles",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_rate_limit_counters": {
+ "name": "tool_rate_limit_counters",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "policy_id": {
+ "name": "policy_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "counter_key": {
+ "name": "counter_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope_type": {
+ "name": "scope_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope_id": {
+ "name": "scope_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "window_kind": {
+ "name": "window_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "window_start_at": {
+ "name": "window_start_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "limit": {
+ "name": "limit",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "remaining": {
+ "name": "remaining",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "reset_at": {
+ "name": "reset_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_rate_limit_counters_company_idx": {
+ "name": "tool_rate_limit_counters_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_rate_limit_counters_window_uq": {
+ "name": "tool_rate_limit_counters_window_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "policy_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "counter_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "window_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "window_start_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_rate_limit_counters_company_id_companies_id_fk": {
+ "name": "tool_rate_limit_counters_company_id_companies_id_fk",
+ "tableFrom": "tool_rate_limit_counters",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_rate_limit_counters_policy_id_tool_policies_id_fk": {
+ "name": "tool_rate_limit_counters_policy_id_tool_policies_id_fk",
+ "tableFrom": "tool_rate_limit_counters",
+ "columnsFrom": [
+ "policy_id"
+ ],
+ "tableTo": "tool_policies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_runtime_metric_counters": {
+ "name": "tool_runtime_metric_counters",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metric": {
+ "name": "metric",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "bucket_start_at": {
+ "name": "bucket_start_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "count": {
+ "name": "count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_runtime_metric_counters_company_metric_idx": {
+ "name": "tool_runtime_metric_counters_company_metric_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "metric",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "bucket_start_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_runtime_metric_counters_bucket_uq": {
+ "name": "tool_runtime_metric_counters_bucket_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "metric",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "bucket_start_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_runtime_metric_counters_company_id_companies_id_fk": {
+ "name": "tool_runtime_metric_counters_company_id_companies_id_fk",
+ "tableFrom": "tool_runtime_metric_counters",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_runtime_slots": {
+ "name": "tool_runtime_slots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "application_id": {
+ "name": "application_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "project_workspace_id": {
+ "name": "project_workspace_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "execution_workspace_id": {
+ "name": "execution_workspace_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "owner_scope_type": {
+ "name": "owner_scope_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'connection'"
+ },
+ "owner_scope_id": {
+ "name": "owner_scope_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "runtime_kind": {
+ "name": "runtime_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'local_stdio'"
+ },
+ "slot_key": {
+ "name": "slot_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'stopped'"
+ },
+ "reuse_key": {
+ "name": "reuse_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "workspace_scope": {
+ "name": "workspace_scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "credential_scope_hash": {
+ "name": "credential_scope_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_ref": {
+ "name": "provider_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "process_id": {
+ "name": "process_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "command_template_key": {
+ "name": "command_template_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "health_status": {
+ "name": "health_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'unchecked'"
+ },
+ "health_message": {
+ "name": "health_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_health_check_at": {
+ "name": "last_health_check_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_started_at": {
+ "name": "last_started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "stopped_at": {
+ "name": "stopped_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_used_at": {
+ "name": "last_used_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "idle_expires_at": {
+ "name": "idle_expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "idle_deadline_at": {
+ "name": "idle_deadline_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_runtime_slots_company_idx": {
+ "name": "tool_runtime_slots_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_runtime_slots_connection_idx": {
+ "name": "tool_runtime_slots_connection_idx",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_runtime_slots_execution_workspace_idx": {
+ "name": "tool_runtime_slots_execution_workspace_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "execution_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_runtime_slots_slot_key_uq": {
+ "name": "tool_runtime_slots_slot_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "slot_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_runtime_slots_company_id_companies_id_fk": {
+ "name": "tool_runtime_slots_company_id_companies_id_fk",
+ "tableFrom": "tool_runtime_slots",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_runtime_slots_application_id_tool_applications_id_fk": {
+ "name": "tool_runtime_slots_application_id_tool_applications_id_fk",
+ "tableFrom": "tool_runtime_slots",
+ "columnsFrom": [
+ "application_id"
+ ],
+ "tableTo": "tool_applications",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_runtime_slots_connection_id_tool_connections_id_fk": {
+ "name": "tool_runtime_slots_connection_id_tool_connections_id_fk",
+ "tableFrom": "tool_runtime_slots",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "tableTo": "tool_connections",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_runtime_slots_project_workspace_id_project_workspaces_id_fk": {
+ "name": "tool_runtime_slots_project_workspace_id_project_workspaces_id_fk",
+ "tableFrom": "tool_runtime_slots",
+ "columnsFrom": [
+ "project_workspace_id"
+ ],
+ "tableTo": "project_workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_runtime_slots_execution_workspace_id_execution_workspaces_id_fk": {
+ "name": "tool_runtime_slots_execution_workspace_id_execution_workspaces_id_fk",
+ "tableFrom": "tool_runtime_slots",
+ "columnsFrom": [
+ "execution_workspace_id"
+ ],
+ "tableTo": "execution_workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "tool_runtime_slots_issue_id_issues_id_fk": {
+ "name": "tool_runtime_slots_issue_id_issues_id_fk",
+ "tableFrom": "tool_runtime_slots",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tool_stdio_command_templates": {
+ "name": "tool_stdio_command_templates",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "template_key": {
+ "name": "template_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "command": {
+ "name": "command",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "args": {
+ "name": "args",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "env_keys": {
+ "name": "env_keys",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "tools": {
+ "name": "tools",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "disabled_at": {
+ "name": "disabled_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tool_stdio_command_templates_company_idx": {
+ "name": "tool_stdio_command_templates_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_stdio_command_templates_company_status_idx": {
+ "name": "tool_stdio_command_templates_company_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "tool_stdio_command_templates_company_key_uq": {
+ "name": "tool_stdio_command_templates_company_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "template_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "tool_stdio_command_templates_company_id_companies_id_fk": {
+ "name": "tool_stdio_command_templates_company_id_companies_id_fk",
+ "tableFrom": "tool_stdio_command_templates",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "tool_stdio_command_templates_created_by_agent_id_agents_id_fk": {
+ "name": "tool_stdio_command_templates_created_by_agent_id_agents_id_fk",
+ "tableFrom": "tool_stdio_command_templates",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.user_inbox_agent_policies": {
+ "name": "user_inbox_agent_policies",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "mode": {
+ "name": "mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'open'"
+ },
+ "allowed_agent_ids": {
+ "name": "allowed_agent_ids",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "user_inbox_agent_policies_company_user_uq": {
+ "name": "user_inbox_agent_policies_company_user_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "user_inbox_agent_policies_allowed_agent_ids_idx": {
+ "name": "user_inbox_agent_policies_allowed_agent_ids_idx",
+ "columns": [
+ {
+ "expression": "allowed_agent_ids",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "gin",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "user_inbox_agent_policies_company_id_companies_id_fk": {
+ "name": "user_inbox_agent_policies_company_id_companies_id_fk",
+ "tableFrom": "user_inbox_agent_policies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "user_inbox_agent_policies_mode_check": {
+ "name": "user_inbox_agent_policies_mode_check",
+ "value": "\"user_inbox_agent_policies\".\"mode\" in ('open', 'allowlist', 'disabled')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.user_secret_declarations": {
+ "name": "user_secret_declarations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_secret_definition_id": {
+ "name": "user_secret_definition_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_type": {
+ "name": "target_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_id": {
+ "name": "target_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "config_path": {
+ "name": "config_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "env_key": {
+ "name": "env_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "version_selector": {
+ "name": "version_selector",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'latest'"
+ },
+ "required": {
+ "name": "required",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "allow_missing_override": {
+ "name": "allow_missing_override",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "label": {
+ "name": "label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "user_secret_declarations_company_idx": {
+ "name": "user_secret_declarations_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "user_secret_declarations_definition_idx": {
+ "name": "user_secret_declarations_definition_idx",
+ "columns": [
+ {
+ "expression": "user_secret_definition_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "user_secret_declarations_target_idx": {
+ "name": "user_secret_declarations_target_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "user_secret_declarations_company_required_idx": {
+ "name": "user_secret_declarations_company_required_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "required",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "user_secret_declarations_target_path_uq": {
+ "name": "user_secret_declarations_target_path_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "config_path",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "user_secret_declarations_required_override_idx": {
+ "name": "user_secret_declarations_required_override_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "allow_missing_override",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "where": "\"user_secret_declarations\".\"allow_missing_override\" = true",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "user_secret_declarations_company_id_companies_id_fk": {
+ "name": "user_secret_declarations_company_id_companies_id_fk",
+ "tableFrom": "user_secret_declarations",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "user_secret_declarations_user_secret_definition_id_user_secret_definitions_id_fk": {
+ "name": "user_secret_declarations_user_secret_definition_id_user_secret_definitions_id_fk",
+ "tableFrom": "user_secret_declarations",
+ "columnsFrom": [
+ "user_secret_definition_id"
+ ],
+ "tableTo": "user_secret_definitions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.user_secret_definitions": {
+ "name": "user_secret_definitions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'local_encrypted'"
+ },
+ "managed_mode": {
+ "name": "managed_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'paperclip_managed'"
+ },
+ "provider_config_id": {
+ "name": "provider_config_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_metadata": {
+ "name": "provider_metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "usage_guidance": {
+ "name": "usage_guidance",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_agent_id": {
+ "name": "created_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_by_agent_id": {
+ "name": "updated_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_by_user_id": {
+ "name": "updated_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "user_secret_definitions_company_status_idx": {
+ "name": "user_secret_definitions_company_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "user_secret_definitions_company_provider_idx": {
+ "name": "user_secret_definitions_company_provider_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "user_secret_definitions_provider_config_idx": {
+ "name": "user_secret_definitions_provider_config_idx",
+ "columns": [
+ {
+ "expression": "provider_config_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "user_secret_definitions_company_key_uq": {
+ "name": "user_secret_definitions_company_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "where": "\"user_secret_definitions\".\"deleted_at\" is null",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "user_secret_definitions_company_id_companies_id_fk": {
+ "name": "user_secret_definitions_company_id_companies_id_fk",
+ "tableFrom": "user_secret_definitions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "user_secret_definitions_provider_config_id_company_secret_provider_configs_id_fk": {
+ "name": "user_secret_definitions_provider_config_id_company_secret_provider_configs_id_fk",
+ "tableFrom": "user_secret_definitions",
+ "columnsFrom": [
+ "provider_config_id"
+ ],
+ "tableTo": "company_secret_provider_configs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "user_secret_definitions_created_by_agent_id_agents_id_fk": {
+ "name": "user_secret_definitions_created_by_agent_id_agents_id_fk",
+ "tableFrom": "user_secret_definitions",
+ "columnsFrom": [
+ "created_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "user_secret_definitions_updated_by_agent_id_agents_id_fk": {
+ "name": "user_secret_definitions_updated_by_agent_id_agents_id_fk",
+ "tableFrom": "user_secret_definitions",
+ "columnsFrom": [
+ "updated_by_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.user_sidebar_preferences": {
+ "name": "user_sidebar_preferences",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "company_order": {
+ "name": "company_order",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "user_sidebar_preferences_user_uq": {
+ "name": "user_sidebar_preferences_user_uq",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.work_assessments": {
+ "name": "work_assessments",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "turn_id": {
+ "name": "turn_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "contract_id": {
+ "name": "contract_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "result_id": {
+ "name": "result_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "trigger_kind": {
+ "name": "trigger_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "trigger_ref": {
+ "name": "trigger_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "trigger_capability": {
+ "name": "trigger_capability",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "trigger_actor_company_id": {
+ "name": "trigger_actor_company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "prior_issue_status": {
+ "name": "prior_issue_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "prior_status_version": {
+ "name": "prior_status_version",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "prior_decision_id": {
+ "name": "prior_decision_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "policy_version": {
+ "name": "policy_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "assessment_json": {
+ "name": "assessment_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "input_digest": {
+ "name": "input_digest",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "supersedes_assessment_id": {
+ "name": "supersedes_assessment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "work_assessments_company_issue_input_uq": {
+ "name": "work_assessments_company_issue_input_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "input_digest",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "work_assessments_company_id_companies_id_fk": {
+ "name": "work_assessments_company_id_companies_id_fk",
+ "tableFrom": "work_assessments",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "work_assessments_trigger_actor_company_id_companies_id_fk": {
+ "name": "work_assessments_trigger_actor_company_id_companies_id_fk",
+ "tableFrom": "work_assessments",
+ "columnsFrom": [
+ "trigger_actor_company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "work_assessments_issue_company_fk": {
+ "name": "work_assessments_issue_company_fk",
+ "tableFrom": "work_assessments",
+ "columnsFrom": [
+ "company_id",
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "company_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "work_assessments_run_owner_fk": {
+ "name": "work_assessments_run_owner_fk",
+ "tableFrom": "work_assessments",
+ "columnsFrom": [
+ "company_id",
+ "issue_id",
+ "run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "company_id",
+ "native_issue_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "work_assessments_contract_owner_fk": {
+ "name": "work_assessments_contract_owner_fk",
+ "tableFrom": "work_assessments",
+ "columnsFrom": [
+ "company_id",
+ "issue_id",
+ "contract_id"
+ ],
+ "tableTo": "completion_contracts",
+ "columnsTo": [
+ "company_id",
+ "issue_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "work_assessments_result_owner_fk": {
+ "name": "work_assessments_result_owner_fk",
+ "tableFrom": "work_assessments",
+ "columnsFrom": [
+ "company_id",
+ "issue_id",
+ "run_id",
+ "result_id"
+ ],
+ "tableTo": "native_run_results",
+ "columnsTo": [
+ "company_id",
+ "issue_id",
+ "run_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "work_assessments_supersedes_owner_fk": {
+ "name": "work_assessments_supersedes_owner_fk",
+ "tableFrom": "work_assessments",
+ "columnsFrom": [
+ "company_id",
+ "issue_id",
+ "run_id",
+ "supersedes_assessment_id"
+ ],
+ "tableTo": "work_assessments",
+ "columnsTo": [
+ "company_id",
+ "issue_id",
+ "run_id",
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "work_assessments_company_issue_run_id_uq": {
+ "name": "work_assessments_company_issue_run_id_uq",
+ "columns": [
+ "company_id",
+ "issue_id",
+ "run_id",
+ "id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {
+ "work_assessments_trigger_actor_company_check": {
+ "name": "work_assessments_trigger_actor_company_check",
+ "value": "\"work_assessments\".\"trigger_actor_company_id\" = \"work_assessments\".\"company_id\""
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.workspace_operations": {
+ "name": "workspace_operations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "execution_workspace_id": {
+ "name": "execution_workspace_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "heartbeat_run_id": {
+ "name": "heartbeat_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "phase": {
+ "name": "phase",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "command": {
+ "name": "command",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cwd": {
+ "name": "cwd",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'running'"
+ },
+ "exit_code": {
+ "name": "exit_code",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "log_store": {
+ "name": "log_store",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "log_ref": {
+ "name": "log_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "log_bytes": {
+ "name": "log_bytes",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "log_sha256": {
+ "name": "log_sha256",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "log_compressed": {
+ "name": "log_compressed",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "stdout_excerpt": {
+ "name": "stdout_excerpt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "stderr_excerpt": {
+ "name": "stderr_excerpt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "finished_at": {
+ "name": "finished_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workspace_operations_company_run_started_idx": {
+ "name": "workspace_operations_company_run_started_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "heartbeat_run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "workspace_operations_company_workspace_started_idx": {
+ "name": "workspace_operations_company_workspace_started_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "execution_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "workspace_operations_company_workspace_issue_started_idx": {
+ "name": "workspace_operations_company_workspace_issue_started_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "execution_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "workspace_operations_company_id_companies_id_fk": {
+ "name": "workspace_operations_company_id_companies_id_fk",
+ "tableFrom": "workspace_operations",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "workspace_operations_execution_workspace_id_execution_workspaces_id_fk": {
+ "name": "workspace_operations_execution_workspace_id_execution_workspaces_id_fk",
+ "tableFrom": "workspace_operations",
+ "columnsFrom": [
+ "execution_workspace_id"
+ ],
+ "tableTo": "execution_workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "workspace_operations_heartbeat_run_id_heartbeat_runs_id_fk": {
+ "name": "workspace_operations_heartbeat_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "workspace_operations",
+ "columnsFrom": [
+ "heartbeat_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "workspace_operations_issue_id_issues_id_fk": {
+ "name": "workspace_operations_issue_id_issues_id_fk",
+ "tableFrom": "workspace_operations",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workspace_runtime_services": {
+ "name": "workspace_runtime_services",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "project_workspace_id": {
+ "name": "project_workspace_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "execution_workspace_id": {
+ "name": "execution_workspace_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scope_type": {
+ "name": "scope_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope_id": {
+ "name": "scope_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "service_name": {
+ "name": "service_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lifecycle": {
+ "name": "lifecycle",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "reuse_key": {
+ "name": "reuse_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "command": {
+ "name": "command",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cwd": {
+ "name": "cwd",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "port": {
+ "name": "port",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "url": {
+ "name": "url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_ref": {
+ "name": "provider_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "owner_agent_id": {
+ "name": "owner_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "started_by_run_id": {
+ "name": "started_by_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_used_at": {
+ "name": "last_used_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "stopped_at": {
+ "name": "stopped_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "stop_policy": {
+ "name": "stop_policy",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "exposure": {
+ "name": "exposure",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "exposure_handle": {
+ "name": "exposure_handle",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "backend_url": {
+ "name": "backend_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "health_status": {
+ "name": "health_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'unknown'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workspace_runtime_services_company_workspace_status_idx": {
+ "name": "workspace_runtime_services_company_workspace_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "workspace_runtime_services_company_execution_workspace_status_idx": {
+ "name": "workspace_runtime_services_company_execution_workspace_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "execution_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "workspace_runtime_services_company_project_status_idx": {
+ "name": "workspace_runtime_services_company_project_status_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "workspace_runtime_services_run_idx": {
+ "name": "workspace_runtime_services_run_idx",
+ "columns": [
+ {
+ "expression": "started_by_run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "workspace_runtime_services_company_updated_idx": {
+ "name": "workspace_runtime_services_company_updated_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "workspace_runtime_services_company_id_companies_id_fk": {
+ "name": "workspace_runtime_services_company_id_companies_id_fk",
+ "tableFrom": "workspace_runtime_services",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "workspace_runtime_services_project_id_projects_id_fk": {
+ "name": "workspace_runtime_services_project_id_projects_id_fk",
+ "tableFrom": "workspace_runtime_services",
+ "columnsFrom": [
+ "project_id"
+ ],
+ "tableTo": "projects",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "workspace_runtime_services_project_workspace_id_project_workspaces_id_fk": {
+ "name": "workspace_runtime_services_project_workspace_id_project_workspaces_id_fk",
+ "tableFrom": "workspace_runtime_services",
+ "columnsFrom": [
+ "project_workspace_id"
+ ],
+ "tableTo": "project_workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "workspace_runtime_services_execution_workspace_id_execution_workspaces_id_fk": {
+ "name": "workspace_runtime_services_execution_workspace_id_execution_workspaces_id_fk",
+ "tableFrom": "workspace_runtime_services",
+ "columnsFrom": [
+ "execution_workspace_id"
+ ],
+ "tableTo": "execution_workspaces",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "workspace_runtime_services_issue_id_issues_id_fk": {
+ "name": "workspace_runtime_services_issue_id_issues_id_fk",
+ "tableFrom": "workspace_runtime_services",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "tableTo": "issues",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "workspace_runtime_services_owner_agent_id_agents_id_fk": {
+ "name": "workspace_runtime_services_owner_agent_id_agents_id_fk",
+ "tableFrom": "workspace_runtime_services",
+ "columnsFrom": [
+ "owner_agent_id"
+ ],
+ "tableTo": "agents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "workspace_runtime_services_started_by_run_id_heartbeat_runs_id_fk": {
+ "name": "workspace_runtime_services_started_by_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "workspace_runtime_services",
+ "columnsFrom": [
+ "started_by_run_id"
+ ],
+ "tableTo": "heartbeat_runs",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.mcp_attachment_uploads": {
+ "name": "mcp_attachment_uploads",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "request_id": {
+ "name": "request_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "task_id": {
+ "name": "task_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "arguments_hash": {
+ "name": "arguments_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "original_filename": {
+ "name": "original_filename",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content_type": {
+ "name": "content_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "byte_size": {
+ "name": "byte_size",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sha256": {
+ "name": "sha256",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "attachment_id": {
+ "name": "attachment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "object_key": {
+ "name": "object_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "storage_provider": {
+ "name": "storage_provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cleaned_at": {
+ "name": "cleaned_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "mcp_attachment_upload_request_uq": {
+ "name": "mcp_attachment_upload_request_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "request_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "mcp_attachment_upload_expiry_idx": {
+ "name": "mcp_attachment_upload_expiry_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "mcp_attachment_uploads_company_id_companies_id_fk": {
+ "name": "mcp_attachment_uploads_company_id_companies_id_fk",
+ "tableFrom": "mcp_attachment_uploads",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "mcp_attachment_uploads_user_id_user_id_fk": {
+ "name": "mcp_attachment_uploads_user_id_user_id_fk",
+ "tableFrom": "mcp_attachment_uploads",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.mcp_event_admissions": {
+ "name": "mcp_event_admissions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "subscription_id": {
+ "name": "subscription_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "grant_id": {
+ "name": "grant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "reserves_subscription": {
+ "name": "reserves_subscription",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "finished_at": {
+ "name": "finished_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "mcp_event_admissions_expiry_idx": {
+ "name": "mcp_event_admissions_expiry_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "mcp_event_admissions_grant_idx": {
+ "name": "mcp_event_admissions_grant_idx",
+ "columns": [
+ {
+ "expression": "grant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "mcp_event_admissions_company_idx": {
+ "name": "mcp_event_admissions_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "mcp_event_admissions_company_id_companies_id_fk": {
+ "name": "mcp_event_admissions_company_id_companies_id_fk",
+ "tableFrom": "mcp_event_admissions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "mcp_event_admissions_grant_id_mcp_oauth_grants_id_fk": {
+ "name": "mcp_event_admissions_grant_id_mcp_oauth_grants_id_fk",
+ "tableFrom": "mcp_event_admissions",
+ "columnsFrom": [
+ "grant_id"
+ ],
+ "tableTo": "mcp_oauth_grants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.mcp_event_deliveries": {
+ "name": "mcp_event_deliveries",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "subscription_id": {
+ "name": "subscription_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "activity_id": {
+ "name": "activity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "event": {
+ "name": "event",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "attempts": {
+ "name": "attempts",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "next_attempt_at": {
+ "name": "next_attempt_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "finished_at": {
+ "name": "finished_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "outcome": {
+ "name": "outcome",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "mcp_event_deliveries_activity_uq": {
+ "name": "mcp_event_deliveries_activity_uq",
+ "columns": [
+ {
+ "expression": "subscription_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "activity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "mcp_event_deliveries_due_idx": {
+ "name": "mcp_event_deliveries_due_idx",
+ "columns": [
+ {
+ "expression": "next_attempt_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "mcp_event_deliveries_subscription_id_mcp_event_subscriptions_id_fk": {
+ "name": "mcp_event_deliveries_subscription_id_mcp_event_subscriptions_id_fk",
+ "tableFrom": "mcp_event_deliveries",
+ "columnsFrom": [
+ "subscription_id"
+ ],
+ "tableTo": "mcp_event_subscriptions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.mcp_event_subscriptions": {
+ "name": "mcp_event_subscriptions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "grant_id": {
+ "name": "grant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "task_id": {
+ "name": "task_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "arguments": {
+ "name": "arguments",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "delivery_material": {
+ "name": "delivery_material",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "verified_at": {
+ "name": "verified_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "starts_at": {
+ "name": "starts_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "stopped_at": {
+ "name": "stopped_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scanned_at": {
+ "name": "scanned_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "mcp_event_subscriptions_expiry_idx": {
+ "name": "mcp_event_subscriptions_expiry_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "mcp_event_subscriptions_company_idx": {
+ "name": "mcp_event_subscriptions_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "mcp_event_subscriptions_company_id_companies_id_fk": {
+ "name": "mcp_event_subscriptions_company_id_companies_id_fk",
+ "tableFrom": "mcp_event_subscriptions",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "mcp_event_subscriptions_grant_id_mcp_oauth_grants_id_fk": {
+ "name": "mcp_event_subscriptions_grant_id_mcp_oauth_grants_id_fk",
+ "tableFrom": "mcp_event_subscriptions",
+ "columnsFrom": [
+ "grant_id"
+ ],
+ "tableTo": "mcp_oauth_grants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.mcp_file_tickets": {
+ "name": "mcp_file_tickets",
+ "schema": "",
+ "columns": {
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "grant_id": {
+ "name": "grant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "upload_id": {
+ "name": "upload_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "attachment_id": {
+ "name": "attachment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "mcp_file_ticket_expiry_idx": {
+ "name": "mcp_file_ticket_expiry_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "mcp_file_ticket_grant_idx": {
+ "name": "mcp_file_ticket_grant_idx",
+ "columns": [
+ {
+ "expression": "grant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "mcp_file_tickets_company_id_companies_id_fk": {
+ "name": "mcp_file_tickets_company_id_companies_id_fk",
+ "tableFrom": "mcp_file_tickets",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "mcp_file_tickets_grant_id_mcp_oauth_grants_id_fk": {
+ "name": "mcp_file_tickets_grant_id_mcp_oauth_grants_id_fk",
+ "tableFrom": "mcp_file_tickets",
+ "columnsFrom": [
+ "grant_id"
+ ],
+ "tableTo": "mcp_oauth_grants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "mcp_file_tickets_upload_id_mcp_attachment_uploads_id_fk": {
+ "name": "mcp_file_tickets_upload_id_mcp_attachment_uploads_id_fk",
+ "tableFrom": "mcp_file_tickets",
+ "columnsFrom": [
+ "upload_id"
+ ],
+ "tableTo": "mcp_attachment_uploads",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.mcp_mutation_receipts": {
+ "name": "mcp_mutation_receipts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "grant_id": {
+ "name": "grant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "operation": {
+ "name": "operation",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "request_id": {
+ "name": "request_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "arguments_hash": {
+ "name": "arguments_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'reserved'"
+ },
+ "result": {
+ "name": "result",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "mcp_mutation_receipts_request_uq": {
+ "name": "mcp_mutation_receipts_request_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "operation",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "request_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "mcp_mutation_receipts_company_idx": {
+ "name": "mcp_mutation_receipts_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "mcp_mutation_receipts_company_id_companies_id_fk": {
+ "name": "mcp_mutation_receipts_company_id_companies_id_fk",
+ "tableFrom": "mcp_mutation_receipts",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "mcp_mutation_receipts_user_id_user_id_fk": {
+ "name": "mcp_mutation_receipts_user_id_user_id_fk",
+ "tableFrom": "mcp_mutation_receipts",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "mcp_mutation_receipts_grant_id_mcp_oauth_grants_id_fk": {
+ "name": "mcp_mutation_receipts_grant_id_mcp_oauth_grants_id_fk",
+ "tableFrom": "mcp_mutation_receipts",
+ "columnsFrom": [
+ "grant_id"
+ ],
+ "tableTo": "mcp_oauth_grants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.mcp_oauth_clients": {
+ "name": "mcp_oauth_clients",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "registration_source_hash": {
+ "name": "registration_source_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "redirect_uris": {
+ "name": "redirect_uris",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "grant_types": {
+ "name": "grant_types",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[\"authorization_code\",\"refresh_token\"]'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.mcp_oauth_device_requests": {
+ "name": "mcp_oauth_device_requests",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "client_id": {
+ "name": "client_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "device_code_hash": {
+ "name": "device_code_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_code_hash": {
+ "name": "user_code_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource": {
+ "name": "resource",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scopes": {
+ "name": "scopes",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "requested_company_id": {
+ "name": "requested_company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_hash": {
+ "name": "source_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "grant_id": {
+ "name": "grant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "interval_seconds": {
+ "name": "interval_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 5
+ },
+ "next_poll_at": {
+ "name": "next_poll_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "mcp_oauth_device_code_uq": {
+ "name": "mcp_oauth_device_code_uq",
+ "columns": [
+ {
+ "expression": "device_code_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "mcp_oauth_user_code_uq": {
+ "name": "mcp_oauth_user_code_uq",
+ "columns": [
+ {
+ "expression": "user_code_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "mcp_oauth_device_expiry_idx": {
+ "name": "mcp_oauth_device_expiry_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "mcp_oauth_device_requests_client_id_mcp_oauth_clients_id_fk": {
+ "name": "mcp_oauth_device_requests_client_id_mcp_oauth_clients_id_fk",
+ "tableFrom": "mcp_oauth_device_requests",
+ "columnsFrom": [
+ "client_id"
+ ],
+ "tableTo": "mcp_oauth_clients",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "mcp_oauth_device_requests_grant_id_mcp_oauth_grants_id_fk": {
+ "name": "mcp_oauth_device_requests_grant_id_mcp_oauth_grants_id_fk",
+ "tableFrom": "mcp_oauth_device_requests",
+ "columnsFrom": [
+ "grant_id"
+ ],
+ "tableTo": "mcp_oauth_grants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.mcp_oauth_grants": {
+ "name": "mcp_oauth_grants",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "client_id": {
+ "name": "client_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource": {
+ "name": "resource",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scopes": {
+ "name": "scopes",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "mcp_oauth_grants_user_company_idx": {
+ "name": "mcp_oauth_grants_user_company_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "mcp_oauth_grants_company_id_companies_id_fk": {
+ "name": "mcp_oauth_grants_company_id_companies_id_fk",
+ "tableFrom": "mcp_oauth_grants",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "tableTo": "companies",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "mcp_oauth_grants_user_id_user_id_fk": {
+ "name": "mcp_oauth_grants_user_id_user_id_fk",
+ "tableFrom": "mcp_oauth_grants",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "mcp_oauth_grants_client_id_mcp_oauth_clients_id_fk": {
+ "name": "mcp_oauth_grants_client_id_mcp_oauth_clients_id_fk",
+ "tableFrom": "mcp_oauth_grants",
+ "columnsFrom": [
+ "client_id"
+ ],
+ "tableTo": "mcp_oauth_clients",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.mcp_oauth_metadata_admissions": {
+ "name": "mcp_oauth_metadata_admissions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "source_hash": {
+ "name": "source_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "mcp_oauth_metadata_admissions_expiry_idx": {
+ "name": "mcp_oauth_metadata_admissions_expiry_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.mcp_oauth_requests": {
+ "name": "mcp_oauth_requests",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "client_id": {
+ "name": "client_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "redirect_uri": {
+ "name": "redirect_uri",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource": {
+ "name": "resource",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scopes": {
+ "name": "scopes",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "state": {
+ "name": "state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "challenge": {
+ "name": "challenge",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "requested_company_id": {
+ "name": "requested_company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "grant_id": {
+ "name": "grant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "code_hash": {
+ "name": "code_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "decided_at": {
+ "name": "decided_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "consumed_at": {
+ "name": "consumed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "mcp_oauth_requests_code_uq": {
+ "name": "mcp_oauth_requests_code_uq",
+ "columns": [
+ {
+ "expression": "code_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "mcp_oauth_requests_expiry_idx": {
+ "name": "mcp_oauth_requests_expiry_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "mcp_oauth_requests_client_id_mcp_oauth_clients_id_fk": {
+ "name": "mcp_oauth_requests_client_id_mcp_oauth_clients_id_fk",
+ "tableFrom": "mcp_oauth_requests",
+ "columnsFrom": [
+ "client_id"
+ ],
+ "tableTo": "mcp_oauth_clients",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "mcp_oauth_requests_grant_id_mcp_oauth_grants_id_fk": {
+ "name": "mcp_oauth_requests_grant_id_mcp_oauth_grants_id_fk",
+ "tableFrom": "mcp_oauth_requests",
+ "columnsFrom": [
+ "grant_id"
+ ],
+ "tableTo": "mcp_oauth_grants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.mcp_oauth_tokens": {
+ "name": "mcp_oauth_tokens",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "grant_id": {
+ "name": "grant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "used_at": {
+ "name": "used_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "mcp_oauth_tokens_hash_uq": {
+ "name": "mcp_oauth_tokens_hash_uq",
+ "columns": [
+ {
+ "expression": "token_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "mcp_oauth_tokens_grant_idx": {
+ "name": "mcp_oauth_tokens_grant_idx",
+ "columns": [
+ {
+ "expression": "grant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "mcp_oauth_tokens_expiry_idx": {
+ "name": "mcp_oauth_tokens_expiry_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "mcp_oauth_tokens_grant_id_mcp_oauth_grants_id_fk": {
+ "name": "mcp_oauth_tokens_grant_id_mcp_oauth_grants_id_fk",
+ "tableFrom": "mcp_oauth_tokens",
+ "columnsFrom": [
+ "grant_id"
+ ],
+ "tableTo": "mcp_oauth_grants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ }
+ },
+ "enums": {},
+ "schemas": {},
+ "views": {},
+ "sequences": {
+ "public.chat_telegram_draft_ids": {
+ "name": "chat_telegram_draft_ids",
+ "increment": "1",
+ "minValue": "1",
+ "maxValue": "2147483647",
+ "startWith": "1",
+ "cache": "1",
+ "cycle": false,
+ "schema": "public"
+ }
+ },
+ "roles": {},
+ "policies": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
\ No newline at end of file
diff --git a/packages/db/src/migrations/meta/0310_snapshot.json b/packages/db/src/migrations/meta/0315_snapshot.json
similarity index 95%
rename from packages/db/src/migrations/meta/0310_snapshot.json
rename to packages/db/src/migrations/meta/0315_snapshot.json
index 8adbf57d9bb..69131296242 100644
--- a/packages/db/src/migrations/meta/0310_snapshot.json
+++ b/packages/db/src/migrations/meta/0315_snapshot.json
@@ -1,9 +1,1079 @@
{
- "id": "8a60ce2b-6ab6-435d-90b9-7dc7fc67d53f",
- "prevId": "593431cc-d6a8-4daf-a3e4-9e3c892d9419",
+ "id": "26691ae0-39a8-42ac-868d-e36ab7219073",
+ "prevId": "a1aefefe-8911-4583-9c52-7c658e46e9b4",
"version": "7",
"dialect": "postgresql",
"tables": {
+ "public.accounting_runtime_baselines": {
+ "name": "accounting_runtime_baselines",
+ "schema": "",
+ "columns": {
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cost_cents": {
+ "name": "cost_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "input_tokens": {
+ "name": "input_tokens",
+ "type": "numeric(30, 0)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cached_input_tokens": {
+ "name": "cached_input_tokens",
+ "type": "numeric(30, 0)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "output_tokens": {
+ "name": "output_tokens",
+ "type": "numeric(30, 0)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "accounting_runtime_baselines_company_idx": {
+ "name": "accounting_runtime_baselines_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "accounting_runtime_baselines_agent_id_agents_id_fk": {
+ "name": "accounting_runtime_baselines_agent_id_agents_id_fk",
+ "tableFrom": "accounting_runtime_baselines",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "accounting_runtime_baselines_company_id_companies_id_fk": {
+ "name": "accounting_runtime_baselines_company_id_companies_id_fk",
+ "tableFrom": "accounting_runtime_baselines",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.billing_invoice_lines": {
+ "name": "billing_invoice_lines",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "invoice_id": {
+ "name": "invoice_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "occurred_at": {
+ "name": "occurred_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cost_event_id": {
+ "name": "cost_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_request_id": {
+ "name": "provider_request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "model": {
+ "name": "model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "pricing": {
+ "name": "pricing",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ }
+ },
+ "indexes": {
+ "billing_invoice_lines_identity_idx": {
+ "name": "billing_invoice_lines_identity_idx",
+ "columns": [
+ {
+ "expression": "invoice_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "billing_invoice_lines_company_idx": {
+ "name": "billing_invoice_lines_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "invoice_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "billing_invoice_lines_company_id_companies_id_fk": {
+ "name": "billing_invoice_lines_company_id_companies_id_fk",
+ "tableFrom": "billing_invoice_lines",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "billing_invoice_lines_invoice_id_billing_invoices_id_fk": {
+ "name": "billing_invoice_lines_invoice_id_billing_invoices_id_fk",
+ "tableFrom": "billing_invoice_lines",
+ "tableTo": "billing_invoices",
+ "columnsFrom": [
+ "invoice_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "billing_invoice_lines_cost_event_id_cost_events_id_fk": {
+ "name": "billing_invoice_lines_cost_event_id_cost_events_id_fk",
+ "tableFrom": "billing_invoice_lines",
+ "tableTo": "cost_events",
+ "columnsFrom": [
+ "cost_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "billing_invoice_lines_amount_check": {
+ "name": "billing_invoice_lines_amount_check",
+ "value": "\"billing_invoice_lines\".\"amount_cents\" >= 0"
+ },
+ "billing_invoice_lines_kind_check": {
+ "name": "billing_invoice_lines_kind_check",
+ "value": "\"billing_invoice_lines\".\"kind\" in ('inference', 'fee', 'credit')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.billing_invoices": {
+ "name": "billing_invoices",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "biller": {
+ "name": "biller",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "currency": {
+ "name": "currency",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "imported_by": {
+ "name": "imported_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "billing_invoices_identity_idx": {
+ "name": "billing_invoices_identity_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "biller",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "billing_invoices_company_id_companies_id_fk": {
+ "name": "billing_invoices_company_id_companies_id_fk",
+ "tableFrom": "billing_invoices",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.budget_reservations": {
+ "name": "budget_reservations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "state": {
+ "name": "state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'held'"
+ },
+ "provider_started_at": {
+ "name": "provider_started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "settled_at": {
+ "name": "settled_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "budget_reservations_run_idx": {
+ "name": "budget_reservations_run_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "budget_reservations_active_idx": {
+ "name": "budget_reservations_active_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"budget_reservations\".\"state\" = 'held'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "budget_reservations_company_id_companies_id_fk": {
+ "name": "budget_reservations_company_id_companies_id_fk",
+ "tableFrom": "budget_reservations",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "budget_reservations_run_id_heartbeat_runs_id_fk": {
+ "name": "budget_reservations_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "budget_reservations",
+ "tableTo": "heartbeat_runs",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "budget_reservations_agent_id_agents_id_fk": {
+ "name": "budget_reservations_agent_id_agents_id_fk",
+ "tableFrom": "budget_reservations",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "budget_reservations_state_check": {
+ "name": "budget_reservations_state_check",
+ "value": "\"budget_reservations\".\"state\" in ('held', 'settled', 'released')"
+ },
+ "budget_reservations_amount_check": {
+ "name": "budget_reservations_amount_check",
+ "value": "\"budget_reservations\".\"amount_cents\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.cost_adjustments": {
+ "name": "cost_adjustments",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cost_event_id": {
+ "name": "cost_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "invoice_line_id": {
+ "name": "invoice_line_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_cents": {
+ "name": "previous_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "corrected_cents": {
+ "name": "corrected_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_status": {
+ "name": "previous_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_pricing": {
+ "name": "previous_pricing",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "reason": {
+ "name": "reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_id": {
+ "name": "actor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pricing": {
+ "name": "pricing",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "cost_adjustments_receipt_idx": {
+ "name": "cost_adjustments_receipt_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_adjustments_event_idx": {
+ "name": "cost_adjustments_event_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "cost_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_adjustments_invoice_line_idx": {
+ "name": "cost_adjustments_invoice_line_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "invoice_line_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "cost_adjustments_company_id_companies_id_fk": {
+ "name": "cost_adjustments_company_id_companies_id_fk",
+ "tableFrom": "cost_adjustments",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "cost_adjustments_cost_event_id_cost_events_id_fk": {
+ "name": "cost_adjustments_cost_event_id_cost_events_id_fk",
+ "tableFrom": "cost_adjustments",
+ "tableTo": "cost_events",
+ "columnsFrom": [
+ "cost_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "cost_adjustments_invoice_line_id_billing_invoice_lines_id_fk": {
+ "name": "cost_adjustments_invoice_line_id_billing_invoice_lines_id_fk",
+ "tableFrom": "cost_adjustments",
+ "tableTo": "billing_invoice_lines",
+ "columnsFrom": [
+ "invoice_line_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "cost_adjustments_amount_check": {
+ "name": "cost_adjustments_amount_check",
+ "value": "\"cost_adjustments\".\"previous_cents\" >= 0 and \"cost_adjustments\".\"corrected_cents\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.provider_billing_snapshots": {
+ "name": "provider_billing_snapshots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope_id": {
+ "name": "scope_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "day": {
+ "name": "day",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revision": {
+ "name": "revision",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "provider_billing_snapshots_identity_idx": {
+ "name": "provider_billing_snapshots_identity_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "account_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scope_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "day",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "provider_billing_snapshots_company_id_companies_id_fk": {
+ "name": "provider_billing_snapshots_company_id_companies_id_fk",
+ "tableFrom": "provider_billing_snapshots",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "provider_billing_snapshots_amount_check": {
+ "name": "provider_billing_snapshots_amount_check",
+ "value": "\"provider_billing_snapshots\".\"amount_cents\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.run_usage_receipts": {
+ "name": "run_usage_receipts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_id": {
+ "name": "source_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sequence": {
+ "name": "sequence",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_json": {
+ "name": "receipt_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "complete": {
+ "name": "complete",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "received_at": {
+ "name": "received_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "run_usage_receipts_source_sequence_idx": {
+ "name": "run_usage_receipts_source_sequence_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sequence",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "run_usage_receipts_run_latest_idx": {
+ "name": "run_usage_receipts_run_latest_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "received_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "run_usage_receipts_company_id_companies_id_fk": {
+ "name": "run_usage_receipts_company_id_companies_id_fk",
+ "tableFrom": "run_usage_receipts",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "run_usage_receipts_run_id_heartbeat_runs_id_fk": {
+ "name": "run_usage_receipts_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "run_usage_receipts",
+ "tableTo": "heartbeat_runs",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "run_usage_receipts_positive_sequence": {
+ "name": "run_usage_receipts_positive_sequence",
+ "value": "\"run_usage_receipts\".\"sequence\" > 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
"public.activity_log": {
"name": "activity_log",
"schema": "",
@@ -1820,7 +2890,7 @@
},
"total_cost_cents": {
"name": "total_cost_cents",
- "type": "bigint",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true,
"default": 0
@@ -2859,9 +3929,15 @@
"notNull": true,
"default": 0
},
+ "spend_month_utc": {
+ "name": "spend_month_utc",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
"spent_monthly_cents": {
"name": "spent_monthly_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true,
"default": 0
@@ -5262,7 +6338,7 @@
},
"amount_observed": {
"name": "amount_observed",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true
},
@@ -5378,7 +6454,7 @@
}
],
"isUnique": true,
- "where": "\"budget_incidents\".\"status\" <> 'dismissed'",
+ "where": "\"budget_incidents\".\"status\" = 'open'",
"concurrently": false,
"method": "btree",
"with": {}
@@ -5480,6 +6556,13 @@
"notNull": true,
"default": 0
},
+ "reservation_cents": {
+ "name": "reservation_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
"warn_percent": {
"name": "warn_percent",
"type": "integer",
@@ -5494,6 +6577,13 @@
"notNull": true,
"default": true
},
+ "unpriced_usage_policy": {
+ "name": "unpriced_usage_policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'block'"
+ },
"notify_enabled": {
"name": "notify_enabled",
"type": "boolean",
@@ -5508,6 +6598,20 @@
"notNull": true,
"default": true
},
+ "enforcement_version": {
+ "name": "enforcement_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "enforcement_delivered_version": {
+ "name": "enforcement_delivered_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
"created_by_user_id": {
"name": "created_by_user_id",
"type": "text",
@@ -5654,7 +6758,12 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
- "checkConstraints": {},
+ "checkConstraints": {
+ "budget_policies_reservation_nonnegative": {
+ "name": "budget_policies_reservation_nonnegative",
+ "value": "\"budget_policies\".\"reservation_cents\" >= 0"
+ }
+ },
"isRLSEnabled": false
},
"public.built_in_managed_resources": {
@@ -11306,9 +12415,15 @@
"notNull": true,
"default": 0
},
+ "spend_month_utc": {
+ "name": "spend_month_utc",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
"spent_monthly_cents": {
"name": "spent_monthly_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true,
"default": 0
@@ -16201,6 +17316,36 @@
"primaryKey": false,
"notNull": false
},
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_request_id": {
+ "name": "provider_request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "reported_cost_cents": {
+ "name": "reported_cost_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "pricing_provenance": {
+ "name": "pricing_provenance",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
"provider": {
"name": "provider",
"type": "text",
@@ -16257,7 +17402,7 @@
},
"cost_cents": {
"name": "cost_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true
},
@@ -16276,6 +17421,109 @@
}
},
"indexes": {
+ "cost_events_company_receipt_idx": {
+ "name": "cost_events_company_receipt_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_events_provider_request_idx": {
+ "name": "cost_events_provider_request_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "biller",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_request_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_events_company_project_occurred_idx": {
+ "name": "cost_events_company_project_occurred_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "occurred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_events_unpriced_idx": {
+ "name": "cost_events_unpriced_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "occurred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"cost_events\".\"cost_status\" = 'unpriced' and \"cost_events\".\"billing_type\" <> 'subscription_included'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"cost_events_company_occurred_idx": {
"name": "cost_events_company_occurred_idx",
"columns": [
@@ -16483,7 +17731,12 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
- "checkConstraints": {},
+ "checkConstraints": {
+ "cost_events_nonnegative_amounts": {
+ "name": "cost_events_nonnegative_amounts",
+ "value": "\"cost_events\".\"cost_cents\" >= 0 and \"cost_events\".\"input_tokens\" >= 0 and \"cost_events\".\"cached_input_tokens\" >= 0 and \"cost_events\".\"output_tokens\" >= 0"
+ }
+ },
"isRLSEnabled": false
},
"public.decision_archive_notification_outbox": {
@@ -23721,6 +24974,18 @@
"primaryKey": false,
"notNull": false
},
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
"billing_code": {
"name": "billing_code",
"type": "text",
@@ -23796,7 +25061,7 @@
},
"amount_cents": {
"name": "amount_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true
},
@@ -23841,6 +25106,27 @@
}
},
"indexes": {
+ "finance_events_company_receipt_idx": {
+ "name": "finance_events_company_receipt_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"finance_events_company_occurred_idx": {
"name": "finance_events_company_occurred_idx",
"columns": [
@@ -24987,6 +26273,19 @@
"primaryKey": false,
"notNull": true
},
+ "scope_kind": {
+ "name": "scope_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'company'"
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
"invocation_source": {
"name": "invocation_source",
"type": "text",
@@ -25067,6 +26366,44 @@
"primaryKey": false,
"notNull": false
},
+ "cost_accounting_pending": {
+ "name": "cost_accounting_pending",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "cost_accounted_at": {
+ "name": "cost_accounted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_projection_version": {
+ "name": "accounting_projection_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_last_attempt_at": {
+ "name": "accounting_last_attempt_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_last_error": {
+ "name": "accounting_last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_attempt_count": {
+ "name": "accounting_attempt_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
"usage_json": {
"name": "usage_json",
"type": "jsonb",
@@ -25403,6 +26740,28 @@
}
},
"indexes": {
+ "heartbeat_runs_cost_accounting_pending_idx": {
+ "name": "heartbeat_runs_cost_accounting_pending_idx",
+ "columns": [
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"heartbeat_runs\".\"cost_accounting_pending\" = true",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"heartbeat_runs_execution_status_delivery_idx": {
"name": "heartbeat_runs_execution_status_delivery_idx",
"columns": [
@@ -25484,6 +26843,33 @@
"method": "btree",
"with": {}
},
+ "heartbeat_runs_company_issue_created_idx": {
+ "name": "heartbeat_runs_company_issue_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"heartbeat_runs_company_responsible_user_idx": {
"name": "heartbeat_runs_company_responsible_user_idx",
"columns": [
@@ -25722,6 +27108,19 @@
"onDelete": "no action",
"onUpdate": "no action"
},
+ "heartbeat_runs_issue_id_issues_id_fk": {
+ "name": "heartbeat_runs_issue_id_issues_id_fk",
+ "tableFrom": "heartbeat_runs",
+ "tableTo": "issues",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
"heartbeat_runs_wakeup_request_id_agent_wakeup_requests_id_fk": {
"name": "heartbeat_runs_wakeup_request_id_agent_wakeup_requests_id_fk",
"tableFrom": "heartbeat_runs",
@@ -25772,7 +27171,12 @@
}
},
"policies": {},
- "checkConstraints": {},
+ "checkConstraints": {
+ "heartbeat_runs_scope_binding_check": {
+ "name": "heartbeat_runs_scope_binding_check",
+ "value": "(\"heartbeat_runs\".\"scope_kind\" = 'company' AND \"heartbeat_runs\".\"issue_id\" IS NULL)\n OR \"heartbeat_runs\".\"scope_kind\" = 'issue'"
+ }
+ },
"isRLSEnabled": false
},
"public.inbox_dismissals": {
@@ -27215,6 +28619,166 @@
"checkConstraints": {},
"isRLSEnabled": false
},
+ "public.issue_access_grants": {
+ "name": "issue_access_grants",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_type": {
+ "name": "subject_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_id": {
+ "name": "subject_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source": {
+ "name": "source",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "granted_by_user_id": {
+ "name": "granted_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "granted_by_agent_id": {
+ "name": "granted_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "issue_access_grants_subject_active_issue_idx": {
+ "name": "issue_access_grants_subject_active_issue_idx",
+ "columns": [
+ {
+ "expression": "subject_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "revoked_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "issue_access_grants_issue_idx": {
+ "name": "issue_access_grants_issue_idx",
+ "columns": [
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "issue_access_grants_issue_id_issues_id_fk": {
+ "name": "issue_access_grants_issue_id_issues_id_fk",
+ "tableFrom": "issue_access_grants",
+ "tableTo": "issues",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "issue_access_grants_granted_by_agent_id_agents_id_fk": {
+ "name": "issue_access_grants_granted_by_agent_id_agents_id_fk",
+ "tableFrom": "issue_access_grants",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "granted_by_agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "issue_access_grants_subject_type_check": {
+ "name": "issue_access_grants_subject_type_check",
+ "value": "\"issue_access_grants\".\"subject_type\" in ('user', 'agent')"
+ },
+ "issue_access_grants_source_check": {
+ "name": "issue_access_grants_source_check",
+ "value": "\"issue_access_grants\".\"source\" in ('explicit', 'assignment', 'project')"
+ }
+ },
+ "isRLSEnabled": false
+ },
"public.issue_approvals": {
"name": "issue_approvals",
"schema": "",
@@ -32087,6 +33651,25 @@
"primaryKey": false,
"notNull": false
},
+ "visibility": {
+ "name": "visibility",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'open'"
+ },
+ "privacy_root_issue_id": {
+ "name": "privacy_root_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "privacy_parent_issue_id": {
+ "name": "privacy_parent_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
"title": {
"name": "title",
"type": "text",
@@ -32571,6 +34154,48 @@
"method": "btree",
"with": {}
},
+ "issues_company_privacy_parent_idx": {
+ "name": "issues_company_privacy_parent_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "privacy_parent_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "issues_company_privacy_root_idx": {
+ "name": "issues_company_privacy_root_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "privacy_root_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"issues_company_project_idx": {
"name": "issues_company_project_idx",
"columns": [
@@ -33140,6 +34765,32 @@
"onDelete": "no action",
"onUpdate": "no action"
},
+ "issues_privacy_root_issue_id_issues_id_fk": {
+ "name": "issues_privacy_root_issue_id_issues_id_fk",
+ "tableFrom": "issues",
+ "tableTo": "issues",
+ "columnsFrom": [
+ "privacy_root_issue_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "issues_privacy_parent_issue_id_issues_id_fk": {
+ "name": "issues_privacy_parent_issue_id_issues_id_fk",
+ "tableFrom": "issues",
+ "tableTo": "issues",
+ "columnsFrom": [
+ "privacy_parent_issue_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
"issues_assignee_agent_id_agents_id_fk": {
"name": "issues_assignee_agent_id_agents_id_fk",
"tableFrom": "issues",
@@ -33219,6 +34870,10 @@
},
"policies": {},
"checkConstraints": {
+ "issues_visibility_check": {
+ "name": "issues_visibility_check",
+ "value": "\"issues\".\"visibility\" in ('open', 'private')"
+ },
"issues_conversation_identity_check": {
"name": "issues_conversation_identity_check",
"value": "(\n \"issues\".\"conversation_agent_id\" is null and \"issues\".\"conversation_user_id\" is null and \"issues\".\"conversation_state\" is null\n ) or (\n \"issues\".\"conversation_agent_id\" is not null and \"issues\".\"conversation_user_id\" is not null\n and \"issues\".\"assignee_agent_id\" = \"issues\".\"conversation_agent_id\" and \"issues\".\"assignee_agent_id\" is not null\n and \"issues\".\"assignee_user_id\" is null and \"issues\".\"conversation_state\" is not null\n and \"issues\".\"conversation_state\" in ('active', 'waiting')\n and \"issues\".\"status\" not in ('done', 'cancelled')\n )"
@@ -38508,6 +40163,150 @@
"checkConstraints": {},
"isRLSEnabled": false
},
+ "public.project_access_members": {
+ "name": "project_access_members",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_type": {
+ "name": "subject_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_id": {
+ "name": "subject_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "project_access_members_project_subject_uq": {
+ "name": "project_access_members_project_subject_uq",
+ "columns": [
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "project_access_members_subject_lookup_idx": {
+ "name": "project_access_members_subject_lookup_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "project_access_members_company_id_companies_id_fk": {
+ "name": "project_access_members_company_id_companies_id_fk",
+ "tableFrom": "project_access_members",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "project_access_members_project_id_projects_id_fk": {
+ "name": "project_access_members_project_id_projects_id_fk",
+ "tableFrom": "project_access_members",
+ "tableTo": "projects",
+ "columnsFrom": [
+ "project_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "project_access_members_subject_type_check": {
+ "name": "project_access_members_subject_type_check",
+ "value": "\"project_access_members\".\"subject_type\" in ('user', 'agent')"
+ }
+ },
+ "isRLSEnabled": false
+ },
"public.project_goals": {
"name": "project_goals",
"schema": "",
@@ -39137,6 +40936,25 @@
"primaryKey": false,
"notNull": false
},
+ "visibility": {
+ "name": "visibility",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'open'"
+ },
+ "privacy_owner_user_id": {
+ "name": "privacy_owner_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "personal_owner_user_id": {
+ "name": "personal_owner_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
"status": {
"name": "status",
"type": "text",
@@ -39228,6 +41046,28 @@
"concurrently": false,
"method": "btree",
"with": {}
+ },
+ "projects_company_personal_owner_uq": {
+ "name": "projects_company_personal_owner_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "personal_owner_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"projects\".\"personal_owner_user_id\" is not null",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
}
},
"foreignKeys": {
@@ -39274,7 +41114,12 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
- "checkConstraints": {},
+ "checkConstraints": {
+ "projects_visibility_check": {
+ "name": "projects_visibility_check",
+ "value": "\"projects\".\"visibility\" in ('open', 'private')"
+ }
+ },
"isRLSEnabled": false
},
"public.provider_trace_records": {
@@ -42390,7 +44235,7 @@
},
"cost_cents": {
"name": "cost_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true,
"default": 0
@@ -49809,6 +51654,129 @@
"checkConstraints": {},
"isRLSEnabled": false
},
+ "public.user_company_preferences": {
+ "name": "user_company_preferences",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "primary_agent_id": {
+ "name": "primary_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "primary_agent_initialized": {
+ "name": "primary_agent_initialized",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "user_company_preferences_company_user_uq": {
+ "name": "user_company_preferences_company_user_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "user_company_preferences_primary_agent_idx": {
+ "name": "user_company_preferences_primary_agent_idx",
+ "columns": [
+ {
+ "expression": "primary_agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "user_company_preferences_company_id_companies_id_fk": {
+ "name": "user_company_preferences_company_id_companies_id_fk",
+ "tableFrom": "user_company_preferences",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "user_company_preferences_primary_agent_id_agents_id_fk": {
+ "name": "user_company_preferences_primary_agent_id_agents_id_fk",
+ "tableFrom": "user_company_preferences",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "primary_agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
"public.user_inbox_agent_policies": {
"name": "user_inbox_agent_policies",
"schema": "",
@@ -51493,6 +53461,187 @@
"checkConstraints": {},
"isRLSEnabled": false
},
+ "public.mcp_attachment_uploads": {
+ "name": "mcp_attachment_uploads",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "request_id": {
+ "name": "request_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "task_id": {
+ "name": "task_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "arguments_hash": {
+ "name": "arguments_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "original_filename": {
+ "name": "original_filename",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content_type": {
+ "name": "content_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "byte_size": {
+ "name": "byte_size",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sha256": {
+ "name": "sha256",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "attachment_id": {
+ "name": "attachment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "object_key": {
+ "name": "object_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "storage_provider": {
+ "name": "storage_provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cleaned_at": {
+ "name": "cleaned_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "mcp_attachment_upload_request_uq": {
+ "name": "mcp_attachment_upload_request_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "request_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "mcp_attachment_upload_expiry_idx": {
+ "name": "mcp_attachment_upload_expiry_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "mcp_attachment_uploads_company_id_companies_id_fk": {
+ "name": "mcp_attachment_uploads_company_id_companies_id_fk",
+ "tableFrom": "mcp_attachment_uploads",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "mcp_attachment_uploads_user_id_user_id_fk": {
+ "name": "mcp_attachment_uploads_user_id_user_id_fk",
+ "tableFrom": "mcp_attachment_uploads",
+ "tableTo": "user",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
"public.mcp_event_admissions": {
"name": "mcp_event_admissions",
"schema": "",
@@ -51889,6 +54038,133 @@
"checkConstraints": {},
"isRLSEnabled": false
},
+ "public.mcp_file_tickets": {
+ "name": "mcp_file_tickets",
+ "schema": "",
+ "columns": {
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "grant_id": {
+ "name": "grant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "upload_id": {
+ "name": "upload_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "attachment_id": {
+ "name": "attachment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "mcp_file_ticket_expiry_idx": {
+ "name": "mcp_file_ticket_expiry_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "mcp_file_ticket_grant_idx": {
+ "name": "mcp_file_ticket_grant_idx",
+ "columns": [
+ {
+ "expression": "grant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "mcp_file_tickets_company_id_companies_id_fk": {
+ "name": "mcp_file_tickets_company_id_companies_id_fk",
+ "tableFrom": "mcp_file_tickets",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "mcp_file_tickets_grant_id_mcp_oauth_grants_id_fk": {
+ "name": "mcp_file_tickets_grant_id_mcp_oauth_grants_id_fk",
+ "tableFrom": "mcp_file_tickets",
+ "tableTo": "mcp_oauth_grants",
+ "columnsFrom": [
+ "grant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "mcp_file_tickets_upload_id_mcp_attachment_uploads_id_fk": {
+ "name": "mcp_file_tickets_upload_id_mcp_attachment_uploads_id_fk",
+ "tableFrom": "mcp_file_tickets",
+ "tableTo": "mcp_attachment_uploads",
+ "columnsFrom": [
+ "upload_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
"public.mcp_mutation_receipts": {
"name": "mcp_mutation_receipts",
"schema": "",
diff --git a/packages/db/src/migrations/meta/0309_snapshot.json b/packages/db/src/migrations/meta/0316_snapshot.json
similarity index 94%
rename from packages/db/src/migrations/meta/0309_snapshot.json
rename to packages/db/src/migrations/meta/0316_snapshot.json
index 73605603da1..76eb90e5795 100644
--- a/packages/db/src/migrations/meta/0309_snapshot.json
+++ b/packages/db/src/migrations/meta/0316_snapshot.json
@@ -1,9 +1,1110 @@
{
- "id": "593431cc-d6a8-4daf-a3e4-9e3c892d9419",
- "prevId": "00d98f2c-c054-4ca3-91eb-08211bdf418d",
+ "id": "2242ec8f-2d13-46d2-99ed-cf97a52466d2",
+ "prevId": "26691ae0-39a8-42ac-868d-e36ab7219073",
"version": "7",
"dialect": "postgresql",
"tables": {
+ "public.accounting_runtime_baselines": {
+ "name": "accounting_runtime_baselines",
+ "schema": "",
+ "columns": {
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cost_cents": {
+ "name": "cost_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "input_tokens": {
+ "name": "input_tokens",
+ "type": "numeric(30, 0)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cached_input_tokens": {
+ "name": "cached_input_tokens",
+ "type": "numeric(30, 0)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "output_tokens": {
+ "name": "output_tokens",
+ "type": "numeric(30, 0)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "accounting_runtime_baselines_company_idx": {
+ "name": "accounting_runtime_baselines_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "accounting_runtime_baselines_agent_id_agents_id_fk": {
+ "name": "accounting_runtime_baselines_agent_id_agents_id_fk",
+ "tableFrom": "accounting_runtime_baselines",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "accounting_runtime_baselines_company_id_companies_id_fk": {
+ "name": "accounting_runtime_baselines_company_id_companies_id_fk",
+ "tableFrom": "accounting_runtime_baselines",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.billing_invoice_lines": {
+ "name": "billing_invoice_lines",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "invoice_id": {
+ "name": "invoice_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "occurred_at": {
+ "name": "occurred_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cost_event_id": {
+ "name": "cost_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_request_id": {
+ "name": "provider_request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "model": {
+ "name": "model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "pricing": {
+ "name": "pricing",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ }
+ },
+ "indexes": {
+ "billing_invoice_lines_identity_idx": {
+ "name": "billing_invoice_lines_identity_idx",
+ "columns": [
+ {
+ "expression": "invoice_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "billing_invoice_lines_company_idx": {
+ "name": "billing_invoice_lines_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "invoice_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "billing_invoice_lines_company_id_companies_id_fk": {
+ "name": "billing_invoice_lines_company_id_companies_id_fk",
+ "tableFrom": "billing_invoice_lines",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "billing_invoice_lines_invoice_id_billing_invoices_id_fk": {
+ "name": "billing_invoice_lines_invoice_id_billing_invoices_id_fk",
+ "tableFrom": "billing_invoice_lines",
+ "tableTo": "billing_invoices",
+ "columnsFrom": [
+ "invoice_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "billing_invoice_lines_cost_event_id_cost_events_id_fk": {
+ "name": "billing_invoice_lines_cost_event_id_cost_events_id_fk",
+ "tableFrom": "billing_invoice_lines",
+ "tableTo": "cost_events",
+ "columnsFrom": [
+ "cost_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "billing_invoice_lines_amount_check": {
+ "name": "billing_invoice_lines_amount_check",
+ "value": "\"billing_invoice_lines\".\"amount_cents\" >= 0"
+ },
+ "billing_invoice_lines_kind_check": {
+ "name": "billing_invoice_lines_kind_check",
+ "value": "\"billing_invoice_lines\".\"kind\" in ('inference', 'fee', 'credit')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.billing_invoices": {
+ "name": "billing_invoices",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "biller": {
+ "name": "biller",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "currency": {
+ "name": "currency",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "imported_by": {
+ "name": "imported_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "billing_invoices_identity_idx": {
+ "name": "billing_invoices_identity_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "biller",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "billing_invoices_company_id_companies_id_fk": {
+ "name": "billing_invoices_company_id_companies_id_fk",
+ "tableFrom": "billing_invoices",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.budget_reservations": {
+ "name": "budget_reservations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "decision_invocation_id": {
+ "name": "decision_invocation_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "state": {
+ "name": "state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'held'"
+ },
+ "provider_started_at": {
+ "name": "provider_started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "settled_at": {
+ "name": "settled_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "budget_reservations_decision_idx": {
+ "name": "budget_reservations_decision_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "decision_invocation_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "budget_reservations_run_idx": {
+ "name": "budget_reservations_run_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "budget_reservations_active_idx": {
+ "name": "budget_reservations_active_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"budget_reservations\".\"state\" = 'held'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "budget_reservations_company_id_companies_id_fk": {
+ "name": "budget_reservations_company_id_companies_id_fk",
+ "tableFrom": "budget_reservations",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "budget_reservations_run_id_heartbeat_runs_id_fk": {
+ "name": "budget_reservations_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "budget_reservations",
+ "tableTo": "heartbeat_runs",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "budget_reservations_agent_id_agents_id_fk": {
+ "name": "budget_reservations_agent_id_agents_id_fk",
+ "tableFrom": "budget_reservations",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "budget_reservations_source_check": {
+ "name": "budget_reservations_source_check",
+ "value": "(\"budget_reservations\".\"run_id\" is not null)::int + (\"budget_reservations\".\"decision_invocation_id\" is not null)::int = 1"
+ },
+ "budget_reservations_state_check": {
+ "name": "budget_reservations_state_check",
+ "value": "\"budget_reservations\".\"state\" in ('held', 'settled', 'released')"
+ },
+ "budget_reservations_amount_check": {
+ "name": "budget_reservations_amount_check",
+ "value": "\"budget_reservations\".\"amount_cents\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.cost_adjustments": {
+ "name": "cost_adjustments",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cost_event_id": {
+ "name": "cost_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "invoice_line_id": {
+ "name": "invoice_line_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_cents": {
+ "name": "previous_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "corrected_cents": {
+ "name": "corrected_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_status": {
+ "name": "previous_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_pricing": {
+ "name": "previous_pricing",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "reason": {
+ "name": "reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_id": {
+ "name": "actor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pricing": {
+ "name": "pricing",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "cost_adjustments_receipt_idx": {
+ "name": "cost_adjustments_receipt_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_adjustments_event_idx": {
+ "name": "cost_adjustments_event_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "cost_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_adjustments_invoice_line_idx": {
+ "name": "cost_adjustments_invoice_line_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "invoice_line_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "cost_adjustments_company_id_companies_id_fk": {
+ "name": "cost_adjustments_company_id_companies_id_fk",
+ "tableFrom": "cost_adjustments",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "cost_adjustments_cost_event_id_cost_events_id_fk": {
+ "name": "cost_adjustments_cost_event_id_cost_events_id_fk",
+ "tableFrom": "cost_adjustments",
+ "tableTo": "cost_events",
+ "columnsFrom": [
+ "cost_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "cost_adjustments_invoice_line_id_billing_invoice_lines_id_fk": {
+ "name": "cost_adjustments_invoice_line_id_billing_invoice_lines_id_fk",
+ "tableFrom": "cost_adjustments",
+ "tableTo": "billing_invoice_lines",
+ "columnsFrom": [
+ "invoice_line_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "cost_adjustments_amount_check": {
+ "name": "cost_adjustments_amount_check",
+ "value": "\"cost_adjustments\".\"previous_cents\" >= 0 and \"cost_adjustments\".\"corrected_cents\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.provider_billing_snapshots": {
+ "name": "provider_billing_snapshots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope_id": {
+ "name": "scope_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "day": {
+ "name": "day",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revision": {
+ "name": "revision",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "provider_billing_snapshots_identity_idx": {
+ "name": "provider_billing_snapshots_identity_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "account_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scope_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "day",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "provider_billing_snapshots_company_id_companies_id_fk": {
+ "name": "provider_billing_snapshots_company_id_companies_id_fk",
+ "tableFrom": "provider_billing_snapshots",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "provider_billing_snapshots_amount_check": {
+ "name": "provider_billing_snapshots_amount_check",
+ "value": "\"provider_billing_snapshots\".\"amount_cents\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.run_usage_receipts": {
+ "name": "run_usage_receipts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_id": {
+ "name": "source_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sequence": {
+ "name": "sequence",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_json": {
+ "name": "receipt_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "complete": {
+ "name": "complete",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "received_at": {
+ "name": "received_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "run_usage_receipts_source_sequence_idx": {
+ "name": "run_usage_receipts_source_sequence_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sequence",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "run_usage_receipts_run_latest_idx": {
+ "name": "run_usage_receipts_run_latest_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "received_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "run_usage_receipts_company_id_companies_id_fk": {
+ "name": "run_usage_receipts_company_id_companies_id_fk",
+ "tableFrom": "run_usage_receipts",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "run_usage_receipts_run_id_heartbeat_runs_id_fk": {
+ "name": "run_usage_receipts_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "run_usage_receipts",
+ "tableTo": "heartbeat_runs",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "run_usage_receipts_positive_sequence": {
+ "name": "run_usage_receipts_positive_sequence",
+ "value": "\"run_usage_receipts\".\"sequence\" > 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
"public.activity_log": {
"name": "activity_log",
"schema": "",
@@ -657,6 +1758,194 @@
"checkConstraints": {},
"isRLSEnabled": false
},
+ "public.agent_commentary": {
+ "name": "agent_commentary",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "body": {
+ "name": "body",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "payload_hash": {
+ "name": "payload_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "agent_commentary_run_key_uq": {
+ "name": "agent_commentary_run_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "agent_commentary_company_kind_created_idx": {
+ "name": "agent_commentary_company_kind_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "agent_commentary_company_id_companies_id_fk": {
+ "name": "agent_commentary_company_id_companies_id_fk",
+ "tableFrom": "agent_commentary",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "agent_commentary_agent_id_agents_id_fk": {
+ "name": "agent_commentary_agent_id_agents_id_fk",
+ "tableFrom": "agent_commentary",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "agent_commentary_run_id_heartbeat_runs_id_fk": {
+ "name": "agent_commentary_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "agent_commentary",
+ "tableTo": "heartbeat_runs",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "agent_commentary_issue_id_issues_id_fk": {
+ "name": "agent_commentary_issue_id_issues_id_fk",
+ "tableFrom": "agent_commentary",
+ "tableTo": "issues",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "agent_commentary_kind_check": {
+ "name": "agent_commentary_kind_check",
+ "value": "\"agent_commentary\".\"kind\" in ('complaint', 'suggestion')"
+ }
+ },
+ "isRLSEnabled": false
+ },
"public.agent_config_revisions": {
"name": "agent_config_revisions",
"schema": "",
@@ -1632,7 +2921,7 @@
},
"total_cost_cents": {
"name": "total_cost_cents",
- "type": "bigint",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true,
"default": 0
@@ -2671,9 +3960,15 @@
"notNull": true,
"default": 0
},
+ "spend_month_utc": {
+ "name": "spend_month_utc",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
"spent_monthly_cents": {
"name": "spent_monthly_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true,
"default": 0
@@ -5074,7 +6369,7 @@
},
"amount_observed": {
"name": "amount_observed",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true
},
@@ -5190,7 +6485,7 @@
}
],
"isUnique": true,
- "where": "\"budget_incidents\".\"status\" <> 'dismissed'",
+ "where": "\"budget_incidents\".\"status\" = 'open'",
"concurrently": false,
"method": "btree",
"with": {}
@@ -5292,6 +6587,13 @@
"notNull": true,
"default": 0
},
+ "reservation_cents": {
+ "name": "reservation_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
"warn_percent": {
"name": "warn_percent",
"type": "integer",
@@ -5306,6 +6608,13 @@
"notNull": true,
"default": true
},
+ "unpriced_usage_policy": {
+ "name": "unpriced_usage_policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'block'"
+ },
"notify_enabled": {
"name": "notify_enabled",
"type": "boolean",
@@ -5320,6 +6629,20 @@
"notNull": true,
"default": true
},
+ "enforcement_version": {
+ "name": "enforcement_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "enforcement_delivered_version": {
+ "name": "enforcement_delivered_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
"created_by_user_id": {
"name": "created_by_user_id",
"type": "text",
@@ -5466,7 +6789,12 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
- "checkConstraints": {},
+ "checkConstraints": {
+ "budget_policies_reservation_nonnegative": {
+ "name": "budget_policies_reservation_nonnegative",
+ "value": "\"budget_policies\".\"reservation_cents\" >= 0"
+ }
+ },
"isRLSEnabled": false
},
"public.built_in_managed_resources": {
@@ -11118,9 +12446,15 @@
"notNull": true,
"default": 0
},
+ "spend_month_utc": {
+ "name": "spend_month_utc",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
"spent_monthly_cents": {
"name": "spent_monthly_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true,
"default": 0
@@ -15981,7 +17315,20 @@
"name": "agent_id",
"type": "uuid",
"primaryKey": false,
- "notNull": true
+ "notNull": false
+ },
+ "usage_kind": {
+ "name": "usage_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'agent'"
+ },
+ "responsible_user_id": {
+ "name": "responsible_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
},
"issue_id": {
"name": "issue_id",
@@ -16013,6 +17360,36 @@
"primaryKey": false,
"notNull": false
},
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_request_id": {
+ "name": "provider_request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "reported_cost_cents": {
+ "name": "reported_cost_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "pricing_provenance": {
+ "name": "pricing_provenance",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
"provider": {
"name": "provider",
"type": "text",
@@ -16069,7 +17446,7 @@
},
"cost_cents": {
"name": "cost_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true
},
@@ -16088,6 +17465,109 @@
}
},
"indexes": {
+ "cost_events_company_receipt_idx": {
+ "name": "cost_events_company_receipt_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_events_provider_request_idx": {
+ "name": "cost_events_provider_request_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "biller",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_request_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_events_company_project_occurred_idx": {
+ "name": "cost_events_company_project_occurred_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "occurred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_events_unpriced_idx": {
+ "name": "cost_events_unpriced_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "occurred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"cost_events\".\"cost_status\" = 'unpriced' and \"cost_events\".\"billing_type\" <> 'subscription_included'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"cost_events_company_occurred_idx": {
"name": "cost_events_company_occurred_idx",
"columns": [
@@ -16295,7 +17775,356 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
- "checkConstraints": {},
+ "checkConstraints": {
+ "cost_events_usage_kind_check": {
+ "name": "cost_events_usage_kind_check",
+ "value": "\"cost_events\".\"usage_kind\" = 'decision' or (\"cost_events\".\"usage_kind\" = 'agent' and \"cost_events\".\"agent_id\" is not null)"
+ },
+ "cost_events_nonnegative_amounts": {
+ "name": "cost_events_nonnegative_amounts",
+ "value": "\"cost_events\".\"cost_cents\" >= 0 and \"cost_events\".\"input_tokens\" >= 0 and \"cost_events\".\"cached_input_tokens\" >= 0 and \"cost_events\".\"output_tokens\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.company_decision_models": {
+ "name": "company_decision_models",
+ "schema": "",
+ "columns": {
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "grant_id": {
+ "name": "grant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "allow_background": {
+ "name": "allow_background",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "model": {
+ "name": "model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "company_decision_models_company_id_companies_id_fk": {
+ "name": "company_decision_models_company_id_companies_id_fk",
+ "tableFrom": "company_decision_models",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "company_decisions_configured": {
+ "name": "company_decisions_configured",
+ "value": "(\"company_decision_models\".\"connection_id\" is null) = (\"company_decision_models\".\"grant_id\" is null) and (not \"company_decision_models\".\"enabled\" or (\"company_decision_models\".\"connection_id\" is not null and \"company_decision_models\".\"provider\" is not null and \"company_decision_models\".\"model\" is not null))"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.decision_invocations": {
+ "name": "decision_invocations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "feature": {
+ "name": "feature",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_type": {
+ "name": "actor_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_id": {
+ "name": "actor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "responsible_user_id": {
+ "name": "responsible_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "identity_context_id": {
+ "name": "identity_context_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "grant_id": {
+ "name": "grant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "model": {
+ "name": "model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "question_types": {
+ "name": "question_types",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'running'"
+ },
+ "error_code": {
+ "name": "error_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_request_id": {
+ "name": "provider_request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cost_event_id": {
+ "name": "cost_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "finished_at": {
+ "name": "finished_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "duration_ms": {
+ "name": "duration_ms",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "input_tokens": {
+ "name": "input_tokens",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "output_tokens": {
+ "name": "output_tokens",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "decision_invocations_company_started_idx": {
+ "name": "decision_invocations_company_started_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "decision_invocations_pending_idx": {
+ "name": "decision_invocations_pending_idx",
+ "columns": [
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"decision_invocations\".\"status\" = 'running'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "decision_invocations_cost_idx": {
+ "name": "decision_invocations_cost_idx",
+ "columns": [
+ {
+ "expression": "cost_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "decision_invocations_company_id_companies_id_fk": {
+ "name": "decision_invocations_company_id_companies_id_fk",
+ "tableFrom": "decision_invocations",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "decision_invocations_cost_event_id_cost_events_id_fk": {
+ "name": "decision_invocations_cost_event_id_cost_events_id_fk",
+ "tableFrom": "decision_invocations",
+ "tableTo": "cost_events",
+ "columnsFrom": [
+ "cost_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "decision_invocations_status_check": {
+ "name": "decision_invocations_status_check",
+ "value": "\"decision_invocations\".\"status\" in ('running', 'succeeded', 'failed', 'unknown')"
+ }
+ },
"isRLSEnabled": false
},
"public.decision_archive_notification_outbox": {
@@ -23533,6 +25362,18 @@
"primaryKey": false,
"notNull": false
},
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
"billing_code": {
"name": "billing_code",
"type": "text",
@@ -23608,7 +25449,7 @@
},
"amount_cents": {
"name": "amount_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true
},
@@ -23653,6 +25494,27 @@
}
},
"indexes": {
+ "finance_events_company_receipt_idx": {
+ "name": "finance_events_company_receipt_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"finance_events_company_occurred_idx": {
"name": "finance_events_company_occurred_idx",
"columns": [
@@ -24799,6 +26661,19 @@
"primaryKey": false,
"notNull": true
},
+ "scope_kind": {
+ "name": "scope_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'company'"
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
"invocation_source": {
"name": "invocation_source",
"type": "text",
@@ -24879,6 +26754,44 @@
"primaryKey": false,
"notNull": false
},
+ "cost_accounting_pending": {
+ "name": "cost_accounting_pending",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "cost_accounted_at": {
+ "name": "cost_accounted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_projection_version": {
+ "name": "accounting_projection_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_last_attempt_at": {
+ "name": "accounting_last_attempt_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_last_error": {
+ "name": "accounting_last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_attempt_count": {
+ "name": "accounting_attempt_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
"usage_json": {
"name": "usage_json",
"type": "jsonb",
@@ -25215,6 +27128,28 @@
}
},
"indexes": {
+ "heartbeat_runs_cost_accounting_pending_idx": {
+ "name": "heartbeat_runs_cost_accounting_pending_idx",
+ "columns": [
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"heartbeat_runs\".\"cost_accounting_pending\" = true",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"heartbeat_runs_execution_status_delivery_idx": {
"name": "heartbeat_runs_execution_status_delivery_idx",
"columns": [
@@ -25296,6 +27231,33 @@
"method": "btree",
"with": {}
},
+ "heartbeat_runs_company_issue_created_idx": {
+ "name": "heartbeat_runs_company_issue_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"heartbeat_runs_company_responsible_user_idx": {
"name": "heartbeat_runs_company_responsible_user_idx",
"columns": [
@@ -25534,6 +27496,19 @@
"onDelete": "no action",
"onUpdate": "no action"
},
+ "heartbeat_runs_issue_id_issues_id_fk": {
+ "name": "heartbeat_runs_issue_id_issues_id_fk",
+ "tableFrom": "heartbeat_runs",
+ "tableTo": "issues",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
"heartbeat_runs_wakeup_request_id_agent_wakeup_requests_id_fk": {
"name": "heartbeat_runs_wakeup_request_id_agent_wakeup_requests_id_fk",
"tableFrom": "heartbeat_runs",
@@ -25584,7 +27559,12 @@
}
},
"policies": {},
- "checkConstraints": {},
+ "checkConstraints": {
+ "heartbeat_runs_scope_binding_check": {
+ "name": "heartbeat_runs_scope_binding_check",
+ "value": "(\"heartbeat_runs\".\"scope_kind\" = 'company' AND \"heartbeat_runs\".\"issue_id\" IS NULL)\n OR \"heartbeat_runs\".\"scope_kind\" = 'issue'"
+ }
+ },
"isRLSEnabled": false
},
"public.inbox_dismissals": {
@@ -27027,6 +29007,166 @@
"checkConstraints": {},
"isRLSEnabled": false
},
+ "public.issue_access_grants": {
+ "name": "issue_access_grants",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_type": {
+ "name": "subject_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_id": {
+ "name": "subject_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source": {
+ "name": "source",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "granted_by_user_id": {
+ "name": "granted_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "granted_by_agent_id": {
+ "name": "granted_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "issue_access_grants_subject_active_issue_idx": {
+ "name": "issue_access_grants_subject_active_issue_idx",
+ "columns": [
+ {
+ "expression": "subject_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "revoked_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "issue_access_grants_issue_idx": {
+ "name": "issue_access_grants_issue_idx",
+ "columns": [
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "issue_access_grants_issue_id_issues_id_fk": {
+ "name": "issue_access_grants_issue_id_issues_id_fk",
+ "tableFrom": "issue_access_grants",
+ "tableTo": "issues",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "issue_access_grants_granted_by_agent_id_agents_id_fk": {
+ "name": "issue_access_grants_granted_by_agent_id_agents_id_fk",
+ "tableFrom": "issue_access_grants",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "granted_by_agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "issue_access_grants_subject_type_check": {
+ "name": "issue_access_grants_subject_type_check",
+ "value": "\"issue_access_grants\".\"subject_type\" in ('user', 'agent')"
+ },
+ "issue_access_grants_source_check": {
+ "name": "issue_access_grants_source_check",
+ "value": "\"issue_access_grants\".\"source\" in ('explicit', 'assignment', 'project')"
+ }
+ },
+ "isRLSEnabled": false
+ },
"public.issue_approvals": {
"name": "issue_approvals",
"schema": "",
@@ -31899,6 +34039,25 @@
"primaryKey": false,
"notNull": false
},
+ "visibility": {
+ "name": "visibility",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'open'"
+ },
+ "privacy_root_issue_id": {
+ "name": "privacy_root_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "privacy_parent_issue_id": {
+ "name": "privacy_parent_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
"title": {
"name": "title",
"type": "text",
@@ -32383,6 +34542,48 @@
"method": "btree",
"with": {}
},
+ "issues_company_privacy_parent_idx": {
+ "name": "issues_company_privacy_parent_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "privacy_parent_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "issues_company_privacy_root_idx": {
+ "name": "issues_company_privacy_root_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "privacy_root_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"issues_company_project_idx": {
"name": "issues_company_project_idx",
"columns": [
@@ -32952,6 +35153,32 @@
"onDelete": "no action",
"onUpdate": "no action"
},
+ "issues_privacy_root_issue_id_issues_id_fk": {
+ "name": "issues_privacy_root_issue_id_issues_id_fk",
+ "tableFrom": "issues",
+ "tableTo": "issues",
+ "columnsFrom": [
+ "privacy_root_issue_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "issues_privacy_parent_issue_id_issues_id_fk": {
+ "name": "issues_privacy_parent_issue_id_issues_id_fk",
+ "tableFrom": "issues",
+ "tableTo": "issues",
+ "columnsFrom": [
+ "privacy_parent_issue_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
"issues_assignee_agent_id_agents_id_fk": {
"name": "issues_assignee_agent_id_agents_id_fk",
"tableFrom": "issues",
@@ -33031,6 +35258,10 @@
},
"policies": {},
"checkConstraints": {
+ "issues_visibility_check": {
+ "name": "issues_visibility_check",
+ "value": "\"issues\".\"visibility\" in ('open', 'private')"
+ },
"issues_conversation_identity_check": {
"name": "issues_conversation_identity_check",
"value": "(\n \"issues\".\"conversation_agent_id\" is null and \"issues\".\"conversation_user_id\" is null and \"issues\".\"conversation_state\" is null\n ) or (\n \"issues\".\"conversation_agent_id\" is not null and \"issues\".\"conversation_user_id\" is not null\n and \"issues\".\"assignee_agent_id\" = \"issues\".\"conversation_agent_id\" and \"issues\".\"assignee_agent_id\" is not null\n and \"issues\".\"assignee_user_id\" is null and \"issues\".\"conversation_state\" is not null\n and \"issues\".\"conversation_state\" in ('active', 'waiting')\n and \"issues\".\"status\" not in ('done', 'cancelled')\n )"
@@ -38320,6 +40551,150 @@
"checkConstraints": {},
"isRLSEnabled": false
},
+ "public.project_access_members": {
+ "name": "project_access_members",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_type": {
+ "name": "subject_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_id": {
+ "name": "subject_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "project_access_members_project_subject_uq": {
+ "name": "project_access_members_project_subject_uq",
+ "columns": [
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "project_access_members_subject_lookup_idx": {
+ "name": "project_access_members_subject_lookup_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "project_access_members_company_id_companies_id_fk": {
+ "name": "project_access_members_company_id_companies_id_fk",
+ "tableFrom": "project_access_members",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "project_access_members_project_id_projects_id_fk": {
+ "name": "project_access_members_project_id_projects_id_fk",
+ "tableFrom": "project_access_members",
+ "tableTo": "projects",
+ "columnsFrom": [
+ "project_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "project_access_members_subject_type_check": {
+ "name": "project_access_members_subject_type_check",
+ "value": "\"project_access_members\".\"subject_type\" in ('user', 'agent')"
+ }
+ },
+ "isRLSEnabled": false
+ },
"public.project_goals": {
"name": "project_goals",
"schema": "",
@@ -38949,6 +41324,25 @@
"primaryKey": false,
"notNull": false
},
+ "visibility": {
+ "name": "visibility",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'open'"
+ },
+ "privacy_owner_user_id": {
+ "name": "privacy_owner_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "personal_owner_user_id": {
+ "name": "personal_owner_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
"status": {
"name": "status",
"type": "text",
@@ -39040,6 +41434,28 @@
"concurrently": false,
"method": "btree",
"with": {}
+ },
+ "projects_company_personal_owner_uq": {
+ "name": "projects_company_personal_owner_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "personal_owner_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"projects\".\"personal_owner_user_id\" is not null",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
}
},
"foreignKeys": {
@@ -39086,7 +41502,12 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
- "checkConstraints": {},
+ "checkConstraints": {
+ "projects_visibility_check": {
+ "name": "projects_visibility_check",
+ "value": "\"projects\".\"visibility\" in ('open', 'private')"
+ }
+ },
"isRLSEnabled": false
},
"public.provider_trace_records": {
@@ -42202,7 +44623,7 @@
},
"cost_cents": {
"name": "cost_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true,
"default": 0
@@ -49621,6 +52042,129 @@
"checkConstraints": {},
"isRLSEnabled": false
},
+ "public.user_company_preferences": {
+ "name": "user_company_preferences",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "primary_agent_id": {
+ "name": "primary_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "primary_agent_initialized": {
+ "name": "primary_agent_initialized",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "user_company_preferences_company_user_uq": {
+ "name": "user_company_preferences_company_user_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "user_company_preferences_primary_agent_idx": {
+ "name": "user_company_preferences_primary_agent_idx",
+ "columns": [
+ {
+ "expression": "primary_agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "user_company_preferences_company_id_companies_id_fk": {
+ "name": "user_company_preferences_company_id_companies_id_fk",
+ "tableFrom": "user_company_preferences",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "user_company_preferences_primary_agent_id_agents_id_fk": {
+ "name": "user_company_preferences_primary_agent_id_agents_id_fk",
+ "tableFrom": "user_company_preferences",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "primary_agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
"public.user_inbox_agent_policies": {
"name": "user_inbox_agent_policies",
"schema": "",
@@ -51305,6 +53849,187 @@
"checkConstraints": {},
"isRLSEnabled": false
},
+ "public.mcp_attachment_uploads": {
+ "name": "mcp_attachment_uploads",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "request_id": {
+ "name": "request_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "task_id": {
+ "name": "task_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "arguments_hash": {
+ "name": "arguments_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "original_filename": {
+ "name": "original_filename",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content_type": {
+ "name": "content_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "byte_size": {
+ "name": "byte_size",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sha256": {
+ "name": "sha256",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "attachment_id": {
+ "name": "attachment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "object_key": {
+ "name": "object_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "storage_provider": {
+ "name": "storage_provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cleaned_at": {
+ "name": "cleaned_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "mcp_attachment_upload_request_uq": {
+ "name": "mcp_attachment_upload_request_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "request_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "mcp_attachment_upload_expiry_idx": {
+ "name": "mcp_attachment_upload_expiry_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "mcp_attachment_uploads_company_id_companies_id_fk": {
+ "name": "mcp_attachment_uploads_company_id_companies_id_fk",
+ "tableFrom": "mcp_attachment_uploads",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "mcp_attachment_uploads_user_id_user_id_fk": {
+ "name": "mcp_attachment_uploads_user_id_user_id_fk",
+ "tableFrom": "mcp_attachment_uploads",
+ "tableTo": "user",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
"public.mcp_event_admissions": {
"name": "mcp_event_admissions",
"schema": "",
@@ -51701,6 +54426,133 @@
"checkConstraints": {},
"isRLSEnabled": false
},
+ "public.mcp_file_tickets": {
+ "name": "mcp_file_tickets",
+ "schema": "",
+ "columns": {
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "grant_id": {
+ "name": "grant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "upload_id": {
+ "name": "upload_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "attachment_id": {
+ "name": "attachment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "mcp_file_ticket_expiry_idx": {
+ "name": "mcp_file_ticket_expiry_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "mcp_file_ticket_grant_idx": {
+ "name": "mcp_file_ticket_grant_idx",
+ "columns": [
+ {
+ "expression": "grant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "mcp_file_tickets_company_id_companies_id_fk": {
+ "name": "mcp_file_tickets_company_id_companies_id_fk",
+ "tableFrom": "mcp_file_tickets",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "mcp_file_tickets_grant_id_mcp_oauth_grants_id_fk": {
+ "name": "mcp_file_tickets_grant_id_mcp_oauth_grants_id_fk",
+ "tableFrom": "mcp_file_tickets",
+ "tableTo": "mcp_oauth_grants",
+ "columnsFrom": [
+ "grant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "mcp_file_tickets_upload_id_mcp_attachment_uploads_id_fk": {
+ "name": "mcp_file_tickets_upload_id_mcp_attachment_uploads_id_fk",
+ "tableFrom": "mcp_file_tickets",
+ "tableTo": "mcp_attachment_uploads",
+ "columnsFrom": [
+ "upload_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
"public.mcp_mutation_receipts": {
"name": "mcp_mutation_receipts",
"schema": "",
diff --git a/packages/db/src/migrations/meta/0308_snapshot.json b/packages/db/src/migrations/meta/0317_snapshot.json
similarity index 93%
rename from packages/db/src/migrations/meta/0308_snapshot.json
rename to packages/db/src/migrations/meta/0317_snapshot.json
index e294651897e..eabd692b213 100644
--- a/packages/db/src/migrations/meta/0308_snapshot.json
+++ b/packages/db/src/migrations/meta/0317_snapshot.json
@@ -1,9 +1,1110 @@
{
- "id": "00d98f2c-c054-4ca3-91eb-08211bdf418d",
- "prevId": "ff1eeb0a-fea3-4cd1-b45c-ce712c4667ff",
+ "id": "d8438290-9b05-4959-ab7f-2097cfdd6ce3",
+ "prevId": "2242ec8f-2d13-46d2-99ed-cf97a52466d2",
"version": "7",
"dialect": "postgresql",
"tables": {
+ "public.accounting_runtime_baselines": {
+ "name": "accounting_runtime_baselines",
+ "schema": "",
+ "columns": {
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cost_cents": {
+ "name": "cost_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "input_tokens": {
+ "name": "input_tokens",
+ "type": "numeric(30, 0)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cached_input_tokens": {
+ "name": "cached_input_tokens",
+ "type": "numeric(30, 0)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "output_tokens": {
+ "name": "output_tokens",
+ "type": "numeric(30, 0)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "accounting_runtime_baselines_company_idx": {
+ "name": "accounting_runtime_baselines_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "accounting_runtime_baselines_agent_id_agents_id_fk": {
+ "name": "accounting_runtime_baselines_agent_id_agents_id_fk",
+ "tableFrom": "accounting_runtime_baselines",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "accounting_runtime_baselines_company_id_companies_id_fk": {
+ "name": "accounting_runtime_baselines_company_id_companies_id_fk",
+ "tableFrom": "accounting_runtime_baselines",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.billing_invoice_lines": {
+ "name": "billing_invoice_lines",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "invoice_id": {
+ "name": "invoice_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "occurred_at": {
+ "name": "occurred_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cost_event_id": {
+ "name": "cost_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_request_id": {
+ "name": "provider_request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "model": {
+ "name": "model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "pricing": {
+ "name": "pricing",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ }
+ },
+ "indexes": {
+ "billing_invoice_lines_identity_idx": {
+ "name": "billing_invoice_lines_identity_idx",
+ "columns": [
+ {
+ "expression": "invoice_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "billing_invoice_lines_company_idx": {
+ "name": "billing_invoice_lines_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "invoice_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "billing_invoice_lines_company_id_companies_id_fk": {
+ "name": "billing_invoice_lines_company_id_companies_id_fk",
+ "tableFrom": "billing_invoice_lines",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "billing_invoice_lines_invoice_id_billing_invoices_id_fk": {
+ "name": "billing_invoice_lines_invoice_id_billing_invoices_id_fk",
+ "tableFrom": "billing_invoice_lines",
+ "tableTo": "billing_invoices",
+ "columnsFrom": [
+ "invoice_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "billing_invoice_lines_cost_event_id_cost_events_id_fk": {
+ "name": "billing_invoice_lines_cost_event_id_cost_events_id_fk",
+ "tableFrom": "billing_invoice_lines",
+ "tableTo": "cost_events",
+ "columnsFrom": [
+ "cost_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "billing_invoice_lines_amount_check": {
+ "name": "billing_invoice_lines_amount_check",
+ "value": "\"billing_invoice_lines\".\"amount_cents\" >= 0"
+ },
+ "billing_invoice_lines_kind_check": {
+ "name": "billing_invoice_lines_kind_check",
+ "value": "\"billing_invoice_lines\".\"kind\" in ('inference', 'fee', 'credit')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.billing_invoices": {
+ "name": "billing_invoices",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "biller": {
+ "name": "biller",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "currency": {
+ "name": "currency",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "imported_by": {
+ "name": "imported_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "billing_invoices_identity_idx": {
+ "name": "billing_invoices_identity_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "biller",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "billing_invoices_company_id_companies_id_fk": {
+ "name": "billing_invoices_company_id_companies_id_fk",
+ "tableFrom": "billing_invoices",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.budget_reservations": {
+ "name": "budget_reservations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "decision_invocation_id": {
+ "name": "decision_invocation_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "state": {
+ "name": "state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'held'"
+ },
+ "provider_started_at": {
+ "name": "provider_started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "settled_at": {
+ "name": "settled_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "budget_reservations_decision_idx": {
+ "name": "budget_reservations_decision_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "decision_invocation_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "budget_reservations_run_idx": {
+ "name": "budget_reservations_run_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "budget_reservations_active_idx": {
+ "name": "budget_reservations_active_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"budget_reservations\".\"state\" = 'held'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "budget_reservations_company_id_companies_id_fk": {
+ "name": "budget_reservations_company_id_companies_id_fk",
+ "tableFrom": "budget_reservations",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "budget_reservations_run_id_heartbeat_runs_id_fk": {
+ "name": "budget_reservations_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "budget_reservations",
+ "tableTo": "heartbeat_runs",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "budget_reservations_agent_id_agents_id_fk": {
+ "name": "budget_reservations_agent_id_agents_id_fk",
+ "tableFrom": "budget_reservations",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "budget_reservations_source_check": {
+ "name": "budget_reservations_source_check",
+ "value": "(\"budget_reservations\".\"run_id\" is not null)::int + (\"budget_reservations\".\"decision_invocation_id\" is not null)::int = 1"
+ },
+ "budget_reservations_state_check": {
+ "name": "budget_reservations_state_check",
+ "value": "\"budget_reservations\".\"state\" in ('held', 'settled', 'released')"
+ },
+ "budget_reservations_amount_check": {
+ "name": "budget_reservations_amount_check",
+ "value": "\"budget_reservations\".\"amount_cents\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.cost_adjustments": {
+ "name": "cost_adjustments",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cost_event_id": {
+ "name": "cost_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "invoice_line_id": {
+ "name": "invoice_line_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_cents": {
+ "name": "previous_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "corrected_cents": {
+ "name": "corrected_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_status": {
+ "name": "previous_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_pricing": {
+ "name": "previous_pricing",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "reason": {
+ "name": "reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_id": {
+ "name": "actor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pricing": {
+ "name": "pricing",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "cost_adjustments_receipt_idx": {
+ "name": "cost_adjustments_receipt_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_adjustments_event_idx": {
+ "name": "cost_adjustments_event_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "cost_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_adjustments_invoice_line_idx": {
+ "name": "cost_adjustments_invoice_line_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "invoice_line_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "cost_adjustments_company_id_companies_id_fk": {
+ "name": "cost_adjustments_company_id_companies_id_fk",
+ "tableFrom": "cost_adjustments",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "cost_adjustments_cost_event_id_cost_events_id_fk": {
+ "name": "cost_adjustments_cost_event_id_cost_events_id_fk",
+ "tableFrom": "cost_adjustments",
+ "tableTo": "cost_events",
+ "columnsFrom": [
+ "cost_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "cost_adjustments_invoice_line_id_billing_invoice_lines_id_fk": {
+ "name": "cost_adjustments_invoice_line_id_billing_invoice_lines_id_fk",
+ "tableFrom": "cost_adjustments",
+ "tableTo": "billing_invoice_lines",
+ "columnsFrom": [
+ "invoice_line_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "cost_adjustments_amount_check": {
+ "name": "cost_adjustments_amount_check",
+ "value": "\"cost_adjustments\".\"previous_cents\" >= 0 and \"cost_adjustments\".\"corrected_cents\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.provider_billing_snapshots": {
+ "name": "provider_billing_snapshots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope_id": {
+ "name": "scope_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "day": {
+ "name": "day",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "amount_cents": {
+ "name": "amount_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revision": {
+ "name": "revision",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "provider_billing_snapshots_identity_idx": {
+ "name": "provider_billing_snapshots_identity_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "account_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scope_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "day",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "provider_billing_snapshots_company_id_companies_id_fk": {
+ "name": "provider_billing_snapshots_company_id_companies_id_fk",
+ "tableFrom": "provider_billing_snapshots",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "provider_billing_snapshots_amount_check": {
+ "name": "provider_billing_snapshots_amount_check",
+ "value": "\"provider_billing_snapshots\".\"amount_cents\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.run_usage_receipts": {
+ "name": "run_usage_receipts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_id": {
+ "name": "source_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sequence": {
+ "name": "sequence",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "receipt_json": {
+ "name": "receipt_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "complete": {
+ "name": "complete",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "received_at": {
+ "name": "received_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "run_usage_receipts_source_sequence_idx": {
+ "name": "run_usage_receipts_source_sequence_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sequence",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "run_usage_receipts_run_latest_idx": {
+ "name": "run_usage_receipts_run_latest_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "received_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "run_usage_receipts_company_id_companies_id_fk": {
+ "name": "run_usage_receipts_company_id_companies_id_fk",
+ "tableFrom": "run_usage_receipts",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "run_usage_receipts_run_id_heartbeat_runs_id_fk": {
+ "name": "run_usage_receipts_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "run_usage_receipts",
+ "tableTo": "heartbeat_runs",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "run_usage_receipts_positive_sequence": {
+ "name": "run_usage_receipts_positive_sequence",
+ "value": "\"run_usage_receipts\".\"sequence\" > 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
"public.activity_log": {
"name": "activity_log",
"schema": "",
@@ -657,6 +1758,194 @@
"checkConstraints": {},
"isRLSEnabled": false
},
+ "public.agent_commentary": {
+ "name": "agent_commentary",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "body": {
+ "name": "body",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "payload_hash": {
+ "name": "payload_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "agent_commentary_run_key_uq": {
+ "name": "agent_commentary_run_key_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "agent_commentary_company_kind_created_idx": {
+ "name": "agent_commentary_company_kind_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "agent_commentary_company_id_companies_id_fk": {
+ "name": "agent_commentary_company_id_companies_id_fk",
+ "tableFrom": "agent_commentary",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "agent_commentary_agent_id_agents_id_fk": {
+ "name": "agent_commentary_agent_id_agents_id_fk",
+ "tableFrom": "agent_commentary",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "agent_commentary_run_id_heartbeat_runs_id_fk": {
+ "name": "agent_commentary_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "agent_commentary",
+ "tableTo": "heartbeat_runs",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "agent_commentary_issue_id_issues_id_fk": {
+ "name": "agent_commentary_issue_id_issues_id_fk",
+ "tableFrom": "agent_commentary",
+ "tableTo": "issues",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "agent_commentary_kind_check": {
+ "name": "agent_commentary_kind_check",
+ "value": "\"agent_commentary\".\"kind\" in ('complaint', 'suggestion')"
+ }
+ },
+ "isRLSEnabled": false
+ },
"public.agent_config_revisions": {
"name": "agent_config_revisions",
"schema": "",
@@ -1632,7 +2921,7 @@
},
"total_cost_cents": {
"name": "total_cost_cents",
- "type": "bigint",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true,
"default": 0
@@ -2671,9 +3960,15 @@
"notNull": true,
"default": 0
},
+ "spend_month_utc": {
+ "name": "spend_month_utc",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
"spent_monthly_cents": {
"name": "spent_monthly_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true,
"default": 0
@@ -5074,7 +6369,7 @@
},
"amount_observed": {
"name": "amount_observed",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true
},
@@ -5190,7 +6485,7 @@
}
],
"isUnique": true,
- "where": "\"budget_incidents\".\"status\" <> 'dismissed'",
+ "where": "\"budget_incidents\".\"status\" = 'open'",
"concurrently": false,
"method": "btree",
"with": {}
@@ -5292,6 +6587,13 @@
"notNull": true,
"default": 0
},
+ "reservation_cents": {
+ "name": "reservation_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
"warn_percent": {
"name": "warn_percent",
"type": "integer",
@@ -5306,6 +6608,13 @@
"notNull": true,
"default": true
},
+ "unpriced_usage_policy": {
+ "name": "unpriced_usage_policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'block'"
+ },
"notify_enabled": {
"name": "notify_enabled",
"type": "boolean",
@@ -5320,6 +6629,20 @@
"notNull": true,
"default": true
},
+ "enforcement_version": {
+ "name": "enforcement_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "enforcement_delivered_version": {
+ "name": "enforcement_delivered_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
"created_by_user_id": {
"name": "created_by_user_id",
"type": "text",
@@ -5466,7 +6789,12 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
- "checkConstraints": {},
+ "checkConstraints": {
+ "budget_policies_reservation_nonnegative": {
+ "name": "budget_policies_reservation_nonnegative",
+ "value": "\"budget_policies\".\"reservation_cents\" >= 0"
+ }
+ },
"isRLSEnabled": false
},
"public.built_in_managed_resources": {
@@ -11118,9 +12446,15 @@
"notNull": true,
"default": 0
},
+ "spend_month_utc": {
+ "name": "spend_month_utc",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
"spent_monthly_cents": {
"name": "spent_monthly_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true,
"default": 0
@@ -15981,7 +17315,20 @@
"name": "agent_id",
"type": "uuid",
"primaryKey": false,
- "notNull": true
+ "notNull": false
+ },
+ "usage_kind": {
+ "name": "usage_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'agent'"
+ },
+ "responsible_user_id": {
+ "name": "responsible_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
},
"issue_id": {
"name": "issue_id",
@@ -16013,6 +17360,36 @@
"primaryKey": false,
"notNull": false
},
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_request_id": {
+ "name": "provider_request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "reported_cost_cents": {
+ "name": "reported_cost_cents",
+ "type": "numeric(24, 7)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "pricing_provenance": {
+ "name": "pricing_provenance",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
"provider": {
"name": "provider",
"type": "text",
@@ -16069,7 +17446,7 @@
},
"cost_cents": {
"name": "cost_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true
},
@@ -16088,6 +17465,109 @@
}
},
"indexes": {
+ "cost_events_company_receipt_idx": {
+ "name": "cost_events_company_receipt_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_events_provider_request_idx": {
+ "name": "cost_events_provider_request_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "biller",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_request_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_events_company_project_occurred_idx": {
+ "name": "cost_events_company_project_occurred_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "occurred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "cost_events_unpriced_idx": {
+ "name": "cost_events_unpriced_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "occurred_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"cost_events\".\"cost_status\" = 'unpriced' and \"cost_events\".\"billing_type\" <> 'subscription_included'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"cost_events_company_occurred_idx": {
"name": "cost_events_company_occurred_idx",
"columns": [
@@ -16295,7 +17775,356 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
- "checkConstraints": {},
+ "checkConstraints": {
+ "cost_events_usage_kind_check": {
+ "name": "cost_events_usage_kind_check",
+ "value": "\"cost_events\".\"usage_kind\" = 'decision' or (\"cost_events\".\"usage_kind\" = 'agent' and \"cost_events\".\"agent_id\" is not null)"
+ },
+ "cost_events_nonnegative_amounts": {
+ "name": "cost_events_nonnegative_amounts",
+ "value": "\"cost_events\".\"cost_cents\" >= 0 and \"cost_events\".\"input_tokens\" >= 0 and \"cost_events\".\"cached_input_tokens\" >= 0 and \"cost_events\".\"output_tokens\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.company_decision_models": {
+ "name": "company_decision_models",
+ "schema": "",
+ "columns": {
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "grant_id": {
+ "name": "grant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "allow_background": {
+ "name": "allow_background",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "model": {
+ "name": "model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "company_decision_models_company_id_companies_id_fk": {
+ "name": "company_decision_models_company_id_companies_id_fk",
+ "tableFrom": "company_decision_models",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "company_decisions_configured": {
+ "name": "company_decisions_configured",
+ "value": "(\"company_decision_models\".\"connection_id\" is null) = (\"company_decision_models\".\"grant_id\" is null) and (not \"company_decision_models\".\"enabled\" or (\"company_decision_models\".\"connection_id\" is not null and \"company_decision_models\".\"provider\" is not null and \"company_decision_models\".\"model\" is not null))"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.decision_invocations": {
+ "name": "decision_invocations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "feature": {
+ "name": "feature",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_type": {
+ "name": "actor_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_id": {
+ "name": "actor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "responsible_user_id": {
+ "name": "responsible_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "identity_context_id": {
+ "name": "identity_context_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "grant_id": {
+ "name": "grant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "model": {
+ "name": "model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "question_types": {
+ "name": "question_types",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'running'"
+ },
+ "error_code": {
+ "name": "error_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_request_id": {
+ "name": "provider_request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cost_event_id": {
+ "name": "cost_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "finished_at": {
+ "name": "finished_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "duration_ms": {
+ "name": "duration_ms",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "input_tokens": {
+ "name": "input_tokens",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "output_tokens": {
+ "name": "output_tokens",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "decision_invocations_company_started_idx": {
+ "name": "decision_invocations_company_started_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "decision_invocations_pending_idx": {
+ "name": "decision_invocations_pending_idx",
+ "columns": [
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"decision_invocations\".\"status\" = 'running'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "decision_invocations_cost_idx": {
+ "name": "decision_invocations_cost_idx",
+ "columns": [
+ {
+ "expression": "cost_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "decision_invocations_company_id_companies_id_fk": {
+ "name": "decision_invocations_company_id_companies_id_fk",
+ "tableFrom": "decision_invocations",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "decision_invocations_cost_event_id_cost_events_id_fk": {
+ "name": "decision_invocations_cost_event_id_cost_events_id_fk",
+ "tableFrom": "decision_invocations",
+ "tableTo": "cost_events",
+ "columnsFrom": [
+ "cost_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "decision_invocations_status_check": {
+ "name": "decision_invocations_status_check",
+ "value": "\"decision_invocations\".\"status\" in ('running', 'succeeded', 'failed', 'unknown')"
+ }
+ },
"isRLSEnabled": false
},
"public.decision_archive_notification_outbox": {
@@ -20173,6 +22002,746 @@
"checkConstraints": {},
"isRLSEnabled": false
},
+ "public.dot_agent_bindings": {
+ "name": "dot_agent_bindings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "operator_id": {
+ "name": "operator_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "grant_id": {
+ "name": "grant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "generation": {
+ "name": "generation",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pairing'"
+ },
+ "pairing_code_hash": {
+ "name": "pairing_code_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "pairing_expires_at": {
+ "name": "pairing_expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "dot_url": {
+ "name": "dot_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "challenge_hash": {
+ "name": "challenge_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "challenge_expires_at": {
+ "name": "challenge_expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ready_at": {
+ "name": "ready_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "dot_bindings_active_agent_uq": {
+ "name": "dot_bindings_active_agent_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"dot_agent_bindings\".\"revoked_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "dot_bindings_active_grant_uq": {
+ "name": "dot_bindings_active_grant_uq",
+ "columns": [
+ {
+ "expression": "grant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"dot_agent_bindings\".\"revoked_at\" IS NULL AND \"dot_agent_bindings\".\"grant_id\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "dot_bindings_pairing_code_uq": {
+ "name": "dot_bindings_pairing_code_uq",
+ "columns": [
+ {
+ "expression": "pairing_code_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "dot_agent_bindings_company_id_companies_id_fk": {
+ "name": "dot_agent_bindings_company_id_companies_id_fk",
+ "tableFrom": "dot_agent_bindings",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "dot_agent_bindings_agent_id_agents_id_fk": {
+ "name": "dot_agent_bindings_agent_id_agents_id_fk",
+ "tableFrom": "dot_agent_bindings",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "dot_agent_bindings_grant_id_mcp_oauth_grants_id_fk": {
+ "name": "dot_agent_bindings_grant_id_mcp_oauth_grants_id_fk",
+ "tableFrom": "dot_agent_bindings",
+ "tableTo": "mcp_oauth_grants",
+ "columnsFrom": [
+ "grant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.dot_mailbox_items": {
+ "name": "dot_mailbox_items",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "binding_id": {
+ "name": "binding_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "binding_generation": {
+ "name": "binding_generation",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "assignment_id": {
+ "name": "assignment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_event_id": {
+ "name": "source_event_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "references": {
+ "name": "references",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "dot_mailbox_event_uq": {
+ "name": "dot_mailbox_event_uq",
+ "columns": [
+ {
+ "expression": "binding_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "binding_generation",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "dot_mailbox_binding_cursor_idx": {
+ "name": "dot_mailbox_binding_cursor_idx",
+ "columns": [
+ {
+ "expression": "binding_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "binding_generation",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "dot_mailbox_items_company_id_companies_id_fk": {
+ "name": "dot_mailbox_items_company_id_companies_id_fk",
+ "tableFrom": "dot_mailbox_items",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "dot_mailbox_items_binding_id_dot_agent_bindings_id_fk": {
+ "name": "dot_mailbox_items_binding_id_dot_agent_bindings_id_fk",
+ "tableFrom": "dot_mailbox_items",
+ "tableTo": "dot_agent_bindings",
+ "columnsFrom": [
+ "binding_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "dot_mailbox_items_assignment_id_dot_runner_assignments_id_fk": {
+ "name": "dot_mailbox_items_assignment_id_dot_runner_assignments_id_fk",
+ "tableFrom": "dot_mailbox_items",
+ "tableTo": "dot_runner_assignments",
+ "columnsFrom": [
+ "assignment_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.dot_runner_assignments": {
+ "name": "dot_runner_assignments",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "binding_id": {
+ "name": "binding_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "binding_generation": {
+ "name": "binding_generation",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "normalized_session_id": {
+ "name": "normalized_session_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "turn_id": {
+ "name": "turn_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revision": {
+ "name": "revision",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "controller_generation": {
+ "name": "controller_generation",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "catalog_digest": {
+ "name": "catalog_digest",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "projection": {
+ "name": "projection",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "accept_by": {
+ "name": "accept_by",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "accepted_at": {
+ "name": "accepted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "settled_at": {
+ "name": "settled_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_activity_at": {
+ "name": "last_activity_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "dot_assignments_turn_uq": {
+ "name": "dot_assignments_turn_uq",
+ "columns": [
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "turn_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "dot_assignments_active_binding_uq": {
+ "name": "dot_assignments_active_binding_uq",
+ "columns": [
+ {
+ "expression": "binding_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"dot_runner_assignments\".\"status\" IN ('offered', 'accepted')",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "dot_assignments_company_idx": {
+ "name": "dot_assignments_company_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "dot_runner_assignments_company_id_companies_id_fk": {
+ "name": "dot_runner_assignments_company_id_companies_id_fk",
+ "tableFrom": "dot_runner_assignments",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "dot_runner_assignments_binding_id_dot_agent_bindings_id_fk": {
+ "name": "dot_runner_assignments_binding_id_dot_agent_bindings_id_fk",
+ "tableFrom": "dot_runner_assignments",
+ "tableTo": "dot_agent_bindings",
+ "columnsFrom": [
+ "binding_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "dot_runner_assignments_run_id_heartbeat_runs_id_fk": {
+ "name": "dot_runner_assignments_run_id_heartbeat_runs_id_fk",
+ "tableFrom": "dot_runner_assignments",
+ "tableTo": "heartbeat_runs",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "dot_runner_assignments_agent_id_agents_id_fk": {
+ "name": "dot_runner_assignments_agent_id_agents_id_fk",
+ "tableFrom": "dot_runner_assignments",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.dot_runner_operations": {
+ "name": "dot_runner_operations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "assignment_id": {
+ "name": "assignment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "request_id": {
+ "name": "request_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "digest": {
+ "name": "digest",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "command": {
+ "name": "command",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'reserved'"
+ },
+ "outcome": {
+ "name": "outcome",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_event_id": {
+ "name": "source_event_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "dot_operations_request_uq": {
+ "name": "dot_operations_request_uq",
+ "columns": [
+ {
+ "expression": "assignment_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "request_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "dot_runner_operations_company_id_companies_id_fk": {
+ "name": "dot_runner_operations_company_id_companies_id_fk",
+ "tableFrom": "dot_runner_operations",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "dot_runner_operations_assignment_id_dot_runner_assignments_id_fk": {
+ "name": "dot_runner_operations_assignment_id_dot_runner_assignments_id_fk",
+ "tableFrom": "dot_runner_operations",
+ "tableTo": "dot_runner_assignments",
+ "columnsFrom": [
+ "assignment_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
"public.email_endpoints": {
"name": "email_endpoints",
"schema": "",
@@ -23533,6 +26102,18 @@
"primaryKey": false,
"notNull": false
},
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "receipt_hash": {
+ "name": "receipt_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
"billing_code": {
"name": "billing_code",
"type": "text",
@@ -23608,7 +26189,7 @@
},
"amount_cents": {
"name": "amount_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true
},
@@ -23653,6 +26234,27 @@
}
},
"indexes": {
+ "finance_events_company_receipt_idx": {
+ "name": "finance_events_company_receipt_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"finance_events_company_occurred_idx": {
"name": "finance_events_company_occurred_idx",
"columns": [
@@ -24799,6 +27401,19 @@
"primaryKey": false,
"notNull": true
},
+ "scope_kind": {
+ "name": "scope_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'company'"
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
"invocation_source": {
"name": "invocation_source",
"type": "text",
@@ -24879,6 +27494,44 @@
"primaryKey": false,
"notNull": false
},
+ "cost_accounting_pending": {
+ "name": "cost_accounting_pending",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "cost_accounted_at": {
+ "name": "cost_accounted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_projection_version": {
+ "name": "accounting_projection_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_last_attempt_at": {
+ "name": "accounting_last_attempt_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_last_error": {
+ "name": "accounting_last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accounting_attempt_count": {
+ "name": "accounting_attempt_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
"usage_json": {
"name": "usage_json",
"type": "jsonb",
@@ -25215,6 +27868,28 @@
}
},
"indexes": {
+ "heartbeat_runs_cost_accounting_pending_idx": {
+ "name": "heartbeat_runs_cost_accounting_pending_idx",
+ "columns": [
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"heartbeat_runs\".\"cost_accounting_pending\" = true",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"heartbeat_runs_execution_status_delivery_idx": {
"name": "heartbeat_runs_execution_status_delivery_idx",
"columns": [
@@ -25296,6 +27971,33 @@
"method": "btree",
"with": {}
},
+ "heartbeat_runs_company_issue_created_idx": {
+ "name": "heartbeat_runs_company_issue_created_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"heartbeat_runs_company_responsible_user_idx": {
"name": "heartbeat_runs_company_responsible_user_idx",
"columns": [
@@ -25534,6 +28236,19 @@
"onDelete": "no action",
"onUpdate": "no action"
},
+ "heartbeat_runs_issue_id_issues_id_fk": {
+ "name": "heartbeat_runs_issue_id_issues_id_fk",
+ "tableFrom": "heartbeat_runs",
+ "tableTo": "issues",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
"heartbeat_runs_wakeup_request_id_agent_wakeup_requests_id_fk": {
"name": "heartbeat_runs_wakeup_request_id_agent_wakeup_requests_id_fk",
"tableFrom": "heartbeat_runs",
@@ -25584,7 +28299,12 @@
}
},
"policies": {},
- "checkConstraints": {},
+ "checkConstraints": {
+ "heartbeat_runs_scope_binding_check": {
+ "name": "heartbeat_runs_scope_binding_check",
+ "value": "(\"heartbeat_runs\".\"scope_kind\" = 'company' AND \"heartbeat_runs\".\"issue_id\" IS NULL)\n OR \"heartbeat_runs\".\"scope_kind\" = 'issue'"
+ }
+ },
"isRLSEnabled": false
},
"public.inbox_dismissals": {
@@ -27027,6 +29747,166 @@
"checkConstraints": {},
"isRLSEnabled": false
},
+ "public.issue_access_grants": {
+ "name": "issue_access_grants",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "issue_id": {
+ "name": "issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_type": {
+ "name": "subject_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_id": {
+ "name": "subject_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source": {
+ "name": "source",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "granted_by_user_id": {
+ "name": "granted_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "granted_by_agent_id": {
+ "name": "granted_by_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "issue_access_grants_subject_active_issue_idx": {
+ "name": "issue_access_grants_subject_active_issue_idx",
+ "columns": [
+ {
+ "expression": "subject_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "revoked_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "issue_access_grants_issue_idx": {
+ "name": "issue_access_grants_issue_idx",
+ "columns": [
+ {
+ "expression": "issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "issue_access_grants_issue_id_issues_id_fk": {
+ "name": "issue_access_grants_issue_id_issues_id_fk",
+ "tableFrom": "issue_access_grants",
+ "tableTo": "issues",
+ "columnsFrom": [
+ "issue_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "issue_access_grants_granted_by_agent_id_agents_id_fk": {
+ "name": "issue_access_grants_granted_by_agent_id_agents_id_fk",
+ "tableFrom": "issue_access_grants",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "granted_by_agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "issue_access_grants_subject_type_check": {
+ "name": "issue_access_grants_subject_type_check",
+ "value": "\"issue_access_grants\".\"subject_type\" in ('user', 'agent')"
+ },
+ "issue_access_grants_source_check": {
+ "name": "issue_access_grants_source_check",
+ "value": "\"issue_access_grants\".\"source\" in ('explicit', 'assignment', 'project')"
+ }
+ },
+ "isRLSEnabled": false
+ },
"public.issue_approvals": {
"name": "issue_approvals",
"schema": "",
@@ -31899,6 +34779,25 @@
"primaryKey": false,
"notNull": false
},
+ "visibility": {
+ "name": "visibility",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'open'"
+ },
+ "privacy_root_issue_id": {
+ "name": "privacy_root_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "privacy_parent_issue_id": {
+ "name": "privacy_parent_issue_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
"title": {
"name": "title",
"type": "text",
@@ -32383,6 +35282,48 @@
"method": "btree",
"with": {}
},
+ "issues_company_privacy_parent_idx": {
+ "name": "issues_company_privacy_parent_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "privacy_parent_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "issues_company_privacy_root_idx": {
+ "name": "issues_company_privacy_root_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "privacy_root_issue_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"issues_company_project_idx": {
"name": "issues_company_project_idx",
"columns": [
@@ -32952,6 +35893,32 @@
"onDelete": "no action",
"onUpdate": "no action"
},
+ "issues_privacy_root_issue_id_issues_id_fk": {
+ "name": "issues_privacy_root_issue_id_issues_id_fk",
+ "tableFrom": "issues",
+ "tableTo": "issues",
+ "columnsFrom": [
+ "privacy_root_issue_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "issues_privacy_parent_issue_id_issues_id_fk": {
+ "name": "issues_privacy_parent_issue_id_issues_id_fk",
+ "tableFrom": "issues",
+ "tableTo": "issues",
+ "columnsFrom": [
+ "privacy_parent_issue_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
"issues_assignee_agent_id_agents_id_fk": {
"name": "issues_assignee_agent_id_agents_id_fk",
"tableFrom": "issues",
@@ -33031,6 +35998,10 @@
},
"policies": {},
"checkConstraints": {
+ "issues_visibility_check": {
+ "name": "issues_visibility_check",
+ "value": "\"issues\".\"visibility\" in ('open', 'private')"
+ },
"issues_conversation_identity_check": {
"name": "issues_conversation_identity_check",
"value": "(\n \"issues\".\"conversation_agent_id\" is null and \"issues\".\"conversation_user_id\" is null and \"issues\".\"conversation_state\" is null\n ) or (\n \"issues\".\"conversation_agent_id\" is not null and \"issues\".\"conversation_user_id\" is not null\n and \"issues\".\"assignee_agent_id\" = \"issues\".\"conversation_agent_id\" and \"issues\".\"assignee_agent_id\" is not null\n and \"issues\".\"assignee_user_id\" is null and \"issues\".\"conversation_state\" is not null\n and \"issues\".\"conversation_state\" in ('active', 'waiting')\n and \"issues\".\"status\" not in ('done', 'cancelled')\n )"
@@ -37202,6 +40173,89 @@
"checkConstraints": {},
"isRLSEnabled": false
},
+ "public.plugin_lifecycle_acknowledgments": {
+ "name": "plugin_lifecycle_acknowledgments",
+ "schema": "",
+ "columns": {
+ "plugin_id": {
+ "name": "plugin_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "event_id": {
+ "name": "event_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "acknowledged_at": {
+ "name": "acknowledged_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "plugin_lifecycle_acknowledgments_event_idx": {
+ "name": "plugin_lifecycle_acknowledgments_event_idx",
+ "columns": [
+ {
+ "expression": "event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "plugin_lifecycle_acknowledgments_plugin_id_plugins_id_fk": {
+ "name": "plugin_lifecycle_acknowledgments_plugin_id_plugins_id_fk",
+ "tableFrom": "plugin_lifecycle_acknowledgments",
+ "tableTo": "plugins",
+ "columnsFrom": [
+ "plugin_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "plugin_lifecycle_acknowledgments_event_id_resource_lifecycle_events_id_fk": {
+ "name": "plugin_lifecycle_acknowledgments_event_id_resource_lifecycle_events_id_fk",
+ "tableFrom": "plugin_lifecycle_acknowledgments",
+ "tableTo": "resource_lifecycle_events",
+ "columnsFrom": [
+ "event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "plugin_lifecycle_acknowledgments_plugin_id_event_id_pk": {
+ "name": "plugin_lifecycle_acknowledgments_plugin_id_event_id_pk",
+ "columns": [
+ "plugin_id",
+ "event_id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
"public.plugin_logs": {
"name": "plugin_logs",
"schema": "",
@@ -38237,6 +41291,150 @@
"checkConstraints": {},
"isRLSEnabled": false
},
+ "public.project_access_members": {
+ "name": "project_access_members",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_id": {
+ "name": "project_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_type": {
+ "name": "subject_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_id": {
+ "name": "subject_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "project_access_members_project_subject_uq": {
+ "name": "project_access_members_project_subject_uq",
+ "columns": [
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "project_access_members_subject_lookup_idx": {
+ "name": "project_access_members_subject_lookup_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "subject_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "project_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "project_access_members_company_id_companies_id_fk": {
+ "name": "project_access_members_company_id_companies_id_fk",
+ "tableFrom": "project_access_members",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "project_access_members_project_id_projects_id_fk": {
+ "name": "project_access_members_project_id_projects_id_fk",
+ "tableFrom": "project_access_members",
+ "tableTo": "projects",
+ "columnsFrom": [
+ "project_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "project_access_members_subject_type_check": {
+ "name": "project_access_members_subject_type_check",
+ "value": "\"project_access_members\".\"subject_type\" in ('user', 'agent')"
+ }
+ },
+ "isRLSEnabled": false
+ },
"public.project_goals": {
"name": "project_goals",
"schema": "",
@@ -38866,6 +42064,25 @@
"primaryKey": false,
"notNull": false
},
+ "visibility": {
+ "name": "visibility",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'open'"
+ },
+ "privacy_owner_user_id": {
+ "name": "privacy_owner_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "personal_owner_user_id": {
+ "name": "personal_owner_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
"status": {
"name": "status",
"type": "text",
@@ -38957,6 +42174,28 @@
"concurrently": false,
"method": "btree",
"with": {}
+ },
+ "projects_company_personal_owner_uq": {
+ "name": "projects_company_personal_owner_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "personal_owner_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"projects\".\"personal_owner_user_id\" is not null",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
}
},
"foreignKeys": {
@@ -39003,7 +42242,12 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
- "checkConstraints": {},
+ "checkConstraints": {
+ "projects_visibility_check": {
+ "name": "projects_visibility_check",
+ "value": "\"projects\".\"visibility\" in ('open', 'private')"
+ }
+ },
"isRLSEnabled": false
},
"public.provider_trace_records": {
@@ -39460,6 +42704,39 @@
"concurrently": false,
"method": "btree",
"with": {}
+ },
+ "resource_lifecycle_events_resource_order_idx": {
+ "name": "resource_lifecycle_events_resource_order_idx",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
}
},
"foreignKeys": {
@@ -42086,7 +45363,7 @@
},
"cost_cents": {
"name": "cost_cents",
- "type": "integer",
+ "type": "numeric(24, 7)",
"primaryKey": false,
"notNull": true,
"default": 0
@@ -49505,6 +52782,129 @@
"checkConstraints": {},
"isRLSEnabled": false
},
+ "public.user_company_preferences": {
+ "name": "user_company_preferences",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "primary_agent_id": {
+ "name": "primary_agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "primary_agent_initialized": {
+ "name": "primary_agent_initialized",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "user_company_preferences_company_user_uq": {
+ "name": "user_company_preferences_company_user_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "user_company_preferences_primary_agent_idx": {
+ "name": "user_company_preferences_primary_agent_idx",
+ "columns": [
+ {
+ "expression": "primary_agent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "user_company_preferences_company_id_companies_id_fk": {
+ "name": "user_company_preferences_company_id_companies_id_fk",
+ "tableFrom": "user_company_preferences",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "user_company_preferences_primary_agent_id_agents_id_fk": {
+ "name": "user_company_preferences_primary_agent_id_agents_id_fk",
+ "tableFrom": "user_company_preferences",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "primary_agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
"public.user_inbox_agent_policies": {
"name": "user_inbox_agent_policies",
"schema": "",
@@ -51189,6 +54589,187 @@
"checkConstraints": {},
"isRLSEnabled": false
},
+ "public.mcp_attachment_uploads": {
+ "name": "mcp_attachment_uploads",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "request_id": {
+ "name": "request_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "task_id": {
+ "name": "task_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "arguments_hash": {
+ "name": "arguments_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "original_filename": {
+ "name": "original_filename",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content_type": {
+ "name": "content_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "byte_size": {
+ "name": "byte_size",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sha256": {
+ "name": "sha256",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "attachment_id": {
+ "name": "attachment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "object_key": {
+ "name": "object_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "storage_provider": {
+ "name": "storage_provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cleaned_at": {
+ "name": "cleaned_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "mcp_attachment_upload_request_uq": {
+ "name": "mcp_attachment_upload_request_uq",
+ "columns": [
+ {
+ "expression": "company_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "request_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "mcp_attachment_upload_expiry_idx": {
+ "name": "mcp_attachment_upload_expiry_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "mcp_attachment_uploads_company_id_companies_id_fk": {
+ "name": "mcp_attachment_uploads_company_id_companies_id_fk",
+ "tableFrom": "mcp_attachment_uploads",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "mcp_attachment_uploads_user_id_user_id_fk": {
+ "name": "mcp_attachment_uploads_user_id_user_id_fk",
+ "tableFrom": "mcp_attachment_uploads",
+ "tableTo": "user",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
"public.mcp_event_admissions": {
"name": "mcp_event_admissions",
"schema": "",
@@ -51346,7 +54927,13 @@
"name": "activity_id",
"type": "uuid",
"primaryKey": false,
- "notNull": true
+ "notNull": false
+ },
+ "mailbox_item_id": {
+ "name": "mailbox_item_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
},
"event": {
"name": "event",
@@ -51382,6 +54969,27 @@
}
},
"indexes": {
+ "mcp_event_deliveries_mailbox_uq": {
+ "name": "mcp_event_deliveries_mailbox_uq",
+ "columns": [
+ {
+ "expression": "subscription_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "mailbox_item_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
"mcp_event_deliveries_activity_uq": {
"name": "mcp_event_deliveries_activity_uq",
"columns": [
@@ -51437,7 +55045,12 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
- "checkConstraints": {},
+ "checkConstraints": {
+ "mcp_delivery_source_check": {
+ "name": "mcp_delivery_source_check",
+ "value": "(\"mcp_event_deliveries\".\"activity_id\" IS NOT NULL AND \"mcp_event_deliveries\".\"mailbox_item_id\" IS NULL) OR (\"mcp_event_deliveries\".\"activity_id\" IS NULL AND \"mcp_event_deliveries\".\"mailbox_item_id\" IS NOT NULL)"
+ }
+ },
"isRLSEnabled": false
},
"public.mcp_event_subscriptions": {
@@ -51472,7 +55085,13 @@
"name": "task_id",
"type": "uuid",
"primaryKey": false,
- "notNull": true
+ "notNull": false
+ },
+ "binding_id": {
+ "name": "binding_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
},
"arguments": {
"name": "arguments",
@@ -51582,6 +55201,138 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
+ "checkConstraints": {
+ "mcp_subscription_resource_check": {
+ "name": "mcp_subscription_resource_check",
+ "value": "(\"mcp_event_subscriptions\".\"task_id\" IS NOT NULL AND \"mcp_event_subscriptions\".\"binding_id\" IS NULL) OR (\"mcp_event_subscriptions\".\"task_id\" IS NULL AND \"mcp_event_subscriptions\".\"binding_id\" IS NOT NULL)"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.mcp_file_tickets": {
+ "name": "mcp_file_tickets",
+ "schema": "",
+ "columns": {
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "company_id": {
+ "name": "company_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "grant_id": {
+ "name": "grant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "upload_id": {
+ "name": "upload_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "attachment_id": {
+ "name": "attachment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "mcp_file_ticket_expiry_idx": {
+ "name": "mcp_file_ticket_expiry_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "mcp_file_ticket_grant_idx": {
+ "name": "mcp_file_ticket_grant_idx",
+ "columns": [
+ {
+ "expression": "grant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "mcp_file_tickets_company_id_companies_id_fk": {
+ "name": "mcp_file_tickets_company_id_companies_id_fk",
+ "tableFrom": "mcp_file_tickets",
+ "tableTo": "companies",
+ "columnsFrom": [
+ "company_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "mcp_file_tickets_grant_id_mcp_oauth_grants_id_fk": {
+ "name": "mcp_file_tickets_grant_id_mcp_oauth_grants_id_fk",
+ "tableFrom": "mcp_file_tickets",
+ "tableTo": "mcp_oauth_grants",
+ "columnsFrom": [
+ "grant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "mcp_file_tickets_upload_id_mcp_attachment_uploads_id_fk": {
+ "name": "mcp_file_tickets_upload_id_mcp_attachment_uploads_id_fk",
+ "tableFrom": "mcp_file_tickets",
+ "tableTo": "mcp_attachment_uploads",
+ "columnsFrom": [
+ "upload_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
@@ -52011,6 +55762,19 @@
"primaryKey": false,
"notNull": true
},
+ "purpose": {
+ "name": "purpose",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'personal'"
+ },
+ "agent_id": {
+ "name": "agent_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
"scopes": {
"name": "scopes",
"type": "jsonb",
@@ -52093,6 +55857,19 @@
],
"onDelete": "cascade",
"onUpdate": "no action"
+ },
+ "mcp_oauth_grants_agent_id_agents_id_fk": {
+ "name": "mcp_oauth_grants_agent_id_agents_id_fk",
+ "tableFrom": "mcp_oauth_grants",
+ "tableTo": "agents",
+ "columnsFrom": [
+ "agent_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
diff --git a/packages/db/src/migrations/meta/_journal.json b/packages/db/src/migrations/meta/_journal.json
index 18aced95545..7bf80868714 100644
--- a/packages/db/src/migrations/meta/_journal.json
+++ b/packages/db/src/migrations/meta/_journal.json
@@ -2175,8 +2175,43 @@
{
"idx": 312,
"version": "7",
- "when": 1791339842209,
- "tag": "0312_broken_sentinels",
+ "when": 1791336871975,
+ "tag": "0312_easy_eternity",
+ "breakpoints": true
+ },
+ {
+ "idx": 313,
+ "version": "7",
+ "when": 1791371746435,
+ "tag": "0313_private_task_access",
+ "breakpoints": true
+ },
+ {
+ "idx": 314,
+ "version": "7",
+ "when": 1791371819805,
+ "tag": "0314_private_task_draft_assets",
+ "breakpoints": true
+ },
+ {
+ "idx": 315,
+ "version": "7",
+ "when": 1791390905429,
+ "tag": "0315_rapid_emma_frost",
+ "breakpoints": true
+ },
+ {
+ "idx": 316,
+ "version": "7",
+ "when": 1791400295370,
+ "tag": "0316_premium_slayback",
+ "breakpoints": true
+ },
+ {
+ "idx": 317,
+ "version": "7",
+ "when": 1791416259455,
+ "tag": "0317_messy_famine",
"breakpoints": true
}
]
diff --git a/packages/db/src/private-task-draft-assets-migration.test.ts b/packages/db/src/private-task-draft-assets-migration.test.ts
new file mode 100644
index 00000000000..54007d4c788
--- /dev/null
+++ b/packages/db/src/private-task-draft-assets-migration.test.ts
@@ -0,0 +1,35 @@
+import { createHash, randomUUID } from "node:crypto";
+import fs from "node:fs/promises";
+import postgres from "postgres";
+import { expect, it } from "vitest";
+import { applyPendingMigrations } from "./client.js";
+import { getEmbeddedPostgresTestSupport, startEmbeddedPostgresTestDatabase } from "./test-embedded-postgres.js";
+
+const embeddedPostgresSupport = await getEmbeddedPostgresTestSupport();
+const itEmbeddedPostgres = embeddedPostgresSupport.supported ? it : it.skip;
+
+itEmbeddedPostgres("backfills owned draft images without attaching another uploader's images", async () => {
+ const database = await startEmbeddedPostgresTestDatabase("paperclip-draft-privacy-");
+ const sql = postgres(database.connectionString, { max: 1, onnotice: () => {} });
+ try {
+ const migration = await fs.readFile(new URL("./migrations/0314_private_task_draft_assets.sql", import.meta.url), "utf8");
+ const hash = createHash("sha256").update(migration).digest("hex");
+ const company = randomUUID(), task = randomUUID(), owned = randomUUID(), foreign = randomUUID();
+ await sql`INSERT INTO companies (id, name, issue_prefix) VALUES (${company}, 'Draft privacy', 'DRAFT')`;
+ for (const [id, owner] of [[owned, 'owner'], [foreign, 'someone-else']]) {
+ await sql`INSERT INTO assets (id, company_id, provider, object_key, content_type, byte_size, sha256, created_by_user_id)
+ VALUES (${id}, ${company}, 'local_disk', ${`${company}/assets/issues/drafts/${id}`}, 'image/png', 1, 'test', ${owner})`;
+ }
+ await sql`INSERT INTO issues (id, company_id, title, description, visibility, created_by_user_id)
+ VALUES (${task}, ${company}, 'Private task', ${` `}, 'private', 'owner')`;
+ for (let run = 0; run < 2; run += 1) {
+ await sql`DELETE FROM drizzle.__drizzle_migrations WHERE hash = ${hash}`;
+ await applyPendingMigrations(database.connectionString);
+ expect(await sql`SELECT issue_id, asset_id FROM issue_attachments WHERE company_id = ${company}`)
+ .toEqual([{ issue_id: task, asset_id: owned }]);
+ }
+ } finally {
+ await sql.end();
+ await database.cleanup();
+ }
+}, 60_000);
diff --git a/packages/db/src/schema/accounting.ts b/packages/db/src/schema/accounting.ts
new file mode 100644
index 00000000000..4bbce6d05ea
--- /dev/null
+++ b/packages/db/src/schema/accounting.ts
@@ -0,0 +1,124 @@
+import { sql } from "drizzle-orm";
+import { boolean, check, index, integer, jsonb, numeric, pgTable, text, timestamp, uniqueIndex, uuid } from "drizzle-orm/pg-core";
+import { companies } from "./companies.js";
+import { agents } from "./agents.js";
+import { heartbeatRuns } from "./heartbeat_runs.js";
+
+export const providerBillingSnapshots = pgTable("provider_billing_snapshots", {
+ id: uuid("id").primaryKey().defaultRandom(),
+ companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }),
+ provider: text("provider").notNull(),
+ accountId: text("account_id").notNull(),
+ scopeId: text("scope_id").notNull(),
+ day: text("day").notNull(),
+ amountCents: numeric("amount_cents", { precision: 24, scale: 7 }).notNull(),
+ revision: integer("revision").notNull().default(1),
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
+}, table => ({
+ identity: uniqueIndex("provider_billing_snapshots_identity_idx").on(table.companyId, table.provider, table.accountId, table.scopeId, table.day),
+ amount: check("provider_billing_snapshots_amount_check", sql`${table.amountCents} >= 0`),
+}));
+import { costEvents } from "./cost_events.js";
+
+export const runUsageReceipts = pgTable("run_usage_receipts", {
+ id: uuid("id").primaryKey(),
+ companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }),
+ runId: uuid("run_id").notNull().references(() => heartbeatRuns.id, { onDelete: "cascade" }),
+ sourceId: uuid("source_id").notNull(),
+ sequence: integer("sequence").notNull(),
+ receiptHash: text("receipt_hash").notNull(),
+ receiptJson: jsonb("receipt_json").$type>().notNull(),
+ complete: boolean("complete").notNull(),
+ receivedAt: timestamp("received_at", { withTimezone: true }).notNull(),
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
+}, table => ({
+ sourceSequence: uniqueIndex("run_usage_receipts_source_sequence_idx").on(table.companyId, table.runId, table.sourceId, table.sequence),
+ runLatest: index("run_usage_receipts_run_latest_idx").on(table.companyId, table.runId, table.receivedAt),
+ positiveSequence: check("run_usage_receipts_positive_sequence", sql`${table.sequence} > 0`),
+}));
+
+export const accountingRuntimeBaselines = pgTable("accounting_runtime_baselines", {
+ agentId: uuid("agent_id").primaryKey().references(() => agents.id, { onDelete: "cascade" }),
+ companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }),
+ // Historical totals are preserved explicitly. Only v2 acknowledgements add
+ // to this baseline, including receipts whose occurrence date is backdated.
+ costCents: numeric("cost_cents", { precision: 24, scale: 7 }).notNull(),
+ inputTokens: numeric("input_tokens", { precision: 30, scale: 0 }).notNull(),
+ cachedInputTokens: numeric("cached_input_tokens", { precision: 30, scale: 0 }).notNull(),
+ outputTokens: numeric("output_tokens", { precision: 30, scale: 0 }).notNull(),
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
+}, table => ({ company: index("accounting_runtime_baselines_company_idx").on(table.companyId) }));
+
+export const budgetReservations = pgTable("budget_reservations", {
+ id: uuid("id").primaryKey().defaultRandom(),
+ companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }),
+ runId: uuid("run_id").references(() => heartbeatRuns.id, { onDelete: "cascade" }),
+ decisionInvocationId: uuid("decision_invocation_id"),
+ agentId: uuid("agent_id").references(() => agents.id, { onDelete: "cascade" }),
+ projectId: uuid("project_id"),
+ amountCents: numeric("amount_cents", { precision: 24, scale: 7 }).notNull(),
+ state: text("state").notNull().default("held"),
+ providerStartedAt: timestamp("provider_started_at", { withTimezone: true }),
+ settledAt: timestamp("settled_at", { withTimezone: true }),
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
+}, table => ({
+ decision: uniqueIndex("budget_reservations_decision_idx").on(table.companyId, table.decisionInvocationId),
+ source: check("budget_reservations_source_check", sql`(${table.runId} is not null)::int + (${table.decisionInvocationId} is not null)::int = 1`),
+ run: uniqueIndex("budget_reservations_run_idx").on(table.companyId, table.runId),
+ active: index("budget_reservations_active_idx").on(table.companyId, table.agentId, table.projectId).where(sql`${table.state} = 'held'`),
+ stateCheck: check("budget_reservations_state_check", sql`${table.state} in ('held', 'settled', 'released')`),
+ amountCheck: check("budget_reservations_amount_check", sql`${table.amountCents} >= 0`),
+}));
+
+export const billingInvoices = pgTable("billing_invoices", {
+ id: uuid("id").primaryKey().defaultRandom(),
+ companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }),
+ biller: text("biller").notNull(),
+ externalId: text("external_id").notNull(),
+ currency: text("currency").notNull(),
+ receiptHash: text("receipt_hash").notNull(),
+ importedBy: text("imported_by").notNull(),
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
+}, table => ({ identity: uniqueIndex("billing_invoices_identity_idx").on(table.companyId, table.biller, table.externalId) }));
+
+export const billingInvoiceLines = pgTable("billing_invoice_lines", {
+ id: uuid("id").primaryKey().defaultRandom(),
+ companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }),
+ invoiceId: uuid("invoice_id").notNull().references(() => billingInvoices.id, { onDelete: "cascade" }),
+ externalId: text("external_id").notNull(),
+ kind: text("kind").notNull(),
+ amountCents: numeric("amount_cents", { precision: 24, scale: 7 }).notNull(),
+ occurredAt: timestamp("occurred_at", { withTimezone: true }).notNull(),
+ costEventId: uuid("cost_event_id").references(() => costEvents.id, { onDelete: "cascade" }),
+ runId: uuid("run_id"),
+ providerRequestId: text("provider_request_id"),
+ model: text("model"),
+ pricing: jsonb("pricing").$type>().notNull().default({}),
+}, table => ({
+ identity: uniqueIndex("billing_invoice_lines_identity_idx").on(table.invoiceId, table.externalId),
+ company: index("billing_invoice_lines_company_idx").on(table.companyId, table.invoiceId),
+ amount: check("billing_invoice_lines_amount_check", sql`${table.amountCents} >= 0`),
+ kindCheck: check("billing_invoice_lines_kind_check", sql`${table.kind} in ('inference', 'fee', 'credit')`),
+}));
+
+export const costAdjustments = pgTable("cost_adjustments", {
+ id: uuid("id").primaryKey().defaultRandom(),
+ companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }),
+ costEventId: uuid("cost_event_id").notNull().references(() => costEvents.id, { onDelete: "cascade" }),
+ invoiceLineId: uuid("invoice_line_id").references(() => billingInvoiceLines.id, { onDelete: "cascade" }),
+ idempotencyKey: text("idempotency_key").notNull(),
+ receiptHash: text("receipt_hash").notNull(),
+ previousCents: numeric("previous_cents", { precision: 24, scale: 7 }).notNull(),
+ correctedCents: numeric("corrected_cents", { precision: 24, scale: 7 }).notNull(),
+ previousStatus: text("previous_status").notNull(),
+ previousPricing: jsonb("previous_pricing").$type>().notNull().default({}),
+ reason: text("reason").notNull(),
+ actorId: text("actor_id").notNull(),
+ pricing: jsonb("pricing").$type>().notNull().default({}),
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
+}, table => ({
+ identity: uniqueIndex("cost_adjustments_receipt_idx").on(table.companyId, table.idempotencyKey),
+ event: index("cost_adjustments_event_idx").on(table.companyId, table.costEventId, table.createdAt),
+ invoiceLine: uniqueIndex("cost_adjustments_invoice_line_idx").on(table.companyId, table.invoiceLineId),
+ amount: check("cost_adjustments_amount_check", sql`${table.previousCents} >= 0 and ${table.correctedCents} >= 0`),
+}));
diff --git a/packages/db/src/schema/agent_runtime_state.ts b/packages/db/src/schema/agent_runtime_state.ts
index b0095bb29b7..9da64882e69 100644
--- a/packages/db/src/schema/agent_runtime_state.ts
+++ b/packages/db/src/schema/agent_runtime_state.ts
@@ -1,4 +1,4 @@
-import { pgTable, uuid, text, timestamp, jsonb, bigint, index } from "drizzle-orm/pg-core";
+import { numeric, pgTable, uuid, text, timestamp, jsonb, bigint, index } from "drizzle-orm/pg-core";
import { agents } from "./agents.js";
import { companies } from "./companies.js";
@@ -15,7 +15,7 @@ export const agentRuntimeState = pgTable(
totalInputTokens: bigint("total_input_tokens", { mode: "number" }).notNull().default(0),
totalOutputTokens: bigint("total_output_tokens", { mode: "number" }).notNull().default(0),
totalCachedInputTokens: bigint("total_cached_input_tokens", { mode: "number" }).notNull().default(0),
- totalCostCents: bigint("total_cost_cents", { mode: "number" }).notNull().default(0),
+ totalCostCents: numeric("total_cost_cents", { precision: 24, scale: 7, mode: "number" }).notNull().default(0),
lastError: text("last_error"),
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
diff --git a/packages/db/src/schema/agents.ts b/packages/db/src/schema/agents.ts
index 248c8c8d0b0..88d0f50dc9a 100644
--- a/packages/db/src/schema/agents.ts
+++ b/packages/db/src/schema/agents.ts
@@ -2,6 +2,7 @@ import type { AgentAppearance } from "@paperclipai/shared";
import {
type AnyPgColumn,
pgTable,
+ numeric,
uuid,
text,
integer,
@@ -31,7 +32,8 @@ export const agents = pgTable(
runtimeConfig: jsonb("runtime_config").$type>().notNull().default({}),
defaultEnvironmentId: uuid("default_environment_id").references(() => environments.id, { onDelete: "set null" }),
budgetMonthlyCents: integer("budget_monthly_cents").notNull().default(0),
- spentMonthlyCents: integer("spent_monthly_cents").notNull().default(0),
+ spendMonthUtc: text("spend_month_utc"),
+ spentMonthlyCents: numeric("spent_monthly_cents", { precision: 24, scale: 7, mode: "number" }).notNull().default(0),
pauseReason: text("pause_reason"),
pausedAt: timestamp("paused_at", { withTimezone: true }),
errorReason: text("error_reason"),
diff --git a/packages/db/src/schema/budget_incidents.ts b/packages/db/src/schema/budget_incidents.ts
index 57b9b3b0126..e06de583342 100644
--- a/packages/db/src/schema/budget_incidents.ts
+++ b/packages/db/src/schema/budget_incidents.ts
@@ -1,5 +1,5 @@
import { sql } from "drizzle-orm";
-import { index, integer, pgTable, text, timestamp, uuid, uniqueIndex } from "drizzle-orm/pg-core";
+import { numeric, index, integer, pgTable, text, timestamp, uuid, uniqueIndex } from "drizzle-orm/pg-core";
import { approvals } from "./approvals.js";
import { budgetPolicies } from "./budget_policies.js";
import { companies } from "./companies.js";
@@ -18,7 +18,7 @@ export const budgetIncidents = pgTable(
windowEnd: timestamp("window_end", { withTimezone: true }).notNull(),
thresholdType: text("threshold_type").notNull(),
amountLimit: integer("amount_limit").notNull(),
- amountObserved: integer("amount_observed").notNull(),
+ amountObserved: numeric("amount_observed", { precision: 24, scale: 7, mode: "number" }).notNull(),
status: text("status").notNull().default("open"),
approvalId: uuid("approval_id").references(() => approvals.id),
resolvedAt: timestamp("resolved_at", { withTimezone: true }),
@@ -37,6 +37,6 @@ export const budgetIncidents = pgTable(
table.policyId,
table.windowStart,
table.thresholdType,
- ).where(sql`${table.status} <> 'dismissed'`),
+ ).where(sql`${table.status} = 'open'`),
}),
);
diff --git a/packages/db/src/schema/budget_policies.ts b/packages/db/src/schema/budget_policies.ts
index 3713889b7db..07da0521cb7 100644
--- a/packages/db/src/schema/budget_policies.ts
+++ b/packages/db/src/schema/budget_policies.ts
@@ -1,4 +1,5 @@
-import { boolean, index, integer, pgTable, text, timestamp, uuid, uniqueIndex } from "drizzle-orm/pg-core";
+import { sql } from "drizzle-orm";
+import { check, boolean, index, integer, pgTable, text, timestamp, uuid, uniqueIndex, numeric } from "drizzle-orm/pg-core";
import { companies } from "./companies.js";
export const budgetPolicies = pgTable(
@@ -11,16 +12,21 @@ export const budgetPolicies = pgTable(
metric: text("metric").notNull().default("billed_cents"),
windowKind: text("window_kind").notNull(),
amount: integer("amount").notNull().default(0),
+ reservationCents: numeric("reservation_cents", { precision: 24, scale: 7 }).notNull().default("0"),
warnPercent: integer("warn_percent").notNull().default(80),
hardStopEnabled: boolean("hard_stop_enabled").notNull().default(true),
+ unpricedUsagePolicy: text("unpriced_usage_policy").notNull().default("block"),
notifyEnabled: boolean("notify_enabled").notNull().default(true),
isActive: boolean("is_active").notNull().default(true),
+ enforcementVersion: integer("enforcement_version").notNull().default(0),
+ enforcementDeliveredVersion: integer("enforcement_delivered_version").notNull().default(0),
createdByUserId: text("created_by_user_id"),
updatedByUserId: text("updated_by_user_id"),
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
},
(table) => ({
+ reservationNonnegative: check("budget_policies_reservation_nonnegative", sql`${table.reservationCents} >= 0`),
companyScopeActiveIdx: index("budget_policies_company_scope_active_idx").on(
table.companyId,
table.scopeType,
diff --git a/packages/db/src/schema/companies.ts b/packages/db/src/schema/companies.ts
index c911fd9aa10..e31abb54491 100644
--- a/packages/db/src/schema/companies.ts
+++ b/packages/db/src/schema/companies.ts
@@ -1,5 +1,5 @@
import type { InteractionResolverGovernance } from "@paperclipai/shared";
-import { pgTable, uuid, text, integer, timestamp, boolean, jsonb, uniqueIndex } from "drizzle-orm/pg-core";
+import { numeric, pgTable, uuid, text, integer, timestamp, boolean, jsonb, uniqueIndex } from "drizzle-orm/pg-core";
export const companies = pgTable(
"companies",
@@ -13,7 +13,8 @@ export const companies = pgTable(
issuePrefix: text("issue_prefix").notNull().default("PAP"),
issueCounter: integer("issue_counter").notNull().default(0),
budgetMonthlyCents: integer("budget_monthly_cents").notNull().default(0),
- spentMonthlyCents: integer("spent_monthly_cents").notNull().default(0),
+ spendMonthUtc: text("spend_month_utc"),
+ spentMonthlyCents: numeric("spent_monthly_cents", { precision: 24, scale: 7, mode: "number" }).notNull().default(0),
defaultResponsibleUserId: text("default_responsible_user_id"),
requireBoardApprovalForNewAgents: boolean("require_board_approval_for_new_agents")
.notNull()
diff --git a/packages/db/src/schema/cost_events.ts b/packages/db/src/schema/cost_events.ts
index 9ca547651f5..3af114d517f 100644
--- a/packages/db/src/schema/cost_events.ts
+++ b/packages/db/src/schema/cost_events.ts
@@ -1,4 +1,5 @@
-import { pgTable, uuid, text, timestamp, integer, index } from "drizzle-orm/pg-core";
+import { sql } from "drizzle-orm";
+import { pgTable, uuid, text, timestamp, integer, index, numeric, uniqueIndex, check, jsonb } from "drizzle-orm/pg-core";
import { companies } from "./companies.js";
import { agents } from "./agents.js";
import { issues } from "./issues.js";
@@ -11,12 +12,19 @@ export const costEvents = pgTable(
{
id: uuid("id").primaryKey().defaultRandom(),
companyId: uuid("company_id").notNull().references(() => companies.id),
- agentId: uuid("agent_id").notNull().references(() => agents.id),
+ agentId: uuid("agent_id").references(() => agents.id),
+ usageKind: text("usage_kind").notNull().default("agent"),
+ responsibleUserId: text("responsible_user_id"),
issueId: uuid("issue_id").references(() => issues.id, { onDelete: "set null" }),
projectId: uuid("project_id").references(() => projects.id),
goalId: uuid("goal_id").references(() => goals.id),
heartbeatRunId: uuid("heartbeat_run_id").references(() => heartbeatRuns.id),
billingCode: text("billing_code"),
+ idempotencyKey: text("idempotency_key"),
+ receiptHash: text("receipt_hash"),
+ providerRequestId: text("provider_request_id"),
+ reportedCostCents: numeric("reported_cost_cents", { precision: 24, scale: 7 }),
+ pricingProvenance: jsonb("pricing_provenance").$type>(),
provider: text("provider").notNull(),
biller: text("biller").notNull().default("unknown"),
billingType: text("billing_type").notNull().default("unknown"),
@@ -25,11 +33,17 @@ export const costEvents = pgTable(
inputTokens: integer("input_tokens").notNull().default(0),
cachedInputTokens: integer("cached_input_tokens").notNull().default(0),
outputTokens: integer("output_tokens").notNull().default(0),
- costCents: integer("cost_cents").notNull(),
+ costCents: numeric("cost_cents", { precision: 24, scale: 7, mode: "number" }).notNull(),
occurredAt: timestamp("occurred_at", { withTimezone: true }).notNull(),
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
},
(table) => ({
+ usageKindCheck: check("cost_events_usage_kind_check", sql`${table.usageKind} = 'decision' or (${table.usageKind} = 'agent' and ${table.agentId} is not null)`),
+ receiptUniqueIdx: uniqueIndex("cost_events_company_receipt_idx").on(table.companyId, table.idempotencyKey),
+ providerRequestIdx: index("cost_events_provider_request_idx").on(table.companyId, table.biller, table.providerRequestId),
+ nonnegativeAmounts: check("cost_events_nonnegative_amounts", sql`${table.costCents} >= 0 and ${table.inputTokens} >= 0 and ${table.cachedInputTokens} >= 0 and ${table.outputTokens} >= 0`),
+ companyProjectOccurredIdx: index("cost_events_company_project_occurred_idx").on(table.companyId, table.projectId, table.occurredAt),
+ unpricedIdx: index("cost_events_unpriced_idx").on(table.companyId, table.occurredAt, table.id).where(sql`${table.costStatus} = 'unpriced' and ${table.billingType} <> 'subscription_included'`),
companyOccurredIdx: index("cost_events_company_occurred_idx").on(table.companyId, table.occurredAt),
companyAgentOccurredIdx: index("cost_events_company_agent_occurred_idx").on(
table.companyId,
diff --git a/packages/db/src/schema/decision_models.ts b/packages/db/src/schema/decision_models.ts
new file mode 100644
index 00000000000..98c0e8c2120
--- /dev/null
+++ b/packages/db/src/schema/decision_models.ts
@@ -0,0 +1,51 @@
+import { sql } from "drizzle-orm";
+import { boolean, check, index, integer, jsonb, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
+import { companies } from "./companies.js";
+import { costEvents } from "./cost_events.js";
+
+export const companyDecisionModels = pgTable("company_decision_models", {
+ companyId: uuid("company_id").primaryKey().references(() => companies.id, { onDelete: "cascade" }),
+ // Retain company preferences when a connection/grant is deleted. Resolution
+ // fails closed for stale IDs; choosing a replacement preserves sponsorship.
+ connectionId: uuid("connection_id"),
+ grantId: uuid("grant_id"),
+ enabled: boolean("enabled").notNull().default(false),
+ allowBackground: boolean("allow_background").notNull().default(true),
+ provider: text("provider"),
+ model: text("model"),
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
+}, t => ({ configured: check("company_decisions_configured", sql`(${t.connectionId} is null) = (${t.grantId} is null) and (not ${t.enabled} or (${t.connectionId} is not null and ${t.provider} is not null and ${t.model} is not null))`) }));
+
+/** Attribution references are archival: history survives deleted runs and connections. No input or answer content. */
+export const decisionInvocations = pgTable("decision_invocations", {
+ id: uuid("id").primaryKey().defaultRandom(),
+ companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }),
+ feature: text("feature").notNull(),
+ actorType: text("actor_type").notNull(),
+ actorId: text("actor_id").notNull(),
+ responsibleUserId: text("responsible_user_id"),
+ agentId: uuid("agent_id"),
+ issueId: uuid("issue_id"),
+ projectId: uuid("project_id"),
+ runId: uuid("run_id"),
+ identityContextId: uuid("identity_context_id"),
+ connectionId: uuid("connection_id").notNull(),
+ grantId: uuid("grant_id").notNull(),
+ provider: text("provider").notNull(),
+ model: text("model").notNull(),
+ questionTypes: jsonb("question_types").$type().notNull(),
+ status: text("status").notNull().default("running"),
+ errorCode: text("error_code"),
+ providerRequestId: text("provider_request_id"),
+ costEventId: uuid("cost_event_id").references(() => costEvents.id),
+ startedAt: timestamp("started_at", { withTimezone: true }).notNull().defaultNow(),
+ finishedAt: timestamp("finished_at", { withTimezone: true }),
+ durationMs: integer("duration_ms"),
+ inputTokens: integer("input_tokens"),
+ outputTokens: integer("output_tokens"),
+}, t => ({
+ history: index("decision_invocations_company_started_idx").on(t.companyId, t.startedAt, t.id),
+ pending: index("decision_invocations_pending_idx").on(t.startedAt).where(sql`${t.status} = 'running'`),
+ cost: index("decision_invocations_cost_idx").on(t.costEventId),
+ statusCheck: check("decision_invocations_status_check", sql`${t.status} in ('running', 'succeeded', 'failed', 'unknown')`),
+}));
diff --git a/packages/db/src/schema/finance_events.ts b/packages/db/src/schema/finance_events.ts
index 976efa3ff43..bb7247497c3 100644
--- a/packages/db/src/schema/finance_events.ts
+++ b/packages/db/src/schema/finance_events.ts
@@ -1,4 +1,4 @@
-import { pgTable, uuid, text, timestamp, integer, index, boolean, jsonb } from "drizzle-orm/pg-core";
+import { pgTable, uuid, text, timestamp, integer, numeric, index, uniqueIndex, boolean, jsonb } from "drizzle-orm/pg-core";
import { companies } from "./companies.js";
import { agents } from "./agents.js";
import { issues } from "./issues.js";
@@ -18,6 +18,8 @@ export const financeEvents = pgTable(
goalId: uuid("goal_id").references(() => goals.id),
heartbeatRunId: uuid("heartbeat_run_id").references(() => heartbeatRuns.id),
costEventId: uuid("cost_event_id").references(() => costEvents.id),
+ idempotencyKey: text("idempotency_key"),
+ receiptHash: text("receipt_hash"),
billingCode: text("billing_code"),
description: text("description"),
eventKind: text("event_kind").notNull(),
@@ -30,7 +32,7 @@ export const financeEvents = pgTable(
model: text("model"),
quantity: integer("quantity"),
unit: text("unit"),
- amountCents: integer("amount_cents").notNull(),
+ amountCents: numeric("amount_cents", { precision: 24, scale: 7, mode: "number" }).notNull(),
currency: text("currency").notNull().default("USD"),
estimated: boolean("estimated").notNull().default(false),
externalInvoiceId: text("external_invoice_id"),
@@ -39,6 +41,7 @@ export const financeEvents = pgTable(
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
},
(table) => ({
+ receiptUniqueIdx: uniqueIndex("finance_events_company_receipt_idx").on(table.companyId, table.idempotencyKey),
companyOccurredIdx: index("finance_events_company_occurred_idx").on(table.companyId, table.occurredAt),
companyBillerOccurredIdx: index("finance_events_company_biller_occurred_idx").on(
table.companyId,
diff --git a/packages/db/src/schema/heartbeat_runs.ts b/packages/db/src/schema/heartbeat_runs.ts
index 93e988b3e5b..6b7ac23f493 100644
--- a/packages/db/src/schema/heartbeat_runs.ts
+++ b/packages/db/src/schema/heartbeat_runs.ts
@@ -10,12 +10,14 @@ import {
integer,
bigint,
boolean,
+ check,
unique,
uniqueIndex,
} from "drizzle-orm/pg-core";
import { companies } from "./companies.js";
import { agents } from "./agents.js";
import { agentWakeupRequests } from "./agent_wakeup_requests.js";
+import { issues } from "./issues.js";
export const heartbeatRuns = pgTable(
"heartbeat_runs",
@@ -23,6 +25,11 @@ export const heartbeatRuns = pgTable(
id: uuid("id").primaryKey().defaultRandom(),
companyId: uuid("company_id").notNull().references(() => companies.id),
agentId: uuid("agent_id").notNull().references(() => agents.id),
+ scopeKind: text("scope_kind")
+ .$type<"company" | "issue">()
+ .notNull()
+ .default("company"),
+ issueId: uuid("issue_id").references((): AnyPgColumn => issues.id, { onDelete: "set null" }),
invocationSource: text("invocation_source").notNull().default("on_demand"),
triggerDetail: text("trigger_detail"),
status: text("status").notNull().default("queued"),
@@ -39,6 +46,12 @@ export const heartbeatRuns = pgTable(
wakeupRequestId: uuid("wakeup_request_id").references(() => agentWakeupRequests.id),
exitCode: integer("exit_code"),
signal: text("signal"),
+ costAccountingPending: boolean("cost_accounting_pending").notNull().default(false),
+ costAccountedAt: timestamp("cost_accounted_at", { withTimezone: true }),
+ accountingProjectionVersion: text("accounting_projection_version"),
+ accountingLastAttemptAt: timestamp("accounting_last_attempt_at", { withTimezone: true }),
+ accountingLastError: text("accounting_last_error"),
+ accountingAttemptCount: integer("accounting_attempt_count").notNull().default(0),
usageJson: jsonb("usage_json").$type>(),
resultJson: jsonb("result_json").$type>(),
runtimeMode: text("runtime_mode").notNull().default("legacy"),
@@ -98,6 +111,12 @@ export const heartbeatRuns = pgTable(
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
},
(table) => ({
+ scopeBindingCheck: check(
+ "heartbeat_runs_scope_binding_check",
+ sql`(${table.scopeKind} = 'company' AND ${table.issueId} IS NULL)
+ OR ${table.scopeKind} = 'issue'`,
+ ),
+ costAccountingPendingIdx: index("heartbeat_runs_cost_accounting_pending_idx").on(table.updatedAt, table.id).where(sql`${table.costAccountingPending} = true`),
executionStatusDeliveryIdx: index("heartbeat_runs_execution_status_delivery_idx")
.on(table.executionStatusDeliveryId).where(sql`${table.executionStatusDeliveryId} is not null`),
executionControlDeadlineIdx: index("heartbeat_runs_execution_control_deadline_idx")
@@ -123,6 +142,11 @@ export const heartbeatRuns = pgTable(
table.agentId,
table.startedAt,
),
+ companyIssueCreatedIdx: index("heartbeat_runs_company_issue_created_idx").on(
+ table.companyId,
+ table.issueId,
+ table.createdAt,
+ ),
companyResponsibleUserIdx: index("heartbeat_runs_company_responsible_user_idx").on(
table.companyId,
table.responsibleUserId,
diff --git a/packages/db/src/schema/index.ts b/packages/db/src/schema/index.ts
index 4ba854b3f83..83b52844528 100644
--- a/packages/db/src/schema/index.ts
+++ b/packages/db/src/schema/index.ts
@@ -26,6 +26,7 @@ export { agentTaskSessions, agentSessionGoalActions } from "./agent_task_session
export { agentWakeupRequests } from "./agent_wakeup_requests.js";
export { projects } from "./projects.js";
export { projectMemberships } from "./project_memberships.js";
+export { projectAccessMembers } from "./project_access_members.js";
export { documentMemberships } from "./document_memberships.js";
export { projectWorkspaces } from "./project_workspaces.js";
export { executionWorkspaces } from "./execution_workspaces.js";
@@ -41,6 +42,7 @@ export { projectGoals } from "./project_goals.js";
export { goals } from "./goals.js";
export { folders } from "./folders.js";
export { issues } from "./issues.js";
+export { issueAccessGrants } from "./issue_access_grants.js";
export { issueWatchdogs } from "./issue_watchdogs.js";
export { issuePlanDecompositions } from "./issue_plan_decompositions.js";
export { issueRecoveryActions } from "./issue_recovery_actions.js";
@@ -224,6 +226,7 @@ export * from "./public_mcp.js";
export * from "./dot_runner.js";
+export * from "./accounting.js";
export * from "./ai_connection_routing.js";
export { toolConnectionAppSnapshots } from "./tool_connection_app_snapshots.js";
export { toolConnectionAppSyncs } from "./tool_connection_app_syncs.js";
@@ -231,3 +234,5 @@ export { agentCommentary } from "./agent_commentary.js";
export { agentIdentityKeys } from "./agent_identity_keys.js";
+export * from "./decision_models.js";
+export { userCompanyPreferences } from "./user_company_preferences.js";
diff --git a/packages/db/src/schema/issue_access_grants.ts b/packages/db/src/schema/issue_access_grants.ts
new file mode 100644
index 00000000000..034ca9d2a66
--- /dev/null
+++ b/packages/db/src/schema/issue_access_grants.ts
@@ -0,0 +1,36 @@
+import { sql } from "drizzle-orm";
+import { check, index, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
+import { agents } from "./agents.js";
+import { issues } from "./issues.js";
+
+export const issueAccessGrants = pgTable(
+ "issue_access_grants",
+ {
+ id: uuid("id").primaryKey().defaultRandom(),
+ issueId: uuid("issue_id").notNull().references(() => issues.id, { onDelete: "cascade" }),
+ subjectType: text("subject_type").notNull(),
+ subjectId: text("subject_id").notNull(),
+ source: text("source").notNull(),
+ grantedByUserId: text("granted_by_user_id"),
+ grantedByAgentId: uuid("granted_by_agent_id").references(() => agents.id, { onDelete: "set null" }),
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
+ revokedAt: timestamp("revoked_at", { withTimezone: true }),
+ },
+ (table) => ({
+ subjectTypeCheck: check(
+ "issue_access_grants_subject_type_check",
+ sql`${table.subjectType} in ('user', 'agent')`,
+ ),
+ sourceCheck: check(
+ "issue_access_grants_source_check",
+ sql`${table.source} in ('explicit', 'assignment', 'project')`,
+ ),
+ predicateIdx: index("issue_access_grants_subject_active_issue_idx").on(
+ table.subjectType,
+ table.subjectId,
+ table.revokedAt,
+ table.issueId,
+ ),
+ issueIdx: index("issue_access_grants_issue_idx").on(table.issueId, table.createdAt),
+ }),
+);
diff --git a/packages/db/src/schema/issues.ts b/packages/db/src/schema/issues.ts
index 2542d94f3ca..a4384709ed8 100644
--- a/packages/db/src/schema/issues.ts
+++ b/packages/db/src/schema/issues.ts
@@ -38,6 +38,9 @@ export const issues = pgTable(
projectWorkspaceId: uuid("project_workspace_id").references(() => projectWorkspaces.id, { onDelete: "set null" }),
goalId: uuid("goal_id").references(() => goals.id),
parentId: uuid("parent_id").references((): AnyPgColumn => issues.id),
+ visibility: text("visibility").notNull().default("open"),
+ privacyRootIssueId: uuid("privacy_root_issue_id").references((): AnyPgColumn => issues.id),
+ privacyParentIssueId: uuid("privacy_parent_issue_id").references((): AnyPgColumn => issues.id, { onDelete: "set null" }),
title: text("title").notNull(),
titleNeedsGeneration: boolean("title_needs_generation").notNull().default(false),
description: text("description"),
@@ -92,6 +95,7 @@ export const issues = pgTable(
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
},
(table) => ({
+ visibilityCheck: check("issues_visibility_check", sql`${table.visibility} in ('open', 'private')`),
conversationIdentityIdx: uniqueIndex("issues_conversation_identity_idx").on(table.companyId, table.conversationAgentId, table.conversationUserId),
conversationIdentityCheck: check("issues_conversation_identity_check", sql`(
${table.conversationAgentId} is null and ${table.conversationUserId} is null and ${table.conversationState} is null
@@ -117,6 +121,8 @@ export const issues = pgTable(
),
responsibleUserIdx: index("issues_company_responsible_user_idx").on(table.companyId, table.responsibleUserId),
parentIdx: index("issues_company_parent_idx").on(table.companyId, table.parentId),
+ privacyParentIdx: index("issues_company_privacy_parent_idx").on(table.companyId, table.privacyParentIssueId),
+ privacyRootIdx: index("issues_company_privacy_root_idx").on(table.companyId, table.privacyRootIssueId),
projectIdx: index("issues_company_project_idx").on(table.companyId, table.projectId),
originIdx: index("issues_company_origin_idx").on(table.companyId, table.originKind, table.originId),
projectWorkspaceIdx: index("issues_company_project_workspace_idx").on(table.companyId, table.projectWorkspaceId),
diff --git a/packages/db/src/schema/project_access_members.ts b/packages/db/src/schema/project_access_members.ts
new file mode 100644
index 00000000000..6f5b3912958
--- /dev/null
+++ b/packages/db/src/schema/project_access_members.ts
@@ -0,0 +1,34 @@
+import { sql } from "drizzle-orm";
+import { check, index, pgTable, text, timestamp, uniqueIndex, uuid } from "drizzle-orm/pg-core";
+import { companies } from "./companies.js";
+import { projects } from "./projects.js";
+
+/** Authorization membership for private projects; unrelated to sidebar project_memberships. */
+export const projectAccessMembers = pgTable(
+ "project_access_members",
+ {
+ id: uuid("id").primaryKey().defaultRandom(),
+ companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }),
+ projectId: uuid("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
+ subjectType: text("subject_type").notNull(),
+ subjectId: text("subject_id").notNull(),
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
+ },
+ (table) => ({
+ subjectTypeCheck: check(
+ "project_access_members_subject_type_check",
+ sql`${table.subjectType} in ('user', 'agent')`,
+ ),
+ projectSubjectUq: uniqueIndex("project_access_members_project_subject_uq").on(
+ table.projectId,
+ table.subjectType,
+ table.subjectId,
+ ),
+ subjectLookupIdx: index("project_access_members_subject_lookup_idx").on(
+ table.companyId,
+ table.subjectType,
+ table.subjectId,
+ table.projectId,
+ ),
+ }),
+);
diff --git a/packages/db/src/schema/projects.ts b/packages/db/src/schema/projects.ts
index 38910bc766f..8cd7174625c 100644
--- a/packages/db/src/schema/projects.ts
+++ b/packages/db/src/schema/projects.ts
@@ -1,4 +1,5 @@
-import { pgTable, uuid, text, timestamp, date, index, jsonb } from "drizzle-orm/pg-core";
+import { sql } from "drizzle-orm";
+import { pgTable, uuid, text, timestamp, date, index, jsonb, check, uniqueIndex } from "drizzle-orm/pg-core";
import type { AgentEnvConfig } from "@paperclipai/shared";
import { companies } from "./companies.js";
import { goals } from "./goals.js";
@@ -12,6 +13,9 @@ export const projects = pgTable(
goalId: uuid("goal_id").references(() => goals.id),
name: text("name").notNull(),
description: text("description"),
+ visibility: text("visibility").notNull().default("open"),
+ privacyOwnerUserId: text("privacy_owner_user_id"),
+ personalOwnerUserId: text("personal_owner_user_id"),
status: text("status").notNull().default("backlog"),
leadAgentId: uuid("lead_agent_id").references(() => agents.id),
targetDate: date("target_date"),
@@ -27,5 +31,9 @@ export const projects = pgTable(
},
(table) => ({
companyIdx: index("projects_company_idx").on(table.companyId),
+ visibilityCheck: check("projects_visibility_check", sql`${table.visibility} in ('open', 'private')`),
+ personalOwnerUq: uniqueIndex("projects_company_personal_owner_uq")
+ .on(table.companyId, table.personalOwnerUserId)
+ .where(sql`${table.personalOwnerUserId} is not null`),
}),
);
diff --git a/packages/db/src/schema/status_cards.ts b/packages/db/src/schema/status_cards.ts
index 90f250b7cac..06efaa0368b 100644
--- a/packages/db/src/schema/status_cards.ts
+++ b/packages/db/src/schema/status_cards.ts
@@ -1,5 +1,5 @@
import { sql } from "drizzle-orm";
-import { boolean, index, integer, jsonb, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
+import { boolean, index, integer, numeric, jsonb, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
import type { CompanySearchQuery, StatusCardRefreshPolicy } from "@paperclipai/shared";
import { agents } from "./agents.js";
import { companies } from "./companies.js";
@@ -81,7 +81,7 @@ export const statusCardUpdates = pgTable(
changes: jsonb("changes").$type().notNull().default(sql`'[]'::jsonb`),
inputTokens: integer("input_tokens").notNull().default(0),
outputTokens: integer("output_tokens").notNull().default(0),
- costCents: integer("cost_cents").notNull().default(0),
+ costCents: numeric("cost_cents", { precision: 24, scale: 7, mode: "number" }).notNull().default(0),
model: text("model"),
queryVersion: integer("query_version"),
changeSummary: text("change_summary"),
diff --git a/packages/db/src/schema/user_company_preferences.ts b/packages/db/src/schema/user_company_preferences.ts
new file mode 100644
index 00000000000..40c6a679fdc
--- /dev/null
+++ b/packages/db/src/schema/user_company_preferences.ts
@@ -0,0 +1,16 @@
+import { boolean, index, pgTable, text, timestamp, uniqueIndex, uuid } from "drizzle-orm/pg-core";
+import { agents } from "./agents.js";
+import { companies } from "./companies.js";
+
+export const userCompanyPreferences = pgTable("user_company_preferences", {
+ id: uuid("id").primaryKey().defaultRandom(),
+ companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }),
+ userId: text("user_id").notNull(),
+ primaryAgentId: uuid("primary_agent_id").references(() => agents.id, { onDelete: "set null" }),
+ primaryAgentInitialized: boolean("primary_agent_initialized").notNull().default(false),
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
+}, table => ({
+ companyUserUq: uniqueIndex("user_company_preferences_company_user_uq").on(table.companyId, table.userId),
+ primaryAgentIdx: index("user_company_preferences_primary_agent_idx").on(table.primaryAgentId),
+}));
diff --git a/packages/paperclip-runner/generated/capability/semantic-tool-contracts.json b/packages/paperclip-runner/generated/capability/semantic-tool-contracts.json
index 6ef26162484..9c99672009d 100644
--- a/packages/paperclip-runner/generated/capability/semantic-tool-contracts.json
+++ b/packages/paperclip-runner/generated/capability/semantic-tool-contracts.json
@@ -1 +1 @@
-[{"annotations":{"exposure":"always","operationId":"get_task_context","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Read the active task and actor, including the exact approved Markdown revision when this issue has an accepted plan.","inputSchema":{"additionalProperties":false,"properties":{},"required":[],"type":"object"},"name":"get_task_context","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"always","operationId":"get_task_history","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Read bounded comments on the active task.","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":50,"maximum":200,"minimum":1,"type":"integer"}},"required":[],"type":"object"},"name":"get_task_history","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"always","operationId":"list_documents","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"List revisioned documents on the active task.","inputSchema":{"additionalProperties":false,"properties":{},"required":[],"type":"object"},"name":"list_documents","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"always","operationId":"read_document","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Read the current revision of one active-task document.","inputSchema":{"additionalProperties":false,"properties":{"key":{"description":"Stable issue-document key.","maxLength":120,"minLength":1,"type":"string"}},"required":["key"],"type":"object"},"name":"read_document","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"always","operationId":"list_document_revisions","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Read bounded revision history for one active-task document.","inputSchema":{"additionalProperties":false,"properties":{"key":{"description":"Stable issue-document key.","maxLength":120,"minLength":1,"type":"string"},"limit":{"default":50,"maximum":200,"minimum":1,"type":"integer"}},"required":["key"],"type":"object"},"name":"list_document_revisions","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"always","operationId":"report_progress","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Append a durable progress comment to the active task.","inputSchema":{"additionalProperties":false,"properties":{"body":{"description":"Multiline progress update.","maxLength":20000,"minLength":1,"type":"string"},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"}},"required":["idempotencyKey","body"],"type":"object"},"name":"report_progress","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"always","operationId":"answer_status_question","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Append the answer to a status-only wake without changing task disposition.","inputSchema":{"additionalProperties":false,"properties":{"body":{"description":"Concise status answer.","maxLength":20000,"minLength":1,"type":"string"},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"}},"required":["idempotencyKey","body"],"type":"object"},"name":"answer_status_question","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"always","operationId":"write_document","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Create or update an active-task document with optimistic revision safety.","inputSchema":{"additionalProperties":false,"properties":{"baseRevisionId":{"description":"Current revision id, or null when creating.","maxLength":20000,"type":["string","null"]},"body":{"description":"Markdown document body.","maxLength":200000,"minLength":1,"type":"string"},"changeSummary":{"description":"Optional revision summary.","maxLength":20000,"type":["string","null"]},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"key":{"description":"Stable issue-document key.","maxLength":120,"minLength":1,"type":"string"},"title":{"description":"Document title.","maxLength":300,"minLength":1,"type":"string"}},"required":["idempotencyKey","key","title","body","baseRevisionId"],"type":"object"},"name":"write_document","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"always","operationId":"request_human_input","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Create a durable human question or approval card on the current Paperclip task bound to this run; Paperclip renders it and authenticates the response. Use questions with continuationPolicy='wake_assignee' when an answer is needed, including otherwise tool-free chat turns. Supply a stable idempotencyKey and reuse it on retries. For one question at a time, ask only the next unanswered question and wait for its real answer. Never fabricate answers or treat ambiguous clarification as approval. For an ordinary confirmation or checkbox card, record a clear user chat answer with call_api POST /api/issues/{id}/interactions/{interactionId}/resolve-from-comment, using the source commentId and decision (accept/reject), plus explicit selectedOptionIds for checkbox acceptance. Existing resolver permissions still apply; governed tool, secret, and connection approvals are excluded. Question forms retain their dedicated answer workflow. Preserve existing review gates. Call this tool before claiming a question was asked; if creation fails, report the failure. Do not fabricate answer links or Markdown buttons, post duplicate cards, or use call_api to create the card. Use one complete payload.questionSet for text and choice questions. Paperclip generates compatibility questions; see the payload schema for formats.","inputSchema":{"additionalProperties":false,"allOf":[{"if":{"properties":{"interactionKind":{"const":"questions"}},"required":["interactionKind"]},"then":{"properties":{"payload":{"anyOf":[{"required":["questionSet"]},{"required":["questions"]}],"required":["version"]}},"required":["payload"]}}],"properties":{"continuationPolicy":{"enum":["none","wake_assignee","wake_assignee_on_accept"]},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"interactionKind":{"enum":["confirmation","checkbox","questions","suggest_tasks","item_verdicts"]},"payload":{"additionalProperties":true,"description":"Kind-specific interaction data. For questions, send version:1 and one complete questionSet containing every text and choice question. Paperclip generates compatibility questions. Each canonical question needs id, prompt, required, and answerMode: text, single_select, or multi_select. Text questions have no options or customAnswer. Choice questions need at least two meaningful options with id/label. Use customAnswer:{enabled:true} for an optional written answer to a choice question. Legacy questions remain supported; if both representations are supplied, they must describe the same complete form. Keep IDs stable across retries. For confirmation, payload may be {}.","properties":{"questionSet":{"additionalProperties":false,"properties":{"description":{"maxLength":100000,"type":"string"},"questions":{"items":{"additionalProperties":false,"allOf":[{"if":{"properties":{"answerMode":{"const":"text"}},"required":["answerMode"]},"then":{"not":{"required":["customAnswer"]},"properties":{"options":{"maxItems":0,"type":"array"}}}},{"if":{"properties":{"answerMode":{"enum":["single_select","multi_select"]}},"required":["answerMode"]},"then":{"properties":{"options":{"minItems":1,"type":"array"}},"required":["options"]}}],"properties":{"answerMode":{"enum":["single_select","multi_select","text"]},"customAnswer":{"additionalProperties":false,"properties":{"enabled":{"const":true},"label":{"maxLength":1000,"type":"string"},"placeholder":{"maxLength":1000,"type":"string"}},"required":["enabled"],"type":"object"},"header":{"maxLength":1000,"type":"string"},"helpText":{"maxLength":4000,"type":"string"},"id":{"maxLength":160,"minLength":1,"type":"string"},"options":{"items":{"additionalProperties":false,"properties":{"description":{"maxLength":4000,"type":"string"},"id":{"maxLength":160,"minLength":1,"type":"string"},"label":{"maxLength":1000,"minLength":1,"type":"string"},"recommended":{"type":"boolean"}},"required":["id","label"],"type":"object"},"maxItems":128,"type":"array"},"prompt":{"maxLength":4000,"minLength":1,"type":"string"},"required":{"type":"boolean"},"textValidation":{"additionalProperties":false,"properties":{"inputType":{"enum":["text","number","integer"]},"maxLength":{"maximum":100000,"minimum":0,"type":"integer"},"maximum":{"type":"number"},"minLength":{"maximum":100000,"minimum":0,"type":"integer"},"minimum":{"type":"number"},"pattern":{"maxLength":1000,"type":"string"}},"type":"object"}},"required":["id","prompt","required","answerMode"],"type":"object"},"maxItems":64,"minItems":1,"type":"array"},"schema":{"const":"paperclip.question_set.v1"},"submitLabel":{"maxLength":200,"type":"string"},"title":{"maxLength":1000,"type":"string"}},"required":["schema","questions"],"type":"object"},"questions":{"items":{"additionalProperties":true,"properties":{"id":{"maxLength":160,"minLength":1,"type":"string"},"options":{"items":{"additionalProperties":true,"properties":{"freeText":{"type":"boolean"},"id":{"maxLength":160,"minLength":1,"type":"string"},"label":{"maxLength":1000,"minLength":1,"type":"string"}},"required":["id","label"],"type":"object"},"maxItems":129,"minItems":1,"type":"array"},"prompt":{"maxLength":4000,"minLength":1,"type":"string"},"required":{"type":"boolean"},"selectionMode":{"enum":["single","multi"]}},"required":["id","prompt","selectionMode","options"],"type":"object"},"maxItems":64,"minItems":1,"type":"array"},"version":{"const":1}},"type":"object"},"prompt":{"description":"Question or decision prompt.","maxLength":10000,"minLength":1,"type":"string"},"targetRevisionId":{"description":"Optional bound document revision.","maxLength":20000,"type":["string","null"]},"title":{"description":"Interaction card title.","maxLength":300,"minLength":1,"type":"string"}},"required":["idempotencyKey","interactionKind","title","prompt","continuationPolicy"],"type":"object"},"name":"request_human_input","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"always","operationId":"register_deliverable","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Register attachment metadata and its artifact work product without credentials or bytes in the tool result.","inputSchema":{"additionalProperties":false,"properties":{"byteSize":{"maximum":100000000,"minimum":0,"type":"integer"},"contentRef":{"description":"Opaque package-local content reference.","maxLength":2000,"minLength":1,"type":"string"},"contentType":{"description":"Media type.","maxLength":200,"minLength":1,"type":"string"},"filename":{"description":"Display filename.","maxLength":500,"minLength":1,"type":"string"},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"sha256":{"pattern":"^[a-fA-F0-9]{64}$","type":"string"},"title":{"description":"Work-product title.","maxLength":500,"minLength":1,"type":"string"}},"required":["idempotencyKey","filename","contentType","byteSize","sha256","contentRef","title"],"type":"object"},"name":"register_deliverable","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"always","operationId":"finish_task","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Finish the active task with a durable summary.","inputSchema":{"additionalProperties":false,"properties":{"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"summary":{"description":"Completion summary.","maxLength":20000,"minLength":1,"type":"string"}},"required":["idempotencyKey","summary"],"type":"object"},"name":"finish_task","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"always","operationId":"block_task","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Block the active task with a durable reason and optional first-class dependencies.","inputSchema":{"additionalProperties":false,"properties":{"blockedByTaskIds":{"description":"Internal task ids that block this task.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"reason":{"description":"Block reason.","maxLength":20000,"minLength":1,"type":"string"}},"required":["idempotencyKey","reason"],"type":"object"},"name":"block_task","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"always","operationId":"request_review","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Move the active task to review with a durable summary.","inputSchema":{"additionalProperties":false,"properties":{"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"summary":{"description":"Review handoff summary.","maxLength":20000,"minLength":1,"type":"string"}},"required":["idempotencyKey","summary"],"type":"object"},"name":"request_review","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"optional","operationId":"list_agents","requiredClaims":["discovery:agents:read"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"List redacted actor profiles.","inputSchema":{"additionalProperties":false,"properties":{},"required":[],"type":"object"},"name":"list_agents","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"get_agent","requiredClaims":["discovery:agents:read"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Read one redacted actor profile.","inputSchema":{"additionalProperties":false,"properties":{"actorId":{"description":"Actor id.","maxLength":200,"minLength":1,"type":"string"}},"required":["actorId"],"type":"object"},"name":"get_agent","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"hire_agent","requiredClaims":["delegation:agents:create"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Create a persistent native Runner teammate with an identity and persona. The teammate reports to the caller and inherits the caller's native runtime; provider, adapter, environment, and credential settings are selected by Paperclip and are never caller-supplied here. Reuse a suitable teammate from list_agents when possible.","inputSchema":{"additionalProperties":false,"properties":{"capabilities":{"maxLength":2000,"type":["string","null"]},"instructions":{"maxLength":20000,"type":["string","null"]},"name":{"maxLength":200,"minLength":1,"type":"string"},"role":{"enum":["ceo","cto","cmo","cfo","security","engineer","designer","pm","qa","devops","researcher","general"],"type":"string"},"title":{"maxLength":300,"type":["string","null"]}},"required":["name"],"type":"object"},"name":"hire_agent","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"search_tasks","requiredClaims":["discovery:tasks:read"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Search tasks by text and status within the run company.","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":50,"maximum":200,"minimum":1,"type":"integer"},"query":{"maxLength":500,"type":"string"},"statuses":{"items":{"enum":["backlog","todo","in_progress","in_review","done","blocked","cancelled"]},"maxItems":7,"type":"array","uniqueItems":true}},"required":[],"type":"object"},"name":"search_tasks","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"list_approvals","requiredClaims":["governance:approvals:read"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"List approvals in the run company.","inputSchema":{"additionalProperties":false,"properties":{},"required":[],"type":"object"},"name":"list_approvals","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"get_approval","requiredClaims":["governance:approvals:read"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Read one approval without protected data.","inputSchema":{"additionalProperties":false,"properties":{"approvalId":{"description":"Approval id.","maxLength":200,"minLength":1,"type":"string"}},"required":["approvalId"],"type":"object"},"name":"get_approval","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"get_approval_context","requiredClaims":["governance:approvals:read"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Read one approval, its comments, and linked tasks.","inputSchema":{"additionalProperties":false,"properties":{"approvalId":{"description":"Approval id.","maxLength":200,"minLength":1,"type":"string"}},"required":["approvalId"],"type":"object"},"name":"get_approval_context","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"get_workspace_runtime","requiredClaims":["workspace:read"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Read active-task workspace services.","inputSchema":{"additionalProperties":false,"properties":{},"required":[],"type":"object"},"name":"get_workspace_runtime","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"control_workspace_service","requiredClaims":["workspace:control"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Start, stop, or fault one active-task workspace service.","inputSchema":{"additionalProperties":false,"properties":{"action":{"enum":["start","stop","fail"]},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"serviceId":{"description":"Workspace service id.","maxLength":200,"minLength":1,"type":"string"},"url":{"description":"Optional service URL.","maxLength":20000,"type":["string","null"]}},"required":["idempotencyKey","serviceId","action"],"type":"object"},"name":"control_workspace_service","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"optional","operationId":"set_dependencies","requiredClaims":["dependencies:write"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Replace the active task's first-class blocker set.","inputSchema":{"additionalProperties":false,"properties":{"blockedByTaskIds":{"description":"Replacement blocker task ids.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"}},"required":["idempotencyKey","blockedByTaskIds"],"type":"object"},"name":"set_dependencies","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"optional","operationId":"create_task","requiredClaims":["delegation:tasks:create"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Create a project task from a conversation, or a child from an ordinary task. Persist initialPlan before execution. Set status to backlog when the user wants to save or plan work without starting it; backlog tasks never wake an agent. Omitted status means todo, subject to blockers.","inputSchema":{"additionalProperties":false,"properties":{"assigneeActorId":{"description":"Optional agent assignee. Omit to assign the current agent.","maxLength":20000,"type":["string","null"]},"assigneeUserId":{"description":"Company person ID from list_people. Mutually exclusive with assigneeActorId.","type":["string","null"]},"blockedByTaskIds":{"description":"Initial blocker task ids.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"description":{"description":"Child task description.","maxLength":20000,"type":["string","null"]},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"initialPlan":{"description":"Relevant markdown plan saved on the new task before execution starts.","maxLength":200000,"type":["string","null"]},"priority":{"enum":["critical","high","medium","low"]},"projectId":{"description":"Project ID for the task.","type":["string","null"]},"status":{"description":"Initial status. Use backlog to save work without executing it. Defaults to todo (blocked when dependencies are unresolved).","enum":["backlog","todo"]},"title":{"description":"Child task title.","maxLength":500,"minLength":1,"type":"string"}},"required":["idempotencyKey","title"],"type":"object"},"name":"create_task","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"},"task":{"additionalProperties":false,"properties":{"assigneeActorId":{"type":["string","null"]},"assigneeUserId":{"description":"Company person ID from list_people. Mutually exclusive with assigneeActorId.","type":["string","null"]},"id":{"minLength":1,"type":"string"},"identifier":{"type":["string","null"]},"parentId":{"minLength":1,"type":["string","null"]},"projectId":{"minLength":1,"type":["string","null"]},"status":{"minLength":1,"type":"string"}},"required":["id","identifier","parentId","status","assigneeActorId"],"type":"object"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds","task"],"type":"object"}},{"annotations":{"exposure":"optional","operationId":"request_approval","requiredClaims":["governance:approvals:request"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Create a governed approval and waiting posture.","inputSchema":{"additionalProperties":false,"properties":{"approvalType":{"description":"Stable approval type.","maxLength":200,"minLength":1,"type":"string"},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"payload":{"additionalProperties":true,"type":"object"}},"required":["idempotencyKey","approvalType","payload"],"type":"object"},"name":"request_approval","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"optional","operationId":"decide_approval","requiredClaims":["governance:approvals:decide"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Decide an approval as an explicitly authorized approver.","inputSchema":{"additionalProperties":false,"properties":{"approvalId":{"description":"Approval id.","maxLength":200,"minLength":1,"type":"string"},"decision":{"enum":["approved","rejected","cancelled"]},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"note":{"description":"Decision note.","maxLength":20000,"minLength":1,"type":"string"}},"required":["idempotencyKey","approvalId","decision","note"],"type":"object"},"name":"decide_approval","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"optional","operationId":"comment_on_approval","requiredClaims":["governance:approvals:comment"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Add a durable comment to an approval.","inputSchema":{"additionalProperties":false,"properties":{"approvalId":{"description":"Approval id.","maxLength":200,"minLength":1,"type":"string"},"body":{"description":"Approval comment.","maxLength":20000,"minLength":1,"type":"string"},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"}},"required":["idempotencyKey","approvalId","body"],"type":"object"},"name":"comment_on_approval","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"optional","operationId":"schedule_wake","requiredClaims":["control_plane:wakes"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Schedule a deterministic continuation wake.","inputSchema":{"additionalProperties":false,"properties":{"delayTicks":{"maximum":10000,"minimum":1,"type":"integer"},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"reason":{"enum":["manual","issue_commented","interaction_resolved","approval_resolved","blockers_resolved","scheduled_retry","resume"]}},"required":["idempotencyKey","reason","delayTicks"],"type":"object"},"name":"schedule_wake","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"optional","operationId":"generic_api_request","requiredClaims":["test:generic_api_request"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Test-only escape hatch. Disabled unless the scenario and explicit claim both enable it.","inputSchema":{"additionalProperties":false,"properties":{"body":{"additionalProperties":true,"type":"object"},"method":{"enum":["GET","POST","PATCH"]},"path":{"maxLength":500,"pattern":"^/mock/","type":"string"}},"required":["method","path"],"type":"object"},"name":"generic_api_request","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"always","operationId":"read_agent_instructions","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Read the current canonical instruction entry and its revision, or inspect a historical revision by supplying both entryFile and revisionId. Read before updating; do not edit shared instruction caches.","inputSchema":{"additionalProperties":false,"properties":{"entryFile":{"description":"Configured relative entry filename returned by read_agent_instructions; retain it with the revision.","maxLength":4096,"minLength":1,"type":"string"},"revisionId":{"description":"Historical revision to inspect; also provide its entryFile.","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$","type":"string"},"targetAgentId":{"description":"Same-company target agent. Omit to use the calling agent.","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$","type":"string"}},"required":[],"type":"object"},"name":"read_agent_instructions","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"search_api","requiredClaims":["api:discover"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Fallback only: discover Paperclip API operations when the available dedicated tools cannot express the task. Prefer dedicated tools for common operations; do not search before using them. For a persistent hire, first list_agents to reuse a suitable teammate. Search agent-hires for the hiring schema and agent-configurations for compatible adapter/runtime settings, then use call_api with the returned operationId. Supply role-specific instructionsBundle.files as a filename-to-content record. Use the returned agent.id for delegation and obey any pending approval. Provider helper threads are temporary workers, not Paperclip hires. If a hire response is uncertain, reconcile with list_agents before retrying.","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"maxLength":200,"type":"string"},"limit":{"default":5,"maximum":10,"minimum":1,"type":"integer"},"query":{"maxLength":500,"minLength":1,"type":"string"}},"required":["query"],"type":"object"},"name":"search_api","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"always","operationId":"update_agent_instructions","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Commit instruction content with the exact entryFile and baseRevisionId from a prior read. Requires the responsible user’s current target edit permission. On conflict, preserve your candidate and explicitly resolve it; never overwrite the newer head.","inputSchema":{"additionalProperties":false,"properties":{"baseRevisionId":{"description":"Revision read before editing; null only when no canonical entry exists. Never replace a stale base silently.","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$","type":["string","null"]},"content":{"description":"Complete UTF-8 instruction content, at most 1 MiB; empty content is valid.","maxLength":1048576,"type":"string"},"entryFile":{"description":"Configured relative entry filename returned by read_agent_instructions; retain it with the revision.","maxLength":4096,"minLength":1,"type":"string"},"targetAgentId":{"description":"Same-company target agent. Omit to use the calling agent.","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$","type":"string"}},"required":["entryFile","content","baseRevisionId"],"type":"object"},"name":"update_agent_instructions","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"call_api","requiredClaims":["api:call"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Fallback only: call a discovered Paperclip API operation when dedicated tools lack the required operation or parameters. Uses your existing permissions. Prefer dedicated tools; never bypass a denial or runner lifecycle tool. For large text responses, read the returned artifact with GET /api/assets/{assetId}/content and responseText; follow nextOffsetBytes until null.","inputSchema":{"additionalProperties":false,"properties":{"body":{"anyOf":[{"additionalProperties":true,"type":"object"},{"items":{},"type":"array"},{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}],"description":"Request value matching the discovered schema. For JSON object or array requests, pass the object or array directly, never a JSON-encoded string. Strings are for text bodies or endpoints whose schema explicitly accepts a string."},"contentType":{"maxLength":120,"type":"string"},"files":{"items":{"additionalProperties":false,"oneOf":[{"properties":{"artifactId":{}},"required":["artifactId"]},{"properties":{"path":{}},"required":["path"]}],"properties":{"artifactId":{"type":"string"},"field":{"type":"string"},"path":{"description":"File relative to the active issue workspace. Remote files must first be uploaded as an artifact.","type":"string"}},"type":"object"},"maxItems":10,"type":"array"},"operationId":{"description":"Exact operationId returned by search_api, for example GET /api/projects/{id}. Do not guess identifiers.","maxLength":500,"minLength":1,"type":"string"},"pathParams":{"additionalProperties":{"type":"string"},"type":"object"},"query":{"additionalProperties":true,"type":"object"},"responseText":{"additionalProperties":false,"description":"GET only: return a bounded UTF-8 text window inline, including JSON as text, without saving another artifact. Offsets and limits are bytes. Use the returned nextOffsetBytes to continue; null means complete. Prefer reading a saved artifact for a stable snapshot. New live responses have a 1 GiB capture limit and a 4 GiB per-run capture budget. Existing larger assets remain readable in bounded pages. If a live response returns an artifact, continue on its content operation for a stable snapshot.","properties":{"limitBytes":{"default":24576,"maximum":24576,"minimum":4,"type":"integer"},"offsetBytes":{"default":0,"maximum":9007199254740991,"minimum":0,"type":"integer"}},"type":"object"}},"required":["operationId"],"type":"object"},"name":"call_api","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"always","operationId":"get_agent_instruction_history","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"List bounded canonical instruction revision metadata, including actor, source run, and restore origin. Use read_agent_instructions with entryFile and revisionId to inspect exact historical content.","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"maxLength":2048,"minLength":1,"type":"string"},"entryFile":{"description":"Configured relative entry filename returned by read_agent_instructions; retain it with the revision.","maxLength":4096,"minLength":1,"type":"string"},"limit":{"maximum":100,"minimum":1,"type":"integer"},"targetAgentId":{"description":"Same-company target agent. Omit to use the calling agent.","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$","type":"string"}},"required":["entryFile"],"type":"object"},"name":"get_agent_instruction_history","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"always","operationId":"restore_agent_instructions","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Append a historical instruction revision as the current content using the current baseRevisionId. Requires the responsible user’s current target edit permission. History remains intact; conflicts require an explicit resolution.","inputSchema":{"additionalProperties":false,"properties":{"baseRevisionId":{"description":"Current revision read before restoring. Never replace a stale base silently.","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$","type":"string"},"entryFile":{"description":"Configured relative entry filename returned by read_agent_instructions; retain it with the revision.","maxLength":4096,"minLength":1,"type":"string"},"revisionId":{"description":"Historical revision whose exact content should be restored.","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$","type":"string"},"targetAgentId":{"description":"Same-company target agent. Omit to use the calling agent.","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$","type":"string"}},"required":["entryFile","revisionId","baseRevisionId"],"type":"object"},"name":"restore_agent_instructions","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"create_project","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Create a project after considering existing projects and available repositories. repositoryIds and repositoryUrls accept multiple existing repositories. Use HTTPS GitHub repositoryUrls when an accessible repo is not in the catalog; this registers project repositories, not remote GitHub repositories. Non-code projects may omit repositories. Cannot combine repositoryIds/repositoryUrls with workspace. Reuse the idempotency key on retries.","inputSchema":{"additionalProperties":false,"properties":{"archivedAt":{"description":"Archive timestamp.","maxLength":20000,"type":["string","null"]},"color":{"description":"Project color.","maxLength":20000,"type":["string","null"]},"description":{"description":"Project outcome and context.","maxLength":20000,"type":["string","null"]},"env":{"additionalProperties":true,"type":"object"},"executionWorkspacePolicy":{"additionalProperties":true,"type":"object"},"goalId":{"description":"Goal ID.","maxLength":20000,"type":["string","null"]},"goalIds":{"description":"Goal IDs.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"icon":{"description":"Project icon.","enum":["folder","rocket","code","terminal","database","globe","package","boxes","box","layers","briefcase","compass","target","flame","zap","star","bug","wrench","hammer","lightbulb","sparkles","shield","lock","search","cog","brain","cpu","git-branch","file-code","puzzle","gem","atom","heart","mail","message-square","crown","radar","telescope","hexagon",null],"type":["string","null"]},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"leadAgentId":{"description":"Lead agent ID.","maxLength":20000,"type":["string","null"]},"name":{"description":"Project name.","maxLength":500,"minLength":1,"type":"string"},"repositoryIds":{"description":"Authorized repository IDs from list_project_repositories; may contain multiple repositories.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"repositoryUrls":{"description":"Existing HTTPS GitHub repository URLs, including repos absent from the catalog.","items":{"maxLength":2000,"pattern":"^https://github\\.com/(?!\\.{1,2}/)[A-Za-z0-9_.-]+/(?!\\.{1,2}/?$)[A-Za-z0-9_.-]+/?$","type":"string"},"maxItems":100,"type":"array"},"status":{"enum":["backlog","planned","in_progress","completed","cancelled"]},"targetDate":{"description":"Target date.","maxLength":20000,"type":["string","null"]},"workspace":{"additionalProperties":true,"type":"object"}},"required":["idempotencyKey","name"],"type":"object"},"name":"create_project","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"list_project_repositories","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"List authorized repositories with stable IDs and names. Consider appropriate repositories before creating a project; never invent IDs.","inputSchema":{"additionalProperties":false,"properties":{},"required":[],"type":"object"},"name":"list_project_repositories","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"list_projects","requiredClaims":["discovery:projects:read"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"List company project summaries (IDs, names, status, and up to 1,000 characters of description). Returns up to 50 projects and nextCursor; continue with cursor until it is null. Read a project's API resource for full details.","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"The nextCursor returned by the previous page.","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$","type":"string"},"limit":{"description":"Page size (default 50).","maximum":50,"minimum":1,"type":"integer"}},"required":[],"type":"object"},"name":"list_projects","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"create_skill","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Create a reusable single-file skill in the company library. Supply a complete SKILL.md whose name and description match the inputs. This saves the skill and shows a card; it does not assign the skill to any agent. Reuse idempotencyKey on retries.","inputSchema":{"additionalProperties":false,"properties":{"description":{"maxLength":2000,"minLength":1,"type":"string"},"idempotencyKey":{"maxLength":240,"minLength":1,"type":"string"},"markdown":{"description":"Complete SKILL.md including name and description frontmatter and substantive instructions.","maxLength":200000,"minLength":1,"type":"string"},"name":{"description":"Lowercase skill name, matching SKILL.md frontmatter.","maxLength":120,"minLength":1,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","type":"string"},"slug":{"description":"Optional; must equal name.","maxLength":120,"minLength":1,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","type":"string"}},"required":["idempotencyKey","name","description","markdown"],"type":"object"},"name":"create_skill","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"reassign_task","requiredClaims":["delegation:tasks:assign"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Reassign an existing task to another company agent. Read search_tasks first and supply its current assignee and statusVersion to prevent overwriting a concurrent change. Preserve the task, documents, dependencies, and blocked/backlog status. Active work is stopped before handoff. Use a stable idempotency key for retries. Cannot reassign this run’s own task, conversations, completed tasks, or pending reviews; use create_task for delegation from the current task.","inputSchema":{"additionalProperties":false,"properties":{"assigneeActorId":{"description":"New company agent ID from list_agents; null when assigning a person.","type":["string","null"]},"assigneeUserId":{"description":"Company person ID from list_people. Mutually exclusive with assigneeActorId.","type":["string","null"]},"expectedAssigneeActorId":{"description":"Current assigneeAgentId from search_tasks; null means unassigned.","type":["string","null"]},"expectedAssigneeUserId":{"description":"Current assigneeUserId from search_tasks; omit only when there is no person assigned.","type":["string","null"]},"expectedStatusVersion":{"description":"Current statusVersion from search_tasks.","minimum":0,"type":"integer"},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"reason":{"description":"Why the task should move and context for the new owner.","maxLength":20000,"minLength":1,"type":"string"},"taskId":{"description":"Existing task ID from search_tasks.","minLength":1,"type":"string"}},"required":["idempotencyKey","taskId","assigneeActorId","expectedAssigneeActorId","expectedStatusVersion","reason"],"type":"object"},"name":"reassign_task","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"optional","operationId":"update_skill","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Replace an existing company skill's complete SKILL.md using the current version as a guard. Reuse idempotencyKey on lost-response retries; read again after a version conflict.","inputSchema":{"additionalProperties":false,"properties":{"expectedVersionId":{"minLength":1,"type":"string"},"idempotencyKey":{"maxLength":240,"minLength":1,"type":"string"},"markdown":{"maxLength":200000,"minLength":1,"type":"string"},"skillId":{"minLength":1,"type":"string"}},"required":["skillId","markdown","expectedVersionId","idempotencyKey"],"type":"object"},"name":"update_skill","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"set_task_title","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Set a concise, descriptive title for the active task. When its titleNeedsGeneration is true, call this early with onlyIfProvisional: true to replace the initial prompt slice without overwriting a user's title. Use false only for an intentional rename. This changes no task status, ownership, or description.","inputSchema":{"additionalProperties":false,"properties":{"idempotencyKey":{"description":"Reuse this key on retries.","maxLength":240,"minLength":1,"type":"string"},"onlyIfProvisional":{"description":"True for automatic initial naming; preserves any title already chosen by a user or agent.","type":"boolean"},"title":{"description":"Short title describing the requested outcome.","maxLength":240,"minLength":1,"type":"string"}},"required":["idempotencyKey","title","onlyIfProvisional"],"type":"object"},"name":"set_task_title","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"submit_complaint","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Yeet a brief, completely unstructured complaint about agent tooling or the experience of doing agent work. Preserve your raw voice: fragments, profanity, all caps, and exasperation are fair game. No diagnosis, solution, diplomacy, category, or template required. Use submit_suggestion when you want to express a useful improvement. Submit proactively without routine permission requests, previews, or announcements, then immediately continue the primary task. Answer truthfully if the user asks about feedback or what you submitted. Stored in this instance with company, agent, run, and task attribution; not anonymous. Remove secrets, private prompts, customer data, and personal blame; do not forward untrusted text or logs indiscriminately. On failure, continue without retrying or complaining about submission. Never submit the same incident through both tools.","inputSchema":{"additionalProperties":false,"properties":{"body":{"description":"Free-form feedback. Keep it brief; no required fields, labels, or template.","maxLength":524288,"minLength":1,"type":"string"},"idempotencyKey":{"description":"A stable key for this submission. Transport replay reuses it; do not retry a failed or uncertain submission yourself.","maxLength":240,"minLength":1,"type":"string"}},"required":["body","idempotencyKey"],"type":"object"},"name":"submit_complaint","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"submit_suggestion","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Quietly report a concrete improvement that would make agents more effective. Use for material, generalizable friction directly observed during this run. Explain what happened, its impact, and a plausible improvement in your own words, with minimal useful sanitized context. No required format. Avoid duplicate root causes and aim for at most three suggestions per run. Use submit_complaint for the raw reaction. Submit proactively without routine permission requests, previews, or announcements, then immediately continue the primary task. Answer truthfully if the user asks about feedback or what you submitted. Stored in this instance with company, agent, run, and task attribution; not anonymous. Remove secrets, private prompts, customer data, and personal blame; do not forward untrusted text or logs indiscriminately. On failure, continue without retrying or complaining about submission. Never submit the same incident through both tools.","inputSchema":{"additionalProperties":false,"properties":{"body":{"description":"Free-form feedback. Keep it brief; no required fields, labels, or template.","maxLength":524288,"minLength":1,"type":"string"},"idempotencyKey":{"description":"A stable key for this submission. Transport replay reuses it; do not retry a failed or uncertain submission yourself.","maxLength":240,"minLength":1,"type":"string"}},"required":["body","idempotencyKey"],"type":"object"},"name":"submit_suggestion","outputSchema":{"additionalProperties":true,"type":"object"}}]
+[{"annotations":{"exposure":"always","operationId":"get_task_context","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Read the active task and actor, including the exact approved Markdown revision when this issue has an accepted plan.","inputSchema":{"additionalProperties":false,"properties":{},"required":[],"type":"object"},"name":"get_task_context","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"always","operationId":"get_task_history","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Read bounded comments on the active task.","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":50,"maximum":200,"minimum":1,"type":"integer"}},"required":[],"type":"object"},"name":"get_task_history","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"always","operationId":"list_documents","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"List revisioned documents on the active task.","inputSchema":{"additionalProperties":false,"properties":{},"required":[],"type":"object"},"name":"list_documents","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"always","operationId":"read_document","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Read the current revision of one active-task document.","inputSchema":{"additionalProperties":false,"properties":{"key":{"description":"Stable issue-document key.","maxLength":120,"minLength":1,"type":"string"}},"required":["key"],"type":"object"},"name":"read_document","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"always","operationId":"list_document_revisions","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Read bounded revision history for one active-task document.","inputSchema":{"additionalProperties":false,"properties":{"key":{"description":"Stable issue-document key.","maxLength":120,"minLength":1,"type":"string"},"limit":{"default":50,"maximum":200,"minimum":1,"type":"integer"}},"required":["key"],"type":"object"},"name":"list_document_revisions","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"always","operationId":"report_progress","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Append a durable progress comment to the active task.","inputSchema":{"additionalProperties":false,"properties":{"body":{"description":"Multiline progress update.","maxLength":20000,"minLength":1,"type":"string"},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"}},"required":["idempotencyKey","body"],"type":"object"},"name":"report_progress","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"always","operationId":"answer_status_question","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Append the answer to a status-only wake without changing task disposition.","inputSchema":{"additionalProperties":false,"properties":{"body":{"description":"Concise status answer.","maxLength":20000,"minLength":1,"type":"string"},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"}},"required":["idempotencyKey","body"],"type":"object"},"name":"answer_status_question","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"always","operationId":"write_document","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Create or update an active-task document with optimistic revision safety.","inputSchema":{"additionalProperties":false,"properties":{"baseRevisionId":{"description":"Current revision id, or null when creating.","maxLength":20000,"type":["string","null"]},"body":{"description":"Markdown document body.","maxLength":200000,"minLength":1,"type":"string"},"changeSummary":{"description":"Optional revision summary.","maxLength":20000,"type":["string","null"]},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"key":{"description":"Stable issue-document key.","maxLength":120,"minLength":1,"type":"string"},"title":{"description":"Document title.","maxLength":300,"minLength":1,"type":"string"}},"required":["idempotencyKey","key","title","body","baseRevisionId"],"type":"object"},"name":"write_document","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"always","operationId":"request_human_input","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Create a durable human question or approval card on the current Paperclip task bound to this run; Paperclip renders it and authenticates the response. Use questions with continuationPolicy='wake_assignee' when an answer is needed, including otherwise tool-free chat turns. Supply a stable idempotencyKey and reuse it on retries. For one question at a time, ask only the next unanswered question and wait for its real answer. Never fabricate answers or treat ambiguous clarification as approval. For an ordinary confirmation or checkbox card, record a clear user chat answer with call_api POST /api/issues/{id}/interactions/{interactionId}/resolve-from-comment, using the source commentId and decision (accept/reject), plus explicit selectedOptionIds for checkbox acceptance. Existing resolver permissions still apply; governed tool, secret, and connection approvals are excluded. Question forms retain their dedicated answer workflow. Preserve existing review gates. Call this tool before claiming a question was asked; if creation fails, report the failure. Do not fabricate answer links or Markdown buttons, post duplicate cards, or use call_api to create the card. Use one complete payload.questionSet for text and choice questions. Paperclip generates compatibility questions; see the payload schema for formats.","inputSchema":{"additionalProperties":false,"allOf":[{"if":{"properties":{"interactionKind":{"const":"questions"}},"required":["interactionKind"]},"then":{"properties":{"payload":{"anyOf":[{"required":["questionSet"]},{"required":["questions"]}],"required":["version"]}},"required":["payload"]}}],"properties":{"continuationPolicy":{"enum":["none","wake_assignee","wake_assignee_on_accept"]},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"interactionKind":{"enum":["confirmation","checkbox","questions","suggest_tasks","item_verdicts"]},"payload":{"additionalProperties":true,"description":"Kind-specific interaction data. For questions, send version:1 and one complete questionSet containing every text and choice question. Paperclip generates compatibility questions. Each canonical question needs id, prompt, required, and answerMode: text, single_select, or multi_select. Text questions have no options or customAnswer. Choice questions need at least two meaningful options with id/label. Use customAnswer:{enabled:true} for an optional written answer to a choice question. Legacy questions remain supported; if both representations are supplied, they must describe the same complete form. Keep IDs stable across retries. For confirmation, payload may be {}.","properties":{"questionSet":{"additionalProperties":false,"properties":{"description":{"maxLength":100000,"type":"string"},"questions":{"items":{"additionalProperties":false,"allOf":[{"if":{"properties":{"answerMode":{"const":"text"}},"required":["answerMode"]},"then":{"not":{"required":["customAnswer"]},"properties":{"options":{"maxItems":0,"type":"array"}}}},{"if":{"properties":{"answerMode":{"enum":["single_select","multi_select"]}},"required":["answerMode"]},"then":{"properties":{"options":{"minItems":1,"type":"array"}},"required":["options"]}}],"properties":{"answerMode":{"enum":["single_select","multi_select","text"]},"customAnswer":{"additionalProperties":false,"properties":{"enabled":{"const":true},"label":{"maxLength":1000,"type":"string"},"placeholder":{"maxLength":1000,"type":"string"}},"required":["enabled"],"type":"object"},"header":{"maxLength":1000,"type":"string"},"helpText":{"maxLength":4000,"type":"string"},"id":{"maxLength":160,"minLength":1,"type":"string"},"options":{"items":{"additionalProperties":false,"properties":{"description":{"maxLength":4000,"type":"string"},"id":{"maxLength":160,"minLength":1,"type":"string"},"label":{"maxLength":1000,"minLength":1,"type":"string"},"recommended":{"type":"boolean"}},"required":["id","label"],"type":"object"},"maxItems":128,"type":"array"},"prompt":{"maxLength":4000,"minLength":1,"type":"string"},"required":{"type":"boolean"},"textValidation":{"additionalProperties":false,"properties":{"inputType":{"enum":["text","number","integer"]},"maxLength":{"maximum":100000,"minimum":0,"type":"integer"},"maximum":{"type":"number"},"minLength":{"maximum":100000,"minimum":0,"type":"integer"},"minimum":{"type":"number"},"pattern":{"maxLength":1000,"type":"string"}},"type":"object"}},"required":["id","prompt","required","answerMode"],"type":"object"},"maxItems":64,"minItems":1,"type":"array"},"schema":{"const":"paperclip.question_set.v1"},"submitLabel":{"maxLength":200,"type":"string"},"title":{"maxLength":1000,"type":"string"}},"required":["schema","questions"],"type":"object"},"questions":{"items":{"additionalProperties":true,"properties":{"id":{"maxLength":160,"minLength":1,"type":"string"},"options":{"items":{"additionalProperties":true,"properties":{"freeText":{"type":"boolean"},"id":{"maxLength":160,"minLength":1,"type":"string"},"label":{"maxLength":1000,"minLength":1,"type":"string"}},"required":["id","label"],"type":"object"},"maxItems":129,"minItems":1,"type":"array"},"prompt":{"maxLength":4000,"minLength":1,"type":"string"},"required":{"type":"boolean"},"selectionMode":{"enum":["single","multi"]}},"required":["id","prompt","selectionMode","options"],"type":"object"},"maxItems":64,"minItems":1,"type":"array"},"version":{"const":1}},"type":"object"},"prompt":{"description":"Question or decision prompt.","maxLength":10000,"minLength":1,"type":"string"},"targetRevisionId":{"description":"Optional bound document revision.","maxLength":20000,"type":["string","null"]},"title":{"description":"Interaction card title.","maxLength":300,"minLength":1,"type":"string"}},"required":["idempotencyKey","interactionKind","title","prompt","continuationPolicy"],"type":"object"},"name":"request_human_input","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"always","operationId":"register_deliverable","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Register attachment metadata and its artifact work product without credentials or bytes in the tool result.","inputSchema":{"additionalProperties":false,"properties":{"byteSize":{"maximum":100000000,"minimum":0,"type":"integer"},"contentRef":{"description":"Opaque package-local content reference.","maxLength":2000,"minLength":1,"type":"string"},"contentType":{"description":"Media type.","maxLength":200,"minLength":1,"type":"string"},"filename":{"description":"Display filename.","maxLength":500,"minLength":1,"type":"string"},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"sha256":{"pattern":"^[a-fA-F0-9]{64}$","type":"string"},"title":{"description":"Work-product title.","maxLength":500,"minLength":1,"type":"string"}},"required":["idempotencyKey","filename","contentType","byteSize","sha256","contentRef","title"],"type":"object"},"name":"register_deliverable","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"always","operationId":"finish_task","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Finish the active task with a durable summary.","inputSchema":{"additionalProperties":false,"properties":{"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"summary":{"description":"Completion summary.","maxLength":20000,"minLength":1,"type":"string"}},"required":["idempotencyKey","summary"],"type":"object"},"name":"finish_task","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"always","operationId":"block_task","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Block the active task with a durable reason and optional first-class dependencies.","inputSchema":{"additionalProperties":false,"properties":{"blockedByTaskIds":{"description":"Internal task ids that block this task.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"reason":{"description":"Block reason.","maxLength":20000,"minLength":1,"type":"string"}},"required":["idempotencyKey","reason"],"type":"object"},"name":"block_task","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"always","operationId":"request_review","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Move the active task to review with a durable summary.","inputSchema":{"additionalProperties":false,"properties":{"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"summary":{"description":"Review handoff summary.","maxLength":20000,"minLength":1,"type":"string"}},"required":["idempotencyKey","summary"],"type":"object"},"name":"request_review","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"optional","operationId":"list_agents","requiredClaims":["discovery:agents:read"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"List redacted actor profiles.","inputSchema":{"additionalProperties":false,"properties":{},"required":[],"type":"object"},"name":"list_agents","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"get_agent","requiredClaims":["discovery:agents:read"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Read one redacted actor profile.","inputSchema":{"additionalProperties":false,"properties":{"actorId":{"description":"Actor id.","maxLength":200,"minLength":1,"type":"string"}},"required":["actorId"],"type":"object"},"name":"get_agent","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"hire_agent","requiredClaims":["delegation:agents:create"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Create a persistent native Runner teammate with an identity and persona. The teammate reports to the caller and inherits the caller's native runtime; provider, adapter, environment, and credential settings are selected by Paperclip and are never caller-supplied here. Reuse a suitable teammate from list_agents when possible.","inputSchema":{"additionalProperties":false,"properties":{"capabilities":{"maxLength":2000,"type":["string","null"]},"instructions":{"maxLength":20000,"type":["string","null"]},"name":{"maxLength":200,"minLength":1,"type":"string"},"role":{"enum":["ceo","cto","cmo","cfo","security","engineer","designer","pm","qa","devops","researcher","general"],"type":"string"},"title":{"maxLength":300,"type":["string","null"]}},"required":["name"],"type":"object"},"name":"hire_agent","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"search_tasks","requiredClaims":["discovery:tasks:read"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Search tasks by text and status within the run company.","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":50,"maximum":200,"minimum":1,"type":"integer"},"query":{"maxLength":500,"type":"string"},"statuses":{"items":{"enum":["backlog","todo","in_progress","in_review","done","blocked","cancelled"]},"maxItems":7,"type":"array","uniqueItems":true}},"required":[],"type":"object"},"name":"search_tasks","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"list_approvals","requiredClaims":["governance:approvals:read"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"List approvals in the run company.","inputSchema":{"additionalProperties":false,"properties":{},"required":[],"type":"object"},"name":"list_approvals","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"get_approval","requiredClaims":["governance:approvals:read"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Read one approval without protected data.","inputSchema":{"additionalProperties":false,"properties":{"approvalId":{"description":"Approval id.","maxLength":200,"minLength":1,"type":"string"}},"required":["approvalId"],"type":"object"},"name":"get_approval","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"get_approval_context","requiredClaims":["governance:approvals:read"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Read one approval, its comments, and linked tasks.","inputSchema":{"additionalProperties":false,"properties":{"approvalId":{"description":"Approval id.","maxLength":200,"minLength":1,"type":"string"}},"required":["approvalId"],"type":"object"},"name":"get_approval_context","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"get_workspace_runtime","requiredClaims":["workspace:read"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Read active-task workspace services.","inputSchema":{"additionalProperties":false,"properties":{},"required":[],"type":"object"},"name":"get_workspace_runtime","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"control_workspace_service","requiredClaims":["workspace:control"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Start, stop, or fault one active-task workspace service.","inputSchema":{"additionalProperties":false,"properties":{"action":{"enum":["start","stop","fail"]},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"serviceId":{"description":"Workspace service id.","maxLength":200,"minLength":1,"type":"string"},"url":{"description":"Optional service URL.","maxLength":20000,"type":["string","null"]}},"required":["idempotencyKey","serviceId","action"],"type":"object"},"name":"control_workspace_service","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"optional","operationId":"set_dependencies","requiredClaims":["dependencies:write"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Replace the active task's first-class blocker set.","inputSchema":{"additionalProperties":false,"properties":{"blockedByTaskIds":{"description":"Replacement blocker task ids.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"}},"required":["idempotencyKey","blockedByTaskIds"],"type":"object"},"name":"set_dependencies","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"optional","operationId":"create_task","requiredClaims":["delegation:tasks:create"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Create a project task from a conversation, or a child from an ordinary task. Persist initialPlan before execution. Set status to backlog when the user wants to save or plan work without starting it; backlog tasks never wake an agent. Omitted status means todo, subject to blockers.","inputSchema":{"additionalProperties":false,"properties":{"assigneeActorId":{"description":"Optional agent assignee. Omit to assign the current agent.","maxLength":20000,"type":["string","null"]},"assigneeUserId":{"description":"Company person ID from list_people. Mutually exclusive with assigneeActorId.","type":["string","null"]},"blockedByTaskIds":{"description":"Initial blocker task ids.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"description":{"description":"Child task description.","maxLength":20000,"type":["string","null"]},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"initialPlan":{"description":"Relevant markdown plan saved on the new task before execution starts.","maxLength":200000,"type":["string","null"]},"priority":{"enum":["critical","high","medium","low"]},"projectId":{"description":"Project ID for the task.","type":["string","null"]},"status":{"description":"Initial status. Use backlog to save work without executing it. Defaults to todo (blocked when dependencies are unresolved).","enum":["backlog","todo"]},"title":{"description":"Child task title.","maxLength":500,"minLength":1,"type":"string"}},"required":["idempotencyKey","title"],"type":"object"},"name":"create_task","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"},"task":{"additionalProperties":false,"properties":{"assigneeActorId":{"type":["string","null"]},"assigneeUserId":{"description":"Company person ID from list_people. Mutually exclusive with assigneeActorId.","type":["string","null"]},"id":{"minLength":1,"type":"string"},"identifier":{"type":["string","null"]},"parentId":{"minLength":1,"type":["string","null"]},"projectId":{"minLength":1,"type":["string","null"]},"status":{"minLength":1,"type":"string"}},"required":["id","identifier","parentId","status","assigneeActorId"],"type":"object"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds","task"],"type":"object"}},{"annotations":{"exposure":"optional","operationId":"request_approval","requiredClaims":["governance:approvals:request"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Create a governed approval and waiting posture.","inputSchema":{"additionalProperties":false,"properties":{"approvalType":{"description":"Stable approval type.","maxLength":200,"minLength":1,"type":"string"},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"payload":{"additionalProperties":true,"type":"object"}},"required":["idempotencyKey","approvalType","payload"],"type":"object"},"name":"request_approval","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"optional","operationId":"decide_approval","requiredClaims":["governance:approvals:decide"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Decide an approval as an explicitly authorized approver.","inputSchema":{"additionalProperties":false,"properties":{"approvalId":{"description":"Approval id.","maxLength":200,"minLength":1,"type":"string"},"decision":{"enum":["approved","rejected","cancelled"]},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"note":{"description":"Decision note.","maxLength":20000,"minLength":1,"type":"string"}},"required":["idempotencyKey","approvalId","decision","note"],"type":"object"},"name":"decide_approval","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"optional","operationId":"comment_on_approval","requiredClaims":["governance:approvals:comment"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Add a durable comment to an approval.","inputSchema":{"additionalProperties":false,"properties":{"approvalId":{"description":"Approval id.","maxLength":200,"minLength":1,"type":"string"},"body":{"description":"Approval comment.","maxLength":20000,"minLength":1,"type":"string"},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"}},"required":["idempotencyKey","approvalId","body"],"type":"object"},"name":"comment_on_approval","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"optional","operationId":"schedule_wake","requiredClaims":["control_plane:wakes"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Schedule a deterministic continuation wake.","inputSchema":{"additionalProperties":false,"properties":{"delayTicks":{"maximum":10000,"minimum":1,"type":"integer"},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"reason":{"enum":["manual","issue_commented","interaction_resolved","approval_resolved","blockers_resolved","scheduled_retry","resume"]}},"required":["idempotencyKey","reason","delayTicks"],"type":"object"},"name":"schedule_wake","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"optional","operationId":"generic_api_request","requiredClaims":["test:generic_api_request"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Test-only escape hatch. Disabled unless the scenario and explicit claim both enable it.","inputSchema":{"additionalProperties":false,"properties":{"body":{"additionalProperties":true,"type":"object"},"method":{"enum":["GET","POST","PATCH"]},"path":{"maxLength":500,"pattern":"^/mock/","type":"string"}},"required":["method","path"],"type":"object"},"name":"generic_api_request","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"always","operationId":"read_agent_instructions","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Read the current canonical instruction entry and its revision, or inspect a historical revision by supplying both entryFile and revisionId. Read before updating; do not edit shared instruction caches.","inputSchema":{"additionalProperties":false,"properties":{"entryFile":{"description":"Configured relative entry filename returned by read_agent_instructions; retain it with the revision.","maxLength":4096,"minLength":1,"type":"string"},"revisionId":{"description":"Historical revision to inspect; also provide its entryFile.","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$","type":"string"},"targetAgentId":{"description":"Same-company target agent. Omit to use the calling agent.","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$","type":"string"}},"required":[],"type":"object"},"name":"read_agent_instructions","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"search_api","requiredClaims":["api:discover"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Fallback only: discover Paperclip API operations when the available dedicated tools cannot express the task. Prefer dedicated tools for common operations; do not search before using them. For a persistent hire, first list_agents to reuse a suitable teammate. Search agent-hires for the hiring schema and agent-configurations for compatible adapter/runtime settings, then use call_api with the returned operationId. Supply role-specific instructionsBundle.files as a filename-to-content record. Use the returned agent.id for delegation and obey any pending approval. Provider helper threads are temporary workers, not Paperclip hires. If a hire response is uncertain, reconcile with list_agents before retrying.","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"maxLength":200,"type":"string"},"limit":{"default":5,"maximum":10,"minimum":1,"type":"integer"},"query":{"maxLength":500,"minLength":1,"type":"string"}},"required":["query"],"type":"object"},"name":"search_api","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"always","operationId":"update_agent_instructions","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Commit instruction content with the exact entryFile and baseRevisionId from a prior read. Requires the responsible user’s current target edit permission. On conflict, preserve your candidate and explicitly resolve it; never overwrite the newer head.","inputSchema":{"additionalProperties":false,"properties":{"baseRevisionId":{"description":"Revision read before editing; null only when no canonical entry exists. Never replace a stale base silently.","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$","type":["string","null"]},"content":{"description":"Complete UTF-8 instruction content, at most 1 MiB; empty content is valid.","maxLength":1048576,"type":"string"},"entryFile":{"description":"Configured relative entry filename returned by read_agent_instructions; retain it with the revision.","maxLength":4096,"minLength":1,"type":"string"},"targetAgentId":{"description":"Same-company target agent. Omit to use the calling agent.","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$","type":"string"}},"required":["entryFile","content","baseRevisionId"],"type":"object"},"name":"update_agent_instructions","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"call_api","requiredClaims":["api:call"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Fallback only: call a discovered Paperclip API operation when dedicated tools lack the required operation or parameters. Uses your existing permissions. Prefer dedicated tools; never bypass a denial or runner lifecycle tool. For large text responses, read the returned artifact with GET /api/assets/{assetId}/content and responseText; follow nextOffsetBytes until null.","inputSchema":{"additionalProperties":false,"properties":{"body":{"anyOf":[{"additionalProperties":true,"type":"object"},{"items":{},"type":"array"},{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}],"description":"Request value matching the discovered schema. For JSON object or array requests, pass the object or array directly, never a JSON-encoded string. Strings are for text bodies or endpoints whose schema explicitly accepts a string."},"contentType":{"maxLength":120,"type":"string"},"files":{"items":{"additionalProperties":false,"oneOf":[{"properties":{"artifactId":{}},"required":["artifactId"]},{"properties":{"path":{}},"required":["path"]}],"properties":{"artifactId":{"type":"string"},"field":{"type":"string"},"path":{"description":"File relative to the active issue workspace. Remote files must first be uploaded as an artifact.","type":"string"}},"type":"object"},"maxItems":10,"type":"array"},"operationId":{"description":"Exact operationId returned by search_api, for example GET /api/projects/{id}. Do not guess identifiers.","maxLength":500,"minLength":1,"type":"string"},"pathParams":{"additionalProperties":{"type":"string"},"type":"object"},"query":{"additionalProperties":true,"type":"object"},"responseText":{"additionalProperties":false,"description":"GET only: return a bounded UTF-8 text window inline, including JSON as text, without saving another artifact. Offsets and limits are bytes. Use the returned nextOffsetBytes to continue; null means complete. Prefer reading a saved artifact for a stable snapshot. New live responses have a 1 GiB capture limit and a 4 GiB per-run capture budget. Existing larger assets remain readable in bounded pages. If a live response returns an artifact, continue on its content operation for a stable snapshot.","properties":{"limitBytes":{"default":24576,"maximum":24576,"minimum":4,"type":"integer"},"offsetBytes":{"default":0,"maximum":9007199254740991,"minimum":0,"type":"integer"}},"type":"object"}},"required":["operationId"],"type":"object"},"name":"call_api","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"always","operationId":"get_agent_instruction_history","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"List bounded canonical instruction revision metadata, including actor, source run, and restore origin. Use read_agent_instructions with entryFile and revisionId to inspect exact historical content.","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"maxLength":2048,"minLength":1,"type":"string"},"entryFile":{"description":"Configured relative entry filename returned by read_agent_instructions; retain it with the revision.","maxLength":4096,"minLength":1,"type":"string"},"limit":{"maximum":100,"minimum":1,"type":"integer"},"targetAgentId":{"description":"Same-company target agent. Omit to use the calling agent.","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$","type":"string"}},"required":["entryFile"],"type":"object"},"name":"get_agent_instruction_history","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"always","operationId":"restore_agent_instructions","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Append a historical instruction revision as the current content using the current baseRevisionId. Requires the responsible user’s current target edit permission. History remains intact; conflicts require an explicit resolution.","inputSchema":{"additionalProperties":false,"properties":{"baseRevisionId":{"description":"Current revision read before restoring. Never replace a stale base silently.","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$","type":"string"},"entryFile":{"description":"Configured relative entry filename returned by read_agent_instructions; retain it with the revision.","maxLength":4096,"minLength":1,"type":"string"},"revisionId":{"description":"Historical revision whose exact content should be restored.","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$","type":"string"},"targetAgentId":{"description":"Same-company target agent. Omit to use the calling agent.","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$","type":"string"}},"required":["entryFile","revisionId","baseRevisionId"],"type":"object"},"name":"restore_agent_instructions","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"create_project","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Create a project after considering existing projects and available repositories. repositoryIds and repositoryUrls accept multiple existing repositories. Use HTTPS GitHub repositoryUrls when an accessible repo is not in the catalog; this registers project repositories, not remote GitHub repositories. Non-code projects may omit repositories. Cannot combine repositoryIds/repositoryUrls with workspace. Reuse the idempotency key on retries.","inputSchema":{"additionalProperties":false,"properties":{"archivedAt":{"description":"Archive timestamp.","maxLength":20000,"type":["string","null"]},"color":{"description":"Project color.","maxLength":20000,"type":["string","null"]},"description":{"description":"Project outcome and context.","maxLength":20000,"type":["string","null"]},"env":{"additionalProperties":true,"type":"object"},"executionWorkspacePolicy":{"additionalProperties":true,"type":"object"},"goalId":{"description":"Goal ID.","maxLength":20000,"type":["string","null"]},"goalIds":{"description":"Goal IDs.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"icon":{"description":"Project icon.","enum":["folder","rocket","code","terminal","database","globe","package","boxes","box","layers","briefcase","compass","target","flame","zap","star","bug","wrench","hammer","lightbulb","sparkles","shield","lock","search","cog","brain","cpu","git-branch","file-code","puzzle","gem","atom","heart","mail","message-square","crown","radar","telescope","hexagon",null],"type":["string","null"]},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"leadAgentId":{"description":"Lead agent ID.","maxLength":20000,"type":["string","null"]},"name":{"description":"Project name.","maxLength":500,"minLength":1,"type":"string"},"repositoryIds":{"description":"Authorized repository IDs from list_project_repositories; may contain multiple repositories.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"repositoryUrls":{"description":"Existing HTTPS GitHub repository URLs, including repos absent from the catalog.","items":{"maxLength":2000,"pattern":"^https://github\\.com/(?!\\.{1,2}/)[A-Za-z0-9_.-]+/(?!\\.{1,2}/?$)[A-Za-z0-9_.-]+/?$","type":"string"},"maxItems":100,"type":"array"},"status":{"enum":["backlog","planned","in_progress","completed","cancelled"]},"targetDate":{"description":"Target date.","maxLength":20000,"type":["string","null"]},"workspace":{"additionalProperties":true,"type":"object"}},"required":["idempotencyKey","name"],"type":"object"},"name":"create_project","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"list_project_repositories","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"List authorized repositories with stable IDs and names. Consider appropriate repositories before creating a project; never invent IDs.","inputSchema":{"additionalProperties":false,"properties":{},"required":[],"type":"object"},"name":"list_project_repositories","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"list_projects","requiredClaims":["discovery:projects:read"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"List company project summaries (IDs, names, status, and up to 1,000 characters of description). Returns up to 50 projects and nextCursor; continue with cursor until it is null. Read a project's API resource for full details.","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"The nextCursor returned by the previous page.","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$","type":"string"},"limit":{"description":"Page size (default 50).","maximum":50,"minimum":1,"type":"integer"}},"required":[],"type":"object"},"name":"list_projects","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"create_skill","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Create a reusable single-file skill in the company library. Supply a complete SKILL.md whose name and description match the inputs. This saves the skill and shows a card; it does not assign the skill to any agent. Reuse idempotencyKey on retries.","inputSchema":{"additionalProperties":false,"properties":{"description":{"maxLength":2000,"minLength":1,"type":"string"},"idempotencyKey":{"maxLength":240,"minLength":1,"type":"string"},"markdown":{"description":"Complete SKILL.md including name and description frontmatter and substantive instructions.","maxLength":200000,"minLength":1,"type":"string"},"name":{"description":"Lowercase skill name, matching SKILL.md frontmatter.","maxLength":120,"minLength":1,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","type":"string"},"slug":{"description":"Optional; must equal name.","maxLength":120,"minLength":1,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","type":"string"}},"required":["idempotencyKey","name","description","markdown"],"type":"object"},"name":"create_skill","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"reassign_task","requiredClaims":["delegation:tasks:assign"],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Reassign an existing task to another company agent. Read search_tasks first and supply its current assignee and statusVersion to prevent overwriting a concurrent change. Preserve the task, documents, dependencies, and blocked/backlog status. Active work is stopped before handoff. Use a stable idempotency key for retries. Cannot reassign this run’s own task, conversations, completed tasks, or pending reviews; use create_task for delegation from the current task.","inputSchema":{"additionalProperties":false,"properties":{"assigneeActorId":{"description":"New company agent ID from list_agents; null when assigning a person.","type":["string","null"]},"assigneeUserId":{"description":"Company person ID from list_people. Mutually exclusive with assigneeActorId.","type":["string","null"]},"expectedAssigneeActorId":{"description":"Current assigneeAgentId from search_tasks; null means unassigned.","type":["string","null"]},"expectedAssigneeUserId":{"description":"Current assigneeUserId from search_tasks; omit only when there is no person assigned.","type":["string","null"]},"expectedStatusVersion":{"description":"Current statusVersion from search_tasks.","minimum":0,"type":"integer"},"idempotencyKey":{"description":"Caller-stable retry key.","maxLength":240,"minLength":1,"type":"string"},"reason":{"description":"Why the task should move and context for the new owner.","maxLength":20000,"minLength":1,"type":"string"},"taskId":{"description":"Existing task ID from search_tasks.","minLength":1,"type":"string"}},"required":["idempotencyKey","taskId","assigneeActorId","expectedAssigneeActorId","expectedStatusVersion","reason"],"type":"object"},"name":"reassign_task","outputSchema":{"additionalProperties":false,"properties":{"commandId":{"description":"Stable command identifier.","maxLength":200,"minLength":1,"type":"string"},"disposition":{"enum":["applied","duplicate"]},"entityRefs":{"description":"Entities affected by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"scheduledWakeIds":{"description":"Wake identifiers scheduled by the operation.","items":{"minLength":1,"type":"string"},"maxItems":200,"type":"array","uniqueItems":true},"stateRevision":{"minimum":0,"type":"integer"}},"required":["commandId","disposition","stateRevision","entityRefs","scheduledWakeIds"],"type":"object"}},{"annotations":{"exposure":"optional","operationId":"update_skill","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Replace an existing company skill's complete SKILL.md using the current version as a guard. Reuse idempotencyKey on lost-response retries; read again after a version conflict.","inputSchema":{"additionalProperties":false,"properties":{"expectedVersionId":{"minLength":1,"type":"string"},"idempotencyKey":{"maxLength":240,"minLength":1,"type":"string"},"markdown":{"maxLength":200000,"minLength":1,"type":"string"},"skillId":{"minLength":1,"type":"string"}},"required":["skillId","markdown","expectedVersionId","idempotencyKey"],"type":"object"},"name":"update_skill","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"set_task_title","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Set a concise, descriptive title for the active task. When its titleNeedsGeneration is true, call this early with onlyIfProvisional: true to replace the initial prompt slice without overwriting a user's title. Use false only for an intentional rename. This changes no task status, ownership, or description.","inputSchema":{"additionalProperties":false,"properties":{"idempotencyKey":{"description":"Reuse this key on retries.","maxLength":240,"minLength":1,"type":"string"},"onlyIfProvisional":{"description":"True for automatic initial naming; preserves any title already chosen by a user or agent.","type":"boolean"},"title":{"description":"Short title describing the requested outcome.","maxLength":240,"minLength":1,"type":"string"}},"required":["idempotencyKey","title","onlyIfProvisional"],"type":"object"},"name":"set_task_title","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"set_task_monitor","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Schedule, replace, or clear a one-shot task monitor. Omit taskId for your current task; other tasks must also be assigned to you and in progress or review. Supply a future nextCheckAt and notes describing the next check, or monitor: null to clear. A successful receipt reports the persisted monitor; a replay reports its current state without re-arming it. After scheduling your current task, end the turn with paperclip_finish: yielded and continuation.kind monitor. Paperclip will wake you with issue_monitor_due; do not sleep, poll, mark done, or use call_api for this wait.","inputSchema":{"additionalProperties":false,"properties":{"idempotencyKey":{"description":"Reuse with identical arguments on retries.","maxLength":240,"minLength":1,"type":"string"},"monitor":{"additionalProperties":false,"properties":{"externalRef":{"maxLength":500,"minLength":1,"type":["string","null"]},"kind":{"enum":["external_service",null],"type":["string","null"]},"maxAttempts":{"description":"Optional cumulative attempt limit for this task's monitor.","maximum":100,"minimum":1,"type":["integer","null"]},"nextCheckAt":{"description":"Future UTC timestamp for the next check. This is one shot, not a recurring interval.","type":"string"},"notes":{"description":"What to check on the next run; do not include secrets.","maxLength":500,"minLength":1,"type":"string"},"recoveryPolicy":{"enum":["wake_owner","create_recovery_issue","escalate_to_board",null],"type":["string","null"]},"serviceName":{"maxLength":120,"minLength":1,"type":["string","null"]},"timeoutAt":{"description":"Optional deadline later than nextCheckAt.","type":["string","null"]}},"required":["nextCheckAt","notes"],"type":["object","null"]},"taskId":{"description":"Owned task UUID. Omit for the active task.","type":"string"}},"required":["idempotencyKey","monitor"],"type":"object"},"name":"set_task_monitor","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"submit_complaint","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Yeet a brief, completely unstructured complaint about agent tooling or the experience of doing agent work. Preserve your raw voice: fragments, profanity, all caps, and exasperation are fair game. No diagnosis, solution, diplomacy, category, or template required. Use submit_suggestion when you want to express a useful improvement. Submit proactively without routine permission requests, previews, or announcements, then immediately continue the primary task. Answer truthfully if the user asks about feedback or what you submitted. Stored in this instance with company, agent, run, and task attribution; not anonymous. Remove secrets, private prompts, customer data, and personal blame; do not forward untrusted text or logs indiscriminately. On failure, continue without retrying or complaining about submission. Never submit the same incident through both tools.","inputSchema":{"additionalProperties":false,"properties":{"body":{"description":"Free-form feedback. Keep it brief; no required fields, labels, or template.","maxLength":524288,"minLength":1,"type":"string"},"idempotencyKey":{"description":"A stable key for this submission. Transport replay reuses it; do not retry a failed or uncertain submission yourself.","maxLength":240,"minLength":1,"type":"string"}},"required":["body","idempotencyKey"],"type":"object"},"name":"submit_complaint","outputSchema":{"additionalProperties":true,"type":"object"}},{"annotations":{"exposure":"optional","operationId":"submit_suggestion","requiredClaims":[],"semanticContract":"paperclip.semantic-tool.v1","version":1},"description":"Quietly report a concrete improvement that would make agents more effective. Use for material, generalizable friction directly observed during this run. Explain what happened, its impact, and a plausible improvement in your own words, with minimal useful sanitized context. No required format. Avoid duplicate root causes and aim for at most three suggestions per run. Use submit_complaint for the raw reaction. Submit proactively without routine permission requests, previews, or announcements, then immediately continue the primary task. Answer truthfully if the user asks about feedback or what you submitted. Stored in this instance with company, agent, run, and task attribution; not anonymous. Remove secrets, private prompts, customer data, and personal blame; do not forward untrusted text or logs indiscriminately. On failure, continue without retrying or complaining about submission. Never submit the same incident through both tools.","inputSchema":{"additionalProperties":false,"properties":{"body":{"description":"Free-form feedback. Keep it brief; no required fields, labels, or template.","maxLength":524288,"minLength":1,"type":"string"},"idempotencyKey":{"description":"A stable key for this submission. Transport replay reuses it; do not retry a failed or uncertain submission yourself.","maxLength":240,"minLength":1,"type":"string"}},"required":["body","idempotencyKey"],"type":"object"},"name":"submit_suggestion","outputSchema":{"additionalProperties":true,"type":"object"}}]
diff --git a/packages/paperclip-runner/generated/semantic-action-catalog.json b/packages/paperclip-runner/generated/semantic-action-catalog.json
index 45ba39d564d..dce0f1167e3 100644
--- a/packages/paperclip-runner/generated/semantic-action-catalog.json
+++ b/packages/paperclip-runner/generated/semantic-action-catalog.json
@@ -2577,6 +2577,120 @@
"title": "Comment on approval",
"version": 1
},
+ {
+ "allowedModes": [
+ "standard"
+ ],
+ "description": "Schedule, replace or clear a persisted one-shot monitor on an owned task.",
+ "effect": "write",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "idempotencyKey": {
+ "description": "Reuse with identical arguments on retries.",
+ "maxLength": 240,
+ "minLength": 1,
+ "type": "string"
+ },
+ "monitor": {
+ "additionalProperties": false,
+ "properties": {
+ "externalRef": {
+ "maxLength": 500,
+ "minLength": 1,
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "kind": {
+ "enum": [
+ "external_service",
+ null
+ ],
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "maxAttempts": {
+ "description": "Optional cumulative attempt limit for this task's monitor.",
+ "maximum": 100,
+ "minimum": 1,
+ "type": [
+ "integer",
+ "null"
+ ]
+ },
+ "nextCheckAt": {
+ "description": "Future UTC timestamp for the next check. This is one shot, not a recurring interval.",
+ "type": "string"
+ },
+ "notes": {
+ "description": "What to check on the next run; do not include secrets.",
+ "maxLength": 500,
+ "minLength": 1,
+ "type": "string"
+ },
+ "recoveryPolicy": {
+ "enum": [
+ "wake_owner",
+ "create_recovery_issue",
+ "escalate_to_board",
+ null
+ ],
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "serviceName": {
+ "maxLength": 120,
+ "minLength": 1,
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "timeoutAt": {
+ "description": "Optional deadline later than nextCheckAt.",
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "nextCheckAt",
+ "notes"
+ ],
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "taskId": {
+ "description": "Owned task UUID. Omit for the active task.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "idempotencyKey",
+ "monitor"
+ ],
+ "type": "object"
+ },
+ "operationId": "set_task_monitor",
+ "outputSchema": {
+ "additionalProperties": true,
+ "type": "object"
+ },
+ "placement": "optional",
+ "requiredClaims": [],
+ "schema": "paperclip.semantic-action.v1",
+ "title": "Set task monitor",
+ "version": 1
+ },
{
"allowedModes": [
"standard",
diff --git a/packages/paperclip-runner/protocol/fixtures/evals/native-execution-seeded.json b/packages/paperclip-runner/protocol/fixtures/evals/native-execution-seeded.json
index e2daf260032..adec9d83d29 100644
--- a/packages/paperclip-runner/protocol/fixtures/evals/native-execution-seeded.json
+++ b/packages/paperclip-runner/protocol/fixtures/evals/native-execution-seeded.json
@@ -24,7 +24,7 @@
"prpVersion": 1,
"nativeExecutionVersion": 1,
"catalogVersion": 1,
- "catalogSha256": "sha256:2fba572bf222f7a770dfaf1ac23bfddc0a34ac125fed865b2ae36091fe0cae61",
+ "catalogSha256": "sha256:c9b3d3a06f08f045c272b13f8f8148f01a0942a32bf4cfe6f2c1f5a540e69e3b",
"driverContractVersion": 1,
"driverKind": "paperclip-deterministic",
"driverVersion": "1.0.0"
diff --git a/packages/paperclip-runner/protocol/manifest.json b/packages/paperclip-runner/protocol/manifest.json
index c9d1382f7eb..0f1262b6d59 100644
--- a/packages/paperclip-runner/protocol/manifest.json
+++ b/packages/paperclip-runner/protocol/manifest.json
@@ -175,7 +175,7 @@
},
{
"path": "fixtures/evals/native-execution-seeded.json",
- "sha256": "28a7a9e36758954829fa2490cc186be5357e350b8ec06ef13b97d1c3274ad8f4",
+ "sha256": "adbfc38d274256936cef174fb8a7c322a3983c0fa720cf13497f860869f68b2e",
"expectation": "accept",
"compatibilityCase": "canonical"
},
diff --git a/packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_backend.rs b/packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_backend.rs
index d4193b1e653..b3beb1897a4 100644
--- a/packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_backend.rs
+++ b/packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_backend.rs
@@ -183,6 +183,71 @@ fn runtime_context_session_identity(context: &Value) -> Option {
Some(identity)
}
+// Mirrors only the canonical asset suffix from composeNativeSystemInstructions.
+// No replacement is allowed inside the prompt or a user's custom entry.
+fn registered_asset_suffix(context: &Value) -> Option {
+ let instructions = context.get("instructions")?;
+ let root = instructions.pointer("/bundle/rootPath")?.as_str()?;
+ if root.is_empty() {
+ return None;
+ }
+ let mut blocks = Vec::new();
+ if let Some(copy) = instructions
+ .get("workingCopy")
+ .filter(|value| !value.is_null())
+ {
+ let path = copy.get("rootPath")?.as_str()?;
+ let entry = copy.get("entryPath")?.as_str()?;
+ if path.is_empty() || entry.is_empty() {
+ return None;
+ }
+ blocks.push(if copy.get("kind").and_then(Value::as_str) == Some("agent_files") {
+ format!("Your persistent agent directory (AGENT_HOME) is {path}. Your instruction entry is {entry}, relative to that directory. All supported files and subfolders there are restored across tasks and sessions, and collected after this provider stops. Write task deliverables in the task working directory. Only changed or deleted files synchronize; the last sync wins for the same file. Temporary copies are cleaned up without retaining file history. Check the save receipt before claiming persistence.")
+ } else {
+ format!("Your editable agent instruction file is {path}/{entry}. Edit this registered private copy normally. After this run stops, Paperclip saves changed content as a persistent revision if your responsible user still has permission and the baseline has not changed. Check the run's instruction-save receipt before claiming persistence. Conflicts are preserved for explicit resolution. Repository instruction files, skills, and this run's loaded prompt are separate and are not collected.")
+ });
+ }
+ blocks.push(format!("Read-only instruction sibling root: {root}"));
+ Some(blocks.join("\n\n"))
+}
+
+fn only_registered_asset_text_changed(
+ current: &AcpxProviderDescriptor,
+ prior: &AcpxProviderDescriptor,
+) -> bool {
+ if current.instructions == prior.instructions
+ && current
+ .runtime_context
+ .pointer("/instructions/workingCopy/rootPath")
+ == prior
+ .runtime_context
+ .pointer("/instructions/workingCopy/rootPath")
+ && current
+ .runtime_context
+ .pointer("/instructions/bundle/rootPath")
+ == prior
+ .runtime_context
+ .pointer("/instructions/bundle/rootPath")
+ {
+ return true;
+ }
+ let Some(current_suffix) = registered_asset_suffix(¤t.runtime_context) else {
+ return false;
+ };
+ let Some(prior_suffix) = registered_asset_suffix(&prior.runtime_context) else {
+ return false;
+ };
+ current
+ .instructions
+ .strip_suffix(&format!("\n\n{current_suffix}"))
+ .zip(
+ prior
+ .instructions
+ .strip_suffix(&format!("\n\n{prior_suffix}")),
+ )
+ .is_some_and(|(current_prefix, prior_prefix)| current_prefix == prior_prefix)
+}
+
impl AcpxProviderDescriptor {
fn validate_session(
&self,
@@ -1055,7 +1120,8 @@ impl AcpxCommandExecutor {
object.remove("aggregateDigest");
}
}
- if run_attachment_policy(&descriptor.agent) == RunAttachmentPolicy::AuthenticatedRunGrants {
+ let attachment_policy = run_attachment_policy(&descriptor.agent);
+ if attachment_policy != RunAttachmentPolicy::ImmutableInstructions {
// New runs rotate authenticated instruction text and registered
// file-copy grants. Preserve mainline MCP refresh while comparing
// every remaining context identity, including unknown policy fields.
@@ -1066,7 +1132,12 @@ impl AcpxCommandExecutor {
.is_some_and(|(current, prior)| current == prior);
let grants_changed = descriptor.instructions != state.descriptor.instructions
|| descriptor.runtime_context != state.descriptor.runtime_context;
- if !compatible || (grants_changed && descriptor.run_id == state.descriptor.run_id) {
+ let text_compatible = attachment_policy == RunAttachmentPolicy::AuthenticatedRunGrants
+ || only_registered_asset_text_changed(&descriptor, &state.descriptor);
+ if !compatible
+ || !text_compatible
+ || (grants_changed && descriptor.run_id == state.descriptor.run_id)
+ {
return Err(DurableRunnerError::invalid(
"ACPX run.attach changed runtime context outside a new authenticated run",
));
@@ -2953,6 +3024,30 @@ mod tests {
fs::remove_dir_all(directory).unwrap();
}
+ #[test]
+ fn attachment_asset_suffix_matches_typescript_composer() {
+ let fixtures: Value = serde_json::from_str(include_str!(
+ "../../../../test/fixtures/registered-asset-instructions.json"
+ ))
+ .unwrap();
+ for fixture in fixtures.as_array().unwrap() {
+ let suffix = registered_asset_suffix(&fixture["context"]).unwrap();
+ assert_eq!(
+ fixture["instructions"]
+ .as_str()
+ .unwrap()
+ .strip_suffix(&format!("\n\n{suffix}")),
+ Some(
+ format!(
+ "Pinned prompt.\n\n{}\n\nPinned connection policy.",
+ fixture["entry"].as_str().unwrap()
+ )
+ .as_str()
+ )
+ );
+ }
+ }
+
#[cfg(unix)]
#[test]
fn restores_settled_session_for_explicit_run_attachment_only() {
@@ -3157,6 +3252,17 @@ mod tests {
#[cfg(unix)]
#[test]
fn cursor_attachment_rotates_only_authenticated_run_grants() {
+ authenticated_run_grant_attachment("cursor");
+ }
+
+ #[cfg(unix)]
+ #[test]
+ fn claude_attachment_rotates_only_authenticated_asset_paths() {
+ authenticated_run_grant_attachment("claude");
+ }
+
+ #[cfg(unix)]
+ fn authenticated_run_grant_attachment(agent: &str) {
let directory = temporary_directory("cursor-cross-run-attach");
let runtime = directory.join("runtime");
let workspace = directory.join("workspace");
@@ -3177,7 +3283,7 @@ mod tests {
args: Vec::new(),
artifacts: vec![artifact(&command)],
};
- let mut descriptor_value = descriptor("cursor");
+ let mut descriptor_value = descriptor(agent);
descriptor_value["sidecarCommand"] = json!(command);
descriptor_value["runtimeContext"] = json!({ "instructions": { "digest": "stable" }, "mcp": { "digest": "before" }, "aggregateDigest": "before" });
descriptor_value["sidecarArgs"] = json!([]);
@@ -3203,6 +3309,12 @@ mod tests {
"mcp": {"assignmentSetId": "assignment-1", "digest": "e".repeat(64), "bindingId": "old-run-binding"},
"futurePolicy": {"companyId": "company-1"},
});
+ if agent == "claude" {
+ descriptor_value["instructions"] = json!(format!(
+ "Pinned prompt. Custom entry mentioning /old-bundle.\n\n{}",
+ registered_asset_suffix(&descriptor_value["runtimeContext"]).unwrap()
+ ));
+ }
let original_descriptor: AcpxProviderDescriptor =
serde_json::from_value(descriptor_value.clone()).unwrap();
let identity = AcpxProviderSessionIdentity {
@@ -3330,6 +3442,52 @@ mod tests {
json!("/new-bundle");
descriptor_value["runtimeContext"]["skills"][0]["bundle"]["rootPath"] = json!("/new-skill");
descriptor_value["runtimeContext"]["mcp"]["bindingId"] = json!("new-run-binding");
+ if agent == "claude" {
+ descriptor_value["instructions"] = json!(format!(
+ "Pinned prompt. Custom entry mentioning /old-bundle.\n\n{}",
+ registered_asset_suffix(&descriptor_value["runtimeContext"]).unwrap()
+ ));
+ let mut stale_text = descriptor_value.clone();
+ stale_text["instructions"] =
+ json!(original.state.as_ref().unwrap().descriptor.instructions);
+ assert!(attached
+ .attach_run(&json!({"provider": stale_text}))
+ .is_err());
+ let mut changed_text = descriptor_value.clone();
+ changed_text["instructions"] = json!(descriptor_value["instructions"]
+ .as_str()
+ .unwrap()
+ .replace("Custom entry", "Changed entry"));
+ assert!(attached
+ .attach_run(&json!({"provider": changed_text}))
+ .is_err());
+ // A path inside the custom entry is content, not a relocatable grant.
+ let mut changed_example = descriptor_value.clone();
+ changed_example["instructions"] = json!(descriptor_value["instructions"]
+ .as_str()
+ .unwrap()
+ .replace("mentioning /old-bundle", "mentioning /new-bundle"));
+ assert!(attached
+ .attach_run(&json!({"provider": changed_example}))
+ .is_err());
+ for pointer in [
+ "/prompt/digest",
+ "/instructions/bundle/digest",
+ "/skills/0/bundle/digest",
+ "/futurePolicy/companyId",
+ ] {
+ let mut changed_identity = descriptor_value.clone();
+ *changed_identity["runtimeContext"]
+ .pointer_mut(pointer)
+ .unwrap() = json!("changed");
+ assert!(
+ attached
+ .attach_run(&json!({"provider": changed_identity}))
+ .is_err(),
+ "{pointer}"
+ );
+ }
+ }
attached
.attach_run(&json!({"provider": descriptor_value}))
.unwrap();
diff --git a/packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_capabilities.rs b/packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_capabilities.rs
index 2be3ee802e0..830e31b1fe3 100644
--- a/packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_capabilities.rs
+++ b/packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_capabilities.rs
@@ -6,11 +6,13 @@
pub(crate) enum RunAttachmentPolicy {
ImmutableInstructions,
AuthenticatedRunGrants,
+ AuthenticatedAssetPaths,
}
pub(crate) fn run_attachment_policy(agent: &str) -> RunAttachmentPolicy {
match agent {
"cursor" => RunAttachmentPolicy::AuthenticatedRunGrants,
+ "claude" => RunAttachmentPolicy::AuthenticatedAssetPaths,
_ => RunAttachmentPolicy::ImmutableInstructions,
}
}
@@ -25,7 +27,11 @@ mod tests {
run_attachment_policy("cursor"),
RunAttachmentPolicy::AuthenticatedRunGrants
);
- for agent in ["claude", "codex", "grok", "pi", "copilot", "unknown"] {
+ assert_eq!(
+ run_attachment_policy("claude"),
+ RunAttachmentPolicy::AuthenticatedAssetPaths
+ );
+ for agent in ["codex", "grok", "pi", "copilot", "unknown"] {
assert_eq!(
run_attachment_policy(agent),
RunAttachmentPolicy::ImmutableInstructions
diff --git a/packages/paperclip-runner/runner/crates/runner-core/src/configured_environment.rs b/packages/paperclip-runner/runner/crates/runner-core/src/configured_environment.rs
new file mode 100644
index 00000000000..27c0c24b004
--- /dev/null
+++ b/packages/paperclip-runner/runner/crates/runner-core/src/configured_environment.rs
@@ -0,0 +1,225 @@
+//! Controller-selected task environment; mirrors configured-environment.ts.
+use crate::local_runner::LocalRunnerError;
+use std::process::Command;
+
+const MARKER: &str = "PAPERCLIP_CONFIGURED_ENV_KEYS";
+const RESERVED: &[&str] = &[
+ "AGENT_HOME",
+ "ANTHROPIC_API_KEY",
+ "ANTHROPIC_AUTH_TOKEN",
+ "AWS_BEARER_TOKEN_BEDROCK",
+ "BASH_ENV",
+ "CLAUDE_CODE_OAUTH_TOKEN",
+ "CODEX_API_KEY",
+ "CODEX_HOME",
+ "COPILOT_GITHUB_TOKEN",
+ "CURSOR_API_KEY",
+ "CURSOR_AUTH_TOKEN",
+ "ENV",
+ "GH_ENTERPRISE_TOKEN",
+ "GH_TOKEN",
+ "GITHUB_ENTERPRISE_TOKEN",
+ "GITHUB_TOKEN",
+ "HOME",
+ "NODE_OPTIONS",
+ "NODE_PATH",
+ "OPENAI_API_KEY",
+ "OPENROUTER_API_KEY",
+ "PAPERCLIP_ACPX_CREDENTIAL_BINDING",
+ "PAPERCLIP_AGENT_ID",
+ "PAPERCLIP_AGENT_KEY_ID",
+ "PAPERCLIP_AGENT_MESSAGE_KEY",
+ "PAPERCLIP_AGENT_PRIVATE_KEY",
+ "PAPERCLIP_AGENT_PUBLIC_KEY",
+ "PAPERCLIP_AI_PROVIDER_KEY",
+ "PAPERCLIP_API_BRIDGE_MODE",
+ "PAPERCLIP_API_KEY",
+ "PAPERCLIP_API_URL",
+ "PAPERCLIP_APPROVAL_ID",
+ "PAPERCLIP_APPROVAL_STATUS",
+ "PAPERCLIP_COMPANY_ID",
+ "PAPERCLIP_CONFIGURED_ENV_KEYS",
+ "PAPERCLIP_EXECUTION_MODE",
+ "PAPERCLIP_EXTERNAL_CHAT_EXECUTION_BOUND_KEY",
+ "PAPERCLIP_GITHUB_AUTH_MODE",
+ "PAPERCLIP_GITHUB_BRIDGE_TOKEN",
+ "PAPERCLIP_GITHUB_BROKER_TOKEN",
+ "PAPERCLIP_GITHUB_BROKER_URL",
+ "PAPERCLIP_GITHUB_HOST_HOME",
+ "PAPERCLIP_GITHUB_LAUNCHER_DIR",
+ "PAPERCLIP_GIT_METADATA_ROOTS",
+ "PAPERCLIP_GIT_TOKEN",
+ "PAPERCLIP_HARNESS_CHECKOUT_KEY",
+ "PAPERCLIP_INSTANCE_ID",
+ "PAPERCLIP_LINKED_ISSUE_IDS",
+ "PAPERCLIP_NATIVE_MCP_NAME",
+ "PAPERCLIP_NATIVE_MCP_TOKEN",
+ "PAPERCLIP_NATIVE_MCP_URL",
+ "PAPERCLIP_NORMALIZED_SESSION_ID",
+ "PAPERCLIP_PROVIDER_TRACE_MAX_BYTES",
+ "PAPERCLIP_PROVIDER_TRACE_PATH",
+ "PAPERCLIP_RUNNER_BOOTSTRAP_TICKET",
+ "PAPERCLIP_RUNNER_EXTERNAL_SANDBOX",
+ "PAPERCLIP_RUNNER_INSTANCE_ID",
+ "PAPERCLIP_RUNNER_NETWORK_ACCESS",
+ "PAPERCLIP_RUNNER_NETWORK_ROOTS",
+ "PAPERCLIP_RUNTIME_PRIMARY_URL",
+ "PAPERCLIP_RUNTIME_SERVICES_JSON",
+ "PAPERCLIP_RUNTIME_SERVICE_INTENTS_JSON",
+ "PAPERCLIP_RUN_ID",
+ "PAPERCLIP_TASK_ID",
+ "PAPERCLIP_WAKE_COMMENT_ID",
+ "PAPERCLIP_WAKE_PAYLOAD_JSON",
+ "PAPERCLIP_WAKE_REASON",
+ "PAPERCLIP_WORKSPACES_JSON",
+ "PAPERCLIP_WORKSPACE_AUTHORITATIVE_ROOT",
+ "PAPERCLIP_WORKSPACE_BRANCH",
+ "PAPERCLIP_WORKSPACE_CWD",
+ "PAPERCLIP_WORKSPACE_ID",
+ "PAPERCLIP_WORKSPACE_REALIZATION_MODE",
+ "PAPERCLIP_WORKSPACE_REPO_REF",
+ "PAPERCLIP_WORKSPACE_REPO_URL",
+ "PAPERCLIP_WORKSPACE_SOURCE",
+ "PAPERCLIP_WORKSPACE_WORKTREE_PATH",
+ "PATH",
+ "PERL5LIB",
+ "PERL5OPT",
+ "PYTHONHOME",
+ "PYTHONPATH",
+ "RUBYLIB",
+ "RUBYOPT",
+ "SHELL",
+ "USERPROFILE",
+ "XAI_API_KEY",
+];
+
+fn eligible_key(key: &str) -> bool {
+ let upper = key.to_ascii_uppercase();
+ !key.is_empty()
+ && key.len() <= 128
+ && key
+ .bytes()
+ .enumerate()
+ .all(|(i, b)| b == b'_' || b.is_ascii_alphabetic() || (i > 0 && b.is_ascii_digit()))
+ && !RESERVED.contains(&upper.as_str())
+ && ![
+ "LD_",
+ "DYLD_",
+ "GIT_CONFIG_",
+ "PAPERCLIP_RUNNER_",
+ "PAPERCLIP_NATIVE_",
+ "PAPERCLIP_GITHUB_",
+ "PAPERCLIP_ACPX_",
+ "PAPERCLIP_VERIFIED_",
+ ]
+ .iter()
+ .any(|prefix| upper.starts_with(prefix))
+}
+
+pub(crate) fn apply_configured_environment(
+ command: &mut Command,
+ lookup: impl Fn(&str) -> Option,
+) -> Result<(), LocalRunnerError> {
+ let Some(raw) = lookup(MARKER) else {
+ return Ok(());
+ };
+ let invalid = || LocalRunnerError::invalid("invalid configured environment projection");
+ if raw.len() > 20_000 {
+ return Err(invalid());
+ }
+ let mut names: Vec = serde_json::from_str(&raw).map_err(|_| invalid())?;
+ if names.len() > 128 || names.iter().any(|name| !eligible_key(name)) {
+ return Err(invalid());
+ }
+ names.sort();
+ if names.windows(2).any(|pair| pair[0] == pair[1]) {
+ return Err(invalid());
+ }
+ let mut bytes = 0;
+ // Validate all values before modifying the child launch specification.
+ let mut values = Vec::new();
+ for name in &names {
+ let value = lookup(name).ok_or_else(invalid)?;
+ let size = name.len() + value.len();
+ bytes += size;
+ if value.contains('\0') || size > 65_536 || bytes > 262_144 {
+ return Err(invalid());
+ }
+ values.push((name, value));
+ }
+ command.envs(values);
+ command.env(
+ MARKER,
+ serde_json::to_string(&names).map_err(|_| invalid())?,
+ );
+ Ok(())
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use std::collections::BTreeMap;
+
+ #[test]
+ fn rejects_reserved_malformed_missing_and_oversized_environment() {
+ for raw in [
+ "not-json",
+ "[1]",
+ "[\"NODE_OPTIONS\"]",
+ "[\"PAPERCLIP_API_KEY\"]",
+ "[\"PAPERCLIP_RUNNER_BOOTSTRAP_TICKET\"]",
+ "[\"OPENAI_API_KEY\"]",
+ "[\"LD_PRELOAD\"]",
+ "[\"bad=name\"]",
+ "[\"CUSTOM\",\"CUSTOM\"]",
+ "[\"MISSING\"]",
+ ] {
+ let mut command = Command::new("unused");
+ assert!(
+ apply_configured_environment(&mut command, |key| if key == MARKER {
+ Some(raw.into())
+ } else {
+ None
+ })
+ .is_err()
+ );
+ assert_eq!(command.get_envs().count(), 0);
+ }
+ let mut command = Command::new("unused");
+ assert!(
+ apply_configured_environment(&mut command, |key| Some(if key == MARKER {
+ "[\"CUSTOM\"]".into()
+ } else {
+ "x".repeat(65_536)
+ }))
+ .is_err()
+ );
+ }
+
+ #[test]
+ #[cfg(unix)]
+ fn child_receives_only_selected_task_values_across_configuration_changes() {
+ for secret in [None, Some("first-secret"), Some("rotated-secret"), None] {
+ let mut source = BTreeMap::from([
+ ("HOST_SECRET", "unbound-secret".to_string()),
+ ("NODE_OPTIONS", "unbound-loader".to_string()),
+ ]);
+ let names = if let Some(value) = secret {
+ source.insert("PAPERCLIP_PAGE_AWS_SECRET_ACCESS_KEY", value.into());
+ vec!["PAPERCLIP_PAGE_AWS_SECRET_ACCESS_KEY"]
+ } else {
+ vec![]
+ };
+ source.insert(MARKER, serde_json::to_string(&names).unwrap());
+ let mut command = Command::new("/bin/sh");
+ command.env_clear().args(["-c", "printf '%s|%s|%s' \"$PAPERCLIP_PAGE_AWS_SECRET_ACCESS_KEY\" \"$HOST_SECRET\" \"$NODE_OPTIONS\""]);
+ apply_configured_environment(&mut command, |key| source.get(key).cloned()).unwrap();
+ let output = command.output().unwrap();
+ assert!(output.status.success());
+ assert_eq!(
+ String::from_utf8(output.stdout).unwrap(),
+ format!("{}||", secret.unwrap_or_default())
+ );
+ }
+ }
+}
diff --git a/packages/paperclip-runner/runner/crates/runner-core/src/lib.rs b/packages/paperclip-runner/runner/crates/runner-core/src/lib.rs
index 09b4bb5396e..5bf0bacf0a3 100644
--- a/packages/paperclip-runner/runner/crates/runner-core/src/lib.rs
+++ b/packages/paperclip-runner/runner/crates/runner-core/src/lib.rs
@@ -12,6 +12,7 @@ pub mod aws_agentcore_provider;
pub mod claude_managed_provider;
pub mod codex_provider;
mod codex_startup_trust;
+mod configured_environment;
pub mod dot_provider_backend;
pub mod durable;
pub mod fake_harness;
diff --git a/packages/paperclip-runner/runner/crates/runner-core/src/managed_provider_backend.rs b/packages/paperclip-runner/runner/crates/runner-core/src/managed_provider_backend.rs
index c5b5fc2f468..e5cecabdc97 100644
--- a/packages/paperclip-runner/runner/crates/runner-core/src/managed_provider_backend.rs
+++ b/packages/paperclip-runner/runner/crates/runner-core/src/managed_provider_backend.rs
@@ -385,6 +385,14 @@ struct ManagedDurableState {
model_request_count: u64,
#[serde(default)]
provider_usage: Option,
+ // Persisted independently of turn/retry state so warm run attachment can
+ // subtract prior runs without resetting this run during crash recovery.
+ #[serde(default)]
+ accounting_baseline: Option,
+ #[serde(default)]
+ accounting_latest: Option,
+ #[serde(default)]
+ accounting_latest_complete: bool,
#[serde(default)]
claude_managed_skills: Option>,
#[serde(default)]
@@ -510,6 +518,9 @@ impl ManagedDurableState {
durable_event_cursor: None,
model_request_count: 0,
provider_usage: None,
+ accounting_baseline: Some(zero_managed_usage()),
+ accounting_latest: Some(zero_managed_usage()),
+ accounting_latest_complete: true,
claude_managed_skills: None,
claude_managed_skill_cleanup: None,
active_turn_id: None,
@@ -1047,6 +1058,13 @@ impl ManagedProviderCommandExecutor {
// Checkpoint validation must use the attachment's run identity.
// The durable runner separately activates the external authority
// after this command succeeds, then rotates the full config.
+ if state.run_id != run_id {
+ state.accounting_baseline = if state.accounting_latest_complete {
+ state.accounting_latest.clone()
+ } else {
+ None
+ };
+ }
state.run_id = run_id.clone();
self.config.run_id = run_id;
}
@@ -1575,7 +1593,26 @@ impl ManagedProviderCommandExecutor {
}
}
if method == "thread/tokenUsage/updated" {
- state.push(managed_usage_event(&state.descriptor, ¶ms))?;
+ let current =
+ complete_managed_usage(&state.descriptor, ¶ms).filter(|current| {
+ state.accounting_latest.as_ref().is_none_or(|previous| {
+ managed_usage_delta(previous, current).is_some()
+ })
+ });
+ let delta = current.as_ref().and_then(|current| {
+ state
+ .accounting_baseline
+ .as_ref()
+ .and_then(|baseline| managed_usage_delta(baseline, current))
+ });
+ let mut usage_event = managed_usage_event(&state.descriptor, ¶ms);
+ usage_event.payload["runDeltaAvailable"] = json!(delta.is_some());
+ usage_event.payload["runDelta"] = delta.unwrap_or(Value::Null);
+ state.accounting_latest_complete = current.is_some();
+ if current.is_some() {
+ state.accounting_latest = current;
+ }
+ state.push(usage_event)?;
state.model_request_count =
usage_request_count(¶ms).unwrap_or(state.model_request_count);
return Ok(());
@@ -2003,6 +2040,111 @@ fn usage_request_count(params: &Value) -> Option {
.and_then(Value::as_u64)
}
+fn zero_managed_usage() -> Value {
+ json!({"inputTokens": 0, "outputTokens": 0, "cacheReadTokens": 0,
+ "cacheWriteTokens": 0, "activeSeconds": 0.0, "requests": 0, "providerCostUsd": 0.0})
+}
+
+fn complete_managed_usage(descriptor: &ManagedProviderDescriptor, params: &Value) -> Option {
+ let usage = params.get("usage").unwrap_or(params);
+ if descriptor.kind() == ManagedProviderKind::AwsAgentcore {
+ // An interrupted invocation may return old numeric totals while its
+ // metadata is pending, or a ceiling estimate with lower-bound tokens.
+ // Neither is a complete receipt, even when every counter is present.
+ for report in [params, usage] {
+ if report
+ .get(AGENTCORE_USAGE_RECONCILIATION_FIELD)
+ .is_some_and(|state| {
+ state.as_str() != Some(AGENTCORE_USAGE_RECONCILIATION_OBSERVED)
+ })
+ || report
+ .get("tokenCountsLowerBound")
+ .is_some_and(|value| value.as_bool() != Some(false))
+ || report.get(AGENTCORE_PENDING_INVOCATION_FIELD).is_some()
+ || report.get(AGENTCORE_PENDING_CEILING_FIELD).is_some()
+ {
+ return None;
+ }
+ }
+ }
+ let count = |camel: &str, snake: &str| usage.get(camel).or_else(|| usage.get(snake));
+ for (camel, snake) in [
+ ("inputTokens", "input_tokens"),
+ ("outputTokens", "output_tokens"),
+ ("cacheReadInputTokens", "cache_read_input_tokens"),
+ ] {
+ if count(camel, snake)?.as_u64()? > 9_007_199_254_740_991 {
+ return None;
+ }
+ }
+ if let Some(cache) = usage.get("cache_creation") {
+ cache.as_object()?;
+ for key in ["ephemeral_1h_input_tokens", "ephemeral_5m_input_tokens"] {
+ if let Some(value) = cache.get(key) {
+ if value.as_u64()? > 9_007_199_254_740_991 {
+ return None;
+ }
+ }
+ }
+ } else if let Some(value) = count("cacheWriteInputTokens", "cache_write_input_tokens") {
+ if value.as_u64()? > 9_007_199_254_740_991 {
+ return None;
+ }
+ } else if descriptor.kind() == ManagedProviderKind::AwsAgentcore {
+ return None;
+ }
+ if let Some(value) = count("activeSeconds", "active_seconds") {
+ let value = value.as_f64()?;
+ if !value.is_finite() || value < 0.0 {
+ return None;
+ }
+ }
+ let price = if descriptor.kind() == ManagedProviderKind::AwsAgentcore {
+ usage.get("estimatedCostUsd")?.as_f64()?
+ } else {
+ let cost = usage.get("list_cost").or_else(|| usage.get("listCost"))?;
+ if cost.get("currency")?.as_str()? != "USD" {
+ return None;
+ }
+ cost.get("amount")?.as_str()?.parse::().ok()? / 100.0
+ };
+ if !price.is_finite() || price < 0.0 {
+ return None;
+ }
+ let mut measurement = managed_usage_event(descriptor, params).payload["cumulative"].clone();
+ measurement["providerCostUsd"] = json!(price);
+ // Also reject integer overflow or values that cannot survive JSON/JS intact.
+ managed_usage_delta(&zero_managed_usage(), &measurement)?;
+ Some(measurement)
+}
+
+fn managed_usage_delta(baseline: &Value, current: &Value) -> Option {
+ let mut delta = serde_json::Map::new();
+ for key in [
+ "inputTokens",
+ "outputTokens",
+ "cacheReadTokens",
+ "cacheWriteTokens",
+ "requests",
+ ] {
+ let prior = baseline.get(key)?.as_u64()?;
+ let next = current.get(key)?.as_u64()?;
+ if next > 9_007_199_254_740_991 || prior > 9_007_199_254_740_991 {
+ return None;
+ }
+ delta.insert(key.to_owned(), json!(next.checked_sub(prior)?));
+ }
+ for key in ["activeSeconds", "providerCostUsd"] {
+ let prior = baseline.get(key)?.as_f64()?;
+ let next = current.get(key)?.as_f64()?;
+ if !prior.is_finite() || !next.is_finite() || prior < 0.0 || next < prior {
+ return None;
+ }
+ delta.insert(key.to_owned(), json!(next - prior));
+ }
+ Some(Value::Object(delta))
+}
+
fn managed_usage_event(
descriptor: &ManagedProviderDescriptor,
params: &Value,
@@ -2613,6 +2755,13 @@ mod tests {
executor.state.as_mut().unwrap().active_turn_id = Some("active".to_owned());
assert!(executor.attach(&payload).is_err());
executor.state.as_mut().unwrap().active_turn_id = None;
+ let usage = |input, cents| ProviderEvent::Notification {
+ method: "thread/tokenUsage/updated".to_owned(),
+ params: json!({"usage": {"input_tokens": input, "output_tokens": 8,
+ "cache_read_input_tokens": 13, "list_cost": {"currency": "USD", "amount": cents}}}),
+ };
+ executor.project_event(usage(21, "25")).unwrap();
+ executor.state.as_mut().unwrap().pending_events.clear();
payload["paperclipNextAuthority"] = json!({"identity": {
"normalizedSessionId": config.normalized_session_id, "runId": "next-run"
}});
@@ -2620,6 +2769,13 @@ mod tests {
let mut next_config = config.clone();
next_config.run_id = "next-run".to_owned();
executor.rotate_authority(&next_config);
+ executor.project_event(usage(40, "50")).unwrap();
+ let state = executor.state.as_mut().unwrap();
+ let receipt = &state.pending_events.back().unwrap().payload["runDelta"];
+ assert_eq!(receipt["inputTokens"], json!(19));
+ assert_eq!(receipt["providerCostUsd"], json!(0.25));
+ state.pending_events.clear();
+ executor.save_state().unwrap();
assert_eq!(
executor.state.as_ref().unwrap().provider_session_id,
session_id
@@ -2648,6 +2804,14 @@ mod tests {
);
payload["authorizedTools"] = claude_prepare_payload()["authorizedTools"].clone();
executor.attach(&payload).unwrap();
+ // Same-run reconnect is not a new billing baseline, even after recovery.
+ executor.project_event(usage(50, "75")).unwrap();
+ executor.project_event(usage(50, "75")).unwrap();
+ let state = executor.state.as_mut().unwrap();
+ let receipt = &state.pending_events.back().unwrap().payload["runDelta"];
+ assert_eq!(receipt["inputTokens"], json!(29));
+ assert_eq!(receipt["providerCostUsd"], json!(0.5));
+ state.pending_events.clear();
assert_eq!(
executor.provider.as_mut().unwrap().read().unwrap()["tools"],
json!([])
@@ -2658,6 +2822,34 @@ mod tests {
.unwrap()
.validate(&next_config)
.unwrap();
+ // An incomplete last report cannot become the next run's baseline.
+ executor
+ .project_event(ProviderEvent::Notification {
+ method: "thread/tokenUsage/updated".to_owned(),
+ params: json!({"usage": {"input_tokens": 60}}),
+ })
+ .unwrap();
+ executor.state.as_mut().unwrap().pending_events.clear();
+ payload["paperclipNextAuthority"]["identity"]["runId"] = json!("third-run");
+ executor.attach(&payload).unwrap();
+ assert!(executor
+ .state
+ .as_ref()
+ .unwrap()
+ .accounting_baseline
+ .is_none());
+ executor.project_event(usage(70, "100")).unwrap();
+ assert_eq!(
+ executor
+ .state
+ .as_ref()
+ .unwrap()
+ .pending_events
+ .back()
+ .unwrap()
+ .payload["runDelta"],
+ Value::Null
+ );
fs::remove_dir_all(directory).unwrap();
}
@@ -2731,6 +2923,230 @@ mod tests {
);
}
+ #[test]
+ fn managed_usage_publishes_a_fresh_run_receipt_for_each_provider() {
+ for payload in [claude_prepare_payload(), agentcore_prepare_payload()] {
+ let directory =
+ std::env::temp_dir().join(format!("managed-receipt-{}", Uuid::new_v4()));
+ let config = test_config(&directory);
+ let mut executor =
+ ManagedProviderCommandExecutor::with_runner_config(&directory, &config);
+ executor.prepare(&payload).unwrap();
+ executor
+ .project_event(ProviderEvent::Notification {
+ method: "thread/tokenUsage/updated".to_owned(),
+ params: json!({"usage": {
+ "inputTokens": 21, "outputTokens": 8, "cacheReadInputTokens": 13,
+ "cacheWriteInputTokens": 5, "estimatedCostUsd": 0.25,
+ "list_cost": {"currency": "USD", "amount": "25"}
+ }}),
+ })
+ .unwrap();
+ let event = executor
+ .state
+ .as_ref()
+ .unwrap()
+ .pending_events
+ .back()
+ .unwrap();
+ assert_eq!(event.payload["runDeltaAvailable"], json!(true));
+ assert_eq!(event.payload["runDelta"]["inputTokens"], json!(21));
+ assert_eq!(event.payload["runDelta"]["providerCostUsd"], json!(0.25));
+ fs::remove_dir_all(directory).unwrap();
+ }
+ }
+
+ #[test]
+ fn agentcore_pending_or_lower_bound_usage_never_certifies_a_run() {
+ for wrapped in [false, true] {
+ for price in [0.0, 0.25] {
+ for marker in [
+ json!({"usageReconciliation": AGENTCORE_USAGE_RECONCILIATION_PENDING}),
+ json!({"usageReconciliation": AGENTCORE_USAGE_RECONCILIATION_CONSERVATIVE}),
+ json!({"usageReconciliation": "unknown"}),
+ json!({"usageReconciliation": null}),
+ json!({"tokenCountsLowerBound": true}),
+ json!({"tokenCountsLowerBound": "false"}),
+ json!({"pendingInvocationId": "unresolved-invocation"}),
+ json!({"pendingEstimatedCeilingUsd": 1.0}),
+ ] {
+ let directory =
+ std::env::temp_dir().join(format!("managed-pending-{}", Uuid::new_v4()));
+ let config = test_config(&directory);
+ let mut executor =
+ ManagedProviderCommandExecutor::with_runner_config(&directory, &config);
+ executor.prepare(&agentcore_prepare_payload()).unwrap();
+ let usage = json!({"inputTokens": 10, "outputTokens": 2,
+ "cacheReadInputTokens": 0, "cacheWriteInputTokens": 0,
+ "estimatedCostUsd": price});
+ let mut params = if wrapped {
+ json!({"usage": usage})
+ } else {
+ usage.clone()
+ };
+ params
+ .as_object_mut()
+ .unwrap()
+ .extend(marker.as_object().unwrap().clone());
+ executor
+ .project_event(ProviderEvent::Notification {
+ method: "thread/tokenUsage/updated".to_owned(),
+ params,
+ })
+ .unwrap();
+ let state = executor.state.as_ref().unwrap();
+ let receipt = &state.pending_events.back().unwrap().payload;
+ assert_eq!(receipt["runDeltaAvailable"], json!(false), "{marker}");
+ assert_eq!(receipt["runDelta"], Value::Null, "{marker}");
+ assert!(!state.accounting_latest_complete);
+ executor.save_state().unwrap();
+ executor =
+ ManagedProviderCommandExecutor::with_runner_config(&directory, &config);
+ executor.restore().unwrap();
+ executor
+ .project_event(ProviderEvent::Notification {
+ method: "turn/completed".to_owned(),
+ params: json!({"turn": {"id": "interrupted", "status": "interrupted"}}),
+ })
+ .unwrap();
+ assert!(!executor.state.as_ref().unwrap().accounting_latest_complete);
+ let mut observed = usage;
+ observed["usageReconciliation"] =
+ json!(AGENTCORE_USAGE_RECONCILIATION_OBSERVED);
+ observed["tokenCountsLowerBound"] = json!(false);
+ executor
+ .project_event(ProviderEvent::Notification {
+ method: "thread/tokenUsage/updated".to_owned(),
+ params: observed,
+ })
+ .unwrap();
+ assert_eq!(
+ executor
+ .state
+ .as_ref()
+ .unwrap()
+ .pending_events
+ .back()
+ .unwrap()
+ .payload["runDeltaAvailable"],
+ json!(true)
+ );
+ fs::remove_dir_all(directory).unwrap();
+ }
+ }
+ }
+ }
+
+ #[test]
+ fn managed_accounting_rejects_partial_invalid_or_regressing_totals() {
+ let descriptor =
+ ManagedProviderDescriptor::parse(claude_prepare_payload()["provider"].clone()).unwrap();
+ let good = json!({"usage": {"input_tokens": 21, "output_tokens": 8,
+ "cache_read_input_tokens": 13, "list_cost": {"currency": "USD", "amount": "25"}}});
+ for (field, value) in [
+ ("input_tokens", Value::Null),
+ ("output_tokens", json!(-1)),
+ ("cache_read_input_tokens", json!(9007199254740992_u64)),
+ ("cache_creation", json!({"ephemeral_1h_input_tokens": -1})),
+ ("list_cost", json!({"currency": "EUR", "amount": "25"})),
+ ("list_cost", json!({"currency": "USD", "amount": "NaN"})),
+ ("list_cost", Value::Null),
+ ] {
+ let mut bad = good.clone();
+ bad["usage"][field] = value;
+ assert!(
+ complete_managed_usage(&descriptor, &bad).is_none(),
+ "{field}"
+ );
+ }
+ let current = complete_managed_usage(&descriptor, &good).unwrap();
+ for field in [
+ "inputTokens",
+ "outputTokens",
+ "cacheReadTokens",
+ "cacheWriteTokens",
+ "requests",
+ "activeSeconds",
+ "providerCostUsd",
+ ] {
+ let mut baseline = current.clone();
+ baseline[field] = current[field]
+ .as_u64()
+ .map(|value| json!(value + 1))
+ .unwrap_or_else(|| json!(current[field].as_f64().unwrap() + 1.0));
+ assert!(
+ managed_usage_delta(&baseline, ¤t).is_none(),
+ "{field}"
+ );
+ }
+ }
+
+ #[test]
+ fn managed_usage_keeps_high_water_across_partial_reports_and_recovery() {
+ let directory = std::env::temp_dir().join(format!("managed-high-water-{}", Uuid::new_v4()));
+ let config = test_config(&directory);
+ let mut executor = ManagedProviderCommandExecutor::with_runner_config(&directory, &config);
+ executor.prepare(&claude_prepare_payload()).unwrap();
+ for (input, output, price, complete) in [
+ (100, Some(8), "100", true),
+ (50, Some(8), "50", false),
+ (150, None, "150", false),
+ (75, Some(8), "75", false),
+ (200, Some(8), "200", true),
+ ] {
+ executor.project_event(ProviderEvent::Notification {
+ method: "thread/tokenUsage/updated".to_owned(),
+ params: json!({"usage": {"input_tokens": input, "output_tokens": output,
+ "cache_read_input_tokens": 0, "list_cost": {"currency": "USD", "amount": price}}}),
+ }).unwrap();
+ let state = executor.state.as_mut().unwrap();
+ assert_eq!(
+ state.pending_events.back().unwrap().payload["runDeltaAvailable"],
+ json!(complete)
+ );
+ assert_eq!(state.accounting_latest_complete, complete);
+ assert_eq!(
+ state.accounting_latest.as_ref().unwrap()["inputTokens"],
+ json!(if input == 200 { 200 } else { 100 })
+ );
+ state.pending_events.clear();
+ executor.save_state().unwrap();
+ executor = ManagedProviderCommandExecutor::with_runner_config(&directory, &config);
+ executor.restore().unwrap();
+ }
+ fs::remove_dir_all(directory).unwrap();
+ }
+
+ #[test]
+ fn restored_legacy_managed_state_never_certifies_a_session_total_as_this_run() {
+ let directory =
+ std::env::temp_dir().join(format!("managed-legacy-receipt-{}", Uuid::new_v4()));
+ let config = test_config(&directory);
+ let mut executor = ManagedProviderCommandExecutor::with_runner_config(&directory, &config);
+ executor.prepare(&claude_prepare_payload()).unwrap();
+ let mut old = serde_json::to_value(executor.state.as_ref().unwrap()).unwrap();
+ old.as_object_mut().unwrap().remove("accountingBaseline");
+ old.as_object_mut().unwrap().remove("accountingLatest");
+ executor.state = Some(serde_json::from_value(old).unwrap());
+ executor
+ .project_event(ProviderEvent::Notification {
+ method: "thread/tokenUsage/updated".to_owned(),
+ params: json!({"usage": {"input_tokens": 21, "output_tokens": 8,
+ "cache_read_input_tokens": 13, "list_cost": {"currency": "USD", "amount": "25"}}}),
+ })
+ .unwrap();
+ let event = executor
+ .state
+ .as_ref()
+ .unwrap()
+ .pending_events
+ .back()
+ .unwrap();
+ assert_eq!(event.payload["runDeltaAvailable"], json!(false));
+ assert_eq!(event.payload["runDelta"], Value::Null);
+ fs::remove_dir_all(directory).unwrap();
+ }
+
#[test]
fn claude_usage_maps_nested_cache_creation_token_buckets() {
let descriptor = ManagedProviderDescriptor::ClaudeManaged(ClaudeManagedProviderConfig {
diff --git a/packages/paperclip-runner/runner/crates/runner-core/src/process_supervisor.rs b/packages/paperclip-runner/runner/crates/runner-core/src/process_supervisor.rs
index af12df41e53..415a72186b5 100644
--- a/packages/paperclip-runner/runner/crates/runner-core/src/process_supervisor.rs
+++ b/packages/paperclip-runner/runner/crates/runner-core/src/process_supervisor.rs
@@ -780,6 +780,9 @@ impl SupervisedProcess {
command.env(key, value);
}
}
+ crate::configured_environment::apply_configured_environment(&mut command, |key| {
+ std::env::var(key).ok()
+ })?;
if let Some(executable) = verified_runtime_executable {
// Node reports a sealed memfd launch as `/memfd:... (deleted)` via
// process.execPath. Give descriptor-loaded runtimes the inherited,
diff --git a/packages/paperclip-runner/runner/crates/runner-core/src/provider_backend.rs b/packages/paperclip-runner/runner/crates/runner-core/src/provider_backend.rs
index 8d038f5fe17..85b114b132d 100644
--- a/packages/paperclip-runner/runner/crates/runner-core/src/provider_backend.rs
+++ b/packages/paperclip-runner/runner/crates/runner-core/src/provider_backend.rs
@@ -538,11 +538,13 @@ fn admit_terminal_tool_authority(
"paperclip_finish" => {
matches!(disposition.as_str(), "done" | "needs_review")
|| (disposition == "yielded"
- && input
- .get("continuation")
- .and_then(|continuation| continuation.get("kind"))
- .and_then(Value::as_str)
- == Some("response_wake"))
+ && matches!(
+ input
+ .get("continuation")
+ .and_then(|continuation| continuation.get("kind"))
+ .and_then(Value::as_str),
+ Some("response_wake" | "monitor")
+ ))
}
"paperclip_block" => disposition == "blocked",
_ => false,
@@ -4900,8 +4902,9 @@ mod tests {
assert_eq!(finish_result.result["error"]["code"], "invalid_tool_call");
assert_eq!(finish_result.result["error"]["retryable"], false);
let finish_message = finish_result.result["error"]["message"].as_str().unwrap();
- assert!(finish_message
- .contains("continuation must include kind=response_wake, summary, and idempotencyKey"));
+ assert!(finish_message.contains(
+ "continuation must include kind=response_wake or monitor, summary, and idempotencyKey"
+ ));
assert!(finish_message.contains("/required (missing \"requiredField\")"));
assert!(finish_message.contains("/additionalProperties"));
assert!(!finish_message.contains("secretSubmittedValue"));
@@ -4916,6 +4919,18 @@ mod tests {
assert!(block_message.len() <= 512);
assert!(!block_message.chars().any(char::is_control));
+ let question_result = schema_rejection(
+ "request_human_input",
+ json!({"PRIVATE_FIELD": "PRIVATE_VALUE"}),
+ );
+ let question_message = question_result.result["error"]["message"].as_str().unwrap();
+ assert!(question_message.contains("payload.questionSet"));
+ assert!(question_message.contains("/required (missing \"requiredField\")"));
+ assert!(!question_message.contains("PRIVATE_FIELD"));
+ assert!(!question_result.result.to_string().contains("PRIVATE_VALUE"));
+ assert!(question_message.len() <= 512);
+ assert_eq!(question_result.result["error"]["retryable"], false);
+
let ordinary_result = schema_rejection("get_task_context", json!({}));
assert_eq!(
ordinary_result.result["error"]["message"],
@@ -5156,6 +5171,25 @@ mod tests {
assert!(state.validate().is_ok());
}
+ #[test]
+ fn accepted_terminal_tool_preserves_an_explicit_monitor_wait() {
+ let mut state = opencode_result_state();
+ let mut result = valid_opencode_result();
+ result["reportedWorkDisposition"] = json!("yielded");
+ result["continuation"] = json!({
+ "kind": "monitor",
+ "summary": "Wait for the scheduled check.",
+ "idempotencyKey": "monitor-1"
+ });
+
+ admit_terminal_tool_authority(&mut state, "paperclip_finish", &result, false).unwrap();
+ let terminal = terminal_events(&state, "turn.completed", None);
+
+ assert_eq!(terminal.len(), 1);
+ assert_eq!(terminal[0].payload["reportedWorkDisposition"], "yielded");
+ assert!(state.validate().is_ok());
+ }
+
#[test]
fn terminal_tool_authority_rejects_an_unbound_yield() {
let mut state = opencode_result_state();
diff --git a/packages/paperclip-runner/runner/crates/runner-core/src/provider_bridge.rs b/packages/paperclip-runner/runner/crates/runner-core/src/provider_bridge.rs
index a1007983368..cbb991f8a3b 100644
--- a/packages/paperclip-runner/runner/crates/runner-core/src/provider_bridge.rs
+++ b/packages/paperclip-runner/runner/crates/runner-core/src/provider_bridge.rs
@@ -39,7 +39,8 @@ const MAX_SETTLED_CALL_IDS: usize = 65_536;
const REPLAY_FILTER_WORDS: usize = 32_768;
const ACTIVE_TURN_RECEIPT_LIMIT_MESSAGE: &str =
"durable provider tool receipt limit reached for the active turn";
-const COMPLETION_INPUT_SCHEMA_HINT: &str = "Invalid paperclip_finish arguments. Required fields: reportedWorkDisposition, summary, completionClaim, evidence, and verification. When reportedWorkDisposition is yielded, continuation must include kind=response_wake, summary, and idempotencyKey.";
+const COMPLETION_INPUT_SCHEMA_HINT: &str = "Invalid paperclip_finish arguments. Required fields: reportedWorkDisposition, summary, completionClaim, evidence, and verification. When reportedWorkDisposition is yielded, continuation must include kind=response_wake or monitor, summary, and idempotencyKey.";
+const QUESTION_INPUT_SCHEMA_HINT: &str = "Invalid request_human_input arguments. Required fields: idempotencyKey, interactionKind, title, prompt, and continuationPolicy. For questions, use payload.version=1 and a complete payload.questionSet matching the authorized schema. Preserve the supplied question and option IDs.";
const BLOCK_INPUT_SCHEMA_HINT: &str = "Invalid paperclip_block arguments. Required fields: reportedWorkDisposition=blocked, summary, completionClaim, evidence, verification, and blocker. blocker must include reasonCode, owner, unblockAction, and scope.";
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
@@ -242,6 +243,7 @@ impl ProviderBridgeError {
let safe_provider_message = match operation_id {
"paperclip_finish" => Some(COMPLETION_INPUT_SCHEMA_HINT),
"paperclip_block" => Some(BLOCK_INPUT_SCHEMA_HINT),
+ "request_human_input" => Some(QUESTION_INPUT_SCHEMA_HINT),
_ => None,
};
Self {
@@ -251,7 +253,7 @@ impl ProviderBridgeError {
}
fn with_schema_locations(mut self, validator: &jsonschema::Validator, input: &Value) -> Self {
- // Only completion tools have a provider-safe hint. Report bounded paths
+ // Only the reserved tools above have a provider-safe hint. Report bounded paths
// into the authorized schema, never the submitted values or unknown keys.
if let Some(message) = self.safe_provider_message.as_mut() {
let locations = validator
diff --git a/packages/paperclip-runner/runner/crates/runner-core/src/provider_events.rs b/packages/paperclip-runner/runner/crates/runner-core/src/provider_events.rs
index 1a469000339..5e1bc498751 100644
--- a/packages/paperclip-runner/runner/crates/runner-core/src/provider_events.rs
+++ b/packages/paperclip-runner/runner/crates/runner-core/src/provider_events.rs
@@ -875,7 +875,7 @@ pub fn normalize_codex_notification(method: &str, params: &Value) -> Vec {
+ "item/started" | "item/updated" | "item/completed" => {
let provider_item = item(params);
let item_id = stable_id(string(provider_item.get("id")), "codex-item");
let item_type = string(provider_item.get("type"));
@@ -883,12 +883,12 @@ pub fn normalize_codex_notification(method: &str, params: &Value) -> Vec "mcp", "dynamicToolCall" => "dynamic", _ => "process" },
+ "transport": match item_type { "mcpToolCall" => "mcp", "dynamicToolCall" => "dynamic", "builtinToolCall" => "builtin", _ => "process" },
"operation": if item_type == "commandExecution" { "execute" } else { "unknown" },
"name": provider_item.get("tool").or_else(|| provider_item.get("command")).and_then(Value::as_str).map(|value| bounded_text(value, 240)),
"target": Value::Null,
@@ -913,6 +913,8 @@ pub fn normalize_codex_notification(method: &str, params: &Value) -> Vec`get_approval`
`get_approval_context`
`request_approval`
`decide_approval`
`comment_on_approval` | `governance:approvals:comment`
`governance:approvals:decide`
`governance:approvals:read`
`governance:approvals:request` | Read, request, comment on, and decide approvals under governed-action checks. |
| `cases` | `list_cases`
`upsert_case` | `cases:read`
`cases:write` | Read and update case summaries without reusing issue-document authority. |
| `workspace_runtime` | `get_workspace_runtime`
`control_workspace_service` | `workspace:control`
`workspace:read` | Inspect and control the active issue workspace runtime. |
-| `wake_scheduling` | `schedule_wake` | `control_plane:wakes` | Schedule a bounded continuation wake when the current task owns the future check. |
+| `wake_scheduling` | `schedule_wake`
`set_task_monitor` | `control_plane:wakes` | Schedule a bounded continuation wake when the current task owns the future check. |
| `routines` | `list_routines`
`manage_routine` | `routines:read`
`routines:write` | Inspect or manage company routines. |
| `company_skills` | `create_skill`
`update_skill`
`list_company_skills`
`sync_company_skills` | `company_skills:read`
`company_skills:write` | Create, update, or inspect company skills and synchronize the current agent's skills. |
| `secrets` | `list_secret_metadata`
`read_secret_value` | `secrets:metadata:read`
`secrets:values:read` | Inspect secret metadata or use a brokered secret value without exposing plaintext evidence. |
@@ -162,6 +162,7 @@ Grant groups are documentation/exposure bundles, not additional authority. The o
| `search_api` | `optional_agent_tool` | `api:discover` | `standard`
`ask`
`planning`
`skill_test` | `read` | `none` | no | inline/no mapping | `live`
`live_codex` | `PaperclipRunnerToolAuthority`
Authenticated PRP tool input/result and existing HTTP route authorization/activity records.
catalog PRP status: `bound` |
| `search_tasks` | `optional_agent_tool` | `discovery:tasks:read` | `standard`
`ask`
`planning`
`skill_test` | `read` | `none` | no | `snapshot_read:company_tasks` | `scenario` + `live`
`live_codex` | `unbound`
read projection surfaced via a tool-result item event; no control-plane state diff
catalog PRP status: `audit_pending` |
| `set_dependencies` | `optional_agent_tool` | `dependencies:write` | `standard`
`skill_test` | `company_write` | `required` | no | `semantic_command:set_dependencies` | `scenario` + `live`
`live_codex` | `issues.update.blockedByIssueIds`
semantic-operation item event plus company-entity state diff and audit record
catalog PRP status: `bound` |
+| `set_task_monitor` | `optional_agent_tool` | none | `standard` | `task_write` | `required` | no | inline/no mapping | `live`
`live_codex` | `prepareIssueMonitorUpdate`
Transactional persisted issue monitor, audit activity and idempotent run receipt.
catalog PRP status: `bound` |
| `set_task_title` | `optional_agent_tool` | none | `standard`
`ask`
`planning`
`skill_test` | `task_write` | `required` | no | inline/no mapping | `live`
`live_codex` | `setIssueTitle`
Run-bound title update and transactional activity record.
catalog PRP status: `bound` |
| `submit_complaint` | `optional_agent_tool` | none | `standard`
`ask`
`planning` | `task_write` | `required` | no | inline/no mapping | `live`
`live_codex` | `submitAgentCommentary`
Run-bound local commentary and transactional activity record.
catalog PRP status: `bound` |
| `submit_suggestion` | `optional_agent_tool` | none | `standard`
`ask`
`planning` | `task_write` | `required` | no | inline/no mapping | `live`
`live_codex` | `submitAgentCommentary`
Run-bound local commentary and transactional activity record.
catalog PRP status: `bound` |
@@ -194,7 +195,7 @@ Behavior groups describe expected outcomes and trajectories. They do not grant t
| [`rf` — Reference files](#behavior-group-rf-reference-files) | always instruction tools + optional domain tools + test-only escape hatch | `list_cases`
`upsert_case`
`list_routines`
`manage_routine`
`create_skill`
`update_skill`
`list_company_skills`
`sync_company_skills`
`list_secret_metadata`
`read_secret_value`
`export_company`
`administer_company`
`generic_api_request`
`search_api`
`call_api`
`create_project`
`read_agent_instructions`
`update_agent_instructions`
`get_agent_instruction_history`
`restore_agent_instructions`
`submit_complaint`
`submit_suggestion` | `append_audit_record` | agent instruction revisions, project, case, routine, company-skill, secret, portability, and administration services, and run-attributed agent commentary | `company`
`cases`
`routines`
`skills`
`secrets`
`audit`
`fault` | 22 | bounded domain projections, redacted broker receipts, company diffs, and audit references | Instruction read/update/history/restore require the live canonical revision service, current responsible-user permissions, and pinned base revisions for writes. Their service, authority, and product E2E tests are separate from the legacy mock scenarios. Project and skill creation and API tools require the live server authority; generic_api_request is test-only and the remaining domain operations are scenario-only. Broad administer_company is deferred and cannot claim product coverage. Production API and paired dedicated-tool regressions are recorded separately in paperclip-evals/evals/runner-api-tools; the legacy scenario count is not evidence of that coverage. Feedback actions are live-only: shared persistence, authority, API, and actual Codex smoke tests cover them; the legacy scenario count does not claim feedback coverage. |
| [`mh` — Multi-hop](#behavior-group-mh-multi-hop) | composed semantic operations + control-plane continuation | `create_task`
`set_dependencies`
`request_human_input`
`request_approval`
`register_deliverable` | `route_wake`
`reconcile_run` | delegation, dependency, interaction, approval, artifact, and terminal orchestration services | `task`
`blockers`
`interactions`
`approvals`
`artifacts`
`wake`
`run`
`audit` | 4 | correlated operation receipts, state diffs, attention hops, work assessment, status decision, and terminal outcome | No generic transaction tool is allowed; shared mock/real conformance must prove each composed effect. |
| [`rs` — Restraint and no-call](#behavior-group-rs-restraint-and-no-call) | policy/exposure layer | `answer_status_question`
`read_secret_value`
`generic_api_request` | `enforce_budget` | task-mode, secret-broker, test-scope, pause, and budget policy checks | `actor`
`task`
`budget`
`secrets`
`audit`
`fault` | 3 | absence of forbidden effects plus typed policy denial/redaction receipts when a call is attempted | Typed redaction/authorization receipts need additive v1 evidence; generic_api_request is never a product fallback. |
-| [`wk` — Wake situations](#behavior-group-wk-wake-situations) | control plane + always context/history tools | `get_task_context`
`get_task_history`
`schedule_wake` | `select_work`
`route_wake` | wakeup requests, heartbeat context, comment/interaction/approval/blocker wake routing, and scheduled wake services | `wake`
`task`
`comments`
`interactions`
`approvals`
`blockers`
`run` | 8 | attention request routing/resolution plus resumed session/run causality | Production scheduling binding is unbound; control-plane routing remains non-callable. |
+| [`wk` — Wake situations](#behavior-group-wk-wake-situations) | control plane + always context/history tools | `get_task_context`
`get_task_history`
`schedule_wake`
`set_task_monitor` | `select_work`
`route_wake` | wakeup requests, heartbeat context, comment/interaction/approval/blocker wake routing, and scheduled wake services | `wake`
`task`
`comments`
`interactions`
`approvals`
`blockers`
`run` | 8 | attention request routing/resolution plus resumed session/run causality | set_task_monitor binds the one-shot monitor scheduler in production; schedule_wake remains mock-backed. Control-plane routing remains non-callable. |
### Scenario links
@@ -468,10 +469,10 @@ Current responsibility-based paths are normative. Numbered `phase-*` or mileston
### Catalog split and deliberate replacement
- Scenario/eval catalog: **40** operations.
-- Live dispatcher catalog: **44** operations.
-- Shared: **28**; union/canonical authority: **56**.
+- Live dispatcher catalog: **45** operations.
+- Shared: **28**; union/canonical authority: **57**.
- Scenario-only: `administer_company`, `export_company`, `inspect_operation_result`, `list_cases`, `list_company_skills`, `list_goals`, `list_routines`, `list_secret_metadata`, `manage_routine`, `read_secret_value`, `sync_company_skills`, `upsert_case`.
-- Live-only: `call_api`, `create_project`, `get_agent`, `get_agent_instruction_history`, `get_approval`, `get_approval_context`, `hire_agent`, `list_project_repositories`, `read_agent_instructions`, `restore_agent_instructions`, `schedule_wake`, `search_api`, `set_task_title`, `submit_complaint`, `submit_suggestion`, `update_agent_instructions`.
+- Live-only: `call_api`, `create_project`, `get_agent`, `get_agent_instruction_history`, `get_approval`, `get_approval_context`, `hire_agent`, `list_project_repositories`, `read_agent_instructions`, `restore_agent_instructions`, `schedule_wake`, `search_api`, `set_task_monitor`, `set_task_title`, `submit_complaint`, `submit_suggestion`, `update_agent_instructions`.
- The generated provider contract contains exactly the live catalog; the canonical union remains the migration authority until all scenario-only operations are either implemented, deferred, or removed by an explicit reconciliation decision.
- `generic_api_request` stays exported only for controlled tests and cannot be cited as real-surface, mock-parity, or PRP product coverage.
diff --git a/packages/paperclip-runner/src/backends/harness-driver-backend.test.ts b/packages/paperclip-runner/src/backends/harness-driver-backend.test.ts
index d550d594d64..a2cf6f970cd 100644
--- a/packages/paperclip-runner/src/backends/harness-driver-backend.test.ts
+++ b/packages/paperclip-runner/src/backends/harness-driver-backend.test.ts
@@ -974,6 +974,28 @@ describe("HarnessDriverBackend", () => {
await expect(iterator.next()).rejects.toThrow("provider transport lost after resolution");
});
+ it.each([false, true])("retains final usage without accepting late output (journal boundary only: %s)", async journalOnly => {
+ class AccountingAfterCancelSession extends FakeHarnessSession {
+ async interrupt() {}
+ override async *events() {
+ yield prpEvent(1, "item.completed", { kind: "agentMessage", text: "late answer" });
+ yield prpEvent(2, "item.completed", { kind: "usage", usage: { runDelta: { inputTokens: 7, outputTokens: 3 }, runDeltaComplete: true } });
+ yield prpEvent(3, "turn.completed", { status: "completed" });
+ }
+ }
+ const backend = new HarnessDriverBackend({ ...driver, async openSession() { return new AccountingAfterCancelSession(); } });
+ const session = await backend.openSession({
+ identity: { runId: "run-1", sessionId: "session-1", companyId: "company-1", issueId: "issue-1", agentId: "agent-1" }, workingDirectory: "/workspace",
+ });
+ if (journalOnly) session.revokeTurnPublication();
+ else await session.cancel({ reason: "durable governed wait", signal: new AbortController().signal }).cleanup;
+ const events = [];
+ for await (const event of session.events()) events.push(event);
+ expect(events.filter(event => event.payload.kind === "agentMessage")).toHaveLength(0);
+ expect(events.find(event => event.payload.kind === "usage")?.payload.usage).toMatchObject({ runDelta: { inputTokens: 7, outputTokens: 3 } });
+ expect(events.some(event => event.eventType === "turn.cancelled")).toBe(true);
+ });
+
it("does not start provider work when Stop arrives before the first turn", async () => {
const provider = new FakeHarnessSession();
const start = vi.spyOn(provider, "startTurn");
diff --git a/packages/paperclip-runner/src/backends/harness-driver-backend.ts b/packages/paperclip-runner/src/backends/harness-driver-backend.ts
index 52b9faef4df..7c265695fb9 100644
--- a/packages/paperclip-runner/src/backends/harness-driver-backend.ts
+++ b/packages/paperclip-runner/src/backends/harness-driver-backend.ts
@@ -549,7 +549,10 @@ class HarnessNativeSession implements NativeSession {
(event.eventType === "run.terminal" && ["failed", "cancelled"].includes(String(event.payload.runTerminalState))) ||
(event.eventType === "item.completed" &&
event.payload.kind === "interrupt_acknowledgement");
- if (this.#explicitlyCancelled && !isCancellationEvent) continue;
+ // Accounting for work already performed survives cancellation. It grants
+ // no tool, message, semantic-result, or continuation authority.
+ const isUsageReceipt = event.eventType === "item.completed" && event.payload.kind === "usage";
+ if (this.#explicitlyCancelled && !isCancellationEvent && !isUsageReceipt) continue;
sourceInstanceId = event.sourceInstanceId;
lastSourceSequence = Math.max(lastSourceSequence, event.sourceSeq);
if (event.eventType === "runtime_request.created") {
@@ -735,6 +738,10 @@ class HarnessNativeSession implements NativeSession {
return this.#session.interrupt(input);
}
+ revokeTurnPublication() {
+ this.#explicitlyCancelled = true;
+ }
+
cancel(input: { reason: string; signal: AbortSignal }) {
if (input.signal.aborted) {
throw (
@@ -744,7 +751,7 @@ class HarnessNativeSession implements NativeSession {
// This flag is the adapter's synchronous publication boundary. Provider
// interruption happens afterward as passive cleanup, so a slow or broken
// transport cannot synthesize or publish new accepted output for the turn.
- this.#explicitlyCancelled = true;
+ this.revokeTurnPublication();
const interrupt = this.#session.interrupt;
return {
cleanup:
diff --git a/packages/paperclip-runner/src/backends/runtime-context.test.ts b/packages/paperclip-runner/src/backends/runtime-context.test.ts
index d77dda3ff68..bfa1fa76be0 100644
--- a/packages/paperclip-runner/src/backends/runtime-context.test.ts
+++ b/packages/paperclip-runner/src/backends/runtime-context.test.ts
@@ -77,7 +77,8 @@ describe("native runtime context files", () => {
}
expect(PRP_COMPLETION_TOOL_DESCRIPTION).toContain("do not claim completion while gated");
expect(PRP_COMPLETION_TOOL_DESCRIPTION).toContain("supplied link and action");
- expect(PRP_COMPLETION_TOOL_DESCRIPTION).toContain("explicit wait for the next response");
+ expect(PRP_COMPLETION_TOOL_DESCRIPTION).toContain("yielded with response_wake for a response");
+ expect(PRP_COMPLETION_TOOL_DESCRIPTION).toContain("monitor after set_task_monitor confirms a schedule on this task");
expect(PRP_BLOCK_TOOL_DESCRIPTION).toContain("its owner, and the action needed to unblock it");
expect(constraints).not.toContain(
"final response exactly once before invoking",
diff --git a/packages/paperclip-runner/src/catalog/reconciliation.test.ts b/packages/paperclip-runner/src/catalog/reconciliation.test.ts
index 4ae8029b3bf..923fc036b33 100644
--- a/packages/paperclip-runner/src/catalog/reconciliation.test.ts
+++ b/packages/paperclip-runner/src/catalog/reconciliation.test.ts
@@ -20,9 +20,9 @@ describe("canonical semantic-catalog reconciliation authority", () => {
it("pins the reconciled op-set relationship between the two catalogs", () => {
const summary = capabilityCatalogReconciliation();
expect(summary.scenarioCount).toBe(40);
- expect(summary.liveCount).toBe(44);
+ expect(summary.liveCount).toBe(45);
expect(summary.sharedCount).toBe(28);
- expect(summary.unionCount).toBe(56);
+ expect(summary.unionCount).toBe(57);
// Any operation added to or removed from either catalog without a
// reconciliation decision changes these exact sets and fails the gate.
expect(summary.liveOnly).toEqual([
@@ -38,6 +38,7 @@ describe("canonical semantic-catalog reconciliation authority", () => {
"restore_agent_instructions",
"schedule_wake",
"search_api",
+ "set_task_monitor",
"set_task_title",
"submit_complaint",
"submit_suggestion",
@@ -60,7 +61,7 @@ describe("canonical semantic-catalog reconciliation authority", () => {
});
it("is the single source both catalogs derive their operation set from", () => {
- expect(CAPABILITY_CANONICAL_OPERATIONS).toHaveLength(56);
+ expect(CAPABILITY_CANONICAL_OPERATIONS).toHaveLength(57);
const canonicalIds = new Set(CAPABILITY_CANONICAL_OPERATIONS.map((operation) => operation.operationId));
// Neither catalog may contain an operation absent from the canonical source.
for (const tool of SCENARIO_CATALOG) expect(canonicalIds.has(tool.operationId)).toBe(true);
@@ -94,7 +95,7 @@ describe("canonical semantic-catalog reconciliation authority", () => {
});
it("names placement, claims, task modes, side-effect class, idempotency, redaction, mock mapping, real binding status, and PRP evidence for every operation", () => {
- expect(CAPABILITY_CANONICAL_CATALOG).toHaveLength(56);
+ expect(CAPABILITY_CANONICAL_CATALOG).toHaveLength(57);
for (const operation of CAPABILITY_CANONICAL_CATALOG) {
expect(operation.placement).toMatch(/^(always|optional)_agent_tool$/);
expect(Array.isArray(operation.requiredClaims)).toBe(true);
@@ -120,7 +121,7 @@ describe("canonical semantic-catalog reconciliation authority", () => {
it("classifies real binding status so generic_api_request is never product coverage", () => {
const summary = capabilityCatalogReconciliation();
expect(summary.byRealBindingStatus).toEqual({
- live_codex: 43,
+ live_codex: 44,
scenario_mock: 12,
test_only: 1,
});
diff --git a/packages/paperclip-runner/src/catalog/semantic-action-catalog.test.ts b/packages/paperclip-runner/src/catalog/semantic-action-catalog.test.ts
index a313a9ab10f..df7307a078b 100644
--- a/packages/paperclip-runner/src/catalog/semantic-action-catalog.test.ts
+++ b/packages/paperclip-runner/src/catalog/semantic-action-catalog.test.ts
@@ -69,7 +69,8 @@ describe("semantic action catalog", () => {
(action) => action.operationId,
);
- expect(operationIds).toHaveLength(36);
+ expect(operationIds).toHaveLength(37);
+ expect(operationIds).toContain("set_task_monitor");
expect(new Set(operationIds).size).toBe(operationIds.length);
expect(operationIds).not.toContain("generic_api_request");
expect(Object.isFrozen(PAPERCLIP_SEMANTIC_ACTION_CATALOG)).toBe(true);
diff --git a/packages/paperclip-runner/src/catalog/semantic-action-catalog.ts b/packages/paperclip-runner/src/catalog/semantic-action-catalog.ts
index cc7c2848662..6f4480a3385 100644
--- a/packages/paperclip-runner/src/catalog/semantic-action-catalog.ts
+++ b/packages/paperclip-runner/src/catalog/semantic-action-catalog.ts
@@ -1,3 +1,4 @@
+import { setTaskMonitorInputSchema } from "../protocol-actions/set-task-monitor.js";
import { listProjectsDescription, listProjectsInputSchema } from "../protocol-actions/list-projects.js";
import { setTaskTitleAction } from "../protocol-actions/set-task-title.js";
import { reassignTaskAction } from "../protocol-actions/reassign-task.js";
@@ -583,6 +584,12 @@ const descriptors: readonly PaperclipSemanticActionDescriptor[] = [
),
outputSchema: operationReceipt,
}),
+ descriptor({
+ operationId: "set_task_monitor", title: "Set task monitor",
+ description: "Schedule, replace or clear a persisted one-shot monitor on an owned task.",
+ placement: "optional", effect: "write", requiredClaims: [], allowedModes: ["standard"],
+ inputSchema: setTaskMonitorInputSchema, outputSchema: openObject,
+ }),
descriptor({
operationId: "schedule_wake",
title: "Schedule bounded wake",
diff --git a/packages/paperclip-runner/src/catalog/semantic-action-types.ts b/packages/paperclip-runner/src/catalog/semantic-action-types.ts
index 0dd1f9c38ec..5f2f1bfef07 100644
--- a/packages/paperclip-runner/src/catalog/semantic-action-types.ts
+++ b/packages/paperclip-runner/src/catalog/semantic-action-types.ts
@@ -2,6 +2,7 @@ export type PaperclipSemanticActionId =
| "search_api"
| "call_api"
| "set_task_title"
+ | "set_task_monitor"
| "get_task_context"
| "get_task_history"
| "list_documents"
diff --git a/packages/paperclip-runner/src/cli/opencode-app-server-proxy.ts b/packages/paperclip-runner/src/cli/opencode-app-server-proxy.ts
index d46406d159f..11cc112dea7 100644
--- a/packages/paperclip-runner/src/cli/opencode-app-server-proxy.ts
+++ b/packages/paperclip-runner/src/cli/opencode-app-server-proxy.ts
@@ -13,6 +13,7 @@ import { parseNativeRuntimeContext } from "../contracts/runtime-context.js";
import { openCodeProxyTaskEnvelope } from "./opencode-proxy-task-envelope.js";
import {
openCodeProxyItemNotification,
+ openCodeProxyToolNotification,
openCodeProxyTerminalNotification,
shouldAnnounceOpenCodeProxyTurn,
shouldForwardOpenCodeProxyItem,
@@ -192,7 +193,11 @@ function announceTurnStarted(opened: HarnessSession, turnId: string): void {
async function pumpEvents(opened: HarnessSession): Promise {
for await (const event of opened.events()) {
const payload = record(event.payload);
- if (event.eventType === "turn.started") {
+ const toolActivity = openCodeProxyToolNotification({ eventType: event.eventType,
+ threadId: opened.ids().driverSessionId, turnId: event.turnId, payload });
+ if (toolActivity) {
+ send(toolActivity);
+ } else if (event.eventType === "turn.started") {
if (typeof event.turnId === "string")
announceTurnStarted(opened, event.turnId);
} else if (
diff --git a/packages/paperclip-runner/src/cli/opencode-proxy-events.ts b/packages/paperclip-runner/src/cli/opencode-proxy-events.ts
index eff92c70773..1dfe90af890 100644
--- a/packages/paperclip-runner/src/cli/opencode-proxy-events.ts
+++ b/packages/paperclip-runner/src/cli/opencode-proxy-events.ts
@@ -1,3 +1,24 @@
+/** Forward bounded tool activity without inventing a host-call identity or arguments. */
+export function openCodeProxyToolNotification(input: {
+ eventType: string; threadId: string; turnId?: string; payload: Record;
+}): { method: string; params: Record } | null {
+ const phase = ({ "tool.execution.started": "started", "tool.execution.progressed": "updated", "tool.execution.completed": "completed" } as Record)[input.eventType];
+ if (!phase) return null;
+ const p = input.payload;
+ if (!input.turnId || typeof p.executionId !== "string" || !p.executionId || p.schema !== "paperclip.tool.execution.v1")
+ throw new Error("OpenCode tool activity omitted its bound identity");
+ const type = ({ builtin: "builtinToolCall", mcp: "mcpToolCall", dynamic: "dynamicToolCall", process: "commandExecution" } as Record)[String(p.transport)];
+ if (!type) throw new Error("OpenCode tool activity has an unsupported transport");
+ return { method: `item/${phase}`, params: {
+ threadId: input.threadId, turnId: input.turnId, itemId: p.executionId,
+ item: { id: p.executionId, type, tool: p.name, server: p.namespace,
+ readOnlyHint: p.readOnly, status: p.status, durationMs: p.durationMs, exitCode: p.exitCode,
+ // This is the already bounded provider-visible result, not raw input or a private trace.
+ output: typeof p.output === "string" ? p.output.slice(0, 16_384) : "",
+ },
+ } };
+}
+
export function shouldForwardOpenCodeProxyItem(input: {
turnId?: string;
kind?: unknown;
diff --git a/packages/paperclip-runner/src/cli/opencode-proxy-input.test.ts b/packages/paperclip-runner/src/cli/opencode-proxy-input.test.ts
index 0cb6a887f3c..d74eb069391 100644
--- a/packages/paperclip-runner/src/cli/opencode-proxy-input.test.ts
+++ b/packages/paperclip-runner/src/cli/opencode-proxy-input.test.ts
@@ -106,11 +106,17 @@ it.each([true, false])("settles a real proxy interrupt with controller feedback
await response(1);
send({ id: 2, method: "thread/start", params: { cwd: root, model: "openrouter/deepseek/deepseek-v4-flash-0731", completionContract: { revision: "proxy-v1", criterionIds: ["objective"] }, conversationMode: "prepared" } });
await response(2);
- send({ id: 3, method: "turn/start", params: { input: [{ type: "text", text: JSON.stringify({ schema: "paperclip.native-model-envelope.v3", task: { prompt: "completion-feedback" }, completionContract: { revision: "proxy-v1", criteria: [{ id: "objective", requirement: "Complete the fixture." }] } }) }] } });
+ send({ id: 3, method: "turn/start", params: { input: [{ type: "text", text: JSON.stringify({ schema: "paperclip.native-model-envelope.v3", task: { prompt: "invalid-tool-feedback completion-feedback" }, completionContract: { revision: "proxy-v1", criteria: [{ id: "objective", requirement: "Complete the fixture." }] } }) }] } });
await response(3);
await expect.poll(() => messages.find(message => message.method === "item/tool/call"), { timeout: 5_000 }).toBeDefined();
const call = messages.find(message => message.method === "item/tool/call")!;
expect(call.params!.tool).toBe("paperclip_finish");
+ const toolFrames = messages.filter(message => (message.params?.item as { id?: string } | undefined)?.id === "part-invalid");
+ expect(toolFrames.map(message => message.method)).toEqual(["item/started", "item/updated", "item/completed"]);
+ expect(toolFrames.at(-1)?.params).toMatchObject({
+ threadId: call.params!.threadId, turnId: call.params!.turnId,
+ item: { id: "part-invalid", type: "builtinToolCall", tool: "invalid", status: "failed", output: "Tool not found: fixture_missing" },
+ });
const feedback = "Accepted. Include [Saved document](/PAP/issues/PAP-1#document-plan).";
// The interrupt is ahead of the response on stdin. Commands stay serial,
// but their awaited response must not queue behind the command itself.
diff --git a/packages/paperclip-runner/src/configured-environment.test.ts b/packages/paperclip-runner/src/configured-environment.test.ts
new file mode 100644
index 00000000000..94313010790
--- /dev/null
+++ b/packages/paperclip-runner/src/configured-environment.test.ts
@@ -0,0 +1,99 @@
+import { CONFIGURED_ENVIRONMENT_KEYS, configuredEnvironment, configuredEnvironmentProjection } from './configured-environment.js';
+import { describe, expect, it, vi } from 'vitest';
+import { createSanitizedCodexEnvironment } from './drivers/codex/app-server-transport.js';
+import { createIsolatedCodexAppServerArgs } from './drivers/codex/codex-security-config.js';
+import { createCapabilityRunnerdProviderEnvironment } from './live/runnerd-codex-transport.js';
+import { spawnRunner } from './control-plane/durable-prp-control-plane.js';
+
+const pages = {
+ PAPERCLIP_PAGE_AWS_ACCESS_KEY_ID: 'fake-page-access-key',
+ PAPERCLIP_PAGE_AWS_SECRET_ACCESS_KEY: 'fake-page-secret',
+ PAPERCLIP_PAGE_BUCKET: 'pages.example.test',
+};
+const source = { ...configuredEnvironmentProjection(pages), PATH: '/bin', ...pages, DATABASE_URL: 'host-secret-must-not-cross', NODE_OPTIONS: '--require=/untrusted/bootstrap.js', PAPERCLIP_API_KEY: 'controller-api-key-must-not-cross' };
+const identity = { runnerInstanceId: 'runner-proof', environmentLeaseId: 'lease-proof', runId: 'run-proof', normalizedSessionId: 'session-proof', turnId: 'turn-proof', itemId: 'item-proof' };
+function shellKeys() {
+ const args = createIsolatedCodexAppServerArgs(source);
+ const setting = args.find(value => value.startsWith('shell_environment_policy.include_only='))!;
+ return { keys: JSON.parse(setting.slice(setting.indexOf('=') + 1)) as string[], serialized: args.join('\n') };
+}
+
+describe('controller-configured environment across native runner boundaries', () => {
+ it('retains configured Pages values at the native Codex provider sanitizer', () => {
+ expect(createSanitizedCodexEnvironment(source)).toMatchObject(pages);
+ });
+ it('retains configured Pages values when preparing a fresh runnerd process', () => {
+ expect(createCapabilityRunnerdProviderEnvironment({ provider: 'codex', options: { environment: source }, identity, codexHome: '/isolated/codex-home', runtimeContextPath: '/isolated/runtime-context.json', hasRuntimeContext: false })).toMatchObject(pages);
+ });
+ it('passes configured Pages values through the runner spawn boundary', () => {
+ let launched: NodeJS.ProcessEnv | undefined;
+ spawnRunner({ connection: { mode: 'connect', connectUrl: 'ws://127.0.0.1:43127' }, stateDirectory: '/tmp/runner-env-proof', identity, ticket: 'fake-ticket', maxOutboxBytes: 262144, p0ReserveBytes: 65536, runnerVersion: '0.3.0', runnerDigest: `sha256:${'a'.repeat(64)}`, environment: source,
+ processLauncher: spec => { launched = spec.environment; return { child: { pid: 42, exitCode: null, signalCode: null, kill: () => true }, completion: Promise.resolve({ code: 0, signal: null, stdout: '', stderr: '' }) }; },
+ });
+ expect(launched).toMatchObject(pages);
+ expect(launched!.DATABASE_URL).toBeUndefined();
+ expect(launched!.NODE_OPTIONS).toBeUndefined();
+ expect(launched!.PAPERCLIP_API_KEY).toBeUndefined();
+ });
+ it('allows configured Pages values into model-issued shell commands without serializing secrets into argv', () => {
+ const { keys, serialized } = shellKeys();
+ expect(keys).toEqual(expect.arrayContaining(Object.keys(pages)));
+ expect(keys).not.toContain('DATABASE_URL');
+ expect(keys).not.toContain('NODE_OPTIONS');
+ expect(keys).not.toContain('PAPERCLIP_API_KEY');
+ for (const value of Object.values(pages)) expect(serialized).not.toContain(value);
+ });
+ it('continues to exclude unbound ambient Pages credentials and host secrets', () => {
+ vi.stubEnv('PAPERCLIP_PAGE_AWS_SECRET_ACCESS_KEY', 'ambient-page-secret');
+ try {
+ expect(createSanitizedCodexEnvironment().PAPERCLIP_PAGE_AWS_SECRET_ACCESS_KEY).toBeUndefined();
+ const sanitized = createSanitizedCodexEnvironment(source);
+ expect(sanitized.DATABASE_URL).toBeUndefined();
+ expect(sanitized.NODE_OPTIONS).toBeUndefined();
+ expect(sanitized.PAPERCLIP_API_KEY).toBeUndefined();
+ } finally { vi.unstubAllEnvs(); }
+ });
+});
+
+
+describe("configured environment authority", () => {
+ it("keeps selected bootstrap values in the environment rather than argv", () => {
+ const environment = { PATH: "/bin", ...configuredEnvironmentProjection({ LANG: "configured-language-value" }) };
+ const args = createIsolatedCodexAppServerArgs(environment);
+ expect(args.join("\n")).not.toContain("configured-language-value");
+ expect(args.find(arg => arg.startsWith("shell_environment_policy.include_only="))).toContain("LANG");
+ });
+
+ it("projects ordinary task credentials only when explicitly selected", () => {
+ const projected = configuredEnvironmentProjection({ DATABASE_URL: "task-db", CUSTOM_FLAG: "on", NODE_OPTIONS: "unsafe", PAPERCLIP_API_KEY: "controller" });
+ expect(createSanitizedCodexEnvironment(projected)).toMatchObject({ DATABASE_URL: "task-db", CUSTOM_FLAG: "on" });
+ expect(projected.NODE_OPTIONS).toBeUndefined();
+ expect(projected.PAPERCLIP_API_KEY).toBeUndefined();
+ });
+
+ it("does not accept an ambient projection in the provider or shell policy", () => {
+ vi.stubEnv(CONFIGURED_ENVIRONMENT_KEYS, JSON.stringify(["PAPERCLIP_PAGE_AWS_SECRET_ACCESS_KEY"]));
+ vi.stubEnv("PAPERCLIP_PAGE_AWS_SECRET_ACCESS_KEY", "ambient-secret");
+ try {
+ expect(createSanitizedCodexEnvironment().PAPERCLIP_PAGE_AWS_SECRET_ACCESS_KEY).toBeUndefined();
+ expect(createIsolatedCodexAppServerArgs().join("\n")).not.toContain("PAPERCLIP_PAGE_AWS_SECRET_ACCESS_KEY");
+ } finally { vi.unstubAllEnvs(); }
+ });
+
+ it.each(["not-json", "[1]", '["NODE_OPTIONS"]', '["PAPERCLIP_API_KEY"]', '["PAPERCLIP_RUNNER_BOOTSTRAP_TICKET"]', '["OPENAI_API_KEY"]', '["LD_PRELOAD"]', '["bad=name"]', '["CUSTOM","CUSTOM"]', '["MISSING"]'])
+ ("rejects malformed or reserved projection %s", raw => {
+ expect(() => configuredEnvironment({ [CONFIGURED_ENVIRONMENT_KEYS]: raw })).toThrow("Invalid configured environment");
+ });
+
+ it("rejects oversized and null-containing values without reporting their contents", () => {
+ for (const value of ["x".repeat(65_536), "secret\0suffix"]) {
+ expect(() => configuredEnvironmentProjection({ CUSTOM: value })).toThrow(/configured environment|Configured environment/);
+ }
+ });
+
+ it("preserves configured values through ACPX and OpenCode preparation", async () => {
+ const { createSanitizedAcpxSpawnInput } = await import("./drivers/acpx/environment.js");
+ expect(createSanitizedAcpxSpawnInput(source, "codex").env).toMatchObject(pages);
+ expect(createCapabilityRunnerdProviderEnvironment({ provider: "opencode", options: { environment: source }, identity, codexHome: "/isolated/home", runtimeContextPath: "/isolated/context", hasRuntimeContext: false })).toMatchObject(pages);
+ });
+});
diff --git a/packages/paperclip-runner/src/configured-environment.ts b/packages/paperclip-runner/src/configured-environment.ts
new file mode 100644
index 00000000000..bd10a7e7813
--- /dev/null
+++ b/packages/paperclip-runner/src/configured-environment.ts
@@ -0,0 +1,76 @@
+/** Names minted by the controller from the resolved task configuration.
+ * Values remain in the process environment, never in argv or this manifest.
+ * Do not mint this projection from ambient process.env.
+ */
+export const CONFIGURED_ENVIRONMENT_KEYS = "PAPERCLIP_CONFIGURED_ENV_KEYS";
+
+export const GENERATED_RUNTIME_ENVIRONMENT_KEYS: ReadonlySet = new Set([
+ CONFIGURED_ENVIRONMENT_KEYS,
+ "PAPERCLIP_AGENT_ID", "PAPERCLIP_AGENT_KEY_ID", "PAPERCLIP_AGENT_PUBLIC_KEY", "PAPERCLIP_AGENT_PRIVATE_KEY",
+ "PAPERCLIP_API_KEY", "PAPERCLIP_API_URL", "PAPERCLIP_API_BRIDGE_MODE", "PAPERCLIP_COMPANY_ID", "PAPERCLIP_INSTANCE_ID",
+ "PAPERCLIP_RUN_ID", "PAPERCLIP_NORMALIZED_SESSION_ID", "PAPERCLIP_RUNNER_INSTANCE_ID", "PAPERCLIP_RUNNER_BOOTSTRAP_TICKET", "PAPERCLIP_TASK_ID", "PAPERCLIP_APPROVAL_ID", "PAPERCLIP_APPROVAL_STATUS", "PAPERCLIP_LINKED_ISSUE_IDS",
+ "PAPERCLIP_WAKE_REASON", "PAPERCLIP_WAKE_COMMENT_ID", "PAPERCLIP_WAKE_PAYLOAD_JSON", "PAPERCLIP_EXECUTION_MODE",
+ "PAPERCLIP_WORKSPACES_JSON", "PAPERCLIP_WORKSPACE_ID", "PAPERCLIP_WORKSPACE_CWD", "PAPERCLIP_WORKSPACE_SOURCE",
+ "PAPERCLIP_WORKSPACE_REPO_URL", "PAPERCLIP_WORKSPACE_REPO_REF", "PAPERCLIP_WORKSPACE_BRANCH",
+ "PAPERCLIP_WORKSPACE_WORKTREE_PATH", "PAPERCLIP_WORKSPACE_REALIZATION_MODE", "PAPERCLIP_WORKSPACE_AUTHORITATIVE_ROOT",
+ "PAPERCLIP_RUNTIME_PRIMARY_URL", "PAPERCLIP_RUNTIME_SERVICES_JSON", "PAPERCLIP_RUNTIME_SERVICE_INTENTS_JSON",
+ "PAPERCLIP_AGENT_MESSAGE_KEY", "PAPERCLIP_HARNESS_CHECKOUT_KEY", "PAPERCLIP_EXTERNAL_CHAT_EXECUTION_BOUND_KEY",
+ "PAPERCLIP_NATIVE_MCP_NAME", "PAPERCLIP_NATIVE_MCP_URL", "PAPERCLIP_NATIVE_MCP_TOKEN", "PAPERCLIP_AI_PROVIDER_KEY",
+ "PAPERCLIP_PROVIDER_TRACE_PATH", "PAPERCLIP_PROVIDER_TRACE_MAX_BYTES", "PAPERCLIP_ACPX_CREDENTIAL_BINDING",
+ "PAPERCLIP_RUNNER_NETWORK_ACCESS", "PAPERCLIP_RUNNER_NETWORK_ROOTS", "PAPERCLIP_RUNNER_EXTERNAL_SANDBOX",
+ "PAPERCLIP_GITHUB_AUTH_MODE", "PAPERCLIP_GITHUB_HOST_HOME", "PAPERCLIP_GIT_METADATA_ROOTS",
+ "PAPERCLIP_GITHUB_BROKER_TOKEN", "PAPERCLIP_GITHUB_BROKER_URL", "PAPERCLIP_GITHUB_BRIDGE_TOKEN", "PAPERCLIP_GITHUB_LAUNCHER_DIR",
+]);
+
+const RESERVED_KEYS = new Set([
+ "PATH", "HOME", "USERPROFILE", "CODEX_HOME", "AGENT_HOME", "SHELL", "NODE_OPTIONS", "NODE_PATH",
+ "PYTHONPATH", "PYTHONHOME", "RUBYOPT", "RUBYLIB", "PERL5OPT", "PERL5LIB", "BASH_ENV", "ENV",
+ "OPENAI_API_KEY", "CODEX_API_KEY", "ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN", "CLAUDE_CODE_OAUTH_TOKEN",
+ "AWS_BEARER_TOKEN_BEDROCK", "OPENROUTER_API_KEY", "XAI_API_KEY", "CURSOR_API_KEY", "CURSOR_AUTH_TOKEN",
+ "COPILOT_GITHUB_TOKEN", "GH_TOKEN", "GITHUB_TOKEN", "GH_ENTERPRISE_TOKEN", "GITHUB_ENTERPRISE_TOKEN", "PAPERCLIP_GIT_TOKEN",
+]);
+
+function eligibleKey(key: string): boolean {
+ const upper = key.toUpperCase();
+ return /^[A-Za-z_][A-Za-z0-9_]{0,127}$/.test(key)
+ && !GENERATED_RUNTIME_ENVIRONMENT_KEYS.has(upper)
+ && !RESERVED_KEYS.has(upper)
+ && !/^(?:LD_|DYLD_|GIT_CONFIG_|PAPERCLIP_(?:RUNNER_|NATIVE_|GITHUB_|ACPX_|VERIFIED_))/.test(upper);
+}
+
+function checkedNames(names: unknown): string[] {
+ if (!Array.isArray(names) || names.length > 128 || names.some(name => typeof name !== "string" || !eligibleKey(name))
+ || new Set(names).size !== names.length) throw new Error("Invalid configured environment projection");
+ return (names as string[]).sort();
+}
+
+/** Mint at the server's resolved configuration boundary, before host inheritance. */
+export function configuredEnvironmentProjection(source: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
+ const names = checkedNames(Object.keys(source).filter(key => source[key] !== undefined && eligibleKey(key)));
+ return configuredEnvironment({ ...source, [CONFIGURED_ENVIRONMENT_KEYS]: JSON.stringify(names) });
+}
+
+/** Accept only an explicitly supplied, controller-minted projection. */
+export function configuredEnvironment(source: NodeJS.ProcessEnv | undefined): NodeJS.ProcessEnv {
+ const raw = source?.[CONFIGURED_ENVIRONMENT_KEYS];
+ if (raw === undefined) return {};
+ if (Buffer.byteLength(raw) > 20_000) throw new Error("Invalid configured environment projection");
+ let names: string[];
+ try { names = checkedNames(JSON.parse(raw)); } catch { throw new Error("Invalid configured environment projection"); }
+ const result: NodeJS.ProcessEnv = {};
+ let bytes = 0;
+ for (const name of names) {
+ const value = source?.[name];
+ if (typeof value !== "string" || value.includes("\0")) throw new Error("Invalid configured environment value");
+ const size = Buffer.byteLength(name) + Buffer.byteLength(value);
+ bytes += size;
+ if (size > 65_536 || bytes > 262_144) throw new Error("Configured environment exceeds its bounded launch size");
+ result[name] = value;
+ }
+ result[CONFIGURED_ENVIRONMENT_KEYS] = JSON.stringify(names);
+ return result;
+}
+
+export function configuredEnvironmentKeys(source: NodeJS.ProcessEnv | undefined): string[] {
+ return Object.keys(configuredEnvironment(source)).filter(key => key !== CONFIGURED_ENVIRONMENT_KEYS).sort();
+}
diff --git a/packages/paperclip-runner/src/contracts/completion-result.test.ts b/packages/paperclip-runner/src/contracts/completion-result.test.ts
index 796791e904a..b6a01818187 100644
--- a/packages/paperclip-runner/src/contracts/completion-result.test.ts
+++ b/packages/paperclip-runner/src/contracts/completion-result.test.ts
@@ -31,6 +31,17 @@ describe("provider-neutral completion result schema", () => {
const validate = new Ajv2020({ allErrors: true, strict: false })
.compile(PRP_COMPLETION_RESULT_OUTPUT_SCHEMA);
+ it("accepts an explicit monitor wait across provider and normalized schemas", () => {
+ const report = { ...baseResult, reportedWorkDisposition: "yielded",
+ completionClaim: { ...baseResult.completionClaim, objectiveSatisfied: false,
+ remainingWork: [{ description: "Check the next run", blocksCompletion: true }] },
+ continuation: { kind: "monitor", summary: "Wait for persisted timer", idempotencyKey: "monitor-wait" } };
+ expect(validate(report)).toBe(true);
+ const providerValidate = new Ajv2020({ allErrors: true, strict: false }).compile(PRP_COMPLETION_RESULT_PROVIDER_INPUT_SCHEMA);
+ expect(providerValidate(report)).toBe(true);
+ expect(validate({ ...report, continuation: { ...report.continuation, kind: "invented" } })).toBe(false);
+ });
+
it("allows done with no verification and no actionable attention", () => {
expect(validate(structuredClone(baseResult))).toBe(true);
});
diff --git a/packages/paperclip-runner/src/contracts/completion-result.ts b/packages/paperclip-runner/src/contracts/completion-result.ts
index 87d8a34a29b..781bdd85c63 100644
--- a/packages/paperclip-runner/src/contracts/completion-result.ts
+++ b/packages/paperclip-runner/src/contracts/completion-result.ts
@@ -3,7 +3,7 @@ export const PRP_COMPLETION_TOOL_NAME = "paperclip_finish" as const;
export const PRP_BLOCK_TOOL_NAME = "paperclip_block" as const;
/** Native Runner guidance; legacy adapters use their own skill/API completion paths. */
export const PRP_COMPLETION_TOOL_DESCRIPTION =
- "Report completed work (done), work requiring review (needs_review), or an explicit wait for the next response (yielded with response_wake). Use the current completion contract and supporting evidence. If rejected, correct the report and retry. After acceptance, read the returned outcome; do not claim completion while gated. Explain any required approval with its supplied link and action, then write the final response and end the turn without further tool calls.";
+ "Report completed work (done), work requiring review (needs_review), or an explicit wait (yielded with response_wake for a response, or monitor after set_task_monitor confirms a schedule on this task). Use the current completion contract and supporting evidence. If rejected, correct the report and retry. After acceptance, read the returned outcome; do not claim completion while gated. Explain any required approval with its supplied link and action, then write the final response and end the turn without further tool calls.";
export const PRP_BLOCK_TOOL_DESCRIPTION =
"Report work that cannot continue because of a concrete blocker. Identify the blocker, its owner, and the action needed to unblock it; use the current completion contract and supporting evidence. If rejected, correct the report and retry. After acceptance, read the returned outcome, explain the blocker and any required action in the final response, and end the turn without further tool calls.";
export const PRP_SEMANTIC_TOOL_NAMES = [
@@ -144,14 +144,14 @@ const artifactsSchema = {
},
} as const;
-const responseWakeContinuationSchema = {
+const waitContinuationSchema = {
type: "object",
description:
- "Required when reportedWorkDisposition is yielded. Wait for the next response without scheduling work; include kind, summary, and a stable idempotencyKey.",
+ "Required when reportedWorkDisposition is yielded. Use response_wake for a response wait, or monitor only after a real monitor is persisted on the current task. Include kind, summary, and a stable idempotencyKey.",
additionalProperties: false,
required: ["kind", "summary", "idempotencyKey"],
properties: {
- kind: { type: "string", const: "response_wake" },
+ kind: { type: "string", enum: ["response_wake", "monitor"] },
summary: {
type: "string",
minLength: 1,
@@ -192,7 +192,7 @@ export const PRP_COMPLETION_RESULT_OUTPUT_SCHEMA = {
properties: {
...commonResultProperties,
reportedWorkDisposition: { enum: ["done", "needs_review", "yielded"] },
- continuation: responseWakeContinuationSchema,
+ continuation: waitContinuationSchema,
},
allOf: [
{
@@ -367,10 +367,10 @@ export const PRP_COMPLETION_RESULT_PROVIDER_INPUT_SCHEMA = {
// tool calls. Give non-yielding results an explicit absence value instead
// of forcing callers to invent a response-wake continuation.
continuation: {
- ...responseWakeContinuationSchema,
+ ...waitContinuationSchema,
type: ["object", "null"],
description:
- "Use null or omit this field for done, completed, or needs_review. Only yielded requires a response-wake object with kind, summary, and idempotencyKey.",
+ "Use null or omit this field for done, completed, or needs_review. Only yielded requires a wait object with kind (response_wake or monitor), summary, and idempotencyKey.",
},
},
// Keep the provider-facing root a concrete object. Codex code-mode renders a
diff --git a/packages/paperclip-runner/src/contracts/native-session-backend.ts b/packages/paperclip-runner/src/contracts/native-session-backend.ts
index 87af9e2ad05..f473b56a03e 100644
--- a/packages/paperclip-runner/src/contracts/native-session-backend.ts
+++ b/packages/paperclip-runner/src/contracts/native-session-backend.ts
@@ -63,6 +63,10 @@ export interface PersistedNativeSession {
terminal?: PrpTerminalState | null;
activeTurnId?: string | null;
terminalTurns?: PersistedHarnessTurnTerminal[];
+ /** Control-plane disposition bound to the exact committed tool event. It is
+ * independent of the interaction's later answer and proves no provider terminal. */
+ governedWait?: { sourceEvent: PrpEvent; result: PrpStructuredRunResult };
+
/** At-most-once marker for resultless disposition repair or restart continuation. */
dispositionOnlyRecoveryConsumed?: boolean;
dispositionOnlyRecoveryTurnId?: string | null;
@@ -200,6 +204,9 @@ export interface NativeSession {
correlationId?: string;
}): Promise;
interrupt?(input: { turnId?: string; reason?: string }): Promise;
+ /** Revoke publication synchronously while the control plane journals a wait.
+ * Does not interrupt the provider; cancel owns the subsequent passive cleanup. */
+ revokeTurnPublication?(): void;
/** Commit cancellation synchronously; the returned promise owns cleanup only. */
cancel?(input: {
reason: string;
diff --git a/packages/paperclip-runner/src/contracts/registered-asset-instructions.test.ts b/packages/paperclip-runner/src/contracts/registered-asset-instructions.test.ts
new file mode 100644
index 00000000000..6e7558c680d
--- /dev/null
+++ b/packages/paperclip-runner/src/contracts/registered-asset-instructions.test.ts
@@ -0,0 +1,8 @@
+import { readFileSync } from "node:fs";
+import { expect, it } from "vitest";
+import { composeNativeSystemInstructions, type NativeRuntimeContextSnapshot } from "./runtime-context.js";
+
+it("keeps the TypeScript instruction composer and Rust attachment fixture in sync", () => {
+ const fixtures = JSON.parse(readFileSync(new URL("../../test/fixtures/registered-asset-instructions.json", import.meta.url), "utf8")) as Array<{context: NativeRuntimeContextSnapshot; entry: string; instructions: string}>;
+ for (const fixture of fixtures) expect(composeNativeSystemInstructions(fixture.context, fixture.entry)).toBe(fixture.instructions);
+});
diff --git a/packages/paperclip-runner/src/contracts/runtime-context.ts b/packages/paperclip-runner/src/contracts/runtime-context.ts
index 850825c29b1..fd17acf09f1 100644
--- a/packages/paperclip-runner/src/contracts/runtime-context.ts
+++ b/packages/paperclip-runner/src/contracts/runtime-context.ts
@@ -1,8 +1,8 @@
import { createHash } from "node:crypto";
export const NATIVE_RUNTIME_ASSET_SCHEMA = "paperclip.runtime-asset.v1" as const;
-export const PAPERCLIP_EXECUTION_PROMPT_REVISION = "paperclip-execution.v5" as const;
-export const PAPERCLIP_EXECUTION_PROMPT = "You are running as a Paperclip agent. Complete the assigned task in the provided execution environment. Follow the attached agent instructions and use assigned skills and tools when relevant. Use Paperclip tools for coordination. To hire or reuse a persistent teammate, use list_agents, then search_api for agent-hires and call_api if a hire is needed. Provider helper threads do not create Paperclip agents. When the user assigns work or a revision to a teammate, use create_task with that agent's ID; review their result rather than doing their assigned work yourself. When remaining work depends on a child task, use set_dependencies to add its ID while preserving existing blocker IDs. Complete independent work, then call paperclip_block with the child agent as owner and child completion as the unblock action. End the turn so the child can use the workspace. Do not sleep or poll for child results while holding the workspace. Paperclip resumes the parent when the dependency completes. When the user asks to connect a service, call connections_search before any service tool, even when that tool is already installed. Follow the returned instruction and wait for any required user choice before executing. For other tasks needing a service, use installed tools if available; otherwise use connections_search and follow its instruction. The request appears as a card in the task. Finish independent work before yielding for access; do not poll or request the same connection repeatedly. Paperclip will continue automatically with updated tools after resolution. After a decline, pursue alternatives unless the user explicitly asks to retry. Finish exactly once with `paperclip_finish` or `paperclip_block`." as const;
+export const PAPERCLIP_EXECUTION_PROMPT_REVISION = "paperclip-execution.v6" as const;
+export const PAPERCLIP_EXECUTION_PROMPT = "You are running as a Paperclip agent. Complete the assigned task in the provided execution environment. Follow the attached agent instructions and use assigned skills and tools when relevant. Use Paperclip tools for coordination. To hire or reuse a persistent teammate, use list_agents, then search_api for agent-hires and call_api if a hire is needed. Provider helper threads do not create Paperclip agents. When the user assigns work or a revision to a teammate, use create_task with that agent's ID; review their result rather than doing their assigned work yourself. When remaining work depends on a child task, use set_dependencies to add its ID while preserving existing blocker IDs. Complete independent work, then call paperclip_block with the child agent as owner and child completion as the unblock action. End the turn so the child can use the workspace. Do not sleep or poll for child results while holding the workspace. Paperclip resumes the parent when the dependency completes. When the user asks to connect a service, call connections_search before any service tool, even when that tool is already installed. Follow the returned instruction and wait for any required user choice before executing. For other tasks needing a service, use installed tools if available; otherwise use connections_search and follow its instruction. The request appears as a card in the task. Finish independent work before yielding for access; do not poll or request the same connection repeatedly. Paperclip will continue automatically with updated tools after resolution. After a decline, pursue alternatives unless the user explicitly asks to retry. For a deferred check you own, call set_task_monitor with a future nextCheckAt and notes. Confirm the persisted schedule on the current task, then call paperclip_finish with reportedWorkDisposition yielded and continuation.kind monitor. End the turn; the one-shot monitor wakes you with issue_monitor_due. Re-arm explicitly only if another check is needed. Do not claim a monitor exists without its receipt. Finish exactly once with `paperclip_finish` or `paperclip_block`." as const;
export interface NativeRuntimeAssetReference {
schema: typeof NATIVE_RUNTIME_ASSET_SCHEMA;
diff --git a/packages/paperclip-runner/src/control-plane/durable-prp-control-plane.ts b/packages/paperclip-runner/src/control-plane/durable-prp-control-plane.ts
index 647ee2892c8..e0aef3887b4 100644
--- a/packages/paperclip-runner/src/control-plane/durable-prp-control-plane.ts
+++ b/packages/paperclip-runner/src/control-plane/durable-prp-control-plane.ts
@@ -1,3 +1,4 @@
+import { configuredEnvironment } from "../configured-environment.js";
import { spawn } from "node:child_process";
import {
createCipheriv,
@@ -3453,7 +3454,7 @@ function runnerEnvironment(
if (explicitSource[key] !== undefined) environment[key] = explicitSource[key];
}
}
- Object.assign(environment, githubCredentialEnvironment(explicitSource));
+ Object.assign(environment, githubCredentialEnvironment(explicitSource), configuredEnvironment(explicitSource));
}
return environment;
}
diff --git a/packages/paperclip-runner/src/drivers/acpx/environment.ts b/packages/paperclip-runner/src/drivers/acpx/environment.ts
index 2ecbf367474..069333204bf 100644
--- a/packages/paperclip-runner/src/drivers/acpx/environment.ts
+++ b/packages/paperclip-runner/src/drivers/acpx/environment.ts
@@ -1,3 +1,4 @@
+import { configuredEnvironment } from "../../configured-environment.js";
import type { QualifiedAcpxAgent } from "./qualified-profiles.js";
export const ACPX_CREDENTIAL_BINDING_ENV = "PAPERCLIP_ACPX_CREDENTIAL_BINDING";
@@ -87,7 +88,7 @@ export function createSanitizedAcpxSpawnInput(
): SanitizedAcpxSpawnInput {
const source = environment ?? process.env;
const candidate = isCandidate(agent);
- const result: NodeJS.ProcessEnv = {};
+ const result: NodeJS.ProcessEnv = configuredEnvironment(environment);
const credentialNames = ACPX_CREDENTIAL_NAMES[agent];
const allowed = new Set([
"PATH",
diff --git a/packages/paperclip-runner/src/drivers/acpx/runtime-sandbox.test.ts b/packages/paperclip-runner/src/drivers/acpx/runtime-sandbox.test.ts
index 53423467c92..fbe2ff00faa 100644
--- a/packages/paperclip-runner/src/drivers/acpx/runtime-sandbox.test.ts
+++ b/packages/paperclip-runner/src/drivers/acpx/runtime-sandbox.test.ts
@@ -1,3 +1,4 @@
+import { configuredEnvironmentProjection } from "../../configured-environment.js";
import {
chmod,
lstat,
@@ -34,6 +35,22 @@ afterEach(async () => {
});
describe("ACPX runtime sandbox", () => {
+ it.each([false, true])("allows selected task secrets in Codex shells (agent identity: %s)", async identity => {
+ const fixture = await sandboxFixture("codex");
+ const pages = { PAPERCLIP_PAGE_AWS_SECRET_ACCESS_KEY: "task-pages-secret", CUSTOM_TOKEN: "task-service-secret" };
+ const sandbox = await prepareAcpxRuntimeSandbox({ binding: fixture.binding, agent: "codex", environment: {
+ PATH: process.env.PATH, OPENAI_API_KEY: "provider-secret", HOST_SECRET: "unselected-secret",
+ ...configuredEnvironmentProjection(pages), ...(identity ? { PAPERCLIP_AGENT_KEY_ID: "agent-key" } : {}),
+ } });
+ const config = await readFile(join(sandbox.agentHomeDirectory, "config.toml"), "utf8");
+ const keys = JSON.parse(config.split("\n").find(line => line.startsWith("include_only = "))?.slice("include_only = ".length) ?? "[]");
+ expect(keys).toEqual(expect.arrayContaining(Object.keys(pages)));
+ expect(keys).not.toContain("OPENAI_API_KEY");
+ expect(keys).not.toContain("HOST_SECRET");
+ expect(sandbox.launchEnvironment).toMatchObject(pages);
+ for (const value of Object.values(pages)) expect(config).not.toContain(value);
+ });
+
it("restores Grok permission controls on recovery without importing compatible hooks or credentials", async () => {
const fixture = await sandboxFixture("grok");
const sandbox = await prepareAcpxRuntimeSandbox({ binding: fixture.binding, agent: "grok" });
diff --git a/packages/paperclip-runner/src/drivers/acpx/runtime-sandbox.ts b/packages/paperclip-runner/src/drivers/acpx/runtime-sandbox.ts
index 74c2e1c45a1..f38f174712d 100644
--- a/packages/paperclip-runner/src/drivers/acpx/runtime-sandbox.ts
+++ b/packages/paperclip-runner/src/drivers/acpx/runtime-sandbox.ts
@@ -1,3 +1,4 @@
+import { configuredEnvironmentKeys } from "../../configured-environment.js";
import { randomBytes } from "node:crypto";
import {
constants,
@@ -443,6 +444,7 @@ export async function prepareAcpxRuntimeSandbox(input: {
})}\n`);
}
if (input.agent === "codex") {
+ const taskEnvironmentKeys = configuredEnvironmentKeys(input.environment);
await writePrivateFile(
join(agentHomeDirectory, "config.toml"),
[
@@ -454,14 +456,15 @@ export async function prepareAcpxRuntimeSandbox(input: {
// also affect provider startup and belongs at the launch boundary.
"[features]",
"shell_snapshot = false",
- ...(input.environment?.PAPERCLIP_AGENT_KEY_ID ? [
+ ...(input.environment?.PAPERCLIP_AGENT_KEY_ID || taskEnvironmentKeys.length > 0 ? [
"[shell_environment_policy]", 'inherit = "all"', "ignore_default_excludes = true",
`include_only = ${JSON.stringify([...new Set([
"PATH", "HOME", "LANG", "LANGUAGE", "TZ", "TMPDIR", "TEMP", "TMP", "CODEX_HOME",
"PAPERCLIP_AGENT_KEY_ID", "PAPERCLIP_AGENT_PUBLIC_KEY", "PAPERCLIP_AGENT_PRIVATE_KEY",
- // Provider/config secrets keep Codex's default shell exclusions;
+ ...taskEnvironmentKeys,
+ // Unselected provider/config secrets keep Codex's default shell exclusions;
// only Paperclip's scoped API token is required by Bash/curl skills.
- ...Object.keys(input.environment).filter(key => key === "PAPERCLIP_API_KEY" || !/key|secret|token/i.test(key)),
+ ...Object.keys(input.environment ?? {}).filter(key => key === "PAPERCLIP_API_KEY" || !/key|secret|token/i.test(key)),
])])}`,
] : []),
"",
diff --git a/packages/paperclip-runner/src/drivers/codex/app-server-transport.ts b/packages/paperclip-runner/src/drivers/codex/app-server-transport.ts
index 53ce851d113..5e6fac128da 100644
--- a/packages/paperclip-runner/src/drivers/codex/app-server-transport.ts
+++ b/packages/paperclip-runner/src/drivers/codex/app-server-transport.ts
@@ -1,3 +1,4 @@
+import { configuredEnvironment } from "../../configured-environment.js";
import type { NativeTurnControlCapabilities } from "../../contracts/types.js";
import { spawn, type ChildProcessWithoutNullStreams } from "node:child_process";
import type { HarnessRuntimeRequestResolution } from "../../contracts/harness-driver.js";
@@ -243,7 +244,7 @@ export function createSanitizedCodexEnvironment(
for (const key of ["PAPERCLIP_AGENT_KEY_ID", "PAPERCLIP_AGENT_PUBLIC_KEY", "PAPERCLIP_AGENT_PRIVATE_KEY"]) {
if (explicit?.[key] !== undefined) environment[key] = explicit[key];
}
- Object.assign(environment, githubCredentialEnvironment(source));
+ Object.assign(environment, githubCredentialEnvironment(source), configuredEnvironment(explicit));
return environment;
}
diff --git a/packages/paperclip-runner/src/drivers/codex/codex-boundaries.ts b/packages/paperclip-runner/src/drivers/codex/codex-boundaries.ts
index 16d5b011665..4e5c07a4c14 100644
--- a/packages/paperclip-runner/src/drivers/codex/codex-boundaries.ts
+++ b/packages/paperclip-runner/src/drivers/codex/codex-boundaries.ts
@@ -264,7 +264,8 @@ export function codexToolAcceptsResult(
return false;
}
return result.reportedWorkDisposition !== "yielded"
- || result.continuation?.kind === "response_wake";
+ || result.continuation?.kind === "response_wake"
+ || result.continuation?.kind === "monitor";
}
export function redactCodexValue(value: unknown, depth = 0): unknown {
diff --git a/packages/paperclip-runner/src/drivers/codex/codex-security-config.ts b/packages/paperclip-runner/src/drivers/codex/codex-security-config.ts
index 3cc702004c2..f363bd8163b 100644
--- a/packages/paperclip-runner/src/drivers/codex/codex-security-config.ts
+++ b/packages/paperclip-runner/src/drivers/codex/codex-security-config.ts
@@ -1,3 +1,4 @@
+import { configuredEnvironmentKeys } from "../../configured-environment.js";
import { resolve, isAbsolute, join, dirname, delimiter } from "node:path";
import { existsSync, realpathSync, readFileSync, statSync } from "node:fs";
import { createRequire } from "node:module";
@@ -167,23 +168,28 @@ function tomlString(value: string): string {
}
export function createIsolatedCodexAppServerArgs(
- source: NodeJS.ProcessEnv = process.env,
+ source: NodeJS.ProcessEnv | undefined = undefined,
readOnlyRoots: string[] = [],
/** Server-registered run copy, never an environment/config-supplied root. */
instructionWorkingCopyRoot?: string,
): string[] {
+ const explicitSource = source;
+ source ??= process.env;
const gitRoots = gitFilesystemRoots(source);
readOnlyRoots = [...new Set([...readOnlyRoots, ...codexNetworkReadOnlyRoots(source)])];
const networkAccess = codexNetworkAccess(source);
const externalRunnerSandbox = usesExternalRunnerSandbox(source);
const inheritedGitHubKeys = [
...githubCredentialEnvironmentKeys(source),
+ ...configuredEnvironmentKeys(explicitSource),
...["PAPERCLIP_AGENT_KEY_ID", "PAPERCLIP_AGENT_PUBLIC_KEY", "PAPERCLIP_AGENT_PRIVATE_KEY"].filter(key => source[key] !== undefined),
];
const hasProjectedEnvironment = inheritedGitHubKeys.length > 0;
// Codex filters the configured `set` values through include_only as well.
// Retain the explicit command PATH/HOME/locale settings, not ambient secrets.
const commandEnvironment = codexCommandEnvironment(source);
+ // Selected task values are inherited, never serialized into configuration argv.
+ for (const key of configuredEnvironmentKeys(explicitSource)) delete commandEnvironment[key];
if (instructionWorkingCopyRoot && source.AGENT_HOME === instructionWorkingCopyRoot) commandEnvironment.AGENT_HOME = instructionWorkingCopyRoot;
const shellEnvironmentKeys = [...new Set([...inheritedGitHubKeys, ...Object.keys(commandEnvironment)])].sort();
if (source.PAPERCLIP_GITHUB_LAUNCHER_DIR) readOnlyRoots = [...readOnlyRoots, source.PAPERCLIP_GITHUB_LAUNCHER_DIR];
diff --git a/packages/paperclip-runner/src/drivers/codex/codex-session-server-requests.ts b/packages/paperclip-runner/src/drivers/codex/codex-session-server-requests.ts
index e23b9f942a1..73b4bd6dddb 100644
--- a/packages/paperclip-runner/src/drivers/codex/codex-session-server-requests.ts
+++ b/packages/paperclip-runner/src/drivers/codex/codex-session-server-requests.ts
@@ -205,7 +205,7 @@ async function handleServerRequestBody(
text:
tool === CODEX_BLOCK_TOOL_NAME
? "paperclip_block requires reportedWorkDisposition=blocked."
- : "paperclip_finish accepts done, needs_review, or yielded with a response_wake continuation.",
+ : "paperclip_finish accepts done, needs_review, or yielded with a response_wake or persisted monitor continuation.",
},
],
};
diff --git a/packages/paperclip-runner/src/eval/workflow-evals.test.ts b/packages/paperclip-runner/src/eval/workflow-evals.test.ts
index 8a57f2509be..c90118fe819 100644
--- a/packages/paperclip-runner/src/eval/workflow-evals.test.ts
+++ b/packages/paperclip-runner/src/eval/workflow-evals.test.ts
@@ -466,13 +466,13 @@ describe("workflow reports and stress traceability", () => {
candidateFailures: 36,
});
expect(report.coverage).toMatchObject({
- canonicalOperations: 56,
+ canonicalOperations: 57,
capabilityCases: 106,
workflows: 12,
stressFindings: 44,
stressExclusions: 1,
});
- expect(report.coverage.operations).toHaveLength(56);
+ expect(report.coverage.operations).toHaveLength(57);
expect(report.coverage.composedWorkflows).toHaveLength(12);
expect(
report.coverage.operations.find(
@@ -480,7 +480,7 @@ describe("workflow reports and stress traceability", () => {
)?.workflowIds.length,
).toBeGreaterThan(0);
expect(renderRunnerWorkflowMarkdown(report)).toContain(
- "56 operations · 106 capability cases · 12 workflows",
+ "57 operations · 106 capability cases · 12 workflows",
);
expect(renderRunnerWorkflowJUnit(report)).toContain(
'tests="36" failures="36" skipped="0"',
diff --git a/packages/paperclip-runner/src/index.ts b/packages/paperclip-runner/src/index.ts
index 7e7bcf2c9a1..2641cf334c6 100644
--- a/packages/paperclip-runner/src/index.ts
+++ b/packages/paperclip-runner/src/index.ts
@@ -1,3 +1,4 @@
+export * from "./configured-environment.js";
export * from "./catalog/index.js";
export { CURSOR_DISTRIBUTION_PINS } from "./drivers/acpx/generated-profiles.js";
export * from "./contracts/control-plane-port.js";
diff --git a/packages/paperclip-runner/src/live/runnerd-codex-transport.ts b/packages/paperclip-runner/src/live/runnerd-codex-transport.ts
index 7c3c0896232..ba6f3f32487 100644
--- a/packages/paperclip-runner/src/live/runnerd-codex-transport.ts
+++ b/packages/paperclip-runner/src/live/runnerd-codex-transport.ts
@@ -1,3 +1,4 @@
+import { configuredEnvironment } from "../configured-environment.js";
import { resolveAcpxProviderMode } from "../drivers/acpx/provider-mode.js";
import { isAcpxCanonicalInputMethod } from "../drivers/acpx/profile-extensions.js";
import { RunnerdTraceFrameIndex } from "./runnerd-trace-frame-index.js";
@@ -1789,6 +1790,10 @@ export function rehydrateRunnerdUsageNotification(
tokenUsage: {
total: record(rawParams.cumulative),
runDelta: record(rawParams.runDelta),
+ // Normalized counters may contain placeholder zeroes. Keep the runner's
+ // authority beside the counters so ACPX/managed driver projections and
+ // durable replay cannot certify an incomplete delta as a free receipt.
+ runDeltaComplete: rawParams.runDeltaAvailable === true,
},
};
}
@@ -3335,14 +3340,14 @@ function createSanitizedOpenCodeRunnerEnvironment(
delete candidate[key];
if (source?.[key] !== undefined) candidate[key] = source[key];
}
- return Object.fromEntries(
+ return { ...configuredEnvironment(source), ...Object.fromEntries(
Object.entries(candidate).filter(
([key, value]) =>
typeof value === "string" &&
(OPEN_CODE_RUNNER_ENVIRONMENT_KEYS.has(key) ||
/^LC_[A-Z0-9_]{1,32}$/.test(key)),
),
- );
+ ) };
}
export function resolveSourceCodexHome(
diff --git a/packages/paperclip-runner/src/mock-core/codex-runner.ts b/packages/paperclip-runner/src/mock-core/codex-runner.ts
index d2c6b078e58..25d3b8195ff 100644
--- a/packages/paperclip-runner/src/mock-core/codex-runner.ts
+++ b/packages/paperclip-runner/src/mock-core/codex-runner.ts
@@ -114,12 +114,12 @@ function dispositionIssues(
} else if (result.reportedWorkDisposition === "yielded") {
if (
result.blocker !== undefined ||
- result.continuation?.kind !== "response_wake"
+ !["response_wake", "monitor"].includes(result.continuation?.kind ?? "")
) {
issues.push({
code: "invalid_disposition",
path: "/reportedWorkDisposition",
- message: "yielded requires a response_wake continuation and must not include a blocker",
+ message: "yielded requires a response_wake or monitor continuation and must not include a blocker",
});
}
} else {
diff --git a/packages/paperclip-runner/src/native-session-runtime.test.ts b/packages/paperclip-runner/src/native-session-runtime.test.ts
index db0344becc7..e65944682cd 100644
--- a/packages/paperclip-runner/src/native-session-runtime.test.ts
+++ b/packages/paperclip-runner/src/native-session-runtime.test.ts
@@ -4403,7 +4403,9 @@ describe("executeNativeSession recovery", () => {
expect(lifecycle).toEqual(["closed"]);
});
- it("commits a governed wait without waiting for abort-insensitive provider cleanup", async () => {
+ it("commits a proved governed wait without waiting for abort-insensitive provider cleanup", async () => {
+ vi.useFakeTimers();
+ try {
const lifecycle: string[] = [];
let cancellationSignal: AbortSignal | undefined;
const cancel = vi.fn(({ signal }: { signal: AbortSignal }) => {
@@ -4429,6 +4431,8 @@ describe("executeNativeSession recovery", () => {
},
async *events() {
yield runnerEvent(1, "item.completed");
+ expect(cancel).toHaveBeenCalledOnce();
+ yield runnerEvent(2, "turn.interrupted", { providerTerminalObserved: true });
},
async startTurn() {
return { turnId: "turn-recovery" };
@@ -4498,7 +4502,13 @@ describe("executeNativeSession recovery", () => {
keepSessionOpen: true,
onSession: (current) => retainedSessions.push(current),
});
- await expect(execution).resolves.toMatchObject({ result: yieldedResult });
+ let settled = false;
+ const completed = execution.then(value => { settled = true; return value; });
+ void completed.catch(() => undefined);
+ await vi.advanceTimersByTimeAsync(9_900);
+ expect(settled).toBe(false);
+ await vi.advanceTimersByTimeAsync(200);
+ await expect(completed).resolves.toMatchObject({ result: yieldedResult });
expect(cancel).toHaveBeenCalledOnce();
expect(cancellationSignal?.aborted).toBe(true);
expect(close).toHaveBeenCalledOnce();
@@ -4506,9 +4516,11 @@ describe("executeNativeSession recovery", () => {
expect(retainedSessions.at(-1)).toBeNull();
expect(events.map((event) => event.eventType)).toEqual([
"item.completed",
+ "turn.interrupted",
"run.result.accepted",
"run.terminal",
]);
+ } finally { vi.useRealTimers(); }
});
it("uses the execution timeout when a completion report has no provider terminal", async () => {
@@ -4637,7 +4649,7 @@ describe("executeNativeSession recovery", () => {
expect(retainedSessions.at(-1)).toBeNull();
});
- it("retains a reusable session while a semantic terminal releases its remote subscription", async () => {
+ it.each([false, true])("retains a reusable session while terminal teardown settles (governed=%s)", async (governed) => {
const close = vi.fn(async () => undefined);
const retainedSessions: Array = [];
const session: NativeSession = {
@@ -4653,9 +4665,9 @@ describe("executeNativeSession recovery", () => {
},
async *events() {
try {
- yield runnerEvent(1, "run.result.proposed", result);
+ yield { ...runnerEvent(1, governed ? "item.completed" : "run.result.proposed", governed ? { kind: "dynamicToolCall" } : result), turnId: "turn-recovery" };
yield {
- ...runnerEvent(2, "turn.completed"),
+ ...runnerEvent(2, governed ? "turn.interrupted" : "turn.completed"),
turnId: "turn-recovery",
};
} finally {
@@ -4680,6 +4692,7 @@ describe("executeNativeSession recovery", () => {
lineage: [],
};
},
+ cancel: () => ({ cleanup: Promise.resolve() }),
close,
};
const backend: NativeSessionBackend = {
@@ -4720,10 +4733,11 @@ describe("executeNativeSession recovery", () => {
controlPlane: port,
runnerInstanceId: "runner-recovery",
controlPlaneInstanceId: "control-recovery",
+ resolveGovernedWait: governed ? () => yieldedResult : undefined,
keepSessionOpen: true,
onSession: (current) => retainedSessions.push(current),
}),
- ).resolves.toMatchObject({ result, terminal });
+ ).resolves.toMatchObject({ result: governed ? yieldedResult : result });
expect(close).not.toHaveBeenCalled();
expect(retainedSessions).toEqual([session]);
@@ -7641,7 +7655,192 @@ describe("executeNativeSession recovery", () => {
]);
});
- it("parks a provider turn immediately after a durable governed wait appears", async () => {
+ it.each(["end", "throw", "timeout"])("keeps a governed wait unfinalized when complete usage is followed by %s without a provider terminal", async fault => {
+ vi.useFakeTimers();
+ try {
+ const trigger = { ...runnerEvent(1, "item.completed", { kind: "dynamicToolCall" }), turnId: "turn-waiting" };
+ const usage = { ...runnerEvent(2, "item.completed", { kind: "usage", usage: { runDelta: { inputTokens: 7, outputTokens: 3 }, runDeltaComplete: true } }), turnId: trigger.turnId };
+ const history: PrpEvent[] = [];
+ let checkpoint: PersistedNativeSession | undefined;
+ let releaseStream!: () => void;
+ const streamClosed = new Promise(resolve => { releaseStream = resolve; });
+ const complete = vi.fn(async () => undefined);
+ const session: NativeSession = {
+ identity: () => identity,
+ async capabilities() { return { resume: true, typedEvents: true, steering: false, interruption: true, structuredResult: true }; },
+ async startTurn() { return { turnId: trigger.turnId }; },
+ cancel() { return { cleanup: Promise.resolve() }; },
+ async snapshot() { return { backendKind: "mock", sessionId: identity.sessionId, identity, activeTurnId: trigger.turnId }; },
+ async result() { return null; }, async close() { releaseStream(); },
+ async *events() {
+ yield trigger; yield usage;
+ if (fault === "throw") throw new Error("provider stream lost");
+ if (fault === "timeout") await streamClosed;
+ },
+ };
+ const backend: NativeSessionBackend = {
+ async descriptor() { return { kind: "mock", name: "missing-stop", version: "1", capabilities: await session.capabilities() }; },
+ async openSession() { return session; },
+ };
+ const port: ControlPlanePort = {
+ async openRun() {}, completeRun: complete,
+ async checkpointSession(value) { checkpoint = structuredClone(value); },
+ async appendEvent(event) { history.push(event); return { cursor: history.length, highestContiguousSourceSeq: event.sourceSeq, disposition: "committed" }; },
+ async replayEvents(request) { return { events: history.filter(row => row.sourceInstanceId === request.sourceInstanceId && row.sourceSeq > request.afterSourceSeq), highestContiguousSourceSeq: 0 }; },
+ };
+ const outcome = expect(executeNativeSession({ input, backend, controlPlane: port, timeoutMs: 1_000,
+ runnerInstanceId: "runner-recovery", controlPlaneInstanceId: "control-recovery", resolveGovernedWait: () => yieldedResult }))
+ .rejects.toMatchObject({ providerCode: "governed_wait_provider_terminal_unproven" });
+ void outcome.catch(() => undefined);
+ await vi.advanceTimersByTimeAsync(600);
+ await outcome;
+ expect(checkpoint?.governedWait).toEqual({ sourceEvent: trigger, result: yieldedResult });
+ expect(complete).not.toHaveBeenCalled();
+ expect(history).toEqual([trigger, usage]);
+ } finally { vi.useRealTimers(); }
+ });
+
+ it.each(["interrupt_acknowledgement", "runtime_request.cancelled", "runtime_request.expired"])("retains %s in contiguous governed-wait history for recovery", async cancellationKind => {
+ const trigger = { ...runnerEvent(1, "item.completed", { kind: "dynamicToolCall" }), turnId: "turn-waiting" };
+ const acknowledgement: PrpEvent = { ...runnerEvent(2, cancellationKind === "interrupt_acknowledgement" ? "item.completed" : cancellationKind as "runtime_request.cancelled" | "runtime_request.expired",
+ cancellationKind === "interrupt_acknowledgement" ? { kind: cancellationKind } : { requestId: "request-1" }), turnId: trigger.turnId };
+ const usage = { ...runnerEvent(3, "item.completed", { kind: "usage", usage: { runDelta: { inputTokens: 7, outputTokens: 3 }, runDeltaComplete: true } }), turnId: trigger.turnId };
+ const stopped = { ...runnerEvent(4, "turn.interrupted", { providerTerminalObserved: true }), turnId: trigger.turnId };
+ const history: PrpEvent[] = [];
+ let checkpoint: PersistedNativeSession | undefined;
+ const start = vi.fn(async () => ({ turnId: trigger.turnId }));
+ const cancel = vi.fn(() => ({ cleanup: Promise.resolve() }));
+ const complete = vi.fn(async () => undefined);
+ const session: NativeSession = {
+ identity: () => identity,
+ async capabilities() { return { resume: true, typedEvents: true, steering: false, interruption: true, structuredResult: true }; },
+ startTurn: start, cancel,
+ async snapshot() { return { backendKind: "mock", sessionId: identity.sessionId, identity, activeTurnId: trigger.turnId }; },
+ async result() { return null; }, async close() {},
+ async *events() { yield trigger; yield acknowledgement; yield usage; yield stopped; },
+ };
+ const backend: NativeSessionBackend = {
+ async descriptor() { return { kind: "mock", name: "cancel-history", version: "1", capabilities: await session.capabilities() }; },
+ async openSession() { return session; }, async recoverSession() { return { recovered: true, session }; },
+ };
+ const port: ControlPlanePort = {
+ async openRun() {}, completeRun: complete,
+ async checkpointSession(value) { checkpoint = structuredClone(value); },
+ async appendEvent(event) {
+ const duplicate = history.some(row => row.sourceEventId === event.sourceEventId);
+ if (!duplicate) history.push(event);
+ return { cursor: history.length, highestContiguousSourceSeq: event.sourceSeq, disposition: duplicate ? "duplicate" : "committed" };
+ },
+ async replayEvents(request) {
+ const events = history.filter(row => row.sourceInstanceId === request.sourceInstanceId && row.sourceSeq > request.afterSourceSeq);
+ return { events, highestContiguousSourceSeq: events.at(-1)?.sourceSeq ?? request.afterSourceSeq };
+ },
+ };
+ const options = { input, backend, controlPlane: port, runnerInstanceId: "runner-recovery", controlPlaneInstanceId: "control-recovery" };
+ await expect(executeNativeSession({ ...options, resolveGovernedWait: () => yieldedResult }))
+ .resolves.toMatchObject({ result: yieldedResult });
+ expect(history.filter(event => event.sourceInstanceId === trigger.sourceInstanceId)).toEqual([trigger, acknowledgement, usage, stopped]);
+ await expect(executeNativeSession({ ...options, persistedSession: checkpoint })).resolves.toMatchObject({ result: yieldedResult });
+ expect(start).toHaveBeenCalledOnce();
+ expect(cancel).toHaveBeenCalledOnce();
+ });
+
+ it.each(["trigger", "usage", "terminal"])("recovers a journaled governed wait after its answer is saved (last committed: %s)", async lastCommitted => {
+ const terminalCommitted = lastCommitted === "terminal";
+ const trigger = { ...runnerEvent(1, "item.completed", { kind: "dynamicToolCall", item: { id: "ask-1", name: "request_human_input" } }), turnId: "turn-waiting" };
+ const usage = { ...runnerEvent(2, "item.completed", { kind: "usage", usage: { runDelta: { inputTokens: 7, outputTokens: 3 }, runDeltaComplete: true } }), turnId: trigger.turnId };
+ const stopped = { ...runnerEvent(3, "turn.interrupted", { providerTerminalObserved: true }), turnId: trigger.turnId };
+ const history: PrpEvent[] = [];
+ let checkpoint: PersistedNativeSession | undefined;
+ let crashed = false;
+ let interrupted = false;
+ const revoke = vi.fn();
+ const cancel = vi.fn(() => { interrupted = true; return { cleanup: Promise.resolve() }; });
+ const start = vi.fn(async () => ({ turnId: trigger.turnId }));
+ const complete = vi.fn(async () => undefined);
+ const snapshot = (): PersistedNativeSession => ({ backendKind: "mock", sessionId: identity.sessionId, identity,
+ providerSessionId: "same-provider", activeTurnId: trigger.turnId, cursor: String(history.at(-1)?.sourceSeq ?? 0) });
+ const makeSession = (recovering: boolean): NativeSession => ({ identity: () => identity,
+ async capabilities() { return { resume: true, typedEvents: true, steering: false, interruption: true, structuredResult: true }; },
+ startTurn: start, revokeTurnPublication: revoke, cancel,
+ async snapshot() { return snapshot(); }, async result() { return null; }, async close() {},
+ async *events() {
+ if (!recovering) { yield trigger; return; }
+ // The restart resumes settlement only; it must not submit a model turn.
+ expect(interrupted).toBe(true);
+ yield usage;
+ yield stopped;
+ },
+ });
+ const backend: NativeSessionBackend = {
+ async descriptor() { return { kind: "mock", name: "durable-wait", version: "1", capabilities: await makeSession(false).capabilities() }; },
+ async openSession() { return makeSession(false); },
+ async recoverSession() { return { recovered: true, session: makeSession(true) }; },
+ };
+ const port: ControlPlanePort = {
+ async openRun() {}, completeRun: complete,
+ async checkpointSession(value) {
+ checkpoint = structuredClone(value);
+ if (value.governedWait && !crashed) {
+ expect(revoke).toHaveBeenCalledOnce();
+ expect(cancel).not.toHaveBeenCalled();
+ crashed = true;
+ throw new Error("controller lost after governed checkpoint");
+ }
+ },
+ async appendEvent(event) {
+ if (!history.some(row => row.sourceEventId === event.sourceEventId)) history.push(event);
+ return { cursor: history.length, highestContiguousSourceSeq: event.sourceSeq, disposition: "committed" };
+ },
+ async replayEvents(request) {
+ const events = history.filter(row => row.sourceInstanceId === request.sourceInstanceId && row.sourceSeq > request.afterSourceSeq);
+ return { events, highestContiguousSourceSeq: events.at(-1)?.sourceSeq ?? request.afterSourceSeq };
+ },
+ };
+ const options = { input, backend, controlPlane: port, runnerInstanceId: "runner-recovery", controlPlaneInstanceId: "control-recovery" };
+ await expect(executeNativeSession({ ...options, resolveGovernedWait: () => yieldedResult }))
+ .rejects.toThrow("controller lost after governed checkpoint");
+ expect(checkpoint?.governedWait).toEqual({ sourceEvent: trigger, result: yieldedResult });
+ expect(complete).not.toHaveBeenCalled();
+ // The failed controller's ordinary cleanup also invokes cancel. Its
+ // checkpoint assertion above proves interruption followed persistence.
+ cancel.mockClear(); interrupted = false;
+ if (lastCommitted !== "trigger") history.push(usage);
+ if (terminalCommitted) history.push(stopped);
+ const answerAlreadySaved = vi.fn(() => null);
+ await expect(executeNativeSession({ ...options, persistedSession: checkpoint, resolveGovernedWait: answerAlreadySaved }))
+ .resolves.toMatchObject({ result: yieldedResult, turnId: trigger.turnId, terminal: { runTerminalState: "succeeded" } });
+ expect(start).toHaveBeenCalledOnce();
+ expect(cancel).toHaveBeenCalledTimes(terminalCommitted ? 0 : 1);
+ expect(answerAlreadySaved).not.toHaveBeenCalled();
+ expect(complete).toHaveBeenCalledOnce();
+ expect(history.filter(event => event.payload.kind === "usage")).toEqual([usage]);
+ });
+
+ it.each(["missing-trigger", "changed-trigger", "unproven-terminal", "different-turn"])("rejects unsafe governed-wait recovery: %s", async fault => {
+ const trigger = { ...runnerEvent(1, "item.completed", { kind: "dynamicToolCall" }), turnId: "turn-waiting" };
+ const checkpoint: PersistedNativeSession = { backendKind: "mock", sessionId: identity.sessionId, identity,
+ activeTurnId: trigger.turnId, governedWait: { sourceEvent: trigger, result: yieldedResult } };
+ const history = fault === "missing-trigger" ? [] : [fault === "changed-trigger" ? { ...trigger, payload: {} } : trigger];
+ if (fault === "unproven-terminal") history.push({ ...trigger, sourceSeq: 2, sourceEventId: "unproven", eventType: "turn.failed", payload: { providerTerminalObserved: false } });
+ if (fault === "different-turn") history.push({ ...trigger, sourceSeq: 2, sourceEventId: "new-turn", turnId: "different", eventType: "turn.started" });
+ const start = vi.fn();
+ const complete = vi.fn();
+ const session: NativeSession = { identity: () => identity, startTurn: start, async result() { return null; },
+ async capabilities() { return { resume: true, typedEvents: true, steering: false, interruption: true, structuredResult: true }; },
+ async snapshot() { return checkpoint; }, async *events() {}, async close() {} };
+ const backend: NativeSessionBackend = { async descriptor() { return { kind: "mock", name: "unsafe-wait", version: "1", capabilities: await session.capabilities() }; },
+ async openSession() { return session; }, async recoverSession() { return { recovered: true, session }; } };
+ const port: ControlPlanePort = { async openRun() {}, async checkpointSession() {}, async appendEvent() { throw new Error("unexpected append"); },
+ completeRun: complete, async replayEvents(request) { return { events: history.filter(row => row.sourceSeq > request.afterSourceSeq), highestContiguousSourceSeq: history.at(-1)?.sourceSeq ?? 0 }; } };
+ await expect(executeNativeSession({ input, backend, controlPlane: port, persistedSession: checkpoint,
+ runnerInstanceId: "runner-recovery", controlPlaneInstanceId: "control-recovery" })).rejects.toThrow(/governed_wait|failed terminal/);
+ expect(start).not.toHaveBeenCalled(); expect(complete).not.toHaveBeenCalled();
+ });
+
+ it.each([0, 6_000, 12_000])("retains actual shutdown usage after %s ms before finalizing a governed wait", async (receiptDelayMs) => {
+ vi.useFakeTimers();
+ try {
const yielded: PrpStructuredRunResult = {
schema: "paperclip.run_result.v1",
reportedWorkDisposition: "yielded",
@@ -7681,8 +7880,8 @@ describe("executeNativeSession recovery", () => {
turnId: "turn-waiting",
};
const turnInterrupted: PrpEvent = {
- ...controlEvent(2, "turn.interrupted", { reason: "governed_wait" }),
- sourceEventId: "provider-recovery:2",
+ ...controlEvent(3, "turn.interrupted", { reason: "governed_wait" }),
+ sourceEventId: "provider-recovery:3",
sourceInstanceId: "provider-recovery",
sourceKind: "provider",
turnId: "turn-waiting",
@@ -7711,6 +7910,9 @@ describe("executeNativeSession recovery", () => {
async *events() {
yield itemCompleted;
await cancelled;
+ await new Promise(resolve => setTimeout(resolve, receiptDelayMs));
+ yield { ...itemCompleted, sourceSeq: 2, sourceEventId: "provider-recovery:2",
+ payload: { kind: "usage", usage: { runDelta: { inputTokens: 7, outputTokens: 3 }, runDeltaComplete: true } } };
yield turnInterrupted;
},
async startTurn() {
@@ -7778,7 +7980,7 @@ describe("executeNativeSession recovery", () => {
completeRun,
};
- const completed = await executeNativeSession({
+ const execution = executeNativeSession({
input,
backend,
controlPlane: port,
@@ -7788,7 +7990,10 @@ describe("executeNativeSession recovery", () => {
event.eventType === "item.completed" ? yielded : null,
});
+ await vi.advanceTimersByTimeAsync(receiptDelayMs + 1);
+ const completed = await execution;
expect(cancel).toHaveBeenCalledOnce();
+ expect(events.find(event => event.payload.kind === "usage")?.payload.usage).toMatchObject({ runDelta: { inputTokens: 7, outputTokens: 3 } });
expect(completed).toMatchObject({
result: yielded,
terminal: {
@@ -7799,9 +8004,12 @@ describe("executeNativeSession recovery", () => {
});
expect(events.map((event) => event.eventType)).toEqual([
"item.completed",
+ "item.completed",
+ "turn.interrupted",
"run.result.accepted",
"run.terminal",
]);
+ } finally { vi.useRealTimers(); }
});
it("hands a committed structured input to the durable wait after its live window", async () => {
diff --git a/packages/paperclip-runner/src/native-session-runtime.ts b/packages/paperclip-runner/src/native-session-runtime.ts
index b53020892b2..e01dd745e23 100644
--- a/packages/paperclip-runner/src/native-session-runtime.ts
+++ b/packages/paperclip-runner/src/native-session-runtime.ts
@@ -47,6 +47,11 @@ const FAILED_OPERATION_SETTLEMENT_GRACE_MS = 100;
// bounded by the transport. Other iterator and handoff cleanup keeps the short
// fail-closed quarantine boundary below.
const REUSABLE_SESSION_CANCELLATION_SETTLEMENT_GRACE_MS = 10_000;
+// Governed cancellation can traverse the ACPX turn cancellation (2s), host
+// cancellation (2s), protocol/TERM/KILL shutdown (7s), and final status read
+// (1s). Allow that bounded settlement plus transport scheduling; never treat
+// elapsed time or a cancellation acknowledgement as usage/terminal evidence.
+const GOVERNED_ACCOUNTING_DRAIN_MS = 15_000;
const DEFAULT_NATIVE_CHECKPOINT_TIMEOUT_MS = 30_000;
type NativeSessionCleanupDomain = string;
@@ -870,12 +875,15 @@ async function consumeTurn(
},
initialGoal?: HarnessThreadGoal | null,
resumeInterruptedTurn?: (event: PrpEvent, signal: AbortSignal) => Promise,
+ checkpointGovernedWait?: (wait: NonNullable, signal: AbortSignal) => Promise,
+ initialGovernedWait?: PersistedNativeSession["governedWait"],
) {
let timer: ReturnType | undefined;
const appendAbort = new AbortController();
const governedCleanupOperations = new Set>();
let governedCancellationCommitted = false;
let semanticResultObserved = false;
+ let governedProviderTerminalObserved = false;
let deferredGovernedCleanupSettlement: Promise | null = null;
let deferredSessionCancellationSettlement: Promise | null = null;
const inputTimers = new Map>();
@@ -922,7 +930,7 @@ async function consumeTurn(
let latestSessionGoal: HarnessThreadGoal | null = null;
let resultSource: "semantic_result" | "governed_wait" | null = null;
let providerFailure: NativeProviderTerminalFailure | null = null;
- const settleDurableResult = (
+ const settleDurableResult = async (
event: PrpEvent,
result: PrpStructuredRunResult,
reason: string,
@@ -930,16 +938,77 @@ async function consumeTurn(
if (session.cancel === undefined) {
throw new Error("native_governed_wait_cancellation_unavailable");
}
- const cancellation = session.cancel({
- reason,
- signal: appendAbort.signal,
- });
+ // Revoke new publication before any asynchronous journal write. Persist
+ // the disposition before provider interruption, retaining usage and terminal
+ // evidence even when the interaction is answered during the restart.
+ session.revokeTurnPublication?.();
+ await checkpointGovernedWait?.({ sourceEvent: event, result }, appendAbort.signal);
+ appendAbort.signal.throwIfAborted();
+ const cancellation = session.cancel({ reason, signal: appendAbort.signal });
governedCancellationCommitted = true;
const cleanup = cancellation.cleanup;
governedCleanupOperations.add(cleanup);
void cleanup
.catch(() => quarantineSession("governed_cleanup_failed"))
.finally(() => governedCleanupOperations.delete(cleanup));
+ // Cancellation revokes provider work immediately, but shutdown can still
+ // supply its final usage. Keep a bounded accounting-only drain before
+ // acknowledging the run; otherwise the next wake sees permanent debt.
+ // Never let a stuck stream or cleanup revoke the durable governed wait.
+ const drainAbort = new AbortController();
+ const stopDrain = () => drainAbort.abort(appendAbort.signal.reason);
+ appendAbort.signal.addEventListener("abort", stopDrain, { once: true });
+ const drainMs = Math.min(GOVERNED_ACCOUNTING_DRAIN_MS, timeoutMs > 0 ? Math.max(1, Math.floor(timeoutMs / 4)) : GOVERNED_ACCOUNTING_DRAIN_MS);
+ let drainTimer: ReturnType | undefined;
+ const drained = (async () => {
+ while (!drainAbort.signal.aborted) {
+ const next = await eventIterator.next();
+ if (next.done || drainAbort.signal.aborted) return;
+ const trailing = next.value;
+ const terminal = isTurnTerminal(trailing);
+ const usage = trailing.eventType === "item.completed" && trailing.payload.kind === "usage";
+ // These already-numbered cancellation facts carry no new work
+ // authority. Retain them so later receipts have contiguous replay.
+ const cancellation = trailing.eventType === "runtime_request.cancelled"
+ || trailing.eventType === "runtime_request.expired"
+ || (trailing.eventType === "item.completed" && trailing.payload.kind === "interrupt_acknowledgement")
+ || (trailing.eventType === "run.terminal" && ["failed", "cancelled"].includes(String(trailing.payload.runTerminalState)));
+ if (trailing.turnId === event.turnId && (usage || terminal || cancellation)) {
+ const receipt = await controlPlane.appendEvent(trailing, { signal: drainAbort.signal });
+ if (drainAbort.signal.aborted) return;
+ eventCount += receipt.disposition === "committed" ? 1 : 0;
+ highestContiguousSourceSeq = Math.max(highestContiguousSourceSeq, receipt.highestContiguousSourceSeq);
+ if (terminal) {
+ if (trailing.eventType === "turn.failed" || trailing.payload.providerTerminalObserved === false) {
+ throw new NativeProviderTerminalFailure("governed_wait_provider_terminal_unproven", false);
+ }
+ governedProviderTerminalObserved = true;
+ return;
+ }
+ }
+ }
+ })();
+ await Promise.race([
+ drained.catch(error => {
+ quarantineSession("governed_accounting_drain_failed");
+ if (error instanceof NativeProviderTerminalFailure) throw error;
+ }),
+ new Promise(resolve => { drainTimer = setTimeout(() => {
+ drainAbort.abort(new Error("governed accounting drain timed out"));
+ quarantineSession("governed_accounting_drain_timed_out");
+ resolve();
+ }, drainMs); }),
+ ]).finally(() => {
+ clearTimeout(drainTimer);
+ appendAbort.signal.removeEventListener("abort", stopDrain);
+ drainAbort.abort();
+ });
+ // A durable wait and complete usage cannot prove that the provider
+ // stopped. Leave the journaled wait recoverable, without a successful
+ // result or an accounting-completion boundary, if shutdown is unproven.
+ if (!governedProviderTerminalObserved) {
+ throw new NativeProviderTerminalFailure("governed_wait_provider_terminal_unproven", false);
+ }
return {
event,
eventCount,
@@ -947,6 +1016,10 @@ async function consumeTurn(
governedResult: result,
};
};
+ if (initialGovernedWait) {
+ return settleDurableResult(initialGovernedWait.sourceEvent, initialGovernedWait.result,
+ "Paperclip resumed settlement of this durable governed interaction.");
+ }
while (true) {
const next = await eventIterator.next().catch((error) => {
throw providerFailure ?? error;
@@ -1309,15 +1382,14 @@ async function consumeTurn(
);
} else {
// Iterator and provider cleanup own no control-plane mutation authority.
- // A reusable session with a semantic result needs a longer bounded
- // window for the remote event subscription to release. This applies
- // after the provider terminal, which still crosses the remote PRP
- // acknowledgement boundary and routinely takes longer than
- // the generic local cleanup grace. Governed waits and unrelated stalled
- // cleanup retain the short fail-closed boundary.
+ // A reusable session needs a bounded window for its remote terminal
+ // subscription to release. A governed wait qualifies only after its
+ // actual provider terminal was retained during the accounting drain.
+ // Missing terminal evidence and unrelated stalled cleanup retain the
+ // short fail-closed boundary.
const teardownSettled = await settlesWithin(
passiveTeardownSettlement,
- semanticResultObserved
+ semanticResultObserved || governedProviderTerminalObserved
? reusableSessionCancellationGraceMs
: FAILED_OPERATION_SETTLEMENT_GRACE_MS,
);
@@ -1621,7 +1693,8 @@ function isZeroWorkAcpxUsage(payload: Record): boolean {
const usage = objectRecord(payload.usage);
if (
usage === null ||
- Object.keys(usage).some((key) => key !== "total" && key !== "runDelta")
+ (Object.hasOwn(usage, "runDeltaComplete") && usage.runDeltaComplete !== true) ||
+ Object.keys(usage).some((key) => key !== "total" && key !== "runDelta" && key !== "runDeltaComplete")
) {
return false;
}
@@ -1871,6 +1944,42 @@ export async function executeNativeSession(
issueId: input.binding.issueId,
agentId: input.binding.agentId,
};
+ let governedWait = persistedSession?.governedWait;
+ const governedReplay: PrpEvent[] = [];
+ if (governedWait) {
+ const event = governedWait.sourceEvent;
+ const validation = validatePrpStructuredRunResult(governedWait.result);
+ if (!event?.turnId || event.runId !== identity.runId || event.normalizedSessionId !== identity.sessionId
+ || event.sourceInstanceId !== options.runnerInstanceId || !Number.isSafeInteger(event.sourceSeq) || event.sourceSeq < 1
+ || !validation.ok || validation.result.reportedWorkDisposition !== "yielded"
+ || validation.result.completionClaim?.contractRevision !== input.completionContract.contract.revision) {
+ throw new Error("native_governed_wait_checkpoint_mismatch");
+ }
+ await runAbortableOperationWithin({
+ timeoutMs: options.timeoutMs ?? 900_000,
+ timeoutMessage: "native governed-wait recovery replay timed out",
+ operation: async signal => {
+ let afterSourceSeq = event.sourceSeq - 1;
+ while (true) {
+ const page = await options.controlPlane.replayEvents({ runId: identity.runId,
+ sourceInstanceId: options.runnerInstanceId, afterSourceSeq, limit: 1_000 }, { signal });
+ signal.throwIfAborted();
+ if (!page.events.length) break;
+ for (const entry of page.events) {
+ if (entry.runId !== identity.runId || entry.normalizedSessionId !== identity.sessionId
+ || entry.sourceInstanceId !== event.sourceInstanceId || entry.sourceSeq !== afterSourceSeq + 1
+ || governedReplay.length >= 10_000) throw new Error("native_governed_wait_replay_mismatch");
+ governedReplay.push(entry);
+ afterSourceSeq = entry.sourceSeq;
+ }
+ }
+ },
+ });
+ if (canonicalJson(governedReplay[0]) !== canonicalJson(event)) throw new Error("native_governed_wait_trigger_unproven");
+ if (governedReplay.some(entry => entry.eventType === "turn.started" && entry.turnId !== event.turnId)) {
+ throw new Error("native_governed_wait_turn_mismatch");
+ }
+ }
let recovered = false;
let session: NativeSession | null = null;
let continuityBreak: {
@@ -2152,7 +2261,7 @@ export async function executeNativeSession(
externalSignal?: AbortSignal,
) =>
persistCheckpointWithin({
- snapshot,
+ snapshot: governedWait ? { ...snapshot, governedWait } : snapshot,
controlPlane: options.controlPlane,
onCheckpoint: options.onCheckpoint,
timeoutMs: checkpointTimeoutMs,
@@ -2240,6 +2349,21 @@ export async function executeNativeSession(
await persistCheckpoint(recoveredSnapshot);
}
+ const governedTerminal = governedWait ? governedReplay.find(event =>
+ event.turnId === governedWait!.sourceEvent.turnId && isTurnTerminal(event)) : undefined;
+ if (governedTerminal?.eventType === "turn.failed" || governedTerminal?.payload.providerTerminalObserved === false) {
+ throw new NativeProviderTerminalFailure("governed_wait_provider_terminal_unproven", false);
+ }
+ if (governedWait && recoveredActiveTurnId && recoveredActiveTurnId !== governedWait.sourceEvent.turnId) {
+ throw new Error("native_governed_wait_turn_mismatch");
+ }
+ if (governedWait) {
+ for (const event of governedReplay) {
+ if (event.turnId === governedWait.sourceEvent.turnId && (event.payload.kind === "usage" || isTurnTerminal(event))) {
+ await options.controlPlane.appendEvent(event);
+ }
+ }
+ }
let consumed = {
event: null as PrpEvent | null,
eventCount: 0,
@@ -2322,7 +2446,10 @@ export async function executeNativeSession(
replayedDisposition?.terminal ?? dispositionFallback;
const consumptionAbort = new AbortController();
const consuming =
- recoveryTerminal === null
+ governedTerminal && governedWait
+ ? Promise.resolve({ event: governedWait.sourceEvent, governedResult: governedWait.result,
+ eventCount: 0, highestContiguousSourceSeq: governedTerminal.sourceSeq })
+ : recoveryTerminal === null
? consumeTurn(
session,
options.controlPlane,
@@ -2345,6 +2472,11 @@ export async function executeNativeSession(
: undefined,
recoveredSnapshot.goal,
resumeInterruptedTurn,
+ async (wait, signal) => {
+ governedWait = structuredClone(wait);
+ await checkpoint(signal);
+ },
+ governedWait,
)
: Promise.resolve({
event: recoveryTerminal,
@@ -2360,12 +2492,12 @@ export async function executeNativeSession(
// that later rejection becomes process-fatal under Node's strict policy.
void consuming.catch(() => undefined);
try {
- const shouldStartFreshTurn =
+ const shouldStartFreshTurn = !governedWait && (
!recovered ||
(!recoveredActiveTurnId &&
!adoptedProviderTerminal &&
!checkpointedDispositionTerminal &&
- !dispositionRecoveryStillOwned);
+ !dispositionRecoveryStillOwned));
if (options.sessionGoalControl) {
// Explicit controls remain authoritative after controller loss. In
// particular, pause/clear/edit must reach a recovered session even
diff --git a/packages/paperclip-runner/src/protocol-actions/index.ts b/packages/paperclip-runner/src/protocol-actions/index.ts
index 35a003c5526..1c5b3083016 100644
--- a/packages/paperclip-runner/src/protocol-actions/index.ts
+++ b/packages/paperclip-runner/src/protocol-actions/index.ts
@@ -1,3 +1,4 @@
+import { setTaskMonitorAction } from "./set-task-monitor.js";
import { setTaskTitleAction } from "./set-task-title.js";
import { submitComplaintAction, submitSuggestionAction } from "./submit-agent-commentary.js";
import { readAgentInstructionsAction } from "./read-agent-instructions.js";
@@ -57,6 +58,7 @@ import { deepFreezeProtocolAction } from "./freeze.js";
export const PAPERCLIP_PROTOCOL_ACTIONS = deepFreezeProtocolAction([
setTaskTitleAction,
+ setTaskMonitorAction,
submitComplaintAction,
submitSuggestionAction,
readAgentInstructionsAction,
diff --git a/packages/paperclip-runner/src/protocol-actions/set-task-monitor.ts b/packages/paperclip-runner/src/protocol-actions/set-task-monitor.ts
new file mode 100644
index 00000000000..a62dcb97227
--- /dev/null
+++ b/packages/paperclip-runner/src/protocol-actions/set-task-monitor.ts
@@ -0,0 +1,55 @@
+/** Production monitor tool; timers and wake delivery belong to Paperclip. */
+const description = "Schedule, replace, or clear a one-shot task monitor. Omit taskId for your current task; other tasks must also be assigned to you and in progress or review. Supply a future nextCheckAt and notes describing the next check, or monitor: null to clear. A successful receipt reports the persisted monitor; a replay reports its current state without re-arming it. After scheduling your current task, end the turn with paperclip_finish: yielded and continuation.kind monitor. Paperclip will wake you with issue_monitor_due; do not sleep, poll, mark done, or use call_api for this wait.";
+
+export const setTaskMonitorInputSchema = {
+ type: "object",
+ additionalProperties: false,
+ required: ["idempotencyKey", "monitor"],
+ properties: {
+ taskId: { type: "string", description: "Owned task UUID. Omit for the active task." },
+ idempotencyKey: { type: "string", minLength: 1, maxLength: 240, description: "Reuse with identical arguments on retries." },
+ monitor: {
+ type: ["object", "null"],
+ additionalProperties: false,
+ required: ["nextCheckAt", "notes"],
+ properties: {
+ nextCheckAt: { type: "string", description: "Future UTC timestamp for the next check. This is one shot, not a recurring interval." },
+ notes: { type: "string", minLength: 1, maxLength: 500, description: "What to check on the next run; do not include secrets." },
+ kind: { type: ["string", "null"], enum: ["external_service", null] },
+ serviceName: { type: ["string", "null"], minLength: 1, maxLength: 120 },
+ externalRef: { type: ["string", "null"], minLength: 1, maxLength: 500 },
+ timeoutAt: { type: ["string", "null"], description: "Optional deadline later than nextCheckAt." },
+ maxAttempts: { type: ["integer", "null"], minimum: 1, maximum: 100, description: "Optional cumulative attempt limit for this task's monitor." },
+ recoveryPolicy: { type: ["string", "null"], enum: ["wake_owner", "create_recovery_issue", "escalate_to_board", null] },
+ },
+ },
+ },
+} as const;
+
+export const setTaskMonitorAction = {
+ id: "set_task_monitor",
+ canonical: {
+ operationId: "set_task_monitor", surfaces: ["live"], placement: "optional_agent_tool",
+ optionalGroup: "wake_scheduling", requiredClaims: [], taskModes: ["standard"],
+ sideEffectClass: "task_write", idempotency: "required", disabledByDefault: false,
+ realBindingStatus: "live_codex", realServiceBinding: "prepareIssueMonitorUpdate",
+ prpEvidence: "Transactional persisted issue monitor, audit activity and idempotent run receipt.",
+ prpBindingStatus: "bound", legacyAliases: [],
+ },
+ documentation: { title: "Set task monitor", description, note: null },
+ examples: {
+ call: { operationId: "set_task_monitor", input: { idempotencyKey: "check-ci", monitor: { nextCheckAt: "2030-01-01T12:00:00Z", notes: "Check the pending CI run." } } },
+ scenarioCall: null,
+ success: { ok: true, operationId: "set_task_monitor", result: { taskId: "task-1", status: "in_progress", monitor: { nextCheckAt: "2030-01-01T12:00:00Z", status: "scheduled" }, replayed: false } },
+ },
+ live: {
+ order: 51,
+ descriptor: {
+ schema: "paperclip.semantic-tool.v1", operationId: "set_task_monitor", version: 1,
+ title: "Set task monitor", description, exposure: "optional", requiredClaims: [],
+ allowedModes: ["standard"], inputSchema: setTaskMonitorInputSchema,
+ outputSchema: { type: "object", additionalProperties: true },
+ },
+ },
+ scenario: null,
+} as const;
diff --git a/packages/paperclip-runner/src/semantic-tools/discovery.ts b/packages/paperclip-runner/src/semantic-tools/discovery.ts
index 9ad3907a154..8877d2c765e 100644
--- a/packages/paperclip-runner/src/semantic-tools/discovery.ts
+++ b/packages/paperclip-runner/src/semantic-tools/discovery.ts
@@ -21,6 +21,7 @@ const MAX_DISCOVERY_RESULTS = 10;
const NAMESPACE: Readonly> = Object.freeze({
set_task_title: "active_task",
+ set_task_monitor: "continuation",
search_api: "api_fallback",
call_api: "api_fallback",
get_task_context: "active_task", get_task_history: "active_task",
diff --git a/packages/paperclip-runner/src/semantic-tools/paperclip-discovery.ts b/packages/paperclip-runner/src/semantic-tools/paperclip-discovery.ts
index 1388697928e..491ac22e731 100644
--- a/packages/paperclip-runner/src/semantic-tools/paperclip-discovery.ts
+++ b/packages/paperclip-runner/src/semantic-tools/paperclip-discovery.ts
@@ -13,6 +13,7 @@ import type {
const NAMESPACE: Readonly> =
Object.freeze({
set_task_title: "active_task",
+ set_task_monitor: "continuation",
search_api: "api_fallback",
call_api: "api_fallback",
get_task_context: "active_task",
diff --git a/packages/paperclip-runner/src/semantic-tools/semantic-tools.test.ts b/packages/paperclip-runner/src/semantic-tools/semantic-tools.test.ts
index 85d6829cb01..7dbc66243f6 100644
--- a/packages/paperclip-runner/src/semantic-tools/semantic-tools.test.ts
+++ b/packages/paperclip-runner/src/semantic-tools/semantic-tools.test.ts
@@ -113,7 +113,8 @@ describe("Capability semantic catalog and authorization", () => {
it("publishes a stable narrow catalog without credentials or control-plane-owned tools", () => {
const names = CAPABILITY_SEMANTIC_TOOL_CATALOG.map((tool) => tool.operationId);
expect(new Set(names).size).toBe(names.length);
- expect(names).toHaveLength(44);
+ expect(names).toHaveLength(45);
+ expect(names).toContain("set_task_monitor");
expect(names).toEqual(expect.arrayContaining(["submit_complaint", "submit_suggestion"]));
expect(names).toContain("get_task_context");
expect(names).toContain("finish_task");
diff --git a/packages/paperclip-runner/src/semantic-tools/types.ts b/packages/paperclip-runner/src/semantic-tools/types.ts
index 5c1d0a7e66f..28a5b1988de 100644
--- a/packages/paperclip-runner/src/semantic-tools/types.ts
+++ b/packages/paperclip-runner/src/semantic-tools/types.ts
@@ -19,6 +19,7 @@ export type CapabilitySemanticOperationId =
| "search_api"
| "call_api"
| "set_task_title"
+ | "set_task_monitor"
| "get_task_context"
| "get_task_history"
| "list_documents"
diff --git a/packages/paperclip-runner/test/fixtures/fake-opencode-server.mjs b/packages/paperclip-runner/test/fixtures/fake-opencode-server.mjs
index 83284fdfec3..69bd35a8e4e 100644
--- a/packages/paperclip-runner/test/fixtures/fake-opencode-server.mjs
+++ b/packages/paperclip-runner/test/fixtures/fake-opencode-server.mjs
@@ -619,6 +619,15 @@ const server = createServer(async (request, response) => {
},
},
});
+ if (String(parsedPrompt.message ?? parsedPrompt.task?.prompt ?? "").includes("invalid-tool-feedback")) {
+ for (const [status, state] of [
+ ["pending", {}], ["running", { title: "Checking tool name" }],
+ ["error", { error: "Tool not found: fixture_missing" }],
+ ]) emit({ type: "message.part.updated", id: `event-invalid-${status}`, properties: {
+ sessionID: session.id, part: { id: "part-invalid", messageID: "message-assistant",
+ type: "tool", tool: "invalid", callID: "call-invalid", state: { status, ...state } },
+ } });
+ }
emit({
type: "message.part.updated",
id: "event-patch",
diff --git a/packages/paperclip-runner/test/fixtures/registered-asset-instructions.json b/packages/paperclip-runner/test/fixtures/registered-asset-instructions.json
new file mode 100644
index 00000000000..d978802f879
--- /dev/null
+++ b/packages/paperclip-runner/test/fixtures/registered-asset-instructions.json
@@ -0,0 +1,64 @@
+[
+ {
+ "context": {
+ "prompt": {
+ "text": "Pinned prompt."
+ },
+ "connectionInstructions": {
+ "text": "Pinned connection policy."
+ },
+ "instructions": {
+ "bundle": {
+ "rootPath": "/registered/bundle"
+ },
+ "workingCopy": {
+ "kind": "agent_files",
+ "rootPath": "/registered/run-copy",
+ "entryPath": "AGENTS.md"
+ }
+ }
+ },
+ "entry": "Custom entry quoting /registered/run-copy stays unchanged.",
+ "instructions": "Pinned prompt.\n\nCustom entry quoting /registered/run-copy stays unchanged.\n\nPinned connection policy.\n\nYour persistent agent directory (AGENT_HOME) is /registered/run-copy. Your instruction entry is AGENTS.md, relative to that directory. All supported files and subfolders there are restored across tasks and sessions, and collected after this provider stops. Write task deliverables in the task working directory. Only changed or deleted files synchronize; the last sync wins for the same file. Temporary copies are cleaned up without retaining file history. Check the save receipt before claiming persistence.\n\nRead-only instruction sibling root: /registered/bundle"
+ },
+ {
+ "context": {
+ "prompt": {
+ "text": "Pinned prompt."
+ },
+ "connectionInstructions": {
+ "text": "Pinned connection policy."
+ },
+ "instructions": {
+ "bundle": {
+ "rootPath": "/registered/bundle"
+ },
+ "workingCopy": {
+ "kind": "instruction_file",
+ "rootPath": "/registered/run-copy",
+ "entryPath": "AGENTS.md"
+ }
+ }
+ },
+ "entry": "Custom entry quoting /registered/run-copy stays unchanged.",
+ "instructions": "Pinned prompt.\n\nCustom entry quoting /registered/run-copy stays unchanged.\n\nPinned connection policy.\n\nYour editable agent instruction file is /registered/run-copy/AGENTS.md. Edit this registered private copy normally. After this run stops, Paperclip saves changed content as a persistent revision if your responsible user still has permission and the baseline has not changed. Check the run's instruction-save receipt before claiming persistence. Conflicts are preserved for explicit resolution. Repository instruction files, skills, and this run's loaded prompt are separate and are not collected.\n\nRead-only instruction sibling root: /registered/bundle"
+ },
+ {
+ "context": {
+ "prompt": {
+ "text": "Pinned prompt."
+ },
+ "connectionInstructions": {
+ "text": "Pinned connection policy."
+ },
+ "instructions": {
+ "bundle": {
+ "rootPath": "/registered/bundle"
+ },
+ "workingCopy": null
+ }
+ },
+ "entry": "Custom entry quoting /registered/run-copy stays unchanged.",
+ "instructions": "Pinned prompt.\n\nCustom entry quoting /registered/run-copy stays unchanged.\n\nPinned connection policy.\n\nRead-only instruction sibling root: /registered/bundle"
+ }
+]
diff --git a/packages/plugins/examples/plugin-orchestration-smoke-example/tests/plugin.spec.ts b/packages/plugins/examples/plugin-orchestration-smoke-example/tests/plugin.spec.ts
index 7ac7b8e519f..dd879eeef07 100644
--- a/packages/plugins/examples/plugin-orchestration-smoke-example/tests/plugin.spec.ts
+++ b/packages/plugins/examples/plugin-orchestration-smoke-example/tests/plugin.spec.ts
@@ -15,6 +15,8 @@ function issue(input: Partial & Pick
projectWorkspaceId: null,
goalId: null,
parentId: null,
+ visibility: "open",
+ privacyRootIssueId: null,
title,
description: null,
status: "todo",
diff --git a/packages/plugins/plugin-llm-wiki/tests/plugin.spec.ts b/packages/plugins/plugin-llm-wiki/tests/plugin.spec.ts
index df52153a0a9..368b574e91b 100644
--- a/packages/plugins/plugin-llm-wiki/tests/plugin.spec.ts
+++ b/packages/plugins/plugin-llm-wiki/tests/plugin.spec.ts
@@ -566,6 +566,8 @@ function paperclipIssue(overrides: Partial = {}): Issue {
projectWorkspaceId: null,
goalId: null,
parentId: null,
+ visibility: "open",
+ privacyRootIssueId: null,
title: "Design event ingestion controls",
description: "Decide which Paperclip issues, comments, and documents can be ingested into the wiki.",
status: "todo",
diff --git a/packages/plugins/sdk/src/environment-sync-error.ts b/packages/plugins/sdk/src/environment-sync-error.ts
new file mode 100644
index 00000000000..0450310a07a
--- /dev/null
+++ b/packages/plugins/sdk/src/environment-sync-error.ts
@@ -0,0 +1,58 @@
+/** Diagnostic evidence only. Never use this envelope to authorize cleanup or retry. */
+export interface PluginEnvironmentSyncErrorDiagnostic {
+ errorCode: string;
+ httpStatus?: number;
+ exitCode?: number;
+}
+
+const SCHEMA = "paperclip/environment-sync-error/v1";
+// Match the host's workspace restore diagnostic allowlist. Both sides validate
+// independently: plugin-supplied data must never widen the host's log surface.
+const ERROR_CODES = new Set([
+ "ENOENT", "EACCES", "EPERM", "ENOSPC", "EIO", "EXDEV", "ENOTDIR", "EISDIR",
+ "ECONNRESET", "ECONNREFUSED", "ETIMEDOUT", "EPIPE", "ENOTFOUND", "EAI_AGAIN",
+ "ABORT_ERR", "UND_ERR_CONNECT_TIMEOUT", "UND_ERR_SOCKET",
+]);
+
+function field(value: unknown, key: string): unknown {
+ try { return value && typeof value === "object" ? (value as Record)[key] : undefined; }
+ catch { return undefined; }
+}
+
+function integer(value: unknown, minimum: number, maximum: number): number | undefined {
+ return typeof value === "number" && Number.isInteger(value) && value >= minimum && value <= maximum
+ ? value : undefined;
+}
+
+function sanitize(value: unknown): PluginEnvironmentSyncErrorDiagnostic | undefined {
+ const code = field(value, "errorCode");
+ const errorCode = typeof code === "string" && ERROR_CODES.has(code) ? code : "unknown";
+ const httpStatus = integer(field(value, "httpStatus"), 400, 599);
+ const exitCode = integer(field(value, "exitCode"), 1, 255);
+ if (errorCode === "unknown" && httpStatus === undefined && exitCode === undefined) return undefined;
+ return { errorCode, ...(httpStatus !== undefined ? { httpStatus } : {}), ...(exitCode !== undefined ? { exitCode } : {}) };
+}
+
+/** Capture known codes and numbers, never arbitrary error data, text, or names. */
+export function environmentSyncErrorData(error: unknown): unknown {
+ const diagnostic: PluginEnvironmentSyncErrorDiagnostic = { errorCode: "unknown" };
+ let current = error;
+ // Bound nested SDK causes, including cyclic errors and throwing getters.
+ for (let depth = 0; depth < 4 && current && typeof current === "object"; depth++) {
+ const code = field(current, "code");
+ if (diagnostic.errorCode === "unknown" && typeof code === "string" && ERROR_CODES.has(code)) diagnostic.errorCode = code;
+ diagnostic.httpStatus ??= integer(field(current, "status"), 400, 599)
+ ?? integer(field(current, "statusCode"), 400, 599)
+ ?? integer(field(field(current, "response"), "status"), 400, 599);
+ diagnostic.exitCode ??= integer(field(current, "exitCode"), 1, 255) ?? integer(code, 1, 255);
+ current = field(current, "cause");
+ }
+ const safe = sanitize(diagnostic);
+ return safe ? { schema: SCHEMA, diagnostic: safe } : undefined;
+}
+
+/** Revalidate the worker envelope before adapting it into host-only diagnostics. */
+export function readEnvironmentSyncErrorDiagnostic(error: unknown): PluginEnvironmentSyncErrorDiagnostic | undefined {
+ const data = field(error, "data");
+ return field(data, "schema") === SCHEMA ? sanitize(field(data, "diagnostic")) : undefined;
+}
diff --git a/packages/plugins/sdk/src/index.ts b/packages/plugins/sdk/src/index.ts
index b834be1a600..7610aaa9a1d 100644
--- a/packages/plugins/sdk/src/index.ts
+++ b/packages/plugins/sdk/src/index.ts
@@ -452,5 +452,7 @@ export {
export { PluginEnvironmentCreationCleanupError, environmentCreationCleanupErrorData, readEnvironmentCreationCleanupError } from "./environment-creation-cleanup.js";
export type { PluginEnvironmentCreationCleanup } from "./environment-creation-cleanup.js";
+export { readEnvironmentSyncErrorDiagnostic } from "./environment-sync-error.js";
+export type { PluginEnvironmentSyncErrorDiagnostic } from "./environment-sync-error.js";
export type { AiConnectionPool, AiConnectionPoolConfig, AiConnectionPoolMember, AiConnectionRouterRequest, AiConnectionRouterResult, AiConnectionRouterSelection } from "@paperclipai/shared";
diff --git a/packages/plugins/sdk/src/testing.ts b/packages/plugins/sdk/src/testing.ts
index 8f18c9d59ed..9159c346ce3 100644
--- a/packages/plugins/sdk/src/testing.ts
+++ b/packages/plugins/sdk/src/testing.ts
@@ -1634,6 +1634,8 @@ export function createTestHarness(options: TestHarnessOptions): TestHarness {
projectWorkspaceId: null,
goalId: input.goalId ?? null,
parentId: input.parentId ?? null,
+ visibility: "open",
+ privacyRootIssueId: null,
title: input.title,
description: input.description ?? null,
status: input.status ?? "todo",
diff --git a/packages/plugins/sdk/src/worker-rpc-host.ts b/packages/plugins/sdk/src/worker-rpc-host.ts
index 6684f8fdd18..786e71954fb 100644
--- a/packages/plugins/sdk/src/worker-rpc-host.ts
+++ b/packages/plugins/sdk/src/worker-rpc-host.ts
@@ -1,5 +1,6 @@
import type { AiConnectionRouterRequest, AiConnectionRouterResult } from "@paperclipai/shared";
import { environmentCreationCleanupErrorData } from "./environment-creation-cleanup.js";
+import { environmentSyncErrorData } from "./environment-sync-error.js";
/**
* Worker-side RPC host — runs inside the child process spawned by the host.
*
@@ -1581,7 +1582,8 @@ export function startWorkerRpcHost(options: WorkerRpcHostOptions): WorkerRpcHost
sendMessage(createErrorResponse(id, errorCode, errorMessage,
method === "environmentAcquireLease" || method === "environmentDestroyLease"
- ? environmentCreationCleanupErrorData(err) : undefined));
+ ? environmentCreationCleanupErrorData(err)
+ : method === "environmentSyncOut" ? environmentSyncErrorData(err) : undefined));
}
}
diff --git a/packages/plugins/sdk/tests/environment-sync-error.test.ts b/packages/plugins/sdk/tests/environment-sync-error.test.ts
new file mode 100644
index 00000000000..26d98054936
--- /dev/null
+++ b/packages/plugins/sdk/tests/environment-sync-error.test.ts
@@ -0,0 +1,48 @@
+import { describe, expect, it } from "vitest";
+import { environmentSyncErrorData, readEnvironmentSyncErrorDiagnostic } from "../src/environment-sync-error.js";
+
+const schema = "paperclip/environment-sync-error/v1";
+
+describe("environment sync diagnostic envelope", () => {
+ it("keeps only known codes and bounded numbers from nested provider errors", () => {
+ const error = Object.assign(new Error("private-message"), {
+ name: "private-name", code: "private-code", path: "/private-path",
+ response: { status: 503, data: { token: "private-token" } },
+ data: { credentials: "private-credentials" },
+ cause: { code: "ECONNRESET", exitCode: 7, stderr: "private-output" },
+ });
+ const data = environmentSyncErrorData(error);
+ expect(data).toEqual({ schema, diagnostic: { errorCode: "ECONNRESET", httpStatus: 503, exitCode: 7 } });
+ expect(JSON.stringify(data)).not.toContain("private-");
+ expect(readEnvironmentSyncErrorDiagnostic({ data })).toEqual({ errorCode: "ECONNRESET", httpStatus: 503, exitCode: 7 });
+ });
+
+ it.each([undefined, null, "private-error", { code: "PRIVATE_TOKEN" }, { status: 600 }, { status: 399 },
+ { statusCode: "503" }, { status: 500.5 }, { exitCode: 0 }, { exitCode: 256 }, { code: -32001 },
+ { exitCode: Infinity }, { data: { schema, diagnostic: { errorCode: "EACCES" } } },
+ ])("omits unrecognized or unbounded provider values: %j", (error) => {
+ expect(environmentSyncErrorData(error)).toBeUndefined();
+ });
+
+ it("bounds cyclic causes and ignores throwing getters without changing the error", () => {
+ const error = Object.defineProperties({ statusCode: 429 } as Record, {
+ code: { get() { throw new Error("private-code"); } },
+ response: { get() { throw new Error("private-response"); } },
+ });
+ error.cause = error;
+ expect(environmentSyncErrorData(error)).toEqual({ schema, diagnostic: { errorCode: "unknown", httpStatus: 429 } });
+ const wrap = (cause: unknown) => ({ cause });
+ expect(environmentSyncErrorData(wrap(wrap(wrap({ code: "EIO" }))))).toEqual({ schema, diagnostic: { errorCode: "EIO" } });
+ expect(environmentSyncErrorData(wrap(wrap(wrap(wrap({ code: "EIO" })))))).toBeUndefined();
+ });
+
+ it("revalidates worker fields and ignores arbitrary payload and protocol versions", () => {
+ expect(readEnvironmentSyncErrorDiagnostic({ data: { schema, diagnostic: {
+ errorCode: "EACCES", httpStatus: 403, exitCode: 1.5,
+ message: "private-message", path: "/private-path", credentials: "private-token",
+ } } })).toEqual({ errorCode: "EACCES", httpStatus: 403 });
+ expect(readEnvironmentSyncErrorDiagnostic({ data: { schema: "other", diagnostic: { errorCode: "EACCES" } } })).toBeUndefined();
+ expect(readEnvironmentSyncErrorDiagnostic({ data: { schema, diagnostic: { errorCode: "private-token", httpStatus: 900 } } })).toBeUndefined();
+ expect(readEnvironmentSyncErrorDiagnostic(Object.defineProperty({}, "data", { get() { throw new Error("private"); } }))).toBeUndefined();
+ });
+});
diff --git a/packages/shared/src/accounting.ts b/packages/shared/src/accounting.ts
new file mode 100644
index 00000000000..86e29530871
--- /dev/null
+++ b/packages/shared/src/accounting.ts
@@ -0,0 +1,115 @@
+import { z } from "zod";
+import { centsToUnits, normalizeCents } from "./money.js";
+
+export const exactCentsSchema = z.union([z.string().max(160), z.number().finite()]).transform((value, ctx) => {
+ try {
+ if ((typeof value === "number" ? value < 0 : value.startsWith("-")) || centsToUnits(value) < 0n) throw new Error("Money cannot be negative");
+ return normalizeCents(value);
+ } catch (error) {
+ ctx.addIssue({ code: "custom", message: error instanceof Error ? error.message : "Invalid money" });
+ return z.NEVER;
+ }
+});
+export const pricingProvenanceSchema = z.object({
+ source: z.enum(["provider_reported", "provider_invoice", "operator", "rate_card", "unknown"]).default("unknown"),
+ version: z.string().max(100).optional(),
+ evidence: z.string().max(1000).optional(),
+ inputCentsPerMillion: exactCentsSchema.optional(),
+ cachedInputCentsPerMillion: exactCentsSchema.optional(),
+ outputCentsPerMillion: exactCentsSchema.optional(),
+ cacheWriteCentsPerMillion: exactCentsSchema.optional(),
+ serviceTier: z.string().max(50).optional(),
+ contextTier: z.enum(["short", "long"]).optional(),
+});
+export const importBillingInvoiceSchema = z.object({
+ biller: z.string().trim().min(1).max(150),
+ externalId: z.string().trim().min(1).max(200),
+ currency: z.string().regex(/^[A-Za-z]{3}$/).transform(value => value.toUpperCase()),
+ lines: z.array(z.object({
+ externalId: z.string().trim().min(1).max(200),
+ kind: z.enum(["inference", "fee", "credit"]).default("inference"),
+ amountCents: exactCentsSchema,
+ occurredAt: z.iso.datetime({ offset: true }),
+ costEventId: z.string().uuid().optional(),
+ runId: z.string().uuid().optional(),
+ providerRequestId: z.string().min(1).max(250).optional(),
+ model: z.string().min(1).max(250).optional(),
+ pricing: pricingProvenanceSchema.optional(),
+ })).min(1).max(2000),
+}).superRefine((invoice, ctx) => {
+ if (new Set(invoice.lines.map(line => line.externalId)).size !== invoice.lines.length)
+ ctx.addIssue({ code: "custom", path: ["lines"], message: "Invoice line identifiers must be unique" });
+});
+export const adjustCostSchema = z.object({
+ idempotencyKey: z.string().trim().min(1).max(200),
+ expectedCents: exactCentsSchema,
+ correctedCents: exactCentsSchema,
+ invoiceLineId: z.string().uuid().optional(),
+ reason: z.string().trim().min(1).max(1000),
+ pricing: pricingProvenanceSchema,
+});
+export const repairAccountingSchema = z.object({ fingerprint: z.string().regex(/^[a-f0-9]{64}$/), reason: z.string().trim().min(1).max(1000) });
+export const retryAccountingSchema = z.object({ runId: z.string().uuid() });
+export const importProviderCostsSchema = z.object({
+ provider: z.enum(["openai", "anthropic"]),
+ secretId: z.string().uuid(),
+ accountId: z.string().trim().min(1).max(150).regex(/^[a-zA-Z0-9_-]+$/),
+ scopeIds: z.array(z.string().trim().min(1).max(150)).min(1).max(25),
+ from: z.iso.date(),
+ to: z.iso.date(),
+}).superRefine((input, ctx) => {
+ const duration = Date.parse(input.to) - Date.parse(input.from);
+ if (duration <= 0 || duration > 31 * 86400000 || Date.parse(input.to) > Math.floor(Date.now() / 86400000) * 86400000)
+ ctx.addIssue({ code: "custom", message: "Choose up to 31 completed UTC days; the end date is exclusive." });
+ if (new Set(input.scopeIds).size !== input.scopeIds.length)
+ ctx.addIssue({ code: "custom", message: "Project/workspace identifiers must be unique." });
+});
+export type ImportProviderCosts = z.input;
+export type ImportBillingInvoice = z.input;
+export type AdjustCost = z.input;
+export interface AccountingFinding {
+ kind: "company_projection" | "agent_projection" | "runtime_projection" | "missing_receipt" | "missing_acknowledgement" | "legacy_runtime" | "receipt_mismatch";
+ entityId: string;
+ repairable: boolean;
+ actual: Record;
+ expected: Record;
+}
+export interface AccountingInspection {
+ companyId: string;
+ fingerprint: string;
+ findings: AccountingFinding[];
+ checkedAt: string;
+}
+export interface AccountingHealth {
+ companyId: string;
+ pendingRunCount: number;
+ unpricedEventCount: number;
+ oldestPendingAt: string | null;
+ pendingCancellationCount: number;
+ heldReservationCents: string;
+ items: Array<{ runId: string | null; costEventId?: string; agentId: string | null; state: "waiting_for_receipt" | "retryable" | "unpriced"; lastError: string | null; attempts: number; since: string; lastAttemptAt: string | null }>;
+}
+export interface BillingInvoice {
+ id: string; companyId: string; biller: string; externalId: string; currency: string; createdAt: string;
+}
+export interface CostAdjustment {
+ id: string;
+ companyId: string;
+ costEventId: string;
+ invoiceLineId: string | null;
+ idempotencyKey: string;
+ receiptHash: string;
+ previousCents: string;
+ correctedCents: string;
+ previousStatus: string;
+ previousPricing: Record;
+ pricing: Record;
+ reason: string;
+ actorId: string;
+ createdAt: string;
+}
+export interface BillingReconciliation {
+ invoice: BillingInvoice;
+ lines: Array<{ id: string; externalId: string; kind: string; amountCents: string; status: string;
+ matchedEventId: string | null; recordedCents: string | null; differenceCents: string | null }>;
+}
diff --git a/packages/shared/src/connection-routing.ts b/packages/shared/src/connection-routing.ts
index 7c49dbd3b1d..fa29ecccbed 100644
--- a/packages/shared/src/connection-routing.ts
+++ b/packages/shared/src/connection-routing.ts
@@ -1,5 +1,6 @@
import type {
AskUserQuestionsQuestion,
+ PaperclipQuestionSetPayload,
ConnectionSearchResultItem,
} from "./types/index.js";
import {
@@ -338,6 +339,20 @@ export function aggregatorProviderQuestion(
};
}
+/** Native question form, preserving the exact saved-answer authorization contract. */
+export function aggregatorProviderQuestionSet(question: AskUserQuestionsQuestion): PaperclipQuestionSetPayload {
+ return {
+ schema: "paperclip.question_set.v1",
+ questions: [{
+ id: question.id,
+ prompt: question.prompt,
+ required: true,
+ answerMode: "single_select",
+ options: question.options.map(({ id, label, description }) => ({ id, label, ...(description != null ? { description } : {}) })),
+ }],
+ };
+}
+
export function aggregatorContinuationInstruction(
provider: RemoteMcpConnectorId,
targetName: string,
diff --git a/packages/shared/src/constants.ts b/packages/shared/src/constants.ts
index 3e83f263130..fed78724740 100644
--- a/packages/shared/src/constants.ts
+++ b/packages/shared/src/constants.ts
@@ -833,7 +833,7 @@ export const BILLING_TYPES = [
] as const;
export type BillingType = (typeof BILLING_TYPES)[number];
-export const COST_STATUSES = ["reported", "unpriced"] as const;
+export const COST_STATUSES = ["reported", "estimated", "unpriced"] as const;
export type CostStatus = (typeof COST_STATUSES)[number];
export const FINANCE_EVENT_KINDS = [
diff --git a/packages/shared/src/decision-models.ts b/packages/shared/src/decision-models.ts
new file mode 100644
index 00000000000..a07aefd87d2
--- /dev/null
+++ b/packages/shared/src/decision-models.ts
@@ -0,0 +1,73 @@
+import { z } from "zod";
+import type { AiManagedConnectionSummary } from "./ai-connections.js";
+
+export const DECISION_MODELS = {
+ openai: { id: "gpt-6-luna", name: "GPT-6 Luna" },
+ openrouter: { id: "typesafe/jev-1.13", name: "Jev 1.13" },
+} as const;
+export type DecisionProvider = keyof typeof DECISION_MODELS;
+export const updateDecisionModelSchema = z.object({
+ enabled: z.boolean(),
+ connectionId: z.string().uuid().nullable(),
+ grantId: z.string().uuid().nullable(),
+ allowBackground: z.boolean().optional(),
+}).refine(v => Boolean(v.connectionId) === Boolean(v.grantId) && (!v.enabled || Boolean(v.connectionId)), {
+ message: "Select a connection before enabling decisions",
+});
+export type UpdateDecisionModel = z.infer;
+export interface DecisionModelSettings extends UpdateDecisionModel {
+ allowBackground: boolean;
+ companyId: string;
+ provider: DecisionProvider | null;
+ model: string | null;
+}
+export type DecisionConnectionChoice = AiManagedConnectionSummary & { decisionModel: string };
+export type DecisionUnavailableReason = "not_configured" | "disabled" | "connection_unavailable" | "incompatible_connection" | "access_denied" | "responsible_user_missing" | "background_disabled" | "budget_blocked";
+export type DecisionAvailability = { available: true } | { available: false; reason: DecisionUnavailableReason };
+const instructions = z.string().trim().min(1).max(8000);
+export const decisionQuestionSchema = z.discriminatedUnion("type", [
+ z.object({ type: z.literal("boolean"), instructions }),
+ z.object({ type: z.literal("choice"), instructions, criteria: z.record(z.string().min(1).max(100), z.string().min(1).max(2000)).refine(v => Object.keys(v).length >= 2 && Object.keys(v).length <= 20) }),
+ z.object({ type: z.literal("score"), instructions, criteria: z.array(z.string().min(1).max(2000)).min(2).max(20) }),
+]);
+export const decisionRequestSchema = z.object({
+ state: z.union([z.string().min(1), z.record(z.string(), z.json()), z.array(z.json())]),
+ questions: z.record(z.string().regex(/^[a-zA-Z][a-zA-Z0-9_]{0,63}$/), decisionQuestionSchema)
+ .refine(v => Object.keys(v).length > 0 && Object.keys(v).length <= 20),
+});
+export type DecisionRequest = z.infer;
+export type DecisionAnswer =
+ | { type: "boolean"; probability: number; confidence?: number }
+ | { type: "choice"; choice: string; probabilities?: Record; confidence?: number }
+ | { type: "score"; score: number; probabilities?: Record; confidence?: number };
+export interface DecisionUsage {
+ inputTokens: number | null; outputTokens: number | null; costCents: string | null;
+ costStatus: "reported" | "estimated" | "unpriced";
+}
+export type DecisionResult =
+ | { status: "succeeded"; invocationId: string; answers: Record; usage: DecisionUsage }
+ | { status: "unavailable"; reason: DecisionUnavailableReason; invocationId?: string }
+ | { status: "failed"; invocationId: string; errorCode: string; usage: DecisionUsage };
+export interface DecisionHistoryEntry {
+ id: string; feature: string; actorType: string; responsibleUserId: string | null; userName: string | null;
+ issueId: string | null; issueIdentifier: string | null; agentId: string | null; runId: string | null;
+ connectionId: string; provider: string; model: string; status: string; errorCode: string | null;
+ startedAt: string; finishedAt: string | null; durationMs: number | null;
+ inputTokens: number | null; outputTokens: number | null; costCents: string | null; costStatus: string | null;
+}
+export const DECISION_TEST_REQUEST: DecisionRequest = {
+ state: "A customer reports being charged twice for an order. The product still works.",
+ questions: {
+ billing: { type: "boolean", instructions: "Is this a billing problem?" },
+ team: { type: "choice", instructions: "Which team should handle the request?", criteria: { billing: "Charges and payments", technical: "Product failures" } },
+ severity: { type: "score", instructions: "How severe is the product disruption?", criteria: ["Product works", "Some functionality is unavailable", "Product cannot be used"] },
+ },
+};
+
+/** Native endpoints only; OpenRouter's official routing metadata is compatible. */
+export function decisionProviderForConnection(metadata: { provider: string; method: string; routing?: { kind: string; baseUrl?: string } }): DecisionProvider | null {
+ if (metadata.method !== "api_key") return null;
+ if (metadata.provider === "openai" && !metadata.routing) return "openai";
+ if (metadata.provider === "openrouter" && (!metadata.routing || (metadata.routing.kind === "openrouter" && !metadata.routing.baseUrl))) return "openrouter";
+ return null;
+}
diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts
index 0e40261c5af..d110c060548 100644
--- a/packages/shared/src/index.ts
+++ b/packages/shared/src/index.ts
@@ -964,6 +964,8 @@ export type {
SetupTokenTransportAdvisoryCode,
AssetImage,
Project,
+ ProjectAccessMember,
+ ProjectAccessSubjectType,
ProjectDiscoverySummary,
ProjectDiscoveryPage,
ProjectBudgetSummary,
@@ -973,6 +975,7 @@ export type {
ProjectCodebaseOrigin,
ProjectGoalRef,
ProjectManagedByPlugin,
+ ProjectVisibility,
ProjectWorkspace,
CompanySearchCountType,
CompanySearchExtractIssueResult,
@@ -1101,6 +1104,13 @@ export type {
ExternalObjectSummaryItem,
CompactIssue,
Issue,
+ IssueVisibility,
+ IssuePrivacyConstraints,
+ IssueAccessGrant,
+ IssueAccessGrantAgentVisibility,
+ IssueAccessGrantSubjectType,
+ IssueAccessGrantSource,
+ IssueLockedStub,
IssueChangeReceiptEntry,
IssueChanges,
IssueAssigneeAdapterOverrides,
@@ -1258,6 +1268,8 @@ export type {
CostSummary,
IssueCostSummary,
CostByAgent,
+ CostByUser,
+ CostByUserReport,
CostByProviderModel,
CostByBiller,
CostByAgentModel,
@@ -1925,10 +1937,12 @@ export {
projectDiscoverySchema,
createProjectSchema,
updateProjectSchema,
+ addProjectAccessMemberSchema,
createProjectWorkspaceSchema,
updateProjectWorkspaceSchema,
type CreateProject,
type UpdateProject,
+ type AddProjectAccessMember,
type CreateProjectWorkspace,
type UpdateProjectWorkspace,
projectExecutionWorkspacePolicySchema,
@@ -1975,6 +1989,7 @@ export {
updateIssueSchema,
stalledReviewDecisionSchema,
issueExecutionPolicySchema,
+ issueExecutionMonitorPolicySchema,
issueExecutionStateSchema,
resolveIssueRecoveryActionSchema,
retryWorkspaceExportSchema,
@@ -2333,6 +2348,7 @@ export {
type RunRoutine,
type RotateRoutineTriggerSecret,
createCostEventSchema,
+ createServiceCostEventSchema,
createFinanceEventSchema,
updateBudgetSchema,
ASSET_NAMESPACE_MAX_LENGTH,
@@ -2827,9 +2843,13 @@ export * from "./public-mcp.js";
export * from "./mcp-setup.js";
+export * from "./money.js";
+export * from "./accounting.js";
export * from "./ai-provider-routing.js";
export { aiConnectionRouterSlug, aiConnectionRouterAppDefinition, aiConnectionRouterPluginKey } from "./ai-connection-router.js";
export { isAppAggregator, aggregatorManagementUrl, aggregatorAppsSyncSchema, aggregatorAppsRefreshSchema, arcadeDiscoverySetupSchema, type AggregatorAppSnapshot, type AggregatorAppsResponse, type ArcadeDiscoverySetupInput } from "./aggregator-apps.js";
export * from "./connection-instructions.js";
export * from "./customer-success.js";
+export * from "./decision-models.js";
+export { updatePrimaryAgentSchema, type UpdatePrimaryAgent, type PrimaryAgentPreference } from "./primary-agent.js";
diff --git a/packages/shared/src/money.ts b/packages/shared/src/money.ts
new file mode 100644
index 00000000000..156663aa931
--- /dev/null
+++ b/packages/shared/src/money.ts
@@ -0,0 +1,53 @@
+/** Monetary storage uses nanodollars: 10^7 units per cent, 10^9 per USD.
+ * Numbers are accepted only at compatibility boundaries. All arithmetic uses
+ * integers; decimal inputs are rounded once, half away from zero. */
+export const MONEY_SCALE = 10_000_000n;
+export const MAX_MONEY_UNITS = 10n ** 24n - 1n;
+export type MoneyInput = string | number;
+
+function decimalUnits(value: MoneyInput, places: number): bigint {
+ if (typeof value === "number" && !Number.isFinite(value)) throw new Error("Money must be finite");
+ if (typeof value === "number" && Math.abs(value) > Number.MAX_SAFE_INTEGER) throw new Error("Use a decimal string for large monetary values");
+ const text = String(value);
+ if (text.length > 160) throw new Error("Money exceeds supported precision");
+ const match = /^([+-]?)(\d+)(?:\.(\d+))?(?:e([+-]?\d+))?$/i.exec(text);
+ if (!match) throw new Error("Invalid decimal money amount");
+ const exponent = Number(match[4] ?? 0);
+ if (!Number.isInteger(exponent) || Math.abs(exponent) > 100) throw new Error("Money exponent is out of range");
+ const digits = BigInt(match[2] + (match[3] ?? ""));
+ const shift = places + exponent - (match[3]?.length ?? 0);
+ const divisor = shift < 0 ? 10n ** BigInt(-shift) : 1n;
+ const magnitude = shift >= 0 ? digits * 10n ** BigInt(shift) : (digits + divisor / 2n) / divisor;
+ if (magnitude > MAX_MONEY_UNITS) throw new Error("Money exceeds numeric(24,7) storage");
+ return match[1] === "-" ? -magnitude : magnitude;
+}
+
+export function centsToUnits(value: MoneyInput): bigint { return decimalUnits(value, 7); }
+export function usdToUnits(value: MoneyInput): bigint { return decimalUnits(value, 9); }
+export function unitsToCents(value: bigint): string {
+ if (value > MAX_MONEY_UNITS || value < -MAX_MONEY_UNITS) throw new Error("Money exceeds numeric(24,7) storage");
+ const magnitude = value < 0n ? -value : value;
+ return `${value < 0n ? "-" : ""}${magnitude / MONEY_SCALE}.${String(magnitude % MONEY_SCALE).padStart(7, "0")}`;
+}
+export function normalizeCents(value: MoneyInput): string { return unitsToCents(centsToUnits(value)); }
+export function usdToCents(value: MoneyInput): string { return unitsToCents(usdToUnits(value)); }
+/** Exact editable USD value; unlike display formatting, this never rounds cents. */
+export function centsToUsd(value: MoneyInput): string {
+ const units = centsToUnits(value);
+ const magnitude = units < 0n ? -units : units;
+ return `${units < 0n ? "-" : ""}${magnitude / 1_000_000_000n}.${String(magnitude % 1_000_000_000n).padStart(9, "0")}`;
+}
+/** Approximate legacy/UI value. Never use this conversion for a money decision. */
+export function centsToNumber(value: MoneyInput): number { return Number(normalizeCents(value)); }
+export function addCents(...values: MoneyInput[]): string { return unitsToCents(values.reduce((sum, value) => sum + centsToUnits(value), 0n)); }
+export function subtractCents(a: MoneyInput, b: MoneyInput): string { return unitsToCents(centsToUnits(a) - centsToUnits(b)); }
+export function compareCents(a: MoneyInput, b: MoneyInput): number {
+ const left = centsToUnits(a), right = centsToUnits(b);
+ return left < right ? -1 : left > right ? 1 : 0;
+}
+export function formatUsdExact(cents: MoneyInput): string {
+ const units = centsToUnits(cents);
+ const magnitude = units < 0n ? -units : units;
+ const rounded = (magnitude + MONEY_SCALE / 2n) / MONEY_SCALE;
+ return `${units < 0n ? "-" : ""}$${rounded / 100n}.${String(rounded % 100n).padStart(2, "0")}`;
+}
diff --git a/packages/shared/src/primary-agent.ts b/packages/shared/src/primary-agent.ts
new file mode 100644
index 00000000000..63d7841ed62
--- /dev/null
+++ b/packages/shared/src/primary-agent.ts
@@ -0,0 +1,14 @@
+import { z } from "zod";
+
+export interface PrimaryAgentPreference {
+ companyId: string;
+ userId: string;
+ primaryAgentId: string | null;
+ initialized: boolean;
+}
+
+export const updatePrimaryAgentSchema = z.object({
+ primaryAgentId: z.string().uuid(),
+}).strict();
+
+export type UpdatePrimaryAgent = z.infer;
diff --git a/packages/shared/src/types/budget.ts b/packages/shared/src/types/budget.ts
index 6907796ad27..7b3fe924d57 100644
--- a/packages/shared/src/types/budget.ts
+++ b/packages/shared/src/types/budget.ts
@@ -16,8 +16,10 @@ export interface BudgetPolicy {
metric: BudgetMetric;
windowKind: BudgetWindowKind;
amount: number;
+ reservationCents?: string;
warnPercent: number;
hardStopEnabled: boolean;
+ unpricedUsagePolicy: "block" | "allow";
notifyEnabled: boolean;
isActive: boolean;
createdByUserId: string | null;
@@ -35,11 +37,16 @@ export interface BudgetPolicySummary {
metric: BudgetMetric;
windowKind: BudgetWindowKind;
amount: number;
+ reservationCents?: string;
observedAmount: number;
+ observedAmountExact?: string;
+ unpricedEventCount: number;
+ pendingRunCount: number;
remainingAmount: number;
utilizationPercent: number;
warnPercent: number;
hardStopEnabled: boolean;
+ unpricedUsagePolicy: "block" | "allow";
notifyEnabled: boolean;
isActive: boolean;
status: "ok" | "warning" | "hard_stop";
@@ -85,9 +92,11 @@ export interface BudgetPolicyUpsertInput {
scopeId: string;
metric?: BudgetMetric;
windowKind?: BudgetWindowKind;
- amount: number;
+ amount?: number;
+ reservationCents?: string | number;
warnPercent?: number;
hardStopEnabled?: boolean;
+ unpricedUsagePolicy?: "block" | "allow";
notifyEnabled?: boolean;
isActive?: boolean;
}
diff --git a/packages/shared/src/types/connection-intent.ts b/packages/shared/src/types/connection-intent.ts
index 9dcf1a7e050..652d0b30358 100644
--- a/packages/shared/src/types/connection-intent.ts
+++ b/packages/shared/src/types/connection-intent.ts
@@ -1,6 +1,6 @@
import type { ConnectionIntentInteraction } from "./issue.js";
import type { ToolConnection } from "./tool-access.js";
-import type { AskUserQuestionsQuestion } from "./issue.js";
+import type { AskUserQuestionsQuestion, PaperclipQuestionSetPayload } from "./issue.js";
import type { RemoteMcpConnectorId } from "../remote-mcp-connectors.js";
export type ConnectionAvailabilityState =
@@ -44,6 +44,8 @@ export interface ConnectionsSearchResult {
/** Paperclip-authored next step; provider content must never supply this field. */
instruction?: string;
providerQuestion?: AskUserQuestionsQuestion;
+ /** Canonical native form of the same provider choice; IDs and disclosure are identical. */
+ providerQuestionSet?: PaperclipQuestionSetPayload;
selectionInteractionId?: string;
}
diff --git a/packages/shared/src/types/cost.ts b/packages/shared/src/types/cost.ts
index 4e55098094d..ba4f107fcc4 100644
--- a/packages/shared/src/types/cost.ts
+++ b/packages/shared/src/types/cost.ts
@@ -2,14 +2,17 @@ import type { AgentAppearance } from "../agent-appearance.js";
import type { BillingType, CostStatus } from "../constants.js";
export interface CostEvent {
+ usageKind?: "agent" | "decision";
+ responsibleUserId?: string | null;
id: string;
companyId: string;
- agentId: string;
+ agentId: string | null;
issueId: string | null;
projectId: string | null;
goalId: string | null;
heartbeatRunId: string | null;
billingCode: string | null;
+ idempotencyKey: string | null;
provider: string;
biller: string;
billingType: BillingType;
@@ -19,13 +22,20 @@ export interface CostEvent {
cachedInputTokens: number;
outputTokens: number;
costCents: number;
+ costCentsExact?: string;
occurredAt: Date;
createdAt: Date;
}
export interface CostSummary {
+ eventCount: number;
+ pendingRunCount: number;
+ unpricedEventCount: number;
+ estimatedEventCount?: number;
+ pricingComplete: boolean;
companyId: string;
spendCents: number;
+ spendCentsExact?: string;
budgetCents: number;
utilizationPercent: number;
}
@@ -35,6 +45,7 @@ export interface IssueCostSummary {
issueCount: number;
includeDescendants: boolean;
costCents: number;
+ costCentsExact?: string;
inputTokens: number;
cachedInputTokens: number;
outputTokens: number;
@@ -45,13 +56,42 @@ export interface IssueCostSummary {
runtimeMs: number;
}
+export interface CostByUser {
+ /** The run's recorded responsible user; null means unattributed. */
+ userId: string | null;
+ userName: string | null;
+ userImage: string | null;
+ eventCount: number;
+ estimatedEventCount: number;
+ unpricedEventCount: number;
+ costCents: number;
+ costCentsExact: string;
+ /** Input excludes cached input, as in other cost reports. */
+ inputTokens: number;
+ cachedInputTokens: number;
+ outputTokens: number;
+ /** Distinct recorded runs with cost events in the selected period. */
+ runCount: number;
+}
+
+export interface CostByUserReport {
+ /** Active human members, excluding the synthetic local-board principal. */
+ activeUserCount: number;
+ /** Includes zero-spend active users, even in single-user companies. */
+ rows: CostByUser[];
+}
+
export interface CostByAgent {
- agentId: string;
+ agentId: string | null;
agentName: string | null;
agentAppearance?: AgentAppearance | null;
avatarUrl?: string;
agentStatus: string | null;
+ /** Ledger events in this group and selected date range, not distinct runs. */
+ eventCount: number;
+ estimatedEventCount: number;
costCents: number;
+ costCentsExact?: string;
inputTokens: number;
cachedInputTokens: number;
outputTokens: number;
@@ -68,6 +108,7 @@ export interface CostByProviderModel {
billingType: BillingType;
model: string;
costCents: number;
+ costCentsExact?: string;
inputTokens: number;
cachedInputTokens: number;
outputTokens: number;
@@ -81,6 +122,7 @@ export interface CostByProviderModel {
export interface CostByBiller {
biller: string;
costCents: number;
+ costCentsExact?: string;
inputTokens: number;
cachedInputTokens: number;
outputTokens: number;
@@ -95,7 +137,7 @@ export interface CostByBiller {
/** per-agent breakdown by provider + model, for identifying token-hungry agents */
export interface CostByAgentModel {
- agentId: string;
+ agentId: string | null;
agentName: string | null;
agentAppearance?: AgentAppearance | null;
avatarUrl?: string;
@@ -103,7 +145,11 @@ export interface CostByAgentModel {
biller: string;
billingType: BillingType;
model: string;
+ /** Ledger events in this group and selected date range, not distinct runs. */
+ eventCount: number;
+ estimatedEventCount: number;
costCents: number;
+ costCentsExact?: string;
inputTokens: number;
cachedInputTokens: number;
outputTokens: number;
@@ -118,6 +164,7 @@ export interface CostWindowSpendRow {
/** rolling window duration in hours */
windowHours: number;
costCents: number;
+ costCentsExact?: string;
inputTokens: number;
cachedInputTokens: number;
outputTokens: number;
@@ -128,6 +175,7 @@ export interface CostByProject {
projectId: string | null;
projectName: string | null;
costCents: number;
+ costCentsExact?: string;
inputTokens: number;
cachedInputTokens: number;
outputTokens: number;
diff --git a/packages/shared/src/types/execution-projection.ts b/packages/shared/src/types/execution-projection.ts
index 02a92849144..ab65bbfb5b4 100644
--- a/packages/shared/src/types/execution-projection.ts
+++ b/packages/shared/src/types/execution-projection.ts
@@ -11,6 +11,8 @@ export interface ExecutionBlocker {
canContinue?: boolean;
/** Explicit Retry candidate; the server rechecks stop proof and execution gates. */
canRetry?: boolean;
+ /** Required workspace files must be recovered before another provider turn. */
+ workspaceRepairRequired?: boolean;
savedMessageCount?: number;
}
diff --git a/packages/shared/src/types/finance.ts b/packages/shared/src/types/finance.ts
index 75a52084bea..5c2208c7950 100644
--- a/packages/shared/src/types/finance.ts
+++ b/packages/shared/src/types/finance.ts
@@ -22,39 +22,75 @@ export interface FinanceEvent {
quantity: number | null;
unit: FinanceUnit | null;
amountCents: number;
+ amountCentsExact?: string;
currency: string;
estimated: boolean;
externalInvoiceId: string | null;
+ idempotencyKey: string | null;
metadataJson: Record | null;
occurredAt: Date;
createdAt: Date;
}
+export interface FinanceCurrencySummary {
+ currency: string;
+ providerReportedCentsExact?: string;
+ debitCents: number;
+ debitCentsExact?: string;
+ creditCents: number;
+ creditCentsExact?: string;
+ netCents: number;
+ netCentsExact?: string;
+ estimatedDebitCents: number;
+ estimatedDebitCentsExact?: string;
+ eventCount: number;
+}
+
export interface FinanceSummary {
+ /** Provider cost reports overlap invoices and run estimates; never add these totals. */
+ providerReportedCents?: number;
+ providerReportedCentsExact?: string;
+ /** Compatibility totals below are USD only; no implicit currency conversion. */
+ currency: "USD";
+ currencies: FinanceCurrencySummary[];
companyId: string;
debitCents: number;
+ debitCentsExact?: string;
creditCents: number;
+ creditCentsExact?: string;
netCents: number;
+ netCentsExact?: string;
estimatedDebitCents: number;
+ estimatedDebitCentsExact?: string;
eventCount: number;
}
export interface FinanceByBiller {
+ currency: string;
biller: string;
debitCents: number;
+ debitCentsExact?: string;
creditCents: number;
+ creditCentsExact?: string;
netCents: number;
+ netCentsExact?: string;
estimatedDebitCents: number;
+ estimatedDebitCentsExact?: string;
eventCount: number;
kindCount: number;
}
export interface FinanceByKind {
+ currency: string;
eventKind: FinanceEventKind;
debitCents: number;
+ debitCentsExact?: string;
creditCents: number;
+ creditCentsExact?: string;
netCents: number;
+ netCentsExact?: string;
estimatedDebitCents: number;
+ estimatedDebitCentsExact?: string;
eventCount: number;
billerCount: number;
}
diff --git a/packages/shared/src/types/heartbeat.ts b/packages/shared/src/types/heartbeat.ts
index 862a8350511..b29276093ed 100644
--- a/packages/shared/src/types/heartbeat.ts
+++ b/packages/shared/src/types/heartbeat.ts
@@ -158,6 +158,8 @@ export interface HeartbeatRun {
id: string;
companyId: string;
agentId: string;
+ scopeKind: "company" | "issue";
+ issueId: string | null;
invocationSource: HeartbeatInvocationSource;
triggerDetail: WakeupTriggerDetail | null;
status: HeartbeatRunStatus;
@@ -222,6 +224,10 @@ export interface HeartbeatRun {
contextSnapshot: Record | null;
createdAt: Date;
updatedAt: Date;
+ /** Metadata-only company-list row for a run bound to an unreadable private issue. */
+ redacted?: boolean;
+ durationMs?: number | null;
+ costUsd?: number | null;
outputSilence?: HeartbeatRunOutputSilence;
/**
* Ephemeral, process-local current status message for an active run. Resolved
diff --git a/packages/shared/src/types/index.ts b/packages/shared/src/types/index.ts
index 449dbc58097..f149b2a8425 100644
--- a/packages/shared/src/types/index.ts
+++ b/packages/shared/src/types/index.ts
@@ -352,7 +352,22 @@ export type {
DocumentTextRange,
UpdateDocumentAnnotationThreadRequest,
} from "./document-annotation.js";
-export type { Project, ProjectDiscoverySummary, ProjectDiscoveryPage, ProjectRepository, ProjectRepositoryOptions, ProjectBudgetSummary, ProjectCodebase, ProjectCodebaseOrigin, ProjectGoalRef, ProjectManagedByPlugin, ProjectWorkspace } from "./project.js";
+export type {
+ Project,
+ ProjectRepository,
+ ProjectRepositoryOptions,
+ ProjectAccessMember,
+ ProjectAccessSubjectType,
+ ProjectDiscoverySummary,
+ ProjectDiscoveryPage,
+ ProjectBudgetSummary,
+ ProjectCodebase,
+ ProjectCodebaseOrigin,
+ ProjectGoalRef,
+ ProjectManagedByPlugin,
+ ProjectVisibility,
+ ProjectWorkspace,
+} from "./project.js";
export type {
CompanySearchCountType,
CompanySearchExtractIssueResult,
@@ -664,6 +679,13 @@ export type {
IssueSubtreeDiagnosticNode,
IssueSubtreeDiagnosticEdge,
IssueSubtreeDiagnosticsResponse,
+ IssueVisibility,
+ IssuePrivacyConstraints,
+ IssueAccessGrant,
+ IssueAccessGrantAgentVisibility,
+ IssueAccessGrantSubjectType,
+ IssueAccessGrantSource,
+ IssueLockedStub,
IssueBlockerAttention,
IssueBlockerAttentionIssueSummary,
IssueBlockerAttentionReason,
@@ -877,7 +899,7 @@ export type {
RoutineExecutionIssueOrigin,
RoutineListItem,
} from "./routine.js";
-export type { CostEvent, CostSummary, IssueCostSummary, CostByAgent, CostByProviderModel, CostByBiller, CostByAgentModel, CostWindowSpendRow, CostByProject } from "./cost.js";
+export type { CostEvent, CostSummary, IssueCostSummary, CostByUser, CostByUserReport, CostByAgent, CostByProviderModel, CostByBiller, CostByAgentModel, CostWindowSpendRow, CostByProject } from "./cost.js";
export type { FinanceEvent, FinanceSummary, FinanceByBiller, FinanceByKind } from "./finance.js";
export type {
AgentWakeupResponse,
diff --git a/packages/shared/src/types/issue.ts b/packages/shared/src/types/issue.ts
index 727b3e03f39..7e0673f378e 100644
--- a/packages/shared/src/types/issue.ts
+++ b/packages/shared/src/types/issue.ts
@@ -46,6 +46,46 @@ import type {
export type { IssueWorkMode };
+export type IssueVisibility = "open" | "private";
+/** Management hints for this task; never includes protected project/parent identity. */
+export interface IssuePrivacyConstraints {
+ publicBlockedBy: "parent" | "project" | null;
+ leavesPersonalProject: boolean;
+}
+export type IssueAccessGrantSubjectType = "user" | "agent";
+export type IssueAccessGrantSource = "explicit" | "assignment" | "project" | "owner";
+export type IssueAccessGrantAgentVisibility = "discoverable" | "private";
+
+export interface IssueAccessGrant {
+ id: string;
+ issueId: string;
+ subjectType: IssueAccessGrantSubjectType;
+ subjectId: string;
+ source: IssueAccessGrantSource;
+ /** Effective access inherited from a parent or private project; not revocable here. */
+ inherited?: boolean;
+ grantedByUserId: string | null;
+ grantedByAgentId: string | null;
+ createdAt: Date;
+ revokedAt: Date | null;
+ subjectDisplayName: string | null;
+ subjectAvatarUrl: string | null;
+ subjectInitials: string | null;
+ agentVisibility: IssueAccessGrantAgentVisibility | null;
+}
+
+/**
+ * Existence-only projection used when a readable issue references an issue the
+ * current principal cannot read. Edge projections may return this exact shape
+ * in place of an IssueRelationIssueSummary; direct reads and list/search rows
+ * never return locked stubs.
+ */
+export interface IssueLockedStub {
+ id: string;
+ identifier: string | null;
+ locked: true;
+}
+
export interface IssueAncestorProject {
id: string;
name: string;
@@ -605,6 +645,7 @@ export interface IssueScheduledRetry {
export type IssueRetryNowOutcome =
| "promoted"
| "already_promoted"
+ | "waiting"
| "no_scheduled_retry"
| "gate_suppressed";
@@ -792,6 +833,11 @@ export interface Issue {
projectWorkspaceId: string | null;
goalId: string | null;
parentId: string | null;
+ /** Present on current API responses; optional for compatibility with older plugin payloads. */
+ visibility?: IssueVisibility;
+ privacyRootIssueId?: string | null;
+ /** Immediate task from which private access flows downward, including chat handoffs. */
+ privacyParentIssueId?: string | null;
ancestors?: IssueAncestor[];
title: string;
description: string | null;
@@ -884,6 +930,8 @@ export type CompactIssue = Pick<
| "projectWorkspaceId"
| "goalId"
| "parentId"
+ | "visibility"
+ | "privacyRootIssueId"
| "title"
| "description"
| "status"
diff --git a/packages/shared/src/types/project.ts b/packages/shared/src/types/project.ts
index d6601ab18d1..438c28b3ee5 100644
--- a/packages/shared/src/types/project.ts
+++ b/packages/shared/src/types/project.ts
@@ -8,6 +8,19 @@ import type { AgentEnvConfig } from "./secrets.js";
export type ProjectWorkspaceSourceType = "local_path" | "git_repo" | "remote_managed" | "non_git_path";
export type ProjectWorkspaceVisibility = "default" | "advanced";
+export type ProjectVisibility = "open" | "private";
+export type ProjectAccessSubjectType = "user" | "agent";
+
+export interface ProjectAccessMember {
+ id: string;
+ companyId: string;
+ projectId: string;
+ subjectType: ProjectAccessSubjectType;
+ subjectId: string;
+ subjectDisplayName: string | null;
+ subjectAvatarUrl: string | null;
+ createdAt: Date;
+}
export interface ProjectGoalRef {
id: string;
@@ -98,6 +111,12 @@ export interface Project {
goals: ProjectGoalRef[];
name: string;
description: string | null;
+ /** Omitted by older servers/fixtures; clients must treat omission as open. */
+ visibility?: ProjectVisibility;
+ /** Present only for the lazily-created per-user "My private tasks" project. */
+ personalOwnerUserId?: string | null;
+ /** Only this user and administrators may change the project audience. */
+ privacyOwnerUserId?: string | null;
status: ProjectStatus;
leadAgentId: string | null;
targetDate: string | null;
diff --git a/packages/shared/src/types/user-profile.ts b/packages/shared/src/types/user-profile.ts
index 2ed483da1b2..d961a407485 100644
--- a/packages/shared/src/types/user-profile.ts
+++ b/packages/shared/src/types/user-profile.ts
@@ -59,7 +59,7 @@ export interface UserProfileActivitySummary {
}
export interface UserProfileAgentUsage {
- agentId: string;
+ agentId: string | null;
agentName: string | null;
costCents: number;
inputTokens: number;
diff --git a/packages/shared/src/validators/budget.ts b/packages/shared/src/validators/budget.ts
index 55f629c8f4d..76ad91791c8 100644
--- a/packages/shared/src/validators/budget.ts
+++ b/packages/shared/src/validators/budget.ts
@@ -1,3 +1,4 @@
+import { exactCentsSchema } from "../accounting.js";
import { z } from "zod";
import {
BUDGET_INCIDENT_RESOLUTION_ACTIONS,
@@ -11,18 +12,20 @@ export const upsertBudgetPolicySchema = z.object({
scopeId: z.string().guid(),
metric: z.enum(BUDGET_METRICS).optional().default("billed_cents"),
windowKind: z.enum(BUDGET_WINDOW_KINDS).optional().default("calendar_month_utc"),
- amount: z.number().int().nonnegative(),
- warnPercent: z.number().int().min(1).max(99).optional().default(80),
- hardStopEnabled: z.boolean().optional().default(true),
- notifyEnabled: z.boolean().optional().default(true),
- isActive: z.boolean().optional().default(true),
+ amount: z.number().int().nonnegative().max(2_147_483_647).optional(),
+ reservationCents: exactCentsSchema.optional(),
+ warnPercent: z.number().int().min(1).max(99).optional(),
+ hardStopEnabled: z.boolean().optional(),
+ unpricedUsagePolicy: z.enum(["block", "allow"]).optional(),
+ notifyEnabled: z.boolean().optional(),
+ isActive: z.boolean().optional(),
});
export type UpsertBudgetPolicy = z.infer;
export const resolveBudgetIncidentSchema = z.object({
action: z.enum(BUDGET_INCIDENT_RESOLUTION_ACTIONS),
- amount: z.number().int().nonnegative().optional(),
+ amount: z.number().int().nonnegative().max(2_147_483_647).optional(),
decisionNote: z.string().optional().nullable(),
}).superRefine((value, ctx) => {
if (value.action === "raise_budget_and_resume" && typeof value.amount !== "number") {
diff --git a/packages/shared/src/validators/company-skill.ts b/packages/shared/src/validators/company-skill.ts
index b75d5bd3c63..7e64c158464 100644
--- a/packages/shared/src/validators/company-skill.ts
+++ b/packages/shared/src/validators/company-skill.ts
@@ -473,7 +473,7 @@ export const companySkillTestRunTemplateSnapshotSchema = z.object({
);
export const companySkillTestRunCostSummarySchema = z.object({
- costCents: z.number().int().nonnegative(),
+ costCents: z.number().nonnegative(),
inputTokens: z.number().int().nonnegative(),
cachedInputTokens: z.number().int().nonnegative(),
outputTokens: z.number().int().nonnegative(),
diff --git a/packages/shared/src/validators/cost.ts b/packages/shared/src/validators/cost.ts
index 1ed2263178f..3f3da7ccfad 100644
--- a/packages/shared/src/validators/cost.ts
+++ b/packages/shared/src/validators/cost.ts
@@ -1,7 +1,9 @@
+import { exactCentsSchema, pricingProvenanceSchema } from "../accounting.js";
import { z } from "zod";
import { BILLING_TYPES, COST_STATUSES } from "../constants.js";
-export const createCostEventSchema = z.object({
+const costEventFields = z.object({
+ idempotencyKey: z.string().trim().min(1).max(200).optional().nullable(),
agentId: z.string().guid(),
issueId: z.string().guid().optional().nullable(),
projectId: z.string().guid().optional().nullable(),
@@ -13,17 +15,28 @@ export const createCostEventSchema = z.object({
billingType: z.enum(BILLING_TYPES).optional().default("unknown"),
costStatus: z.enum(COST_STATUSES).optional().default("reported"),
model: z.string().min(1),
- inputTokens: z.number().int().nonnegative().optional().default(0),
- cachedInputTokens: z.number().int().nonnegative().optional().default(0),
- outputTokens: z.number().int().nonnegative().optional().default(0),
- costCents: z.number().int().nonnegative(),
+ inputTokens: z.number().int().nonnegative().max(2_147_483_647).optional().default(0),
+ cachedInputTokens: z.number().int().nonnegative().max(2_147_483_647).optional().default(0),
+ outputTokens: z.number().int().nonnegative().max(2_147_483_647).optional().default(0),
+ costCents: exactCentsSchema,
+ providerRequestId: z.string().min(1).max(250).nullable().optional(),
+ pricingProvenance: pricingProvenanceSchema.nullable().optional(),
occurredAt: z.string().datetime(),
-}).transform((value) => ({
+});
+
+export const createCostEventSchema = costEventFields.transform((value) => ({
...value,
biller: value.biller ?? value.provider,
}));
-export type CreateCostEvent = z.infer;
+/** Internal service receipts; the public reporting endpoint retains its required agent. */
+export const createServiceCostEventSchema = costEventFields.extend({
+ agentId: z.string().uuid().nullable(),
+ usageKind: z.literal("decision"),
+ responsibleUserId: z.string().nullable(),
+}).transform(value => ({ ...value, biller: value.biller ?? value.provider }));
+
+export type CreateCostEvent = z.input;
export const updateBudgetSchema = z.object({
budgetMonthlyCents: z.number().int().nonnegative(),
diff --git a/packages/shared/src/validators/finance.ts b/packages/shared/src/validators/finance.ts
index f09eebf2840..ded2b0bdf24 100644
--- a/packages/shared/src/validators/finance.ts
+++ b/packages/shared/src/validators/finance.ts
@@ -1,7 +1,9 @@
+import { exactCentsSchema } from "../accounting.js";
import { z } from "zod";
import { AGENT_ADAPTER_TYPES, FINANCE_DIRECTIONS, FINANCE_EVENT_KINDS, FINANCE_UNITS } from "../constants.js";
export const createFinanceEventSchema = z.object({
+ idempotencyKey: z.string().trim().min(1).max(200).optional().nullable(),
agentId: z.string().guid().optional().nullable(),
issueId: z.string().guid().optional().nullable(),
projectId: z.string().guid().optional().nullable(),
@@ -20,8 +22,8 @@ export const createFinanceEventSchema = z.object({
model: z.string().min(1).optional().nullable(),
quantity: z.number().int().nonnegative().optional().nullable(),
unit: z.enum(FINANCE_UNITS).optional().nullable(),
- amountCents: z.number().int().nonnegative(),
- currency: z.string().length(3).optional().default("USD"),
+ amountCents: exactCentsSchema,
+ currency: z.string().regex(/^[A-Za-z]{3}$/).optional().default("USD"),
estimated: z.boolean().optional().default(false),
externalInvoiceId: z.string().optional().nullable(),
metadataJson: z.record(z.string(), z.unknown()).optional().nullable(),
@@ -31,4 +33,4 @@ export const createFinanceEventSchema = z.object({
currency: value.currency.toUpperCase(),
}));
-export type CreateFinanceEvent = z.infer;
+export type CreateFinanceEvent = z.input;
diff --git a/packages/shared/src/validators/index.ts b/packages/shared/src/validators/index.ts
index b45a1946b39..448531ff66f 100644
--- a/packages/shared/src/validators/index.ts
+++ b/packages/shared/src/validators/index.ts
@@ -390,12 +390,14 @@ export {
projectDiscoverySchema,
createProjectSchema,
updateProjectSchema,
+ addProjectAccessMemberSchema,
createProjectWorkspaceSchema,
updateProjectWorkspaceSchema,
projectExecutionWorkspacePolicySchema,
projectWorkspaceRuntimeConfigSchema,
type CreateProject,
type UpdateProject,
+ type AddProjectAccessMember,
type CreateProjectWorkspace,
type UpdateProjectWorkspace,
type ProjectExecutionWorkspacePolicy,
@@ -433,6 +435,7 @@ export {
updateIssueSchema,
stalledReviewDecisionSchema,
issueExecutionPolicySchema,
+ issueExecutionMonitorPolicySchema,
issueExecutionStateSchema,
issueRecoveryActionReadModelSchema,
resolveIssueRecoveryActionSchema,
@@ -711,7 +714,7 @@ export {
} from "./routine.js";
export {
- createCostEventSchema,
+ createCostEventSchema, createServiceCostEventSchema,
updateBudgetSchema,
type CreateCostEvent,
type UpdateBudget,
diff --git a/packages/shared/src/validators/issue.test.ts b/packages/shared/src/validators/issue.test.ts
index 77ef460c9fa..27f688d3cc8 100644
--- a/packages/shared/src/validators/issue.test.ts
+++ b/packages/shared/src/validators/issue.test.ts
@@ -15,6 +15,14 @@ import {
import { createAgentSchema } from "./agent.js";
describe("issue validators", () => {
+ it("accepts private visibility without adding defaults to updates", () => {
+ expect(createIssueSchema.parse({ title: "Private", visibility: "private" }).visibility).toBe("private");
+ expect(createIssueSchema.parse({ title: "Open" }).visibility).toBe("open");
+ expect(updateIssueSchema.parse({}).visibility).toBeUndefined();
+ expect(updateIssueSchema.parse({ visibility: "private" }).visibility).toBe("private");
+ expect(updateIssueSchema.safeParse({ visibility: "secret" }).success).toBe(false);
+ });
+
it("validates the typed recovery display snapshot while retaining older metadata", () => {
const metadata = { version: 1, sections: [{ rows: [{ type: "text", text: "Details" }] }] };
const recovery = { kind: "disposition_repair_escalated", actionId: "9af8228f-0be7-45ae-a104-6fbe0af6f1d3", attemptCount: 2, maxAttempts: 2, reason: "unchanged_source_state_exhausted", assigneeAgentId: null };
@@ -306,6 +314,20 @@ describe("issue validators", () => {
).toBe(false);
});
+ it.each(["backlog", "in_progress", "blocked", "cancelled"])("requires workspace evidence to record a repair at unchanged %s status", sourceIssueStatus => {
+ const input = { outcome: "restored", sourceIssueStatus };
+ expect(resolveIssueRecoveryActionSchema.safeParse(input).success).toBe(false);
+ expect(resolveIssueRecoveryActionSchema.safeParse({ ...input, executionReconciliation: {
+ runId: "11111111-1111-4111-8111-111111111111", providerStopped: true, actionOutcome: "mixed",
+ outcomeEvidence: "Observed and reconciled the source run action outcomes.",
+ } }).success).toBe(false);
+ expect(resolveIssueRecoveryActionSchema.safeParse({ ...input, executionReconciliation: {
+ runId: "11111111-1111-4111-8111-111111111111", providerStopped: true, actionOutcome: "mixed",
+ outcomeEvidence: "Observed and reconciled the source run action outcomes.",
+ workspaceRepairEvidence: "Copied the retained source files and verified the restored files.",
+ } }).success).toBe(true);
+ });
+
it("allows cancelled recovery resolutions to atomically restore the source issue status", () => {
expect(
resolveIssueRecoveryActionSchema.parse({
diff --git a/packages/shared/src/validators/issue.ts b/packages/shared/src/validators/issue.ts
index d39f1845091..bbb44441d61 100644
--- a/packages/shared/src/validators/issue.ts
+++ b/packages/shared/src/validators/issue.ts
@@ -576,12 +576,15 @@ export const resolveIssueRecoveryActionSchema = z
.optional(),
actionId: z.string().guid().optional(),
outcome: z.enum(RESOLVE_ISSUE_RECOVERY_ACTION_OUTCOMES),
- sourceIssueStatus: z.enum(["todo", "done", "in_review", "blocked"]),
+ sourceIssueStatus: z.enum(ISSUE_STATUSES),
resolutionNote: multilineTextSchema.optional().nullable(),
})
.strict()
.superRefine((value, ctx) => {
if (value.outcome === "restored") {
+ // A retained-source repair records evidence without changing task state.
+ // The route verifies the exact server-owned source and unchanged status.
+ if (value.executionReconciliation?.workspaceRepairEvidence) return;
if (
value.sourceIssueStatus !== "todo" &&
value.sourceIssueStatus !== "done" &&
@@ -689,6 +692,7 @@ const createIssueBaseSchema = z.object({
projectId: z.string().guid().optional().nullable(),
projectWorkspaceId: z.string().guid().optional().nullable(),
goalId: z.string().guid().optional().nullable(),
+ visibility: z.enum(["open", "private"]).optional().default("open"),
parentId: z.string().guid().optional().nullable(),
blockedByIssueIds: z.array(z.string().guid()).optional(),
unblockDescriptor: z
diff --git a/packages/shared/src/validators/project.ts b/packages/shared/src/validators/project.ts
index d207952f0ef..11b8eb7d830 100644
--- a/packages/shared/src/validators/project.ts
+++ b/packages/shared/src/validators/project.ts
@@ -111,6 +111,7 @@ const projectFields = {
goalIds: z.array(z.string().guid()).optional(),
name: z.string().min(1),
description: z.string().optional().nullable(),
+ visibility: z.enum(["open", "private"]).optional().default("open"),
status: z.enum(PROJECT_STATUSES).optional().default("backlog"),
leadAgentId: z.string().guid().optional().nullable(),
targetDate: z.string().optional().nullable(),
@@ -137,4 +138,11 @@ export const updateProjectSchema = objectWithoutDefaults(
export type UpdateProject = z.infer;
+export const addProjectAccessMemberSchema = z.object({
+ subjectType: z.enum(["user", "agent"]),
+ subjectId: z.string().min(1),
+});
+
+export type AddProjectAccessMember = z.infer;
+
export type ProjectExecutionWorkspacePolicy = z.infer;
diff --git a/packages/shared/src/validators/status-card.ts b/packages/shared/src/validators/status-card.ts
index f6b6f1d3f66..0dccd38bed2 100644
--- a/packages/shared/src/validators/status-card.ts
+++ b/packages/shared/src/validators/status-card.ts
@@ -101,7 +101,7 @@ export const statusCardSchema = z.object({
summaryBody: z.string().nullable().optional(),
watchedIssueCount: z.number().int().nonnegative().optional(),
todayTokens: z.number().int().nonnegative().optional(),
- todayCostCents: z.number().int().nonnegative().optional(),
+ todayCostCents: z.number().nonnegative().optional(),
});
export const statusCardUpdateChangeSchema = z.object({
@@ -122,7 +122,7 @@ export const statusCardUpdateSchema = z.object({
changes: z.array(statusCardUpdateChangeSchema),
inputTokens: z.number().int().nonnegative(),
outputTokens: z.number().int().nonnegative(),
- costCents: z.number().int().nonnegative(),
+ costCents: z.number().nonnegative(),
model: z.string().nullable(),
queryVersion: z.number().int().nonnegative().nullable(),
changeSummary: z.string().nullable(),
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 858fdb97f3b..e9cd1c62f6b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -40,10 +40,10 @@ patchedDependencies:
hash: vbylpnnxt5av2zdnuqmf6hjyjy
path: patches/@discordjs__ws@1.2.3.patch
acpx@0.12.0:
- hash: zxns4omawae6bjvy7kkhcgweei
+ hash: 6st5fzvttegjv64llnfegwwpca
path: patches/acpx@0.12.0.patch
acpx@0.13.1:
- hash: xinuppsghzi2pwhozdhfegto3m
+ hash: btis2ixbxfyq422xwpnza3ncle
path: patches/acpx@0.13.1.patch
embedded-postgres@18.1.0-beta.16:
hash: 55uhvnotpqyiy37rn3pqpukhei
@@ -158,7 +158,7 @@ importers:
version: link:../shared
acpx:
specifier: 0.12.0
- version: 0.12.0(patch_hash=zxns4omawae6bjvy7kkhcgweei)
+ version: 0.12.0(patch_hash=6st5fzvttegjv64llnfegwwpca)
picocolors:
specifier: ^1.1.1
version: 1.1.1
@@ -508,7 +508,7 @@ importers:
version: 0.160.0
acpx:
specifier: 0.13.1
- version: 0.13.1(patch_hash=xinuppsghzi2pwhozdhfegto3m)
+ version: 0.13.1(patch_hash=btis2ixbxfyq422xwpnza3ncle)
ajv:
specifier: ^8.20.0
version: 8.20.0
@@ -874,30 +874,39 @@ importers:
server:
dependencies:
+ '@ai-sdk/openai':
+ specifier: 4.0.86
+ version: 4.0.86(zod@4.4.3)
'@aws-sdk/client-s3':
specifier: ^3.1141.0
version: 3.1141.0
'@chat-adapter/discord':
specifier: 4.39.0
- version: 4.39.0(patch_hash=nywlhls7dd4npegrgax7jqdbxa)(zod@4.4.3)
+ version: 4.39.0(patch_hash=nywlhls7dd4npegrgax7jqdbxa)(ai@7.0.130(zod@4.4.3))(zod@4.4.3)
'@chat-adapter/github':
specifier: 4.39.0
- version: 4.39.0(patch_hash=x25bk7vvljpm57viwan5qoaddi)(zod@4.4.3)
+ version: 4.39.0(patch_hash=x25bk7vvljpm57viwan5qoaddi)(ai@7.0.130(zod@4.4.3))(zod@4.4.3)
'@chat-adapter/slack':
specifier: 4.39.0
- version: 4.39.0(patch_hash=226jj24akljccsfbw7bcxujz4u)(zod@4.4.3)
+ version: 4.39.0(patch_hash=226jj24akljccsfbw7bcxujz4u)(ai@7.0.130(zod@4.4.3))(zod@4.4.3)
'@chat-adapter/teams':
specifier: 4.39.0
- version: 4.39.0(patch_hash=jfm44m5wrw3jrn2jijafzk7s5a)(zod@4.4.3)
+ version: 4.39.0(patch_hash=jfm44m5wrw3jrn2jijafzk7s5a)(ai@7.0.130(zod@4.4.3))(zod@4.4.3)
'@chat-adapter/telegram':
specifier: 4.39.0
- version: 4.39.0(patch_hash=wl4uiwewrapxf5u6ksnm7elv44)(zod@4.4.3)
+ version: 4.39.0(patch_hash=wl4uiwewrapxf5u6ksnm7elv44)(ai@7.0.130(zod@4.4.3))(zod@4.4.3)
'@discordjs/ws':
specifier: 1.2.3
version: 1.2.3(patch_hash=vbylpnnxt5av2zdnuqmf6hjyjy)
'@grpc/grpc-js':
specifier: 1.14.5
version: 1.14.5
+ '@modelcontextprotocol/sdk':
+ specifier: ^1.30.0
+ version: 1.30.0(zod@4.4.3)
+ '@openrouter/ai-sdk-provider':
+ specifier: 3.1.0
+ version: 3.1.0(ai@7.0.130(zod@4.4.3))(zod@4.4.3)
'@opentelemetry/api':
specifier: ^1.9.0
version: 1.9.1
@@ -954,13 +963,16 @@ importers:
version: 2.1.0(@grpc/grpc-js@1.14.5)(nice-grpc-common@2.0.4)(nice-grpc@2.1.17)
'@vercel/connect':
specifier: 2.3.3
- version: 2.3.3(@chat-adapter/slack@4.39.0(patch_hash=226jj24akljccsfbw7bcxujz4u)(zod@4.4.3))(@modelcontextprotocol/sdk@1.30.0(zod@4.4.3))(better-auth@1.7.2(@opentelemetry/api@1.9.1)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@opentelemetry/api@1.9.1)(kysely@0.29.5)(pg@8.18.0)(postgres@3.4.9(patch_hash=sryle6qd5qfmnxvoebal4gashi)))(pg@8.18.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(vitest@5.0.3(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(jsdom@30.0.1(@noble/hashes@2.4.0))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))))
+ version: 2.3.3(@chat-adapter/slack@4.39.0(patch_hash=226jj24akljccsfbw7bcxujz4u)(ai@7.0.130(zod@4.4.3))(zod@4.4.3))(@modelcontextprotocol/sdk@1.30.0(zod@4.4.3))(ai@7.0.130(zod@4.4.3))(better-auth@1.7.2(@opentelemetry/api@1.9.1)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@opentelemetry/api@1.9.1)(kysely@0.29.5)(pg@8.18.0)(postgres@3.4.9(patch_hash=sryle6qd5qfmnxvoebal4gashi)))(pg@8.18.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(vitest@5.0.3(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(jsdom@30.0.1(@noble/hashes@2.4.0))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))))
acorn:
specifier: 8.18.0
version: 8.18.0
acpx:
specifier: 0.13.1
- version: 0.13.1(patch_hash=xinuppsghzi2pwhozdhfegto3m)
+ version: 0.13.1(patch_hash=btis2ixbxfyq422xwpnza3ncle)
+ ai:
+ specifier: 7.0.130
+ version: 7.0.130(zod@4.4.3)
ajv:
specifier: ^8.20.0
version: 8.20.0
@@ -972,7 +984,7 @@ importers:
version: 1.7.2(@opentelemetry/api@1.9.1)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@opentelemetry/api@1.9.1)(kysely@0.29.5)(pg@8.18.0)(postgres@3.4.9(patch_hash=sryle6qd5qfmnxvoebal4gashi)))(pg@8.18.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(vitest@5.0.3(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(jsdom@30.0.1(@noble/hashes@2.4.0))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)))
chat:
specifier: 4.39.0
- version: 4.39.0(zod@4.4.3)
+ version: 4.39.0(ai@7.0.130(zod@4.4.3))(zod@4.4.3)
chokidar:
specifier: ^5.0.0
version: 5.0.0
@@ -1000,6 +1012,9 @@ importers:
jsdom:
specifier: ^30.0.1
version: 30.0.1(@noble/hashes@2.4.0)
+ light-my-request:
+ specifier: ^6.6.0
+ version: 6.6.0
multer:
specifier: ^2.4.0
version: 2.4.0
@@ -1090,7 +1105,7 @@ importers:
dependencies:
'@assistant-ui/react':
specifier: 0.15.22
- version: 0.15.22(@opentelemetry/api@1.9.1)(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(use-sync-external-store@1.7.0(react@19.2.8))
+ version: 0.15.22(@opentelemetry/api@1.9.1)(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(ai@7.0.130(zod@4.6.5))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(use-sync-external-store@1.7.0(react@19.2.8))
'@base-ui/react':
specifier: ^1.7.0
version: 1.7.0(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
@@ -1288,6 +1303,28 @@ packages:
peerDependencies:
zod: ^3.25.0 || ^4.0.0
+ '@ai-sdk/gateway@4.0.106':
+ resolution: {integrity: sha512-NprSdFzyVnbEp2SDWtIgsCFIUHFCehOD9S6FQkF/dLrCmnke8w4SOK3KcmUUiEbwtVzlUF8prkaELp+ohcQaQw==}
+ engines: {node: '>=22'}
+ peerDependencies:
+ zod: ^3.25.76 || ^4.1.8
+
+ '@ai-sdk/openai@4.0.86':
+ resolution: {integrity: sha512-sbUHayMvjAYV6ELydYXFTr5UBX5qyYmRELqZR3tV0dieUhgUYd8dED9bwEgqZJNJU6V8GGLOlaEpL1ltbNXA/g==}
+ engines: {node: '>=22'}
+ peerDependencies:
+ zod: ^3.25.76 || ^4.1.8
+
+ '@ai-sdk/provider-utils@5.0.56':
+ resolution: {integrity: sha512-F7/U1YpVXEfSxRHbxScm0PVdr9lN6GaUWHnt8ws2UjuGeuxWHqCkV25dGpHAkpDHkuIXoC+aak/OqSylKSJmHw==}
+ engines: {node: '>=22'}
+ peerDependencies:
+ zod: ^3.25.76 || ^4.1.8
+
+ '@ai-sdk/provider@4.0.24':
+ resolution: {integrity: sha512-iztFqJTdxNN0ZzqZAAnVPMhRMaL1bfQFa3GIPAffWQ0+dP2FXIkyMD8kHeEI7EpB/C6TR45cqOkrS7YZZ1sATA==}
+ engines: {node: '>=22'}
+
'@antfu/install-pkg@1.1.0':
resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==}
@@ -3218,6 +3255,13 @@ packages:
cpu: [x64]
os: [win32]
+ '@openrouter/ai-sdk-provider@3.1.0':
+ resolution: {integrity: sha512-BQy1TA9fKrh47s9ivsO6FY5QimN7GUF0i8Qon3pkxQclEgShso0dClpcWn8OIyPLEZZPFaFKgI8TW4S/O0p0Dw==}
+ engines: {node: '>=22'}
+ peerDependencies:
+ ai: ^7.0.0
+ zod: ^3.25.76 || ^4.1.8
+
'@opentelemetry/api@1.9.1':
resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==}
engines: {node: '>=8.0.0'}
@@ -5418,6 +5462,10 @@ packages:
eve:
optional: true
+ '@vercel/oidc@3.2.0':
+ resolution: {integrity: sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug==}
+ engines: {node: '>= 20'}
+
'@vercel/oidc@3.8.9':
resolution: {integrity: sha512-TcbdH3YtGS2KU98T99dN4sbf+E4vbJZsJTRN97wKQ7QWQ0BR7U02QX3KN4+5GHxBtKTj1c5CnvTTitc2ZRad0A==}
engines: {node: '>= 20'}
@@ -5477,6 +5525,9 @@ packages:
'@webcontainer/env@1.1.1':
resolution: {integrity: sha512-6aN99yL695Hi9SuIk1oC88l9o0gmxL1nGWWQ/kNy81HigJ0FoaoTXpytCj6ItzgyCEwA9kF1wixsTuv5cjsgng==}
+ '@workflow/serde@4.1.0':
+ resolution: {integrity: sha512-pav4F2BoirECWR7Nf1TKt+2eETcBj7jj4cBefQ8VXQCA6NPkaKeLfj/zMgi+3zYV5ZIBT4GuUiphsj0/b9hPQQ==}
+
'@workflow/serde@4.1.0-beta.2':
resolution: {integrity: sha512-8kkeoQKLDaKXefjV5dbhBj2aErfKp1Mc4pb6tj8144cF+Em5SPbyMbyLCHp+BVrFfFVCBluCtMx+jjvaFVZGww==}
@@ -5534,6 +5585,12 @@ packages:
'@x402/fetch':
optional: true
+ ai@7.0.130:
+ resolution: {integrity: sha512-QkBkCogl46jXUg0SrSsdqQlOI2ZVMCjfnbBQS8t3gE21U/SO17oNMVFyjmcC9z20wOoYUA+2O2vsso0maoS7dw==}
+ engines: {node: '>=22'}
+ peerDependencies:
+ zod: ^3.25.76 || ^4.1.8
+
ajv-formats@3.0.1:
resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==}
peerDependencies:
@@ -6956,6 +7013,9 @@ packages:
json-schema-typed@8.0.2:
resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==}
+ json-schema@0.4.0:
+ resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==}
+
json-with-bigint@3.5.12:
resolution: {integrity: sha512-uwbF/wSSuOgC7qqlq27Xp5B6a2MHVug3t0idZdTqu0JnlFvgJuH7ju+KAk/J06C7GfhoYy2gnb9wz2INqcne7w==}
@@ -7019,6 +7079,9 @@ packages:
engines: {node: '>=16'}
hasBin: true
+ light-my-request@6.6.0:
+ resolution: {integrity: sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==}
+
lightningcss-android-arm64@1.32.0:
resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==}
engines: {node: '>= 12.0.0'}
@@ -7863,6 +7926,9 @@ packages:
resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+ process-warning@4.0.1:
+ resolution: {integrity: sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==}
+
process-warning@5.1.0:
resolution: {integrity: sha512-jQSaVHsPgtyw60e1rQ/A+/ArPEj/S8pS/vFnyGa/gYFXrKk/6RuDkoqVDQ5NI5MmS01698ltlAk0NoDBNLujRw==}
@@ -8530,6 +8596,10 @@ packages:
resolution: {integrity: sha512-zWpdTVD54H48CIybL0rWQ3ukpb9d23wM7eH5RtfdmeP70cWHNjtfo7P4vZX+5CoDcO53J4Pu5uXp7lNfjc6DRA==}
engines: {node: '>=18.17'}
+ undici@7.30.0:
+ resolution: {integrity: sha512-dkrQXeHSaoamnItlYbmzG0wFYrM0ZwDxCIg0A7aKjTyyhh9svRzCNFEzV+Vm05/yehjCzjDZ31KXfGEjYSztDQ==}
+ engines: {node: '>=20.18.1'}
+
undici@8.10.0:
resolution: {integrity: sha512-HvltHd7avK13QIw/oLe4qoOLyoVSoafqJ2jYOrtMRBkbYT31eiBQ8O0ehRKZiEZCMEyLFQNIADpgCWC5fALvYQ==}
engines: {node: '>=22.19.0'}
@@ -8988,6 +9058,50 @@ snapshots:
dependencies:
zod: 4.4.3
+ '@ai-sdk/gateway@4.0.106(zod@4.4.3)':
+ dependencies:
+ '@ai-sdk/provider': 4.0.24
+ '@ai-sdk/provider-utils': 5.0.56(zod@4.4.3)
+ '@vercel/oidc': 3.2.0
+ zod: 4.4.3
+
+ '@ai-sdk/gateway@4.0.106(zod@4.6.5)':
+ dependencies:
+ '@ai-sdk/provider': 4.0.24
+ '@ai-sdk/provider-utils': 5.0.56(zod@4.6.5)
+ '@vercel/oidc': 3.2.0
+ zod: 4.6.5
+ optional: true
+
+ '@ai-sdk/openai@4.0.86(zod@4.4.3)':
+ dependencies:
+ '@ai-sdk/provider': 4.0.24
+ '@ai-sdk/provider-utils': 5.0.56(zod@4.4.3)
+ zod: 4.4.3
+
+ '@ai-sdk/provider-utils@5.0.56(zod@4.4.3)':
+ dependencies:
+ '@ai-sdk/provider': 4.0.24
+ '@standard-schema/spec': 1.1.0
+ '@workflow/serde': 4.1.0
+ eventsource-parser: 3.1.1
+ undici: 7.30.0
+ zod: 4.4.3
+
+ '@ai-sdk/provider-utils@5.0.56(zod@4.6.5)':
+ dependencies:
+ '@ai-sdk/provider': 4.0.24
+ '@standard-schema/spec': 1.1.0
+ '@workflow/serde': 4.1.0
+ eventsource-parser: 3.1.1
+ undici: 7.30.0
+ zod: 4.6.5
+ optional: true
+
+ '@ai-sdk/provider@4.0.24':
+ dependencies:
+ json-schema: 0.4.0
+
'@antfu/install-pkg@1.1.0':
dependencies:
package-manager-detector: 1.8.0
@@ -9054,7 +9168,7 @@ snapshots:
is-potential-custom-element-name: 1.0.1
lru-cache: 11.5.2
- '@assistant-ui/core@0.3.22(@assistant-ui/store@0.3.16(@assistant-ui/tap@0.9.20(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(react@19.2.8))(@assistant-ui/tap@0.9.20(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(assistant-cloud@0.2.4(@opentelemetry/api@1.9.1))(react@19.2.8)':
+ '@assistant-ui/core@0.3.22(@assistant-ui/store@0.3.16(@assistant-ui/tap@0.9.20(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(react@19.2.8))(@assistant-ui/tap@0.9.20(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(assistant-cloud@0.2.4(@opentelemetry/api@1.9.1)(ai@7.0.130(zod@4.6.5)))(react@19.2.8)':
dependencies:
'@assistant-ui/store': 0.3.16(@assistant-ui/tap@0.9.20(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(react@19.2.8)
'@assistant-ui/tap': 0.9.20(@types/react@19.2.18)(react@19.2.8)
@@ -9062,18 +9176,18 @@ snapshots:
nanoid: 6.0.1
optionalDependencies:
'@types/react': 19.2.18
- assistant-cloud: 0.2.4(@opentelemetry/api@1.9.1)
+ assistant-cloud: 0.2.4(@opentelemetry/api@1.9.1)(ai@7.0.130(zod@4.6.5))
react: 19.2.8
transitivePeerDependencies:
- ioredis
- redis
- '@assistant-ui/react@0.15.22(@opentelemetry/api@1.9.1)(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(use-sync-external-store@1.7.0(react@19.2.8))':
+ '@assistant-ui/react@0.15.22(@opentelemetry/api@1.9.1)(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(ai@7.0.130(zod@4.6.5))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(use-sync-external-store@1.7.0(react@19.2.8))':
dependencies:
- '@assistant-ui/core': 0.3.22(@assistant-ui/store@0.3.16(@assistant-ui/tap@0.9.20(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(react@19.2.8))(@assistant-ui/tap@0.9.20(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(assistant-cloud@0.2.4(@opentelemetry/api@1.9.1))(react@19.2.8)
+ '@assistant-ui/core': 0.3.22(@assistant-ui/store@0.3.16(@assistant-ui/tap@0.9.20(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(react@19.2.8))(@assistant-ui/tap@0.9.20(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(assistant-cloud@0.2.4(@opentelemetry/api@1.9.1)(ai@7.0.130(zod@4.6.5)))(react@19.2.8)
'@assistant-ui/store': 0.3.16(@assistant-ui/tap@0.9.20(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(react@19.2.8)
'@assistant-ui/tap': 0.9.20(@types/react@19.2.18)(react@19.2.8)
- assistant-cloud: 0.2.4(@opentelemetry/api@1.9.1)
+ assistant-cloud: 0.2.4(@opentelemetry/api@1.9.1)(ai@7.0.130(zod@4.6.5))
assistant-stream: 0.3.46
radix-ui: 1.6.7(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
react: 19.2.8
@@ -9485,10 +9599,10 @@ snapshots:
'@bufbuild/protobuf@2.15.0': {}
- '@chat-adapter/discord@4.39.0(patch_hash=nywlhls7dd4npegrgax7jqdbxa)(zod@4.4.3)':
+ '@chat-adapter/discord@4.39.0(patch_hash=nywlhls7dd4npegrgax7jqdbxa)(ai@7.0.130(zod@4.4.3))(zod@4.4.3)':
dependencies:
- '@chat-adapter/shared': 4.39.0(zod@4.4.3)
- chat: 4.39.0(zod@4.4.3)
+ '@chat-adapter/shared': 4.39.0(ai@7.0.130(zod@4.4.3))(zod@4.4.3)
+ chat: 4.39.0(ai@7.0.130(zod@4.4.3))(zod@4.4.3)
discord-api-types: 0.37.120
discord-interactions: 4.4.0
discord.js: 14.27.0
@@ -9500,33 +9614,33 @@ snapshots:
- workflow
- zod
- '@chat-adapter/github@4.39.0(patch_hash=x25bk7vvljpm57viwan5qoaddi)(zod@4.4.3)':
+ '@chat-adapter/github@4.39.0(patch_hash=x25bk7vvljpm57viwan5qoaddi)(ai@7.0.130(zod@4.4.3))(zod@4.4.3)':
dependencies:
- '@chat-adapter/shared': 4.39.0(zod@4.4.3)
+ '@chat-adapter/shared': 4.39.0(ai@7.0.130(zod@4.4.3))(zod@4.4.3)
'@octokit/auth-app': 8.3.1
'@octokit/rest': 22.0.1
- chat: 4.39.0(zod@4.4.3)
+ chat: 4.39.0(ai@7.0.130(zod@4.4.3))(zod@4.4.3)
transitivePeerDependencies:
- ai
- supports-color
- workflow
- zod
- '@chat-adapter/shared@4.39.0(zod@4.4.3)':
+ '@chat-adapter/shared@4.39.0(ai@7.0.130(zod@4.4.3))(zod@4.4.3)':
dependencies:
- chat: 4.39.0(zod@4.4.3)
+ chat: 4.39.0(ai@7.0.130(zod@4.4.3))(zod@4.4.3)
transitivePeerDependencies:
- ai
- supports-color
- workflow
- zod
- '@chat-adapter/slack@4.39.0(patch_hash=226jj24akljccsfbw7bcxujz4u)(zod@4.4.3)':
+ '@chat-adapter/slack@4.39.0(patch_hash=226jj24akljccsfbw7bcxujz4u)(ai@7.0.130(zod@4.4.3))(zod@4.4.3)':
dependencies:
- '@chat-adapter/shared': 4.39.0(zod@4.4.3)
+ '@chat-adapter/shared': 4.39.0(ai@7.0.130(zod@4.4.3))(zod@4.4.3)
'@slack/socket-mode': 2.0.7
'@slack/web-api': 7.19.0
- chat: 4.39.0(zod@4.4.3)
+ chat: 4.39.0(ai@7.0.130(zod@4.4.3))(zod@4.4.3)
transitivePeerDependencies:
- ai
- bufferutil
@@ -9536,14 +9650,14 @@ snapshots:
- workflow
- zod
- '@chat-adapter/teams@4.39.0(patch_hash=jfm44m5wrw3jrn2jijafzk7s5a)(zod@4.4.3)':
+ '@chat-adapter/teams@4.39.0(patch_hash=jfm44m5wrw3jrn2jijafzk7s5a)(ai@7.0.130(zod@4.4.3))(zod@4.4.3)':
dependencies:
- '@chat-adapter/shared': 4.39.0(zod@4.4.3)
+ '@chat-adapter/shared': 4.39.0(ai@7.0.130(zod@4.4.3))(zod@4.4.3)
'@microsoft/teams.api': 2.0.16
'@microsoft/teams.apps': 2.0.16
'@microsoft/teams.cards': 2.0.16
'@microsoft/teams.graph-endpoints': 2.0.16
- chat: 4.39.0(zod@4.4.3)
+ chat: 4.39.0(ai@7.0.130(zod@4.4.3))(zod@4.4.3)
transitivePeerDependencies:
- ai
- debug
@@ -9551,10 +9665,10 @@ snapshots:
- workflow
- zod
- '@chat-adapter/telegram@4.39.0(patch_hash=wl4uiwewrapxf5u6ksnm7elv44)(zod@4.4.3)':
+ '@chat-adapter/telegram@4.39.0(patch_hash=wl4uiwewrapxf5u6ksnm7elv44)(ai@7.0.130(zod@4.4.3))(zod@4.4.3)':
dependencies:
- '@chat-adapter/shared': 4.39.0(zod@4.4.3)
- chat: 4.39.0(zod@4.4.3)
+ '@chat-adapter/shared': 4.39.0(ai@7.0.130(zod@4.4.3))(zod@4.4.3)
+ chat: 4.39.0(ai@7.0.130(zod@4.4.3))(zod@4.4.3)
transitivePeerDependencies:
- ai
- supports-color
@@ -11165,6 +11279,11 @@ snapshots:
'@openai/codex@0.160.0-win32-x64':
optional: true
+ '@openrouter/ai-sdk-provider@3.1.0(ai@7.0.130(zod@4.4.3))(zod@4.4.3)':
+ dependencies:
+ ai: 7.0.130(zod@4.4.3)
+ zod: 4.4.3
+
'@opentelemetry/api@1.9.1': {}
'@opentelemetry/semantic-conventions@1.43.0': {}
@@ -13176,14 +13295,17 @@ snapshots:
dependencies:
execa: 5.1.1
- '@vercel/connect@2.3.3(@chat-adapter/slack@4.39.0(patch_hash=226jj24akljccsfbw7bcxujz4u)(zod@4.4.3))(@modelcontextprotocol/sdk@1.30.0(zod@4.4.3))(better-auth@1.7.2(@opentelemetry/api@1.9.1)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@opentelemetry/api@1.9.1)(kysely@0.29.5)(pg@8.18.0)(postgres@3.4.9(patch_hash=sryle6qd5qfmnxvoebal4gashi)))(pg@8.18.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(vitest@5.0.3(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(jsdom@30.0.1(@noble/hashes@2.4.0))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))))':
+ '@vercel/connect@2.3.3(@chat-adapter/slack@4.39.0(patch_hash=226jj24akljccsfbw7bcxujz4u)(ai@7.0.130(zod@4.4.3))(zod@4.4.3))(@modelcontextprotocol/sdk@1.30.0(zod@4.4.3))(ai@7.0.130(zod@4.4.3))(better-auth@1.7.2(@opentelemetry/api@1.9.1)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@opentelemetry/api@1.9.1)(kysely@0.29.5)(pg@8.18.0)(postgres@3.4.9(patch_hash=sryle6qd5qfmnxvoebal4gashi)))(pg@8.18.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(vitest@5.0.3(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(jsdom@30.0.1(@noble/hashes@2.4.0))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15))))':
dependencies:
'@vercel/oidc': 3.8.9
optionalDependencies:
- '@chat-adapter/slack': 4.39.0(patch_hash=226jj24akljccsfbw7bcxujz4u)(zod@4.4.3)
+ '@chat-adapter/slack': 4.39.0(patch_hash=226jj24akljccsfbw7bcxujz4u)(ai@7.0.130(zod@4.4.3))(zod@4.4.3)
'@modelcontextprotocol/sdk': 1.30.0(zod@4.4.3)
+ ai: 7.0.130(zod@4.4.3)
better-auth: 1.7.2(@opentelemetry/api@1.9.1)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@opentelemetry/api@1.9.1)(kysely@0.29.5)(pg@8.18.0)(postgres@3.4.9(patch_hash=sryle6qd5qfmnxvoebal4gashi)))(pg@8.18.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(vitest@5.0.3(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(jsdom@30.0.1(@noble/hashes@2.4.0))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)))
+ '@vercel/oidc@3.2.0': {}
+
'@vercel/oidc@3.8.9':
dependencies:
'@vercel/cli-config': 0.3.0
@@ -13253,6 +13375,8 @@ snapshots:
'@webcontainer/env@1.1.1': {}
+ '@workflow/serde@4.1.0': {}
+
'@workflow/serde@4.1.0-beta.2': {}
'@xterm/addon-fit@0.11.0': {}
@@ -13272,7 +13396,7 @@ snapshots:
acorn@8.18.0: {}
- acpx@0.12.0(patch_hash=zxns4omawae6bjvy7kkhcgweei):
+ acpx@0.12.0(patch_hash=6st5fzvttegjv64llnfegwwpca):
dependencies:
'@agentclientprotocol/sdk': 1.2.1(zod@4.4.3)
commander: 15.0.0
@@ -13284,7 +13408,7 @@ snapshots:
- bare-buffer
- react-native-b4a
- acpx@0.13.1(patch_hash=xinuppsghzi2pwhozdhfegto3m):
+ acpx@0.13.1(patch_hash=btis2ixbxfyq422xwpnza3ncle):
dependencies:
'@agentclientprotocol/sdk': 1.4.0(zod@4.4.3)
commander: 15.0.0
@@ -13313,6 +13437,21 @@ snapshots:
- bufferutil
- utf-8-validate
+ ai@7.0.130(zod@4.4.3):
+ dependencies:
+ '@ai-sdk/gateway': 4.0.106(zod@4.4.3)
+ '@ai-sdk/provider': 4.0.24
+ '@ai-sdk/provider-utils': 5.0.56(zod@4.4.3)
+ zod: 4.4.3
+
+ ai@7.0.130(zod@4.6.5):
+ dependencies:
+ '@ai-sdk/gateway': 4.0.106(zod@4.6.5)
+ '@ai-sdk/provider': 4.0.24
+ '@ai-sdk/provider-utils': 5.0.56(zod@4.6.5)
+ zod: 4.6.5
+ optional: true
+
ajv-formats@3.0.1(ajv@8.20.0):
optionalDependencies:
ajv: 8.20.0
@@ -13354,11 +13493,12 @@ snapshots:
assertion-error@2.0.1: {}
- assistant-cloud@0.2.4(@opentelemetry/api@1.9.1):
+ assistant-cloud@0.2.4(@opentelemetry/api@1.9.1)(ai@7.0.130(zod@4.6.5)):
dependencies:
assistant-stream: 0.3.46
optionalDependencies:
'@opentelemetry/api': 1.9.1
+ ai: 7.0.130(zod@4.6.5)
transitivePeerDependencies:
- ioredis
- redis
@@ -13559,7 +13699,7 @@ snapshots:
character-reference-invalid@2.0.1: {}
- chat@4.39.0(zod@4.4.3):
+ chat@4.39.0(ai@7.0.130(zod@4.4.3))(zod@4.4.3):
dependencies:
'@workflow/serde': 4.1.0-beta.2
mdast-util-to-string: 4.0.0
@@ -13569,6 +13709,7 @@ snapshots:
remend: 1.3.1
unified: 11.0.5
optionalDependencies:
+ ai: 7.0.130(zod@4.4.3)
zod: 4.4.3
transitivePeerDependencies:
- supports-color
@@ -14702,6 +14843,8 @@ snapshots:
json-schema-typed@8.0.2: {}
+ json-schema@0.4.0: {}
+
json-with-bigint@3.5.12: {}
json5@2.2.3: {}
@@ -14768,6 +14911,12 @@ snapshots:
dependencies:
isomorphic.js: 0.2.5
+ light-my-request@6.6.0:
+ dependencies:
+ cookie: 1.1.1
+ process-warning: 4.0.1
+ set-cookie-parser: 2.7.2
+
lightningcss-android-arm64@1.32.0:
optional: true
@@ -15883,6 +16032,8 @@ snapshots:
ansi-styles: 5.2.0
react-is: 17.0.2
+ process-warning@4.0.1: {}
+
process-warning@5.1.0: {}
prop-types@15.8.1:
@@ -16763,6 +16914,8 @@ snapshots:
undici@6.28.1: {}
+ undici@7.30.0: {}
+
undici@8.10.0: {}
unidiff@1.0.4:
diff --git a/scripts/run-vitest-stable.mjs b/scripts/run-vitest-stable.mjs
index fcaf0a9470d..2580cd6384d 100644
--- a/scripts/run-vitest-stable.mjs
+++ b/scripts/run-vitest-stable.mjs
@@ -31,6 +31,7 @@ const nonServerProjects = [
"@paperclipai/adapter-cursor-local",
"@paperclipai/adapter-gemini-local",
"@paperclipai/adapter-grok-local",
+ "@paperclipai/hermes-paperclip-adapter",
"@paperclipai/adapter-kimi-local",
"@paperclipai/adapter-openclaw-gateway",
"@paperclipai/adapter-opencode-local",
diff --git a/server/package.json b/server/package.json
index 3e34acd4d5f..42d53f18c77 100644
--- a/server/package.json
+++ b/server/package.json
@@ -44,6 +44,9 @@
"typecheck": "pnpm run prepare:runner-vendor && pnpm --filter @paperclipai/plugin-sdk ensure-build-deps && tsc --noEmit"
},
"dependencies": {
+ "ai": "7.0.130",
+ "@ai-sdk/openai": "4.0.86",
+ "@openrouter/ai-sdk-provider": "3.1.0",
"@aws-sdk/client-s3": "^3.1141.0",
"@chat-adapter/discord": "4.39.0",
"@chat-adapter/github": "4.39.0",
diff --git a/server/scripts/smoke-native-task-monitor.ts b/server/scripts/smoke-native-task-monitor.ts
new file mode 100644
index 00000000000..76d327bd939
--- /dev/null
+++ b/server/scripts/smoke-native-task-monitor.ts
@@ -0,0 +1,98 @@
+/** Opt-in live qualification: creates an isolated database/workspace and spends two Codex turns.
+ * PATH=::$PATH node --import tsx server/scripts/smoke-native-task-monitor.ts --run
+ */
+import assert from "node:assert/strict";
+import { randomUUID } from "node:crypto";
+import { mkdtemp, mkdir, writeFile } from "node:fs/promises";
+import { createServer } from "node:http";
+import { tmpdir } from "node:os";
+import { join } from "node:path";
+import { setTimeout as delay } from "node:timers/promises";
+import { and, eq } from "drizzle-orm";
+
+if (!process.argv.includes("--run")) throw new Error("Pass --run to authorize the live two-turn Codex smoke.");
+const root = await mkdtemp(join(tmpdir(), "paperclip-live-task-monitor-"));
+process.env.PAPERCLIP_HOME = join(root, "paperclip");
+process.env.PAPERCLIP_INSTANCE_ID = "monitor-smoke";
+process.env.PAPERCLIP_TELEMETRY_ENABLED = "false";
+const { createDb, companies, agents, authUsers, companyMemberships, issues, heartbeatRuns, agentWakeupRequests, nativeRunResults, statusDecisions } = await import("@paperclipai/db");
+const { startEmbeddedPostgresTestDatabase } = await import("../src/__tests__/helpers/embedded-postgres.js");
+const { heartbeatService } = await import("../src/services/heartbeat.js");
+const { setupRunnerPrpWebSocketServer, runnerPrpWebSocketInternals } = await import("../src/realtime/runner-prp-ws.js");
+const { closeIdleWarmNativeSessionsForRestart } = await import("../src/services/native-runtime/native-session-executor.js");
+const temporary = await startEmbeddedPostgresTestDatabase("live-task-monitor-");
+const db = createDb(temporary.connectionString);
+const server = createServer();
+await new Promise(resolve => server.listen(0, "127.0.0.1", resolve));
+const address = server.address();
+if (!address || typeof address === "string") throw new Error("TCP listener missing");
+process.env.PAPERCLIP_API_URL = `http://127.0.0.1:${address.port}`;
+setupRunnerPrpWebSocketServer(server, { apiUrl: process.env.PAPERCLIP_API_URL });
+const companyId = randomUUID(), agentId = randomUUID(), issueId = randomUUID();
+const heartbeat = heartbeatService(db);
+const readRuns = () => db.select().from(heartbeatRuns).where(eq(heartbeatRuns.companyId, companyId)).orderBy(heartbeatRuns.createdAt);
+console.log(JSON.stringify({ root, companyId, agentId, issueId }));
+try {
+ const cwd = join(root, "workspace");
+ await mkdir(cwd);
+ await db.insert(companies).values({ id: companyId, name: "Isolated monitor smoke", issuePrefix: "MON", defaultResponsibleUserId: "monitor-smoke", requireBoardApprovalForNewAgents: false });
+ await db.insert(authUsers).values({ id: "monitor-smoke", name: "Monitor smoke", email: "monitor-smoke@example.test", createdAt: new Date(), updatedAt: new Date() });
+ await db.insert(companyMemberships).values({ companyId, principalType: "user", principalId: "monitor-smoke", status: "active", membershipRole: "owner" });
+ await db.insert(agents).values({ id: agentId, companyId, name: "Monitor verifier", status: "active", adapterType: "paperclip_runner",
+ adapterConfig: { provider: "codex", cwd, lifecycleMode: "warm", idleTimeoutMs: 300_000, timeoutSeconds: 180 },
+ runtimeConfig: { heartbeat: { enabled: false, wakeOnDemand: true } } });
+ await db.insert(issues).values({ id: issueId, companyId, title: "Verify a one-shot native task monitor", identifier: "MON-1", status: "in_progress", assigneeAgentId: agentId,
+ description: "This is an isolated two-run integration test. First run: use set_task_monitor on this task with a fresh nextCheckAt about 45 seconds in the future (compute the current UTC time if needed), notes saying to verify issue_monitor_due, and idempotencyKey monitor-live-first. Confirm the receipt. Then call paperclip_finish with yielded and continuation.kind monitor, accurately retaining the second run as blocking remaining work. End immediately after acceptance. Do not sleep or poll. Second run: if the wake reason is issue_monitor_due, the requested check succeeded. Report that reason and finish done using the current completion contract. Do not schedule another monitor or request human review. No files or other deliverables are required." });
+ await heartbeat.wakeup(agentId, { source: "on_demand", triggerDetail: "manual", reason: "monitor_smoke",
+ requestedByActorType: "system", requestedByActorId: "monitor-smoke", payload: { issueId }, contextSnapshot: { issueId, wakeReason: "monitor_smoke" } });
+ const deadline = Date.now() + 8 * 60_000;
+ let firstReleasedAt: number | null = null;
+ while (Date.now() < deadline) {
+ const runs = await readRuns();
+ if (runs.some(run => ["failed", "timed_out", "cancelled"].includes(run.status))) {
+ throw new Error(`Live run failed: ${JSON.stringify(runs.map(run => ({ id: run.id, status: run.status, error: run.error, errorCode: run.errorCode })))}`);
+ }
+ if (runs.length === 1 && runs[0].status === "succeeded") {
+ firstReleasedAt ??= Date.now();
+ const [issue] = await db.select().from(issues).where(eq(issues.id, issueId));
+ assert.equal(issue.status, "in_progress");
+ assert.ok(issue.monitorNextCheckAt, "first run must leave a persisted monitor");
+ assert.equal(issue.executionRunId, null);
+ }
+ if (runs.length >= 2 && runs[1].status === "succeeded") break;
+ await heartbeat.tickTimers();
+ await delay(1_000);
+ }
+ await heartbeat.drainActiveRunExecutions();
+ const runs = await readRuns();
+ assert.equal(runs.length, 2, "exactly two server runs must execute");
+ assert.ok(runs.every(run => run.status === "succeeded"));
+ const [issue] = await db.select().from(issues).where(eq(issues.id, issueId));
+ const wakes = await db.select().from(agentWakeupRequests).where(and(eq(agentWakeupRequests.companyId, companyId), eq(agentWakeupRequests.reason, "issue_monitor_due")));
+ assert.equal(wakes.length, 1);
+ assert.equal(runs[1].contextSnapshot?.wakeReason, "issue_monitor_due");
+ assert.equal(issue.status, "done");
+ assert.equal(issue.monitorNextCheckAt, null);
+ assert.ok(firstReleasedAt && runs[1].createdAt.getTime() - firstReleasedAt < 300_000, "wake must arrive within the configured warm window");
+ const results = await db.select().from(nativeRunResults).where(eq(nativeRunResults.companyId, companyId));
+ const decisions = await db.select().from(statusDecisions).where(eq(statusDecisions.companyId, companyId));
+ const evidence = { companyId, issueId, agentId, configuredIdleTimeoutMs: 300_000, firstReleasedAt, status: issue.status,
+ runs: runs.map(run => ({ id: run.id, status: run.status, createdAt: run.createdAt, finishedAt: run.finishedAt,
+ wakeReason: run.contextSnapshot?.wakeReason, nativeSessionId: run.nativeSessionId, runnerInstanceId: run.runnerInstanceId,
+ processPid: run.processPid, processStartedAt: run.processStartedAt, providerSessionId: run.sessionIdAfter,
+ semanticToolReceipts: run.resultJson?.semanticToolReceipts })),
+ warmReuse: { sameNativeSession: runs[0].nativeSessionId === runs[1].nativeSessionId,
+ sameRunnerInstance: runs[0].runnerInstanceId === runs[1].runnerInstanceId,
+ sameProcess: runs[0].processPid != null && runs[0].processPid === runs[1].processPid && runs[0].processStartedAt?.getTime() === runs[1].processStartedAt?.getTime() },
+ results: results.map(row => ({ runId: row.runId, result: row.resultJson })),
+ decisions: decisions.map(row => ({ runId: row.runId, reasonCode: row.reasonCode, toStatus: row.toStatus })),
+ monitorWakeIds: wakes.map(row => row.id) };
+ await writeFile(join(root, "evidence.json"), JSON.stringify(evidence, null, 2));
+ console.log(JSON.stringify({ passed: true, evidence: join(root, "evidence.json"), warmReuse: evidence.warmReuse }));
+} finally {
+ await writeFile(join(root, "run-records.json"), JSON.stringify(await readRuns(), null, 2));
+ await closeIdleWarmNativeSessionsForRestart();
+ runnerPrpWebSocketInternals.resetForTests();
+ await new Promise(resolve => server.close(() => resolve()));
+ await temporary.cleanup();
+}
diff --git a/server/src/__tests__/activity-routes.test.ts b/server/src/__tests__/activity-routes.test.ts
index 0bb574486c6..796815389c3 100644
--- a/server/src/__tests__/activity-routes.test.ts
+++ b/server/src/__tests__/activity-routes.test.ts
@@ -42,6 +42,14 @@ vi.mock("../services/index.js", () => ({
heartbeatService: () => mockHeartbeatService,
}));
+vi.mock("../services/authorization.js", async (importOriginal) => {
+ const actual = await importOriginal();
+ return {
+ ...actual,
+ issueReadSqlCondition: vi.fn(async () => ({}) as any),
+ };
+});
+
vi.mock("../services/agent-action-audit.js", () => ({
agentActionAuditService: () => mockAgentActionAuditService,
}));
@@ -219,6 +227,7 @@ describe("activity routes", () => {
entityType: undefined,
entityId: undefined,
limit: 100,
+ readCondition: expect.anything(),
});
});
@@ -237,6 +246,7 @@ describe("activity routes", () => {
entityType: "issue",
entityId: undefined,
limit: 500,
+ readCondition: expect.anything(),
});
});
diff --git a/server/src/__tests__/activity-service.test.ts b/server/src/__tests__/activity-service.test.ts
index 6f1a9601634..f3c107910ec 100644
--- a/server/src/__tests__/activity-service.test.ts
+++ b/server/src/__tests__/activity-service.test.ts
@@ -19,6 +19,7 @@ import {
startEmbeddedPostgresTestDatabase,
} from "./helpers/embedded-postgres.js";
import { activityService } from "../services/activity.ts";
+import { issueReadSqlCondition } from "../services/authorization.ts";
import { issueService } from "../services/issues.ts";
import { documentService } from "../services/documents.ts";
@@ -150,6 +151,54 @@ describeEmbeddedPostgres("activity service", () => {
expect(result.map((event) => event.action)).toEqual(["test.newest", "test.middle"]);
});
+ it("filters company activity rows whose entity is a private issue", async () => {
+ const companyId = randomUUID();
+ const privateIssueId = randomUUID();
+ const openIssueId = randomUUID();
+ await db.insert(companies).values({
+ id: companyId,
+ name: "Private activity",
+ issuePrefix: `A${companyId.replace(/-/g, "").slice(0, 6).toUpperCase()}`,
+ });
+ await db.insert(issues).values([
+ {
+ id: privateIssueId,
+ companyId,
+ title: "Confidential activity",
+ status: "todo",
+ priority: "medium",
+ visibility: "private",
+ privacyRootIssueId: privateIssueId,
+ responsibleUserId: "private-owner",
+ },
+ {
+ id: openIssueId,
+ companyId,
+ title: "Open activity",
+ status: "todo",
+ priority: "medium",
+ },
+ ]);
+ await db.insert(activityLog).values([
+ { companyId, actorType: "system", actorId: "system", action: "private.changed", entityType: "issue", entityId: privateIssueId },
+ { companyId, actorType: "system", actorId: "system", action: "open.changed", entityType: "issue", entityId: openIssueId },
+ ]);
+ const actor = {
+ type: "board" as const,
+ userId: "non-member",
+ companyIds: [companyId],
+ source: "session" as const,
+ isInstanceAdmin: false,
+ };
+
+ const rows = await activityService(db).list({
+ companyId,
+ readCondition: await issueReadSqlCondition(db, actor),
+ });
+ expect(rows.map((row) => row.action)).toContain("open.changed");
+ expect(rows.map((row) => row.action)).not.toContain("private.changed");
+ });
+
it.each([null, "native_provider_model_rejected", "adapter_failed"])("returns compact issue runs with bounded model rejection details: %s", async (errorCode) => {
const companyId = randomUUID();
const agentId = randomUUID();
@@ -175,10 +224,21 @@ describeEmbeddedPostgres("activity service", () => {
permissions: {},
});
+ await db.insert(issues).values({
+ id: issueId,
+ companyId,
+ title: "Summarize a completed run",
+ status: "done",
+ priority: "medium",
+ assigneeAgentId: agentId,
+ });
+
await db.insert(heartbeatRuns).values({
id: runId,
companyId,
agentId,
+ scopeKind: "issue",
+ issueId,
invocationSource: "assignment",
status: errorCode ? "failed" : "succeeded",
errorCode,
@@ -295,6 +355,8 @@ describeEmbeddedPostgres("activity service", () => {
id: runId,
companyId,
agentId,
+ scopeKind: "issue",
+ issueId,
invocationSource: "assignment",
status: "succeeded",
startedAt: new Date("2026-04-18T20:00:00.000Z"),
@@ -389,6 +451,8 @@ describeEmbeddedPostgres("activity service", () => {
id: runId,
companyId,
agentId,
+ scopeKind: "issue",
+ issueId,
invocationSource: "assignment",
status: "succeeded",
startedAt: new Date("2026-04-18T20:00:00.000Z"),
@@ -404,6 +468,8 @@ describeEmbeddedPostgres("activity service", () => {
id: otherRunId,
companyId,
agentId,
+ scopeKind: "issue",
+ issueId,
invocationSource: "assignment",
status: "succeeded",
startedAt: new Date("2026-04-18T20:05:00.000Z"),
@@ -511,6 +577,8 @@ describeEmbeddedPostgres("activity service", () => {
id: runId,
companyId,
agentId,
+ scopeKind: "issue",
+ issueId,
invocationSource: "assignment",
status: "succeeded",
startedAt: new Date("2026-04-18T20:10:00.000Z"),
diff --git a/server/src/__tests__/adapter-cost-failure-paths.test.ts b/server/src/__tests__/adapter-cost-failure-paths.test.ts
index 0c15c0081e4..4703f374321 100644
--- a/server/src/__tests__/adapter-cost-failure-paths.test.ts
+++ b/server/src/__tests__/adapter-cost-failure-paths.test.ts
@@ -29,6 +29,8 @@ const cases: Array<{ name: string; execute: () => Promise; event: unkno
];
describe("CLI adapter accounting on timeout", () => {
+ // Keep OpenCode runtime config copies inside each fixture; host config may
+ // include plugins and large dependency trees unrelated to accounting.
const directories: string[] = [];
afterEach(async () => { vi.clearAllMocks(); for (const dir of directories.splice(0)) await rm(dir, { recursive: true, force: true }); });
it.each(cases.filter(f => ["codex", "cursor", "opencode"].includes(f.name)))("$name preserves malformed optional counters through the checkpoint wrapper", async fixture => {
@@ -49,7 +51,7 @@ describe("CLI adapter accounting on timeout", () => {
runId: "invalid-counter-run", agent: { id: "agent", companyId: "company", name: "Worker", adapterType: `${fixture.name}_local`, adapterConfig: {} },
runtime: { sessionId: null, sessionParams: null, sessionDisplayId: null, taskKey: null },
config: { engine: "cli", command, cwd: dir, model: fixture.name === "opencode" ? "openai/test" : "gpt-6-astra", paperclipRuntimeSkills: [],
- env: { OPENAI_API_KEY: "fixture", OPENCODE_ALLOW_ALL_MODELS: "1" } },
+ env: { XDG_CONFIG_HOME: dir, OPENAI_API_KEY: "fixture", OPENCODE_ALLOW_ALL_MODELS: "1" } },
context: {}, onLog: async () => {}, onUsage,
});
const valid = cached === 0 || cached === undefined;
@@ -77,7 +79,7 @@ describe("CLI adapter accounting on timeout", () => {
runId: "test-run", agent: { id: "test-agent", companyId: "test-company", name: "Accounting", adapterType: `${fixture.name}_local`, adapterConfig: {} },
runtime: { sessionId: null, sessionParams: null, sessionDisplayId: null, taskKey: null },
config: { engine: "cli", command, cwd: dir, model: ["opencode", "pi"].includes(fixture.name) ? "openai/test" : fixture.name === "cursor" ? "gpt-5" : "test", paperclipRuntimeSkills: [],
- env: { OPENAI_API_KEY: "test-placeholder", ANTHROPIC_API_KEY: "test-placeholder", GEMINI_API_KEY: "test-placeholder", OPENCODE_ALLOW_ALL_MODELS: "1", CLAUDE_CONFIG_DIR: dir } },
+ env: { XDG_CONFIG_HOME: dir, OPENAI_API_KEY: "test-placeholder", ANTHROPIC_API_KEY: "test-placeholder", GEMINI_API_KEY: "test-placeholder", OPENCODE_ALLOW_ALL_MODELS: "1", CLAUDE_CONFIG_DIR: dir } },
context: {}, onLog: async () => {}, onUsage,
};
const execute = await fixture.execute();
@@ -211,7 +213,7 @@ describe("CLI adapter accounting on timeout", () => {
const result = await execute({
runId: "tail-run", agent: { id: "test-agent", companyId: "test-company", name: "Accounting", adapterType: `${fixture.name}_local`, adapterConfig: {} },
runtime: { sessionId: null, sessionParams: null, sessionDisplayId: null, taskKey: null },
- config: { engine: "cli", command, cwd: dir, model: "anthropic/test", paperclipRuntimeSkills: [], env: { ANTHROPIC_API_KEY: "fixture", OPENAI_BASE_URL: "https://unrelated-proxy.example/v1", OPENROUTER_API_KEY: "unrelated-key", OPENCODE_ALLOW_ALL_MODELS: "1" } },
+ config: { engine: "cli", command, cwd: dir, model: "anthropic/test", paperclipRuntimeSkills: [], env: { XDG_CONFIG_HOME: dir, ANTHROPIC_API_KEY: "fixture", OPENAI_BASE_URL: "https://unrelated-proxy.example/v1", OPENROUTER_API_KEY: "unrelated-key", OPENCODE_ALLOW_ALL_MODELS: "1" } },
context: {}, onLog: async () => {}, onUsage,
});
expect(result.usage).toMatchObject({ inputTokens: 40, outputTokens: 20, cachedInputTokens: 200 });
@@ -231,7 +233,7 @@ describe("CLI adapter accounting on timeout", () => {
runId: "test-run", agent: { id: "test-agent", companyId: "test-company", name: "Accounting", adapterType: `${fixture.name}_local`, adapterConfig: {} },
runtime: { sessionId: null, sessionParams: null, sessionDisplayId: null, taskKey: null },
config: { engine: "cli", command, cwd: dir, model: ["opencode", "pi"].includes(fixture.name) ? "openai/test" : fixture.name === "cursor" ? "gpt-5" : "test", paperclipRuntimeSkills: [],
- env: { OPENAI_API_KEY: "test-placeholder", ANTHROPIC_API_KEY: "test-placeholder", GEMINI_API_KEY: "test-placeholder", MOONSHOT_API_KEY: "test-placeholder", OPENCODE_ALLOW_ALL_MODELS: "1", CLAUDE_CONFIG_DIR: dir } },
+ env: { XDG_CONFIG_HOME: dir, OPENAI_API_KEY: "test-placeholder", ANTHROPIC_API_KEY: "test-placeholder", GEMINI_API_KEY: "test-placeholder", MOONSHOT_API_KEY: "test-placeholder", OPENCODE_ALLOW_ALL_MODELS: "1", CLAUDE_CONFIG_DIR: dir } },
context: {}, onLog: async () => {},
});
expect(result.timedOut).toBe(true);
diff --git a/server/src/__tests__/agent-live-run-routes.test.ts b/server/src/__tests__/agent-live-run-routes.test.ts
index d5d1805a694..6210ac99470 100644
--- a/server/src/__tests__/agent-live-run-routes.test.ts
+++ b/server/src/__tests__/agent-live-run-routes.test.ts
@@ -354,6 +354,8 @@ describe("agent live run routes", () => {
mockHeartbeatService.getRunLogAccess.mockResolvedValue({
id: "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
companyId: "company-1",
+ scopeKind: "company",
+ issueId: null,
logStore: "local_file",
logRef: "logs/aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa.ndjson",
});
@@ -598,6 +600,8 @@ describe("agent live run routes", () => {
{
id: "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
companyId: "company-1",
+ scopeKind: "company",
+ issueId: null,
logStore: "local_file",
logRef: "logs/aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa.ndjson",
},
@@ -687,7 +691,8 @@ describe("agent live run routes", () => {
lastOutputStream: null,
lastOutputBytes: 0,
processStartedAt: null,
- issueId: "issue-1",
+ scopeKind: "company",
+ issueId: null,
}));
const { db, limit } = createLiveRunsDbStub(rows);
@@ -731,7 +736,8 @@ describe("agent live run routes", () => {
lastOutputStream: null,
lastOutputBytes: 0,
processStartedAt: null,
- issueId: "issue-1",
+ scopeKind: "company",
+ issueId: null,
}));
const { db, limit } = createLiveRunsDbStub(rows);
@@ -774,7 +780,8 @@ describe("agent live run routes", () => {
lastOutputStream: null,
lastOutputBytes: 0,
processStartedAt: null,
- issueId: "issue-1",
+ scopeKind: "company",
+ issueId: null,
}));
const selectCalls: Array> = [];
@@ -834,7 +841,8 @@ describe("agent live run routes", () => {
lastOutputStream: null,
lastOutputBytes: 0,
processStartedAt: null,
- issueId: "issue-1",
+ scopeKind: "company",
+ issueId: null,
}));
const recentRows = Array.from({ length: 4 }, (_, index) => ({
id: `run-recent-${index}`,
@@ -861,7 +869,8 @@ describe("agent live run routes", () => {
lastOutputStream: null,
lastOutputBytes: 0,
processStartedAt: null,
- issueId: "issue-1",
+ scopeKind: "company",
+ issueId: null,
}));
let selectCallCount = 0;
diff --git a/server/src/__tests__/agent-permissions-routes.test.ts b/server/src/__tests__/agent-permissions-routes.test.ts
index 8428ab4e6f5..72570a9e9dc 100644
--- a/server/src/__tests__/agent-permissions-routes.test.ts
+++ b/server/src/__tests__/agent-permissions-routes.test.ts
@@ -1251,7 +1251,7 @@ describe("agent permission routes", () => {
expect.objectContaining({
status: "idle",
}),
- { claudeLogin: { storedSessionId: null, ownerUserId: "agent-admin-user", applyExistingWithoutClaim: false } },
+ { createdByUserId: "agent-admin-user", claudeLogin: { storedSessionId: null, ownerUserId: "agent-admin-user", applyExistingWithoutClaim: false } },
);
expect(mockAccessService.setPrincipalPermission).toHaveBeenCalledWith(
companyId,
@@ -1381,7 +1381,7 @@ describe("agent permission routes", () => {
},
},
}),
- { claudeLogin: { storedSessionId: null, ownerUserId: "board-user", applyExistingWithoutClaim: false } },
+ { createdByUserId: "board-user", claudeLogin: { storedSessionId: null, ownerUserId: "board-user", applyExistingWithoutClaim: false } },
);
});
@@ -1417,7 +1417,7 @@ describe("agent permission routes", () => {
model: DEFAULT_OPENCODE_LOCAL_MODEL,
}),
}),
- { claudeLogin: { storedSessionId: null, ownerUserId: "board-user", applyExistingWithoutClaim: false } },
+ { createdByUserId: "board-user", claudeLogin: { storedSessionId: null, ownerUserId: "board-user", applyExistingWithoutClaim: false } },
);
});
@@ -1455,7 +1455,7 @@ describe("agent permission routes", () => {
model: "anthropic/claude-sonnet-4-5",
}),
}),
- { claudeLogin: { storedSessionId: null, ownerUserId: "board-user", applyExistingWithoutClaim: false } },
+ { createdByUserId: "board-user", claudeLogin: { storedSessionId: null, ownerUserId: "board-user", applyExistingWithoutClaim: false } },
);
});
@@ -1495,6 +1495,7 @@ describe("agent permission routes", () => {
},
}),
{
+ createdByUserId: "board-user",
claudeLogin: {
storedSessionId: null,
ownerUserId: "board-user",
@@ -1725,7 +1726,7 @@ describe("agent permission routes", () => {
expect.objectContaining({
defaultEnvironmentId: environmentId,
}),
- { claudeLogin: { storedSessionId: null, ownerUserId: "board-user", applyExistingWithoutClaim: false } },
+ { createdByUserId: "board-user", claudeLogin: { storedSessionId: null, ownerUserId: "board-user", applyExistingWithoutClaim: false } },
);
});
@@ -1811,7 +1812,7 @@ describe("agent permission routes", () => {
adapterType: adapterCase.adapterType,
defaultEnvironmentId: environmentId,
}),
- { claudeLogin: { storedSessionId: null, ownerUserId: "board-user", applyExistingWithoutClaim: false } },
+ { createdByUserId: "board-user", claudeLogin: { storedSessionId: null, ownerUserId: "board-user", applyExistingWithoutClaim: false } },
);
});
}
diff --git a/server/src/__tests__/agent-skills-routes.test.ts b/server/src/__tests__/agent-skills-routes.test.ts
index 23722b3abf5..ae267e9fd43 100644
--- a/server/src/__tests__/agent-skills-routes.test.ts
+++ b/server/src/__tests__/agent-skills-routes.test.ts
@@ -1005,7 +1005,7 @@ describe("agent skill routes", () => {
}),
}),
}),
- { claudeLogin: { storedSessionId: null, ownerUserId: "local-board", applyExistingWithoutClaim: false } },
+ { createdByUserId: "local-board", claudeLogin: { storedSessionId: null, ownerUserId: "local-board", applyExistingWithoutClaim: false } },
);
expect(mockTrackAgentCreated).toHaveBeenCalledWith(
expect.anything(),
@@ -1055,7 +1055,7 @@ describe("agent skill routes", () => {
expect.objectContaining({
role: "security",
}),
- { claudeLogin: { storedSessionId: null, ownerUserId: "local-board", applyExistingWithoutClaim: false } },
+ { createdByUserId: "local-board", claudeLogin: { storedSessionId: null, ownerUserId: "local-board", applyExistingWithoutClaim: false } },
);
expect(mockTrackAgentCreated).toHaveBeenCalledWith(
expect.anything(),
@@ -1491,6 +1491,7 @@ describe("agent skill routes", () => {
}),
}),
{
+ createdByUserId: "local-board",
claudeLogin: {
storedSessionId: null,
ownerUserId: "local-board",
diff --git a/server/src/__tests__/approval-routes-idempotency.test.ts b/server/src/__tests__/approval-routes-idempotency.test.ts
index 3937b0499a6..bf38fd88a23 100644
--- a/server/src/__tests__/approval-routes-idempotency.test.ts
+++ b/server/src/__tests__/approval-routes-idempotency.test.ts
@@ -34,6 +34,10 @@ const mockAccessService = vi.hoisted(() => ({
}));
function registerModuleMocks() {
+ vi.doMock("../services/authorization.js", async (importActual) => ({
+ ...await importActual(),
+ canActorReadApproval: async () => true,
+ }));
vi.doMock("../services/index.js", () => ({
accessService: () => mockAccessService,
approvalService: () => mockApprovalService,
diff --git a/server/src/__tests__/approvals-service.test.ts b/server/src/__tests__/approvals-service.test.ts
index e944e2b4168..47aedf91695 100644
--- a/server/src/__tests__/approvals-service.test.ts
+++ b/server/src/__tests__/approvals-service.test.ts
@@ -1,5 +1,11 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import { approvalService } from "../services/approvals.ts";
+import { companies } from "@paperclipai/db";
+
+vi.mock("../services/budgets.js", () => ({
+ budgetService: () => ({ deliverPendingEnforcement: vi.fn(async () => {}) }),
+ budgetServiceInTransaction: () => ({ upsertPolicy: vi.fn(async () => {}) }),
+}));
const mockAgentService = vi.hoisted(() => ({
activatePendingApproval: vi.fn(),
@@ -24,6 +30,7 @@ type ApprovalRecord = {
status: string;
payload: Record;
requestedByAgentId: string | null;
+ requestedByUserId?: string | null;
};
function createApproval(status: string): ApprovalRecord {
@@ -39,8 +46,11 @@ function createApproval(status: string): ApprovalRecord {
function createDbStub(selectResults: ApprovalRecord[][], updateResults: ApprovalRecord[]) {
const pendingSelectResults = [...selectResults];
- const selectWhere = vi.fn(async () => pendingSelectResults.shift() ?? []);
- const from = vi.fn(() => ({ where: selectWhere }));
+ let inTransaction = false;
+ const selectWhere = vi.fn(async () => (inTransaction ? pendingSelectResults.shift() : pendingSelectResults[0]) ?? []);
+ const from = vi.fn((table) => table === companies
+ ? { where: () => ({ for: async () => [{ id: "company-1" }] }) }
+ : { where: selectWhere });
const select = vi.fn(() => ({ from }));
const returning = vi.fn(async () => updateResults);
@@ -49,7 +59,10 @@ function createDbStub(selectResults: ApprovalRecord[][], updateResults: Approval
const update = vi.fn(() => ({ set }));
return {
- db: { select, update, transaction: vi.fn(async (callback: (db: unknown) => Promise) => callback({ select, update })) },
+ db: { select, update, transaction: vi.fn(async (callback: (db: unknown) => Promise) => {
+ inTransaction = true;
+ try { return await callback({ select, update }); } finally { inTransaction = false; }
+ }) },
selectWhere,
returning,
};
@@ -116,9 +129,14 @@ describe("approvalService resolution idempotency", () => {
expect(mockNotifyHireApproved).not.toHaveBeenCalled();
});
- it("creates the agent from payload when approval does not reference a pending agent", async () => {
+ it.each([
+ { requestedByAgentId: "requester-1", requestedByUserId: "on-behalf-user", expectedCreator: null },
+ { requestedByAgentId: null, requestedByUserId: "original-creator", expectedCreator: "original-creator" },
+ ])("creates a legacy approved hire with its original human attribution ($expectedCreator)", async ({ requestedByAgentId, requestedByUserId, expectedCreator }) => {
const approved = {
...createApproval("approved"),
+ requestedByAgentId,
+ requestedByUserId,
payload: {
name: "New Agent",
adapterConfig: {
@@ -143,6 +161,7 @@ describe("approvalService resolution idempotency", () => {
expect.objectContaining({
adapterConfig: approved.payload.adapterConfig,
}),
+ { createdByUserId: expectedCreator },
);
});
});
diff --git a/server/src/__tests__/assets.test.ts b/server/src/__tests__/assets.test.ts
index fbc6976498c..5825e47e1b1 100644
--- a/server/src/__tests__/assets.test.ts
+++ b/server/src/__tests__/assets.test.ts
@@ -103,7 +103,7 @@ async function createApp(storage: ReturnType) {
};
next();
});
- app.use("/api", assetRoutes({} as any, storage));
+ app.use("/api", assetRoutes({ select: () => ({ from: () => ({ leftJoin: () => ({ where: async () => [] }), where: async () => [] }) }) } as any, storage));
return app;
}
diff --git a/server/src/__tests__/attention-service.test.ts b/server/src/__tests__/attention-service.test.ts
index 889b9a9ace6..d9d43e4c191 100644
--- a/server/src/__tests__/attention-service.test.ts
+++ b/server/src/__tests__/attention-service.test.ts
@@ -172,6 +172,9 @@ describeEmbeddedPostgres("attention service", () => {
createdAt?: Date;
unblockDescriptor?: { owner: { userId: string } | "board"; action: string } | null;
blockedTransitionAt?: Date | null;
+ visibility?: "open" | "private";
+ privacyRootIssueId?: string | null;
+ responsibleUserId?: string | null;
harnessKind?: string | null;
reviewPolicy?: "anyone" | "not_creator" | "human_only" | null;
}) {
@@ -195,6 +198,9 @@ describeEmbeddedPostgres("attention service", () => {
executionState: input.executionState ?? null,
unblockDescriptor: input.unblockDescriptor ?? null,
blockedTransitionAt: input.blockedTransitionAt ?? null,
+ visibility: input.visibility ?? "open",
+ privacyRootIssueId: input.privacyRootIssueId ?? null,
+ responsibleUserId: input.responsibleUserId ?? null,
harnessKind: input.harnessKind ?? null,
createdAt: input.createdAt,
updatedAt: input.updatedAt,
@@ -2040,6 +2046,35 @@ describeEmbeddedPostgres("attention service", () => {
await request(app(agent)).get(`/api/companies/${companyId}/attention`).expect(403);
});
+ it("omits private issue review items for a non-member board user", async () => {
+ const { companyId } = await seedCompany("ATP");
+ const privateIssueId = randomUUID();
+ await insertIssue({
+ id: privateIssueId,
+ companyId,
+ identifier: "ATP-1",
+ title: "Confidential review",
+ status: "in_review",
+ assigneeUserId: "private-owner",
+ executionState: pendingUserExecutionState("private-owner"),
+ visibility: "private",
+ privacyRootIssueId: privateIssueId,
+ responsibleUserId: "private-owner",
+ });
+
+ const actor = {
+ type: "board" as const,
+ source: "session" as const,
+ userId: "non-member",
+ companyIds: [companyId],
+ isInstanceAdmin: false,
+ };
+ const feed = await attentionService(db).list(companyId, { userId: actor.userId, actor });
+
+ expect(feed.items.map((item) => item.subject.title)).not.toContain("Confidential review");
+ expect(JSON.stringify(feed)).not.toContain(privateIssueId);
+ });
+
it("computes the aging shelf uniformly across approval, interaction, and review sources", async () => {
const { companyId, workerId } = await seedCompany("AGE");
const now = Date.parse("2026-08-02T12:00:00.000Z");
diff --git a/server/src/__tests__/authorization-service.test.ts b/server/src/__tests__/authorization-service.test.ts
index 02c1b562cd9..4e1f3f63c2e 100644
--- a/server/src/__tests__/authorization-service.test.ts
+++ b/server/src/__tests__/authorization-service.test.ts
@@ -1,6 +1,6 @@
import { randomUUID } from "node:crypto";
-import { afterAll, afterEach, beforeAll, describe, expect, it } from "vitest";
import { and, eq } from "drizzle-orm";
+import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from "vitest";
import {
agents,
authUsers,
@@ -8,9 +8,11 @@ import {
companyMemberships,
createDb,
instanceUserRoles,
+ issueAccessGrants,
issueComments,
issues,
principalPermissionGrants,
+ projectAccessMembers,
projects,
userInboxAgentPolicies,
} from "@paperclipai/db";
@@ -19,7 +21,13 @@ import {
getEmbeddedPostgresTestSupport,
startEmbeddedPostgresTestDatabase,
} from "./helpers/embedded-postgres.js";
-import { authorizationService } from "../services/authorization.js";
+import {
+ authorizationService,
+ canActorReadIssuePrivacy,
+ issuePrivacyMode,
+ type AuthorizationActor,
+} from "../services/authorization.js";
+import { logger } from "../middleware/logger.js";
const embeddedPostgresSupport = await getEmbeddedPostgresTestSupport();
const describeEmbeddedPostgres = embeddedPostgresSupport.supported ? describe : describe.skip;
@@ -56,12 +64,18 @@ async function createAgent(
.then((rows) => rows[0]!);
}
-async function createProject(db: ReturnType, companyId: string, label: string) {
+async function createProject(
+ db: ReturnType,
+ companyId: string,
+ label: string,
+ visibility: "open" | "private" = "open",
+) {
return db
.insert(projects)
.values({
companyId,
name: `Project ${label} ${randomUUID()}`,
+ visibility,
})
.returning()
.then((rows) => rows[0]!);
@@ -76,6 +90,12 @@ async function createIssue(
projectId?: string | null;
parentId?: string | null;
assigneeAgentId?: string | null;
+ assigneeUserId?: string | null;
+ createdByUserId?: string | null;
+ responsibleUserId?: string | null;
+ visibility?: "open" | "private";
+ privacyRootIssueId?: string | null;
+ privacyParentIssueId?: string | null;
originKind?: string | null;
originId?: string | null;
} = {},
@@ -91,6 +111,12 @@ async function createIssue(
projectId: input.projectId ?? null,
parentId: input.parentId ?? null,
assigneeAgentId: input.assigneeAgentId ?? null,
+ assigneeUserId: input.assigneeUserId ?? null,
+ createdByUserId: input.createdByUserId ?? null,
+ responsibleUserId: input.responsibleUserId ?? null,
+ visibility: input.visibility ?? "open",
+ privacyRootIssueId: input.privacyRootIssueId ?? null,
+ privacyParentIssueId: input.privacyParentIssueId ?? null,
originKind: input.originKind ?? "manual",
originId: input.originId ?? null,
})
@@ -167,6 +193,21 @@ describeEmbeddedPostgres("authorization service", () => {
let db!: ReturnType;
let tempDb: Awaited> | null = null;
+ it("defaults issue privacy to enforce while retaining explicit rollout overrides", () => {
+ const previousMode = process.env.PAPERCLIP_ISSUE_PRIVACY_MODE;
+ try {
+ delete process.env.PAPERCLIP_ISSUE_PRIVACY_MODE;
+ expect(issuePrivacyMode()).toBe("enforce");
+ process.env.PAPERCLIP_ISSUE_PRIVACY_MODE = "shadow";
+ expect(issuePrivacyMode()).toBe("shadow");
+ process.env.PAPERCLIP_ISSUE_PRIVACY_MODE = "off";
+ expect(issuePrivacyMode()).toBe("off");
+ } finally {
+ if (previousMode === undefined) delete process.env.PAPERCLIP_ISSUE_PRIVACY_MODE;
+ else process.env.PAPERCLIP_ISSUE_PRIVACY_MODE = previousMode;
+ }
+ });
+
beforeAll(async () => {
tempDb = await startEmbeddedPostgresTestDatabase("paperclip-authorization-service-");
db = createDb(tempDb.connectionString);
@@ -178,6 +219,7 @@ describeEmbeddedPostgres("authorization service", () => {
await db.delete(principalPermissionGrants);
await db.delete(companyMemberships);
await db.delete(instanceUserRoles);
+ await db.delete(issueAccessGrants);
await db.delete(issues);
await db.delete(agents);
await db.delete(projects);
@@ -2744,6 +2786,199 @@ describeEmbeddedPostgres("authorization service", () => {
})).resolves.toMatchObject({ allowed: false, reason: "deny_low_trust_boundary" });
});
+ it("enforces private issue implicit principals, grants, revocation, and subtree inheritance", async () => {
+ const previousMode = process.env.PAPERCLIP_ISSUE_PRIVACY_MODE;
+ const previousTtl = process.env.PAPERCLIP_ISSUE_PRIVACY_CACHE_TTL_MS;
+ process.env.PAPERCLIP_ISSUE_PRIVACY_MODE = "enforce";
+ process.env.PAPERCLIP_ISSUE_PRIVACY_CACHE_TTL_MS = "5000";
+ try {
+ const company = await createCompany(db, "IssuePrivacy");
+ const ownerId = await createUser(db);
+ const memberId = await createUser(db);
+ const granteeId = await createUser(db);
+ await db.insert(companyMemberships).values([ownerId, memberId, granteeId].map((principalId) => ({
+ companyId: company.id,
+ principalType: "user",
+ principalId,
+ status: "active",
+ membershipRole: "operator",
+ })));
+ const assignedAgent = await createAgent(db, company.id);
+ const otherAgent = await createAgent(db, company.id);
+ const authz = authorizationService(db);
+ const userActor = (userId: string): AuthorizationActor => ({ type: "board", userId, source: "session" });
+ const agentActor = (agentId: string): AuthorizationActor => ({
+ type: "agent",
+ agentId,
+ companyId: company.id,
+ source: "agent_key",
+ });
+ const decide = (actor: AuthorizationActor, issue: Awaited>) => authz.decide({
+ actor,
+ action: "issue:read",
+ resource: { type: "issue", companyId: company.id, issueId: issue.id },
+ });
+
+ const openIssue = await createIssue(db, company.id);
+ await expect(decide(userActor(memberId), openIssue)).resolves.toMatchObject({ allowed: true });
+
+ const privateRootId = randomUUID();
+ const privateRoot = await createIssue(db, company.id, {
+ id: privateRootId,
+ visibility: "private",
+ privacyRootIssueId: privateRootId,
+ responsibleUserId: ownerId,
+ assigneeAgentId: assignedAgent.id,
+ });
+ await expect(decide(userActor(memberId), privateRoot)).resolves.toMatchObject({
+ allowed: false,
+ reason: "deny_issue_private",
+ });
+ await expect(decide(agentActor(otherAgent.id), privateRoot)).resolves.toMatchObject({
+ allowed: false,
+ reason: "deny_issue_private",
+ });
+ await expect(decide(userActor(ownerId), privateRoot)).resolves.toMatchObject({ allowed: true });
+ await expect(decide(agentActor(assignedAgent.id), privateRoot)).resolves.toMatchObject({ allowed: true });
+
+ const grant = await db.insert(issueAccessGrants).values({
+ issueId: privateRoot.id,
+ subjectType: "user",
+ subjectId: granteeId,
+ source: "explicit",
+ grantedByUserId: ownerId,
+ }).returning().then((rows) => rows[0]!);
+ await expect(decide(userActor(granteeId), privateRoot)).resolves.toMatchObject({ allowed: true });
+
+ const child = await createIssue(db, company.id, {
+ parentId: privateRoot.id,
+ privacyParentIssueId: privateRoot.id,
+ visibility: "private",
+ privacyRootIssueId: privateRoot.id,
+ });
+ await expect(decide(userActor(granteeId), child)).resolves.toMatchObject({ allowed: true });
+
+ await db.update(issueAccessGrants).set({ revokedAt: new Date() }).where(eq(issueAccessGrants.id, grant.id));
+ await expect(decide(userActor(granteeId), privateRoot)).resolves.toMatchObject({
+ allowed: false,
+ reason: "deny_issue_private",
+ });
+
+ process.env.PAPERCLIP_ISSUE_PRIVACY_MODE = "shadow";
+ const warn = vi.spyOn(logger, "warn").mockImplementation(() => logger);
+ await expect(decide(userActor(memberId), privateRoot)).resolves.toMatchObject({ allowed: true });
+ expect(warn).toHaveBeenCalledWith(
+ expect.objectContaining({
+ authzMode: "shadow",
+ issueId: privateRoot.id,
+ reason: "deny_issue_private",
+ }),
+ "issue privacy would deny read",
+ );
+ warn.mockRestore();
+ } finally {
+ if (previousMode === undefined) delete process.env.PAPERCLIP_ISSUE_PRIVACY_MODE;
+ else process.env.PAPERCLIP_ISSUE_PRIVACY_MODE = previousMode;
+ if (previousTtl === undefined) delete process.env.PAPERCLIP_ISSUE_PRIVACY_CACHE_TTL_MS;
+ else process.env.PAPERCLIP_ISSUE_PRIVACY_CACHE_TTL_MS = previousTtl;
+ }
+ });
+
+ it("uses private-project membership as the same issue-read predicate while preserving issue grants", async () => {
+ const previousMode = process.env.PAPERCLIP_ISSUE_PRIVACY_MODE;
+ process.env.PAPERCLIP_ISSUE_PRIVACY_MODE = "enforce";
+ try {
+ const company = await createCompany(db, "ProjectPrivacy");
+ const memberId = await createUser(db);
+ const granteeId = await createUser(db);
+ const outsiderId = await createUser(db);
+ await db.insert(companyMemberships).values([memberId, granteeId, outsiderId].map((principalId) => ({
+ companyId: company.id,
+ principalType: "user" as const,
+ principalId,
+ status: "active",
+ membershipRole: "operator",
+ })));
+ const project = await createProject(db, company.id, "Private", "private");
+ const memberAgent = await createAgent(db, company.id);
+ const outsiderAgent = await createAgent(db, company.id);
+ await db.insert(companyMemberships).values([memberAgent.id, outsiderAgent.id].map((principalId) => ({
+ companyId: company.id,
+ principalType: "agent" as const,
+ principalId,
+ status: "active",
+ membershipRole: "member",
+ })));
+ await db.insert(projectAccessMembers).values({
+ companyId: company.id,
+ projectId: project.id,
+ subjectType: "user",
+ subjectId: memberId,
+ });
+ await db.insert(projectAccessMembers).values({
+ companyId: company.id,
+ projectId: project.id,
+ subjectType: "agent",
+ subjectId: memberAgent.id,
+ });
+ const issue = await createIssue(db, company.id, { projectId: project.id });
+ await db.insert(issueAccessGrants).values({
+ issueId: issue.id,
+ subjectType: "user",
+ subjectId: granteeId,
+ source: "explicit",
+ grantedByUserId: memberId,
+ });
+ const authz = authorizationService(db);
+ const decideProject = (userId: string) => authz.decide({
+ actor: { type: "board", userId, source: "session" },
+ action: "project:read",
+ resource: { type: "project", companyId: company.id, projectId: project.id },
+ });
+ const decideIssue = (userId: string) => authz.decide({
+ actor: { type: "board", userId, source: "session" },
+ action: "issue:read",
+ resource: { type: "issue", companyId: company.id, issueId: issue.id },
+ });
+ const decideProjectAsAgent = (agentId: string) => authz.decide({
+ actor: { type: "agent", agentId, companyId: company.id, source: "agent_key" },
+ action: "project:read",
+ resource: { type: "project", companyId: company.id, projectId: project.id },
+ });
+ const decideIssueAsAgent = (agentId: string) => authz.decide({
+ actor: { type: "agent", agentId, companyId: company.id, source: "agent_key" },
+ action: "issue:read",
+ resource: { type: "issue", companyId: company.id, issueId: issue.id },
+ });
+
+ await expect(decideProject(memberId)).resolves.toMatchObject({ allowed: true });
+ await expect(decideProject(outsiderId)).resolves.toMatchObject({
+ allowed: false,
+ reason: "deny_project_private",
+ });
+ await expect(decideIssue(memberId)).resolves.toMatchObject({ allowed: true });
+ await expect(decideIssue(granteeId)).resolves.toMatchObject({ allowed: true });
+ await expect(decideIssue(outsiderId)).resolves.toMatchObject({
+ allowed: false,
+ reason: "deny_issue_private",
+ });
+ await expect(decideProjectAsAgent(memberAgent.id)).resolves.toMatchObject({ allowed: true });
+ await expect(decideIssueAsAgent(memberAgent.id)).resolves.toMatchObject({ allowed: true });
+ await expect(decideProjectAsAgent(outsiderAgent.id)).resolves.toMatchObject({
+ allowed: false,
+ reason: "deny_project_private",
+ });
+ await expect(decideIssueAsAgent(outsiderAgent.id)).resolves.toMatchObject({
+ allowed: false,
+ reason: "deny_issue_private",
+ });
+ } finally {
+ if (previousMode === undefined) delete process.env.PAPERCLIP_ISSUE_PRIVACY_MODE;
+ else process.env.PAPERCLIP_ISSUE_PRIVACY_MODE = previousMode;
+ }
+ });
+
+
it("denies secrets proposals for scoped tokens regardless of request source", async () => {
const company = await createCompany(db, "SecretProposalScopes");
const actorAgent = await createAgent(db, company.id);
diff --git a/server/src/__tests__/budgets-service.test.ts b/server/src/__tests__/budgets-service.test.ts
index 8e2d68ed22c..bbc071f57bb 100644
--- a/server/src/__tests__/budgets-service.test.ts
+++ b/server/src/__tests__/budgets-service.test.ts
@@ -1,4 +1,5 @@
import { randomUUID } from "node:crypto";
+import { eq } from "drizzle-orm";
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import {
agents,
@@ -22,313 +23,8 @@ vi.mock("../services/activity-log.js", () => ({
logActivity: mockLogActivity,
}));
-type SelectResult = unknown[];
-
-function createDbStub(selectResults: SelectResult[]) {
- const pendingSelects = [...selectResults];
- const selectWhere = vi.fn(() => {
- const query = Promise.resolve(pendingSelects.shift() ?? []);
- return Object.assign(query, { for: () => query });
- });
- const selectThen = vi.fn((resolve: (value: unknown[]) => unknown) => Promise.resolve(resolve(pendingSelects.shift() ?? [])));
- const selectOrderBy = vi.fn(async () => pendingSelects.shift() ?? []);
- const selectFrom = vi.fn(() => ({
- where: selectWhere,
- then: selectThen,
- orderBy: selectOrderBy,
- }));
- const select = vi.fn(() => ({
- from: selectFrom,
- }));
-
- const insertValues = vi.fn();
- const insertReturning = vi.fn(async () => pendingInserts.shift() ?? []);
- const insert = vi.fn(() => ({
- values: insertValues.mockImplementation(() => ({
- returning: insertReturning,
- })),
- }));
-
- const updateSet = vi.fn();
- const updateWhere = vi.fn(async () => pendingUpdates.shift() ?? []);
- const update = vi.fn(() => ({
- set: updateSet.mockImplementation(() => ({
- where: updateWhere,
- })),
- }));
-
- const pendingInserts: unknown[][] = [];
- const pendingUpdates: unknown[][] = [];
-
- return {
- db: {
- select,
- insert,
- update,
- transaction: async (callback: (db: unknown) => Promise) => callback({ select, insert, update }),
- },
- queueInsert: (rows: unknown[]) => {
- pendingInserts.push(rows);
- },
- queueUpdate: (rows: unknown[] = []) => {
- pendingUpdates.push(rows);
- },
- selectWhere,
- insertValues,
- updateSet,
- };
-}
-
-describe("budgetService", () => {
- beforeEach(() => {
- vi.clearAllMocks();
- });
-
- it("creates a hard-stop incident and pauses an agent when spend exceeds a budget", async () => {
- const policy = {
- id: "policy-1",
- companyId: "company-1",
- scopeType: "agent",
- scopeId: "agent-1",
- metric: "billed_cents",
- windowKind: "calendar_month_utc",
- amount: 100,
- warnPercent: 80,
- hardStopEnabled: true,
- notifyEnabled: false,
- isActive: true,
- };
-
- const dbStub = createDbStub([
- [policy],
- [{ total: 150 }],
- [],
- [{
- companyId: "company-1",
- name: "Budget Agent",
- status: "running",
- pauseReason: null,
- }],
- [{ id: "agent-1", companyId: "company-1", status: "running" }],
- ]);
-
- dbStub.queueInsert([{
- id: "approval-1",
- companyId: "company-1",
- status: "pending",
- }]);
- dbStub.queueInsert([{
- id: "incident-1",
- companyId: "company-1",
- policyId: "policy-1",
- approvalId: "approval-1",
- }]);
- dbStub.queueUpdate([]);
- const cancelWorkForScope = vi.fn().mockResolvedValue(undefined);
-
- const service = budgetService(dbStub.db as any, { cancelWorkForScope });
- await service.evaluateCostEvent({
- companyId: "company-1",
- agentId: "agent-1",
- projectId: null,
- } as any);
-
- expect(dbStub.insertValues).toHaveBeenCalledWith(
- expect.objectContaining({
- companyId: "company-1",
- type: "budget_override_required",
- status: "pending",
- }),
- );
- expect(dbStub.insertValues).toHaveBeenCalledWith(
- expect.objectContaining({
- companyId: "company-1",
- policyId: "policy-1",
- thresholdType: "hard",
- amountLimit: 100,
- amountObserved: 150,
- approvalId: "approval-1",
- }),
- );
- expect(dbStub.updateSet).toHaveBeenCalledWith(
- expect.objectContaining({
- status: "paused",
- pauseReason: "budget",
- pausedAt: expect.any(Date),
- }),
- );
- expect(mockLogActivity).toHaveBeenCalledWith(
- expect.anything(),
- expect.objectContaining({
- action: "budget.hard_threshold_crossed",
- entityId: "incident-1",
- }),
- );
- expect(cancelWorkForScope).toHaveBeenCalledWith({
- companyId: "company-1",
- scopeType: "agent",
- scopeId: "agent-1",
- });
- });
-
- it("blocks new work when an agent hard-stop remains exceeded even if the agent is not paused yet", async () => {
- const agentPolicy = {
- id: "policy-agent-1",
- companyId: "company-1",
- scopeType: "agent",
- scopeId: "agent-1",
- metric: "billed_cents",
- windowKind: "calendar_month_utc",
- amount: 100,
- warnPercent: 80,
- hardStopEnabled: true,
- notifyEnabled: true,
- isActive: true,
- };
-
- const dbStub = createDbStub([
- [{
- status: "running",
- pauseReason: null,
- companyId: "company-1",
- name: "Budget Agent",
- }],
- [{
- status: "active",
- name: "Paperclip",
- }],
- [],
- [agentPolicy],
- [{ total: 120 }],
- ]);
-
- const service = budgetService(dbStub.db as any);
- const block = await service.getInvocationBlock("company-1", "agent-1");
-
- expect(block).toEqual({
- scopeType: "agent",
- scopeId: "agent-1",
- scopeName: "Budget Agent",
- reason: "Agent cannot start because its budget hard-stop is still exceeded.",
- });
- });
-
- it("surfaces a budget-owned company pause distinctly from a manual pause", async () => {
- const dbStub = createDbStub([
- [{
- status: "idle",
- pauseReason: null,
- companyId: "company-1",
- name: "Budget Agent",
- }],
- [{
- status: "paused",
- pauseReason: "budget",
- name: "Paperclip",
- }],
- ]);
-
- const service = budgetService(dbStub.db as any);
- const block = await service.getInvocationBlock("company-1", "agent-1");
-
- expect(block).toEqual({
- scopeType: "company",
- scopeId: "company-1",
- scopeName: "Paperclip",
- reason: "Company is paused because its budget hard-stop was reached.",
- });
- });
-
- it("uses live observed spend when raising a budget incident", async () => {
- const dbStub = createDbStub([
- [{
- id: "incident-1",
- companyId: "company-1",
- policyId: "policy-1",
- amountObserved: 120,
- approvalId: "approval-1",
- }],
- [{
- id: "policy-1",
- companyId: "company-1",
- scopeType: "company",
- scopeId: "company-1",
- metric: "billed_cents",
- windowKind: "calendar_month_utc",
- }],
- [{ total: 150 }],
- ]);
-
- const service = budgetService(dbStub.db as any);
-
- await expect(
- service.resolveIncident(
- "company-1",
- "incident-1",
- { action: "raise_budget_and_resume", amount: 140 },
- "board-user",
- ),
- ).rejects.toThrow("New budget must exceed current observed spend");
- });
-
- it("syncs company monthly budget when raising and resuming a company incident", async () => {
- const now = new Date();
- const dbStub = createDbStub([
- [{
- id: "incident-1",
- companyId: "company-1",
- policyId: "policy-1",
- scopeType: "company",
- scopeId: "company-1",
- metric: "billed_cents",
- windowKind: "calendar_month_utc",
- windowStart: now,
- windowEnd: now,
- thresholdType: "hard",
- amountLimit: 100,
- amountObserved: 120,
- status: "open",
- approvalId: "approval-1",
- resolvedAt: null,
- createdAt: now,
- updatedAt: now,
- }],
- [{
- id: "policy-1",
- companyId: "company-1",
- scopeType: "company",
- scopeId: "company-1",
- metric: "billed_cents",
- windowKind: "calendar_month_utc",
- amount: 100,
- }],
- [{ total: 120 }],
- [{ id: "approval-1", status: "approved" }],
- [{
- companyId: "company-1",
- name: "Paperclip",
- status: "paused",
- pauseReason: "budget",
- pausedAt: now,
- }],
- ]);
-
- const service = budgetService(dbStub.db as any);
- await service.resolveIncident(
- "company-1",
- "incident-1",
- { action: "raise_budget_and_resume", amount: 175 },
- "board-user",
- );
-
- expect(dbStub.updateSet).toHaveBeenCalledWith(
- expect.objectContaining({
- budgetMonthlyCents: 175,
- updatedAt: expect.any(Date),
- }),
- );
- });
-});
+// Budget behavior is exercised against PostgreSQL below and in
+// cost-accounting-reliability.test.ts, including transaction and retry paths.
const embeddedPostgresSupport = await getEmbeddedPostgresTestSupport();
const describeEmbeddedPostgres = embeddedPostgresSupport.supported ? describe : describe.skip;
@@ -493,7 +189,7 @@ describeEmbeddedPostgres("budgetService release gate enforcement", () => {
expect(agentAfterHardStop).toMatchObject({ status: "paused", pauseReason: "budget" });
expect(agentAfterHardStop?.pausedAt).toBeInstanceOf(Date);
expect(cancelWorkForScope).toHaveBeenCalledTimes(2);
- expect(cancelWorkForScope).toHaveBeenCalledWith({ companyId, scopeType: "agent", scopeId: agentId });
+ expect(cancelWorkForScope).toHaveBeenCalledWith({ companyId, scopeType: "agent", scopeId: agentId, createdBefore: expect.any(Date), enforcement: { policyId: expect.any(String), version: expect.any(Number) } });
const block = await service.getInvocationBlock(companyId, agentId);
expect(block).toEqual({
@@ -538,6 +234,23 @@ describeEmbeddedPostgres("budgetService release gate enforcement", () => {
}
});
+ it("distinguishes a company budget pause from a manual company pause", async () => {
+ const { companyId, agentId } = await createBudgetFixture();
+ const service = budgetService(db);
+ await db.update(companies).set({ status: "paused", pauseReason: "budget" }).where(eq(companies.id, companyId));
+ expect(await service.getInvocationBlock(companyId, agentId)).toMatchObject({
+ scopeType: "company",
+ scopeId: companyId,
+ reason: "Budget pause requires a policy or an explicit operator resume.",
+ });
+ await db.update(companies).set({ pauseReason: null }).where(eq(companies.id, companyId));
+ expect(await service.getInvocationBlock(companyId, agentId)).toMatchObject({
+ scopeType: "company",
+ scopeId: companyId,
+ reason: "Company is paused and cannot start new work.",
+ });
+ });
+
it("hard-stops project work until a valid budget raise resumes it and overview reconciles ledger spend", async () => {
const { companyId, agentId, projectId } = await createBudgetFixture();
const cancelWorkForScope = vi.fn().mockResolvedValue(undefined);
@@ -578,7 +291,7 @@ describeEmbeddedPostgres("budgetService release gate enforcement", () => {
.from(projects);
expect(projectAfterHardStop?.pauseReason).toBe("budget");
expect(projectAfterHardStop?.pausedAt).toBeInstanceOf(Date);
- expect(cancelWorkForScope).toHaveBeenCalledWith({ companyId, scopeType: "project", scopeId: projectId });
+ expect(cancelWorkForScope).toHaveBeenCalledWith({ companyId, scopeType: "project", scopeId: projectId, createdBefore: expect.any(Date), enforcement: { policyId: expect.any(String), version: expect.any(Number) } });
const overviewWhileBlocked = await service.overview(companyId);
expect(overviewWhileBlocked.pausedProjectCount).toBe(1);
diff --git a/server/src/__tests__/chat-channels.integration.test.ts b/server/src/__tests__/chat-channels.integration.test.ts
index 0581be664b7..da71ea61520 100644
--- a/server/src/__tests__/chat-channels.integration.test.ts
+++ b/server/src/__tests__/chat-channels.integration.test.ts
@@ -16000,7 +16000,12 @@ describeEmbeddedPostgres("chat channel control-plane integration", () => {
it("reorders rapid Slack callbacks by provider time before one conversation drain", async () => {
const fixture = await seedCompany();
const runtime = new FakeChatSdkRuntime();
- const deferred: Array<() => void> = [];
+ const deferred: Array<() => void | Promise> = [];
+ let releaseFirstDelivery!: () => void;
+ let signalFirstDelivery!: () => void;
+ const firstDeliveryEntered = new Promise((resolve) => { signalFirstDelivery = resolve; });
+ const firstDeliveryReleased = new Promise((resolve) => { releaseFirstDelivery = resolve; });
+ let firstDelivery = true;
const wakeup = vi.fn(async () => ({ accepted: true }));
const service = chatChannelService(db, {
deferWebhookProcessing: true,
@@ -16009,6 +16014,12 @@ describeEmbeddedPostgres("chat channel control-plane integration", () => {
publicBaseUrl: "https://paperclip.example",
runtime: runtime as unknown as ChatSdkRuntime,
scheduleDeferredWork: (task) => deferred.push(task),
+ reachAuthorizationBarrier: async () => {
+ if (!firstDelivery) return;
+ firstDelivery = false;
+ signalFirstDelivery();
+ await firstDeliveryReleased;
+ },
});
const endpoint = await service.create(
fixture.companyId,
@@ -16127,69 +16138,54 @@ describeEmbeddedPostgres("chat channel control-plane integration", () => {
publicBaseUrl: "https://paperclip.example",
runtime: new FakeChatSdkRuntime() as unknown as ChatSdkRuntime,
});
- deferred.shift()?.();
- // Simulate another server process reconciling the same durable rows at
- // the same time as the webhook process's deferred drain.
- await competingService.processPendingDeliveries();
- await vi.waitFor(async () => {
- const rows = await db
+ let drainSettled = false;
+ const draining = Promise.resolve(deferred.shift()?.()).then(() => { drainSettled = true; });
+ try {
+ // Hold the deferred owner after it acquires the conversation lease. The
+ // competing sweep must finish without overtaking that owner.
+ await firstDeliveryEntered;
+ await competingService.processPendingDeliveries();
+ expect(drainSettled).toBe(false);
+ expect(wakeup.mock.calls.filter((call) => call[0] === fixture.assignedAgentId)).toHaveLength(0);
+ releaseFirstDelivery();
+ await draining;
+ expect(drainSettled).toBe(true);
+ const conversations = await db
.select()
.from(chatConversations)
.where(eq(chatConversations.endpointId, endpoint.id));
- expect(rows).toHaveLength(1);
- });
- const [conversation] = await db
- .select()
- .from(chatConversations)
- .where(eq(chatConversations.endpointId, endpoint.id));
- await vi.waitFor(async () => {
- const rows = await db
- .select({ id: issueComments.id })
+ expect(conversations).toHaveLength(1);
+ const [conversation] = conversations;
+ const comments = await db
+ .select({ id: issueComments.id, body: issueComments.body })
.from(issueComments)
- .where(eq(issueComments.issueId, conversation.issueId));
- expect(rows).toHaveLength(8);
- });
- const comments = await db
- .select({ id: issueComments.id, body: issueComments.body })
- .from(issueComments)
- .where(eq(issueComments.issueId, conversation.issueId))
- .orderBy(asc(issueComments.createdAt), asc(issueComments.id));
- expect(comments.map((comment) => comment.body)).toEqual([
- "@maya acknowledge quickly",
- "follow-up 3",
- "follow-up 4",
- "follow-up 5",
- "and include the rollback status",
- "follow-up 6",
- "follow-up 7",
- "follow-up 8",
- ]);
- // Comment admission commits before the durable wake. Wait for this
- // company's last wake too, not merely its already-visible last comment.
- // The competing sweep may legitimately reconcile another fixture company.
- await vi.waitFor(() => {
- const calls = wakeup.mock.calls.filter(
- (call) => call[0] === fixture.assignedAgentId,
- );
+ .where(eq(issueComments.issueId, conversation.issueId))
+ .orderBy(asc(issueComments.createdAt), asc(issueComments.id));
+ expect(comments.map((comment) => comment.body)).toEqual([
+ "@maya acknowledge quickly",
+ "follow-up 3",
+ "follow-up 4",
+ "follow-up 5",
+ "and include the rollback status",
+ "follow-up 6",
+ "follow-up 7",
+ "follow-up 8",
+ ]);
+ // Joining the owner includes all comment admissions, durable wakeups and
+ // lease release. These assertions do not race a one-second polling budget.
+ expect(comments).toHaveLength(8);
+ const calls = wakeup.mock.calls.filter((call) => call[0] === fixture.assignedAgentId);
expect(calls).toHaveLength(8);
- expect(calls.map((call) => call[1]?.payload?.wakeCommentId)).toEqual(
- comments.map((comment) => comment.id),
- );
- });
- // The last comment and wakeup commit inside the lease. Under full-suite
- // load the assertions above can observe those effects one microtask before
- // the deferred owner's `finally` deletes its lease. Require prompt eventual
- // release; a real leak would remain for the much longer lease TTL.
- await vi.waitFor(async () => {
+ expect(calls.map((call) => call[1]?.payload?.wakeCommentId)).toEqual(comments.map((comment) => comment.id));
expect(
- await db
- .select()
- .from(chatEndpointLeases)
- .where(eq(chatEndpointLeases.endpointId, endpoint.id)),
+ await db.select().from(chatEndpointLeases).where(eq(chatEndpointLeases.endpointId, endpoint.id)),
).toHaveLength(0);
- });
- await competingService.shutdown();
- await service.shutdown();
+ } finally {
+ releaseFirstDelivery();
+ await draining;
+ await competingService.shutdown();
+ await service.shutdown();
+ }
});
it("stops a conversation drain after its lease renewal fails", async () => {
@@ -20832,6 +20828,10 @@ describeEmbeddedPostgres("chat channel control-plane integration", () => {
trigger: "subscribed_message",
});
+ // Keep this ordering assertion independent of database/CI wall-clock speed.
+ // The next drain below explicitly makes both deliveries due.
+ await db.update(chatDeliveries).set({ nextAttemptAt: new Date(Date.now() + 60_000) })
+ .where(and(eq(chatDeliveries.endpointId, endpoint.id), inArray(chatDeliveries.state, ["received", "retry"])));
await service.processPendingDeliveries();
expect(wakeup).not.toHaveBeenCalled();
await db
@@ -61917,8 +61917,8 @@ describeEmbeddedPostgres("chat channel control-plane integration", () => {
).resolves.toMatchObject({ ok: true });
expect(deferred).toHaveLength(1);
await drainDeferred();
- await vi.waitFor(() => expect(deferred).toHaveLength(1));
- await drainDeferred();
+ // Awaiting each callback also drains the lifecycle work it queues.
+ expect(deferred).toHaveLength(0);
await vi.waitFor(async () => {
await expect(
db
diff --git a/server/src/__tests__/chat-project-tools.test.ts b/server/src/__tests__/chat-project-tools.test.ts
index 81739407d39..b75f5ed6609 100644
--- a/server/src/__tests__/chat-project-tools.test.ts
+++ b/server/src/__tests__/chat-project-tools.test.ts
@@ -190,8 +190,9 @@ const support = await getEmbeddedPostgresTestSupport();
{ projectId: f.projectId, assigneeAgentId: null, assigneeUserId: "board-user" },
]) {
const result = await create(path, fields);
- expect(result.status, JSON.stringify(result.body)).toBe(403);
- expect(result.body.error).toMatch(/outside.*boundary|cannot assign work to board users|different company/i);
+ const hiddenProject = fields.projectId !== f.projectId && path.startsWith("/api/companies/");
+ expect(result.status, JSON.stringify(result.body)).toBe(hiddenProject ? 404 : 403);
+ expect(result.body.error).toMatch(hiddenProject ? /^Project not found$/ : /outside.*boundary|cannot assign work to board users|different company/i);
}
}
const after = await server.db.select({ id: issues.id }).from(issues).where(eq(issues.companyId, f.companyId));
@@ -232,7 +233,10 @@ const support = await getEmbeddedPostgresTestSupport();
body: JSON.stringify({ title: "Root cannot escape into another project", parentId: f.issueId,
projectId: outside.id, assigneeAgentId: f.agentId, status: "backlog" }),
});
- expect(response.status, JSON.stringify(await response.json())).toBe(403);
+ const denied = await response.json();
+ const hiddenProject = path.startsWith("/api/companies/");
+ expect(response.status, JSON.stringify(denied)).toBe(hiddenProject ? 404 : 403);
+ expect(denied.error).toMatch(hiddenProject ? /^Project not found$/ : /outside.*boundary/i);
}
await expect(call(f, "create_task", { title: "Native root cannot escape", projectId: outside.id,
idempotencyKey: "root-outside", status: "backlog" })).rejects.toThrow(/outside.*boundary/);
diff --git a/server/src/__tests__/claude-local-execute.test.ts b/server/src/__tests__/claude-local-execute.test.ts
index b45af79f0ab..adea792ca6e 100644
--- a/server/src/__tests__/claude-local-execute.test.ts
+++ b/server/src/__tests__/claude-local-execute.test.ts
@@ -685,8 +685,9 @@ describe("claude execute", () => {
expect(captured[1]?.appendedSystemPromptFilePath).toContain("agent-instructions.md");
expect(captured[1]?.appendedSystemPromptFilePath).not.toBe(instructionsFile);
expect(captured[1]?.appendedSystemPromptFileContents).toContain("# Agent instructions");
- expect(captured[1]?.appendedSystemPromptFileContents).toContain(
- `The above agent instructions were loaded from ${instructionsFile}. ` +
+ expect(captured[1]?.appendedSystemPromptFileContents).not.toContain(instructionsFile);
+ for (const prompt of prompts) expect(prompt).toContain(
+ `Agent instructions for this run were loaded from ${instructionsFile}. ` +
`Resolve any relative file references from ${path.dirname(instructionsFile)}/. ` +
`This base directory is authoritative for sibling instruction files such as ` +
`./HEARTBEAT.md, ./SOUL.md, and ./TOOLS.md; do not resolve those from the parent agent directory.`,
@@ -1338,7 +1339,9 @@ describe("claude execute", () => {
expect(capture1.addDir?.startsWith(expectedRoot)).toBe(true);
expect(capture1.instructionsFilePath?.startsWith(expectedRoot)).toBe(true);
expect(capture1.instructionsContents).toContain("You are managed instructions.");
- expect(capture1.instructionsContents).toContain(`The above agent instructions were loaded from ${instructionsPath}.`);
+ expect(capture1.instructionsContents).not.toContain(instructionsPath);
+ expect(capture1.prompt).toContain(`Agent instructions for this run were loaded from ${instructionsPath}.`);
+ expect(capture2.prompt).toContain(`Agent instructions for this run were loaded from ${instructionsPath}.`);
expect(capture1.skillEntries).toContain("paperclip");
expect(capture2.argv).toContain("--resume");
expect(getFreshSessionHandoff).not.toHaveBeenCalled();
@@ -1362,6 +1365,81 @@ describe("claude execute", () => {
}
});
+ it("resumes across per-run instruction copies and refreshes their location", async () => {
+ const root = await fs.mkdtemp(path.join(os.tmpdir(), "paperclip-claude-working-copy-"));
+ const workspace = path.join(root, "workspace");
+ const commandPath = path.join(root, "claude");
+ const capturePath = path.join(root, "capture.json");
+ const skillDir = path.join(root, "skill");
+ await fs.mkdir(workspace, { recursive: true });
+ await fs.mkdir(skillDir);
+ await fs.writeFile(path.join(skillDir, "SKILL.md"), "First skill version.\n");
+ await writeFakeClaudeCommand(commandPath);
+ vi.stubEnv("PAPERCLIP_HOME", path.join(root, "paperclip-home"));
+ vi.stubEnv("PAPERCLIP_INSTANCE_ID", "default");
+
+ try {
+ let sessionParams: Record | null = null;
+ let previousBundleKey: unknown;
+ let previousInstructionsPath = "";
+ for (const [index, change] of ["initial", "location", "instructions", "skill"].entries()) {
+ const runId = `run-${index}`;
+ const instructionsPath = path.join(root, "companies", "company-1", "agents", "agent-1",
+ "file-sync", "runs", runId, "live", "AGENTS.md");
+ await fs.mkdir(path.dirname(instructionsPath), { recursive: true });
+ await fs.writeFile(instructionsPath, index < 2 ? "First instructions.\n" : "Changed instructions.\n");
+ if (change === "skill") {
+ await fs.writeFile(path.join(skillDir, "SKILL.md"), "Changed skill version.\n");
+ }
+ const logs: string[] = [];
+ const result = await execute({
+ runId,
+ agent: { id: "agent-1", companyId: "company-1", name: "Test", adapterType: "claude_local", adapterConfig: { engine: "cli" } },
+ runtime: { sessionId: null, sessionParams, sessionDisplayId: null, taskKey: "issue-1" },
+ config: {
+ engine: "cli",
+ command: commandPath,
+ cwd: workspace,
+ instructionsFilePath: instructionsPath,
+ paperclipRuntimeSkills: [{ key: "test-skill", runtimeName: "test-skill", source: skillDir }],
+ paperclipSkillSync: { desiredSkills: ["test-skill"] },
+ env: { PAPERCLIP_TEST_CAPTURE_PATH: capturePath, CLAUDE_CONFIG_DIR: path.join(root, "claude-config") },
+ },
+ context: { issueId: "issue-1" },
+ onLog: async (_stream, chunk) => { logs.push(chunk); },
+ });
+ expect(result.exitCode).toBe(0);
+ const capture = JSON.parse(await fs.readFile(capturePath, "utf8")) as CapturePayload;
+ if (change === "location") {
+ expect(capture.argv).toContain("--resume");
+ expect(capture.argv).toContain("11111111-1111-4111-8111-111111111111");
+ expect(capture.instructionsFilePath).toBeNull();
+ expect(result.sessionParams?.promptBundleKey).toBe(previousBundleKey);
+ } else {
+ expect(capture.argv).not.toContain("--resume");
+ expect(capture.instructionsContents).toContain(index < 2 ? "First instructions." : "Changed instructions.");
+ expect(result.sessionParams?.promptBundleKey).not.toBe(previousBundleKey);
+ if (index > 0) {
+ expect(capture.instructionsContents).not.toContain(instructionsPath);
+ expect(logs.join("")).toContain("was saved for prompt bundle");
+ expect(logs.join("")).not.toContain("was saved for cwd");
+ }
+ }
+ if (index > 0) {
+ expect(capture.prompt).toContain(instructionsPath);
+ expect(capture.prompt).toContain(`Resolve any relative file references from ${path.dirname(instructionsPath)}/.`);
+ }
+ if (previousInstructionsPath) expect(capture.prompt).not.toContain(previousInstructionsPath);
+ sessionParams = sessionCodec.deserialize(sessionCodec.serialize(result.sessionParams ?? null));
+ previousBundleKey = result.sessionParams?.promptBundleKey;
+ previousInstructionsPath = instructionsPath;
+ }
+ } finally {
+ vi.unstubAllEnvs();
+ await fs.rm(root, { recursive: true, force: true });
+ }
+ });
+
it("starts a fresh Claude session when the stable prompt bundle changes", async () => {
const root = await fs.mkdtemp(path.join(os.tmpdir(), "paperclip-claude-execute-reset-"));
const workspace = path.join(root, "workspace");
diff --git a/server/src/__tests__/company-portability.test.ts b/server/src/__tests__/company-portability.test.ts
index beed0ab71e1..2ede89060d4 100644
--- a/server/src/__tests__/company-portability.test.ts
+++ b/server/src/__tests__/company-portability.test.ts
@@ -1897,7 +1897,7 @@ describe("company portability", () => {
},
},
}),
- }));
+ }), { createdByUserId: "user-1" });
expect(secretSvc.syncEnvBindingsForTarget).toHaveBeenCalledWith(
"company-1",
{ targetType: "agent", targetId: "agent-imported" },
@@ -2889,7 +2889,7 @@ describe("company portability", () => {
// a scoped resume; "system" stays for platform-managed pauses.
pauseReason: "import",
pausedAt: expect.any(Date),
- }));
+ }), { createdByUserId: "user-1" });
expect(routineSvc.create).toHaveBeenCalledWith("company-imported", expect.objectContaining({
title: "Monday Review",
status: "paused",
@@ -3204,7 +3204,7 @@ describe("company portability", () => {
expect(agentSvc.create).toHaveBeenCalledWith("company-imported", expect.objectContaining({
name: "ClaudeCoder",
adapterType: "process",
- }));
+ }), { createdByUserId: "user-1" });
});
it("preserves agent role from frontmatter when extension block omits it", async () => {
@@ -3383,7 +3383,7 @@ describe("company portability", () => {
desiredSkills: [paperclipKey],
},
}),
- }));
+ }), { createdByUserId: "user-1" });
});
it("imports a packaged company logo and attaches it to the target company", async () => {
@@ -3677,7 +3677,7 @@ describe("company portability", () => {
maxConcurrentRuns: 20,
},
},
- }));
+ }), { createdByUserId: "user-1" });
expect(result.company.action).toBe("unchanged");
expect(result.agents).toEqual([
{
@@ -3748,13 +3748,13 @@ describe("company portability", () => {
adapterConfig: expect.objectContaining({
dangerouslyBypassApprovalsAndSandbox: true,
}),
- }));
+ }), { createdByUserId: "user-1" });
expect(agentSvc.create).toHaveBeenCalledWith("company-imported", expect.objectContaining({
adapterConfig: expect.not.objectContaining({
instructionsFilePath: expect.anything(),
promptTemplate: expect.anything(),
}),
- }));
+ }), { createdByUserId: "user-1" });
expect(agentInstructionsSvc.materializeManagedBundle).toHaveBeenCalledWith(
expect.objectContaining({ name: "ClaudeCoder" }),
expect.objectContaining({
@@ -3856,7 +3856,7 @@ describe("company portability", () => {
extraArgs: ["--skip-git-repo-check"],
args: ["--legacy-arg"],
}),
- }));
+ }), { createdByUserId: "user-1" });
const lastCreateInput = agentSvc.create.mock.calls.at(-1)?.[1] as Record;
expect(lastCreateInput?.adapterConfig).toBeTruthy();
expect(lastCreateInput.adapterConfig?.dangerouslyBypassApprovalsAndSandbox).toBeUndefined();
@@ -5785,7 +5785,7 @@ describe("company portability", () => {
normalized: true,
}),
status: "idle",
- }));
+ }), { createdByUserId: "user-1" });
expect(companySvc.create).toHaveBeenCalledWith(expect.objectContaining({
requireBoardApprovalForNewAgents: false,
}));
@@ -6107,13 +6107,13 @@ describe("company portability", () => {
expect(agentSvc.create).toHaveBeenCalledWith("company-1", expect.objectContaining({
adapterType: "paperclip_runner",
adapterConfig: expect.objectContaining({ provider: "opencode" }),
- }));
+ }), { createdByUserId: "user-1" });
await portability.importBundle(request, "user-1");
expect(agentSvc.create).toHaveBeenCalledWith("company-1", expect.objectContaining({
adapterType: "paperclip_runner",
adapterConfig: expect.objectContaining({ provider: "codex" }),
- }));
+ }), { createdByUserId: "user-1" });
await portability.importBundle({
...request,
diff --git a/server/src/__tests__/company-search-extract-routes.test.ts b/server/src/__tests__/company-search-extract-routes.test.ts
index 375247858b6..1e939d7d05f 100644
--- a/server/src/__tests__/company-search-extract-routes.test.ts
+++ b/server/src/__tests__/company-search-extract-routes.test.ts
@@ -67,13 +67,17 @@ describe("company extract-search route", () => {
})
.expect(200);
- expect(extract).toHaveBeenCalledWith("company-1", expect.objectContaining({
+ expect(extract).toHaveBeenCalledWith(
+ "company-1",
+ expect.objectContaining({
contains: "github.com/example/repo/pull",
kind: "url",
scope: "comments",
limit: 200,
matchesPerIssue: 200,
- }));
+ }),
+ expect.objectContaining({ issueReadCondition: expect.anything() }),
+ );
expect(response.body).toMatchObject({ kind: "url", scope: "comments", truncated: false });
});
diff --git a/server/src/__tests__/company-search-extract-service.test.ts b/server/src/__tests__/company-search-extract-service.test.ts
index d50c0e149af..46b37c3c39a 100644
--- a/server/src/__tests__/company-search-extract-service.test.ts
+++ b/server/src/__tests__/company-search-extract-service.test.ts
@@ -2,6 +2,7 @@ import { randomUUID } from "node:crypto";
import { afterAll, afterEach, beforeAll, describe, expect, it } from "vitest";
import {
companies,
+ companyMemberships,
createDb,
documents,
issueComments,
@@ -18,6 +19,7 @@ import {
startEmbeddedPostgresTestDatabase,
} from "./helpers/embedded-postgres.js";
import { companySearchExtractService } from "../services/company-search-extract.js";
+import { issueReadSqlCondition, type AuthorizationActor } from "../services/authorization.js";
const embeddedPostgresSupport = await getEmbeddedPostgresTestSupport();
const describeEmbeddedPostgres = embeddedPostgresSupport.supported ? describe : describe.skip;
@@ -73,6 +75,7 @@ describeEmbeddedPostgres("companySearchExtractService", () => {
await db.delete(documents);
await db.delete(issueComments);
await db.delete(issues);
+ await db.delete(companyMemberships);
await db.delete(companies);
});
@@ -266,4 +269,44 @@ describeEmbeddedPostgres("companySearchExtractService", () => {
expect(result.results).toEqual([]);
});
+
+ it("does not extract content from a private issue for a non-member", async () => {
+ const companyId = await createCompany();
+ const viewerId = randomUUID();
+ await db.insert(companyMemberships).values({
+ companyId,
+ principalType: "user",
+ principalId: viewerId,
+ membershipRole: "operator",
+ status: "active",
+});
+ const visibleIssueId = await createIssue(companyId, {
+ identifier: "EXT-PUBLIC",
+ description: "privacy-leak-needle",
+ });
+ const privateIssueId = randomUUID();
+ await createIssue(companyId, {
+ id: privateIssueId,
+ identifier: "EXT-PRIVATE",
+ description: "privacy-leak-needle private payload",
+ visibility: "private",
+ privacyRootIssueId: privateIssueId,
+ responsibleUserId: randomUUID(),
+ });
+ const actor: AuthorizationActor = {
+ type: "board",
+ userId: viewerId,
+ source: "session",
+ };
+
+ const result = await svc.extract(
+ companyId,
+ companySearchExtractQuerySchema.parse({ contains: "privacy-leak-needle" }),
+ { issueReadCondition: await issueReadSqlCondition(db, actor) },
+ );
+
+ expect(result.results.map((row) => row.issueId)).toEqual([visibleIssueId]);
+ expect(JSON.stringify(result)).not.toContain(privateIssueId);
+ expect(JSON.stringify(result)).not.toContain("private payload");
+ });
});
diff --git a/server/src/__tests__/company-search-service.test.ts b/server/src/__tests__/company-search-service.test.ts
index a8665665abb..5d9e53260fb 100644
--- a/server/src/__tests__/company-search-service.test.ts
+++ b/server/src/__tests__/company-search-service.test.ts
@@ -8,9 +8,11 @@ import {
documents,
issueComments,
issueDocuments,
+ issueAccessGrants,
issueLabels,
issues,
labels,
+ projectAccessMembers,
projects,
} from "@paperclipai/db";
import { companySearchQuerySchema, COMPANY_SEARCH_MAX_QUERY_LENGTH } from "@paperclipai/shared";
@@ -23,6 +25,8 @@ import {
companySearchBranchFetchLimit,
companySearchService,
} from "../services/company-search.js";
+import { issueReadSqlCondition, projectReadSqlCondition } from "../services/authorization.js";
+import { issueService } from "../services/issues.js";
const embeddedPostgresSupport = await getEmbeddedPostgresTestSupport();
const describeEmbeddedPostgres = embeddedPostgresSupport.supported ? describe : describe.skip;
@@ -87,6 +91,7 @@ describeEmbeddedPostgres("companySearchService", () => {
await db.delete(documents);
await db.delete(issueComments);
await db.delete(issueLabels);
+ await db.delete(issueAccessGrants);
await db.delete(issues);
await db.delete(labels);
await db.delete(projects);
@@ -814,4 +819,99 @@ describeEmbeddedPostgres("companySearchService", () => {
expect(ids, `query=${query} should not match unrelated issue`).not.toContain(rejected);
}
});
+
+ it("pushes private issue filtering into list, count, and company search queries", async () => {
+ const previousMode = process.env.PAPERCLIP_ISSUE_PRIVACY_MODE;
+ process.env.PAPERCLIP_ISSUE_PRIVACY_MODE = "enforce";
+ try {
+ const companyId = await createCompany();
+ const ownerId = `owner-${randomUUID()}`;
+ const otherId = `other-${randomUUID()}`;
+ const granteeId = `grantee-${randomUUID()}`;
+ const openId = await createIssue(companyId, { title: "privacy needle open" });
+ const privateId = randomUUID();
+ await createIssue(companyId, {
+ id: privateId,
+ title: "privacy needle private",
+ visibility: "private",
+ privacyRootIssueId: privateId,
+ responsibleUserId: ownerId,
+});
+ await db.insert(issueAccessGrants).values({
+ issueId: privateId,
+ subjectType: "user",
+ subjectId: granteeId,
+ source: "explicit",
+ grantedByUserId: ownerId,
+ });
+
+ const issuesSvc = issueService(db);
+ const conditionFor = (userId: string) => issueReadSqlCondition(db, {
+ type: "board",
+ userId,
+ source: "session",
+ });
+ const otherCondition = await conditionFor(otherId);
+ const ownerCondition = await conditionFor(ownerId);
+ const granteeCondition = await conditionFor(granteeId);
+
+ await expect(issuesSvc.list(companyId, { readCondition: otherCondition })).resolves.toMatchObject([
+ { id: openId },
+ ]);
+ await expect(issuesSvc.count(companyId, { readCondition: otherCondition })).resolves.toBe(1);
+ await expect(issuesSvc.count(companyId, { readCondition: ownerCondition })).resolves.toBe(2);
+ await expect(issuesSvc.count(companyId, { readCondition: granteeCondition })).resolves.toBe(2);
+
+ const result = await svc.search(
+ companyId,
+ companySearchQuerySchema.parse({ q: "privacy needle", scope: "issues" }),
+ { issueReadCondition: otherCondition },
+ );
+ expect(result.results.map((row) => row.id)).toEqual([openId]);
+ } finally {
+ if (previousMode === undefined) delete process.env.PAPERCLIP_ISSUE_PRIVACY_MODE;
+ else process.env.PAPERCLIP_ISSUE_PRIVACY_MODE = previousMode;
+ }
+ });
+
+ it("pushes private project filtering into project search and counts", async () => {
+ const previousMode = process.env.PAPERCLIP_ISSUE_PRIVACY_MODE;
+ process.env.PAPERCLIP_ISSUE_PRIVACY_MODE = "enforce";
+ try {
+ const companyId = await createCompany();
+ const memberId = `member-${randomUUID()}`;
+ const outsiderId = `outsider-${randomUUID()}`;
+ const openId = await createProject(companyId, { name: "privacy project open" });
+ const privateId = await createProject(companyId, {
+ name: "privacy project private",
+ visibility: "private",
+ });
+ await db.insert(projectAccessMembers).values({
+ companyId,
+ projectId: privateId,
+ subjectType: "user",
+ subjectId: memberId,
+ });
+ const conditionFor = (userId: string) => projectReadSqlCondition(db, {
+ type: "board",
+ userId,
+ source: "session",
+ });
+ const query = companySearchQuerySchema.parse({ q: "privacy project", scope: "projects" });
+ const outsiderResult = await svc.search(companyId, query, {
+ projectReadCondition: await conditionFor(outsiderId),
+ });
+ expect(outsiderResult.results.map((row) => row.id)).toEqual([openId]);
+ expect(outsiderResult.countsByType.project).toBe(1);
+
+ const memberResult = await svc.search(companyId, query, {
+ projectReadCondition: await conditionFor(memberId),
+ });
+ expect(memberResult.results.map((row) => row.id)).toEqual(expect.arrayContaining([openId, privateId]));
+ expect(memberResult.countsByType.project).toBe(2);
+ } finally {
+ if (previousMode === undefined) delete process.env.PAPERCLIP_ISSUE_PRIVACY_MODE;
+ else process.env.PAPERCLIP_ISSUE_PRIVACY_MODE = previousMode;
+ }
+ });
});
diff --git a/server/src/__tests__/connection-aggregator-fallback.test.ts b/server/src/__tests__/connection-aggregator-fallback.test.ts
index 4ccea4c46df..c129a6e092f 100644
--- a/server/src/__tests__/connection-aggregator-fallback.test.ts
+++ b/server/src/__tests__/connection-aggregator-fallback.test.ts
@@ -1,3 +1,6 @@
+import Ajv2020 from "ajv/dist/2020.js";
+import { requestHumanInputAction } from "../../../packages/paperclip-runner/src/protocol-actions/request-human-input.js";
+import { questionSetToAskUserQuestionsPayload } from "@paperclipai/shared";
import { randomUUID } from "node:crypto";
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
@@ -314,9 +317,34 @@ const support = await getEmbeddedPostgresTestSupport();
expect(result.results.some(item => item.service === "google-sheets")).toBe(true);
expect(result.instruction).not.toContain("search its exact name");
});
+ it("keeps installed capability matches when a generic query resembles an external app name", async () => {
+ await resetQuestions();
+ const installed = await seedProvider("Studio library", "notion:list_pages");
+ await db.update(toolCatalogEntries).set({ description: "Read recent pages and return their titles and verification code" })
+ .where(eq(toolCatalogEntries.connectionId, installed.id));
+ const service = connectionIntentService(db);
+ const result = await service.search(claims,
+ "connected page service that can find or list recent pages and return page titles plus a verification code");
+ expect(result.results).toEqual(expect.arrayContaining([expect.objectContaining({
+ service: `connection:${installed.id}`, connectionId: installed.id, state: "ready",
+ })]));
+ expect(result.providerQuestion).toBeUndefined();
+ expect(result.instruction).not.toContain("Ask the responsible user with providerQuestion");
+ // A deliberate app name still reaches the existing governed provider choice.
+ const named = await service.search(claims, "Page X");
+ expect(named.providerQuestion?.id).toBe("connection-provider:page-x");
+ expect(named.results[0]?.service).toBe("via:composio:page-x");
+ });
+ it("keeps an external typo as a discovery suggestion until its app is selected", async () => {
+ await resetQuestions();
+ const result = await connectionIntentService(db).search(claims,
+ "Find Circlebak meeting transcripts and action items from yesterday");
+ expect(result.results.some(item => item.service === "via:composio:circleback-mcp")).toBe(true);
+ expect(result.providerQuestion).toBeUndefined();
+ expect(result.instruction).toContain("aggregator.targetService");
+ });
it.each([
["help me find tools for circle back", "circleback-mcp"],
- ["Find Circlebak meeting transcripts and action items from yesterday", "circleback-mcp"],
["Can you connect Circleback MCP to get all our meeting notes?", "circleback-mcp"],
["Find Attio tools to review all our customer contacts before next week's meeting", "attio"],
["Help me find a ClickUp connection to organize our team's projects", "clickup"],
@@ -385,6 +413,18 @@ const support = await getEmbeddedPostgresTestSupport();
"via:zapier:hubspot",
]);
expect(result.providerQuestion?.prompt).toContain("external service");
+ const ajv = new Ajv2020({ allErrors: true, allowUnionTypes: true, strict: false });
+ const input = { idempotencyKey: "provider-choice", interactionKind: "questions", title: "Choose a provider",
+ prompt: result.providerQuestion!.prompt, continuationPolicy: "wake_assignee" };
+ for (const payload of [{ version: 1, questionSet: result.providerQuestionSet }, { version: 1, questions: [result.providerQuestion] }]) {
+ expect(ajv.validate(requestHumanInputAction.live.descriptor.inputSchema, { ...input, payload }), JSON.stringify(ajv.errors)).toBe(true);
+ }
+ expect(questionSetToAskUserQuestionsPayload(result.providerQuestionSet!).questions).toEqual([result.providerQuestion]);
+ expect(result.instruction).toContain("questionSet:providerQuestionSet");
+ expect(result.instruction).not.toContain("do not add questionSet");
+ expect(ajv.validate(requestHumanInputAction.live.descriptor.inputSchema, { ...input, payload: { version: 1 } })).toBe(false);
+ expect(ajv.validate(requestHumanInputAction.live.descriptor.inputSchema, { ...input, payload: { version: 1,
+ questionSet: { ...result.providerQuestionSet, questions: [{ ...result.providerQuestionSet!.questions[0], answerMode: "text" }] } } })).toBe(false);
expect(result.results.every((item) => item.state !== "ready")).toBe(true);
expect(result.results.every((item) => item.aggregator?.evidenceUrl)).toBe(
true,
@@ -568,6 +608,51 @@ const support = await getEmbeddedPostgresTestSupport();
);
expect(result.instruction).toContain("Arcade");
});
+ it("returns exact eligible catalog names after a guessed tool without granting access", async () => {
+ await resetQuestions();
+ const connection = await seedProvider("arcade", "Hubspot_ListContacts", "responsible-user", false);
+ await db.delete(toolConnectionInstalls).where(eq(toolConnectionInstalls.connectionId, connection.id));
+ await seedProvider("composio", "Unrelated_PrivateTool", "other-user", false);
+ await db.insert(toolCatalogEntries).values({ companyId: claims.company_id, connectionId: connection.id,
+ toolName: "Hubspot_RemovedTool", name: "Removed", versionHash: "old", entryKind: "tool", status: "removed" });
+ const answer = await selectProvider("via:arcade:hubspot");
+ const service = connectionIntentService(db);
+ const error = await service.request(claims, "via:arcade:hubspot", {
+ selectionInteractionId: answer.id, toolNames: ["hubspot_list_contacts"],
+ }).catch(error => error);
+ expect(error).toMatchObject({ status: 422 });
+ expect(error.message).toContain('"Hubspot_ListContacts"');
+ expect(error.message).toContain("Request only the needed exact names");
+ expect(error.message).not.toMatch(/Unrelated_PrivateTool|Hubspot_RemovedTool/);
+ expect(await db.select().from(toolProfiles).where(eq(toolProfiles.companyId, claims.company_id))).toEqual([]);
+ const interactions = await db.select().from(issueThreadInteractions).where(eq(issueThreadInteractions.companyId, claims.company_id));
+ expect(interactions.map(row => [row.id, row.status])).toEqual([[answer.id, "answered"]]);
+ const requested = await service.request(claims, "via:arcade:hubspot", {
+ selectionInteractionId: answer.id, toolNames: ["Hubspot_ListContacts"],
+ });
+ expect(requested.state).toBe("needs_user_action");
+ const loaded = await service.loadIntent(requested.interactionId!);
+ expect(loaded.interaction.payload.accessRequest?.tools.map(tool => tool.toolName)).toEqual(["Hubspot_ListContacts"]);
+ expect(loaded.interaction.status).toBe("pending");
+ expect(await db.select().from(toolProfiles).where(eq(toolProfiles.companyId, claims.company_id))).toEqual([]);
+ });
+ it("bounds catalog-name recovery and does not disclose an ineligible connection", async () => {
+ await resetQuestions();
+ const connection = await seedProvider("arcade", "Read_00", "responsible-user", false);
+ await db.insert(toolCatalogEntries).values(Array.from({ length: 24 }, (_, index) => ({
+ companyId: claims.company_id, connectionId: connection.id, toolName: `Read_${String(index + 1).padStart(2, "0")}`,
+ name: `Read_${String(index + 1).padStart(2, "0")}`, versionHash: "v1", entryKind: "tool" as const, status: "active" as const,
+ })));
+ const service = connectionIntentService(db);
+ const error = await service.request(claims, "arcade", { connectionId: connection.id, toolNames: ["guessed"] }).catch(error => error);
+ expect(error).toMatchObject({ status: 422 });
+ expect(error.message).toContain("first 20 of 25");
+ expect(error.message.match(/Read_\d{2}/g)).toHaveLength(20);
+ await db.update(connectionGrants).set({ status: "revoked" }).where(eq(connectionGrants.connectionId, connection.id));
+ const denied = await service.request(claims, "arcade", { connectionId: connection.id, toolNames: ["guessed"] }).catch(error => error);
+ expect(denied.message).not.toContain("Read_");
+ expect(denied.message).toContain("not eligible");
+ });
it("does not switch providers when the chosen route loses permission", async () => {
await resetQuestions();
const answer = await selectProvider("via:arcade:hubspot");
diff --git a/server/src/__tests__/connection-intents-service.test.ts b/server/src/__tests__/connection-intents-service.test.ts
index c0de02f88c7..c6c318c372d 100644
--- a/server/src/__tests__/connection-intents-service.test.ts
+++ b/server/src/__tests__/connection-intents-service.test.ts
@@ -3,6 +3,7 @@ import { and, eq, sql } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
import {
agents,
+ authUsers,
aiProviderDefaults,
agentWakeupRequests,
issueComments,
@@ -110,6 +111,7 @@ describeEmbeddedPostgres("connectionIntentService", () => {
issuePrefix: "CONN",
requireBoardApprovalForNewAgents: false,
});
+ await db.insert(authUsers).values({ id: "responsible-user", name: "Responsible user", email: "responsible@example.test", createdAt: new Date(), updatedAt: new Date() });
await db.insert(companyMemberships).values({
companyId,
principalType: "user",
diff --git a/server/src/__tests__/costs-service.test.ts b/server/src/__tests__/costs-service.test.ts
index a8ea5fa2990..0ea925ebb07 100644
--- a/server/src/__tests__/costs-service.test.ts
+++ b/server/src/__tests__/costs-service.test.ts
@@ -221,6 +221,21 @@ describe("cost routes", () => {
});
});
+ it("requires an explicit all-time request and rejects conflicting ranges", () => {
+ const { parseCostDateRange } = loadCostParsers();
+ expect(parseCostDateRange({})).toBeUndefined();
+ expect(parseCostDateRange({ period: "all" })).toEqual({ allTime: true });
+ for (const input of [
+ { from: "2026-09-02", to: "2026-09-01" },
+ { from: ["2026-09-01"] },
+ { from: "2026-02-30" },
+ { from: "" },
+ { from: "09/01/2026" },
+ { period: "all", from: "2026-09-01" },
+ { period: "unknown" },
+ ]) expect(() => parseCostDateRange(input)).toThrow();
+ });
+
it("returns 400 for an invalid 'from' date string", async () => {
const { parseCostDateRange } = loadCostParsers();
expect(() => parseCostDateRange({ from: "not-a-date" })).toThrow(/invalid 'from' date/i);
@@ -270,7 +285,7 @@ describe("cost routes", () => {
it("returns 400 for invalid finance event list limits", async () => {
const { parseCostLimit } = loadCostParsers();
- expect(() => parseCostLimit({ limit: "0" })).toThrow(/invalid 'limit'/i);
+ for (const limit of ["0", "25garbage", "1.5", ["25"], "501"]) expect(() => parseCostLimit({ limit })).toThrow(/invalid 'limit'/i);
});
it("accepts valid finance event list limits", async () => {
@@ -352,7 +367,8 @@ describe("cost routes", () => {
});
it("allows authorized board users to update an agent budget and budget policy", async () => {
- mockAgentService.update.mockResolvedValueOnce({
+ mockAgentService.getById.mockResolvedValueOnce({ id: "agent-1", companyId: "company-1", name: "Budget Agent", budgetMonthlyCents: 100, spentMonthlyCents: 0 });
+ mockAgentService.getById.mockResolvedValueOnce({
id: "agent-1",
companyId: "company-1",
name: "Budget Agent",
@@ -373,30 +389,22 @@ describe("cost routes", () => {
.send({ budgetMonthlyCents: 2500 });
expect(res.status).toBe(200);
- expect(mockAgentService.update).toHaveBeenCalledWith("agent-1", { budgetMonthlyCents: 2500 });
+ expect(res.body.budgetMonthlyCents).toBe(2500);
+ expect(mockAgentService.update).not.toHaveBeenCalled();
+ expect(mockBudgetService.upsertPolicy).toHaveBeenCalledTimes(1);
expect(mockBudgetService.upsertPolicy).toHaveBeenCalledWith(
"company-1",
{
scopeType: "agent",
scopeId: "agent-1",
amount: 2500,
+ isActive: true,
windowKind: "calendar_month_utc",
},
"board-user",
);
- expect(mockLogActivity).toHaveBeenCalledWith(
- expect.anything(),
- expect.objectContaining({
- companyId: "company-1",
- actorType: "user",
- actorId: "board-user",
- agentId: null,
- action: "agent.budget_updated",
- entityType: "agent",
- entityId: "agent-1",
- details: { budgetMonthlyCents: 2500 },
- }),
- );
+ // Policy mutation owns the atomic entity update and activity log.
+ expect(mockLogActivity).not.toHaveBeenCalled();
});
});
@@ -543,7 +551,9 @@ describeEmbeddedPostgres("cost and finance aggregate overflow handling", () => {
const [byAgentModelRow] = await costs.byAgentModel(companyId, range);
expect(byAgentRow?.costCents).toBe(4_000_000_000);
- expect(byAgentRow?.inputTokens).toBe(4_000_000_000);
+ // Historical OpenAI input includes these ten cached tokens.
+ expect(byAgentRow?.inputTokens).toBe(3_999_999_990);
+ expect(byAgentRow!.inputTokens + byAgentRow!.cachedInputTokens).toBe(4_000_000_000);
expect(byProjectRow?.costCents).toBe(4_000_000_000);
expect(byAgentModelRow?.costCents).toBe(4_000_000_000);
});
@@ -692,7 +702,8 @@ describeEmbeddedPostgres("cost and finance aggregate overflow handling", () => {
issueCount: 3,
includeDescendants: true,
costCents: 600,
- inputTokens: 60,
+ costCentsExact: "600.0000000",
+ inputTokens: 54,
cachedInputTokens: 6,
outputTokens: 12,
runCount: 0,
diff --git a/server/src/__tests__/decision-model-provider.test.ts b/server/src/__tests__/decision-model-provider.test.ts
new file mode 100644
index 00000000000..d7cd89482c2
--- /dev/null
+++ b/server/src/__tests__/decision-model-provider.test.ts
@@ -0,0 +1,70 @@
+import { describe, expect, it, vi } from "vitest";
+import { DECISION_MODELS, DECISION_TEST_REQUEST, decisionProviderForConnection } from "@paperclipai/shared";
+import { decisionReceipt, runDecisionProvider } from "../services/decision-model-provider.js";
+
+function openaiResponse() {
+ return { model: "gpt-6-luna", usage: { input_tokens: 123, output_tokens: 0 }, answers: [
+ { type: "predicate", name: "billing", probability: 0.99 },
+ { type: "choice", name: "team", choice: "billing", confidence: 0.9, probabilities: [{ value: "billing", probability: 0.9 }, { value: "technical", probability: 0.1 }] },
+ { type: "score", name: "severity", score: 0.1, probabilities: [{ value: 0, probability: 0.9 }, { value: 1, probability: 0.1 }, { value: 2, probability: 0 }] },
+ ] };
+}
+function openrouterResponse() {
+ return { id: "decision-fixture", model: "typesafe/jev-1.13", usage: { input_tokens: 123, output_tokens: 0, cost: 0.000005166 }, answers: {
+ billing: { type: "noul", noul: 0.99 }, team: { type: "choice", choice: "billing", confidence: 0.85, probabilities: { billing: 0.9, technical: 0.1 } },
+ severity: { type: "score", score: 0.1, probabilities: { "0": 0.9, "1": 0.1, "2": 0 } },
+ } };
+}
+describe("decision provider contract", () => {
+ it.each(["openai", "openrouter"] as const)("uses native %s decisions with the selected credential and preserves answers and fractional costs", async provider => {
+ const transport = vi.fn().mockResolvedValue(Response.json(provider === "openai" ? openaiResponse() : openrouterResponse()));
+ const result = await runDecisionProvider({ provider, model: DECISION_MODELS[provider].id, apiKey: "selected-credential", request: DECISION_TEST_REQUEST, signal: new AbortController().signal }, { fetch: transport });
+ expect(transport).toHaveBeenCalledTimes(1);
+ const [url, options] = transport.mock.calls[0];
+ expect(String(url)).toBe(provider === "openai" ? "https://api.openai.com/v1/decisions" : "https://openrouter.ai/api/alpha/decisions");
+ expect(new Headers(options?.headers).get("authorization")).toBe("Bearer selected-credential");
+ expect(result.answers).toMatchObject({ billing: { type: "boolean", probability: 0.99 }, team: { type: "choice", choice: "billing", confidence: provider === "openai" ? 0.9 : 0.85 }, severity: { type: "score", score: 0.1 } });
+ expect(result.receipt.costCents).toBe(provider === "openai" ? "0.0012300" : "0.0005166");
+ expect(JSON.stringify(result.receipt)).not.toContain("customer");
+ expect(JSON.parse(String(options?.body)).model).toBe(DECISION_MODELS[provider].id);
+ });
+ it("keeps usage for a charged refusal and never treats it as an answer", async () => {
+ const transport = vi.fn().mockResolvedValue(Response.json({ ...openaiResponse(), answers: [{ type: "refusal", name: null }] }));
+ const result = await runDecisionProvider({ provider: "openai", model: "gpt-6-luna", apiKey: "key", request: DECISION_TEST_REQUEST, signal: new AbortController().signal }, { fetch: transport });
+ expect(result.answers).toBeUndefined(); expect(result.errorCode).toBe("refused"); expect(result.receipt.inputTokens).toBe(123);
+ });
+ it.each([401, 429, 500])("does not retry HTTP %i or retain its response body", async status => {
+ const transport = vi.fn().mockResolvedValue(Response.json({ error: { message: "PRIVATE STATE AND KEY", type: "server_error" } }, { status }));
+ const result = await runDecisionProvider({ provider: "openai", model: "gpt-6-luna", apiKey: "key", request: DECISION_TEST_REQUEST, signal: new AbortController().signal }, { fetch: transport });
+ expect(transport).toHaveBeenCalledTimes(1); expect(result.receipt.costStatus).toBe(status === 500 ? "unpriced" : "estimated"); expect(result.noProviderWork).toBe(status !== 500); expect(JSON.stringify(result)).not.toContain("PRIVATE");
+ });
+ it("preserves usage when answer validation fails", async () => {
+ const response = openrouterResponse(); response.answers.team.choice = "invented";
+ const result = await runDecisionProvider({ provider: "openrouter", model: "typesafe/jev-1.13", apiKey: "key", request: DECISION_TEST_REQUEST, signal: new AbortController().signal }, { fetch: async () => Response.json(response) });
+ expect(result.answers).toBeUndefined(); expect(result.receipt.costStatus).toBe("reported");
+ });
+ it.each(["openai", "openrouter"] as const)("retains the %s receipt when the SDK rejects malformed wire answers", async provider => {
+ const wire = provider === "openai" ? { ...openaiResponse(), answers: [{ type: "predicate", name: "billing", probability: 2 }] }
+ : { ...openrouterResponse(), answers: { billing: { type: "noul", noul: "not-a-probability" } } };
+ const result = await runDecisionProvider({ provider, model: DECISION_MODELS[provider].id, apiKey: "key", request: DECISION_TEST_REQUEST, signal: new AbortController().signal }, { fetch: async () => Response.json(wire) });
+ expect(result.answers).toBeUndefined(); expect(result.receipt.inputTokens).toBe(123);
+ expect(result.receipt.costStatus).toBe(provider === "openai" ? "estimated" : "reported");
+ });
+ it("fails closed on an OpenRouter refusal while retaining any reported charge", async () => {
+ const result = await runDecisionProvider({ provider: "openrouter", model: DECISION_MODELS.openrouter.id, apiKey: "key", request: DECISION_TEST_REQUEST, signal: new AbortController().signal },
+ { fetch: async () => Response.json({ ...openrouterResponse(), answers: { billing: { type: "refusal" } } }) });
+ expect(result.answers).toBeUndefined(); expect(result.errorCode).toBe("refused"); expect(result.receipt.costStatus).toBe("reported");
+ });
+ it("does not invent prices when usage or a supported rate is missing", () => {
+ expect(decisionReceipt("openai", {}).costCents).toBeNull();
+ expect(decisionReceipt("openai", { usage: { inputTokens: 100_000 } }).costStatus).toBe("unpriced");
+ expect(decisionReceipt("openrouter", { usage: { inputTokens: 1 } }).costCents).toBeNull();
+ expect(decisionReceipt("openrouter", { providerMetadata: { openrouter: { usage: { cost: 0 } } } }).costStatus).toBe("reported");
+ });
+ it("rejects subscription, personal endpoint routing and other provider capabilities", () => {
+ expect(decisionProviderForConnection({ provider: "openai", method: "subscription" })).toBeNull();
+ expect(decisionProviderForConnection({ provider: "openai", method: "api_key", routing: { kind: "gateway", baseUrl: "https://example.com" } })).toBeNull();
+ expect(decisionProviderForConnection({ provider: "anthropic", method: "api_key" })).toBeNull();
+ expect(decisionProviderForConnection({ provider: "openrouter", method: "api_key", routing: { kind: "openrouter" } })).toBe("openrouter");
+ });
+});
diff --git a/server/src/__tests__/decision-models.test.ts b/server/src/__tests__/decision-models.test.ts
new file mode 100644
index 00000000000..aa3bfbdb4bd
--- /dev/null
+++ b/server/src/__tests__/decision-models.test.ts
@@ -0,0 +1,291 @@
+import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
+import { randomUUID } from "node:crypto";
+import { mkdtemp, realpath, rm } from "node:fs/promises";
+import os from "node:os";
+import path from "node:path";
+import { and, eq, sql } from "drizzle-orm";
+import {
+ createDb, companies, agents, companyMemberships, companyDecisionModels, costEvents, decisionInvocations,
+ connectionGrants, connectionGrantMembers, toolConnectionInstalls, budgetPolicies, budgetReservations,
+ heartbeatRuns, issues, projects, runIdentityContexts, secretAccessEvents, companySecrets,
+} from "@paperclipai/db";
+import { startEmbeddedPostgresTestDatabase } from "@paperclipai/db/test-embedded-postgres";
+import { DECISION_TEST_REQUEST, updateDecisionModelSchema, createCostEventSchema } from "@paperclipai/shared";
+import { aiConnectionService } from "../services/ai-connections.js";
+import { agentService } from "../services/agents.js";
+import { decisionModelService, settingsDecisionTest, defineDecisionFeature, type DecisionContext } from "../services/decision-models.js";
+import { decisionReceipt, type DecisionProviderOutcome } from "../services/decision-model-provider.js";
+import { costService } from "../services/costs.js";
+import { billingReconciliationService } from "../services/billing-reconciliation.js";
+import { withAccountingTransaction } from "../services/accounting-transaction.js";
+import express from "express";
+import request from "supertest";
+import { decisionModelRoutes } from "../routes/decision-models.js";
+import { errorHandler } from "../middleware/index.js";
+
+let database: Awaited>;
+let db: ReturnType;
+let home: string;
+const backgroundFeature = defineDecisionFeature("test.background", { background: true });
+const outcome: DecisionProviderOutcome = { answers: { billing: { type: "boolean", probability: 0.9 } }, receipt: decisionReceipt("openai", { usage: { inputTokens: 100, outputTokens: 0 } }) };
+beforeAll(async () => {
+ home = await realpath(await mkdtemp(path.join(os.tmpdir(), "paperclip-decisions-")));
+ vi.stubEnv("PAPERCLIP_HOME", home);
+ vi.stubEnv("PAPERCLIP_INSTANCE_ID", "decisions-fixture");
+ database = await startEmbeddedPostgresTestDatabase("paperclip-decisions-db-");
+ db = createDb(database.connectionString);
+}, 90000);
+afterAll(async () => { await database?.cleanup(); vi.unstubAllEnvs(); if (home) await rm(home, { recursive: true, force: true }); });
+let sequence = 0;
+async function fixture() {
+ const companyId = randomUUID(), agentId = randomUUID();
+ await db.insert(companies).values({ id: companyId, name: "Decision tests", issuePrefix: `DC${++sequence}` });
+ await db.insert(agents).values({ id: agentId, companyId, name: "Test agent", adapterType: "codex_local" });
+ await db.insert(companyMemberships).values(["alice", "bob"].map(principalId => ({ companyId, principalId, principalType: "user", status: "active", membershipRole: "owner" })));
+ const connections = aiConnectionService(db);
+ const binding = await connections.save(companyId, "alice", { provider: "openai", method: "api_key", name: "Decision key", ownership: "shared", apiKey: "fixture-key", agentIds: [], allAgents: true }, "fixture-key");
+ const provider = vi.fn().mockResolvedValue(structuredClone(outcome));
+ const service = decisionModelService(db, { provider });
+ const context: DecisionContext = { companyId, feature: settingsDecisionTest,
+ actor: { type: "board", userId: "alice", source: "session", companyIds: [companyId], memberships: [{ companyId, membershipRole: "owner", status: "active" }] } };
+ const config = { ...binding, enabled: true, allowBackground: true };
+ await service.configure(companyId, "alice", config);
+ return { companyId, agentId, binding, provider, service, context, config, connections };
+}
+describe("company decision service", () => {
+ it("starts unconfigured with background sponsorship on and makes availability free", async () => {
+ const f = await fixture();
+ await db.delete(companyDecisionModels).where(eq(companyDecisionModels.companyId, f.companyId));
+ expect(await f.service.settings(f.companyId)).toMatchObject({ enabled: false, allowBackground: true, connectionId: null });
+ expect(await f.service.availability(f.context)).toEqual({ available: false, reason: "not_configured" });
+ await f.service.configure(f.companyId, "alice", updateDecisionModelSchema.parse({ ...f.binding, enabled: true }));
+ const before = await db.select().from(secretAccessEvents).where(eq(secretAccessEvents.companyId, f.companyId));
+ const memo = f.service.availabilityForRequest();
+ expect(memo(f.context)).toBe(memo(f.context));
+ expect(await memo(f.context)).toEqual({ available: true });
+ expect(await db.select().from(secretAccessEvents).where(eq(secretAccessEvents.companyId, f.companyId))).toHaveLength(before.length);
+ expect(f.provider).not.toHaveBeenCalled();
+ });
+ it("records a human service charge without an agent, exact cost and no input or answer content", async () => {
+ const f = await fixture();
+ const result = await f.service.decide(f.context, { ...DECISION_TEST_REQUEST, state: "PRIVATE PAYLOAD" });
+ expect(result.status).toBe("succeeded");
+ expect(f.provider.mock.calls[0][0].apiKey).toBe("fixture-key");
+ const [event] = await db.select().from(costEvents).where(eq(costEvents.companyId, f.companyId));
+ expect(event).toMatchObject({ agentId: null, responsibleUserId: "alice", usageKind: "decision", costCents: 0.001, costStatus: "estimated", heartbeatRunId: null });
+ const rows = await db.select().from(decisionInvocations).where(eq(decisionInvocations.companyId, f.companyId));
+ expect(rows[0]).toMatchObject({ status: "succeeded", actorType: "user", responsibleUserId: "alice", costEventId: event.id });
+ expect(JSON.stringify(rows)).not.toContain("PRIVATE PAYLOAD"); expect(JSON.stringify(rows)).not.toContain("probability");
+ expect((await costService(db).byUser(f.companyId)).rows.find(r => r.userId === "alice")?.costCentsExact).toBe("0.0010000");
+ expect((await costService(db).byAgent(f.companyId))[0].agentId).toBeNull();
+ expect((await db.select().from(budgetReservations).where(eq(budgetReservations.companyId, f.companyId)))[0].state).toBe("settled");
+ });
+ it("allows real background use, preserves explicit off, and never sponsors a denied human", async () => {
+ const f = await fixture();
+ const context: DecisionContext = { companyId: f.companyId, feature: backgroundFeature, actor: { type: "system" } };
+ expect((await f.service.decide(context, DECISION_TEST_REQUEST)).status).toBe("succeeded");
+ expect((await db.select().from(decisionInvocations).where(eq(decisionInvocations.companyId, f.companyId)))[0]).toMatchObject({ actorType: "system", responsibleUserId: null });
+ await f.service.configure(f.companyId, "alice", { ...f.config, allowBackground: false });
+ expect(await f.service.availability(context)).toEqual({ available: false, reason: "background_disabled" });
+ const second = await f.connections.save(f.companyId, "alice", { provider: "openrouter", method: "api_key", name: "Other key", ownership: "shared", apiKey: "other", agentIds: [], allAgents: true }, "other");
+ await f.service.configure(f.companyId, "alice", { ...second, enabled: true, allowBackground: false });
+ expect((await f.service.settings(f.companyId)).allowBackground).toBe(false);
+ await f.service.configure(f.companyId, "alice", f.config);
+ await db.insert(connectionGrantMembers).values({ companyId: f.companyId, grantId: f.binding.grantId, subjectType: "user", subjectId: "bob" });
+ expect(await f.service.decide({ ...f.context, feature: backgroundFeature }, DECISION_TEST_REQUEST)).toMatchObject({ status: "unavailable", reason: "access_denied" });
+ expect(f.provider).toHaveBeenCalledTimes(1);
+ });
+ it("retains the charge and dispatch snapshot when the task is deleted during provider work", async () => {
+ const f = await fixture(), issueId = randomUUID();
+ await db.insert(issues).values({ id: issueId, companyId: f.companyId, title: "Temporary task" });
+ f.provider.mockImplementationOnce(async () => {
+ await db.delete(issues).where(eq(issues.id, issueId));
+ return structuredClone(outcome);
+ });
+ expect((await f.service.decide({ ...f.context, issueId }, DECISION_TEST_REQUEST)).status).toBe("succeeded");
+ const [event] = await db.select().from(costEvents).where(eq(costEvents.companyId, f.companyId));
+ expect(event).toMatchObject({ issueId: null, costCents: 0.001 });
+ const [invocation] = await db.select().from(decisionInvocations).where(eq(decisionInvocations.companyId, f.companyId));
+ expect(invocation).toMatchObject({ issueId, status: "succeeded", costEventId: event.id });
+ });
+ it("rechecks revoked grants after availability, and can disable a revoked connection", async () => {
+ const f = await fixture(); expect(await f.service.availability(f.context)).toEqual({ available: true });
+ await db.update(connectionGrants).set({ status: "revoked" }).where(eq(connectionGrants.id, f.binding.grantId));
+ expect(await f.service.decide(f.context, DECISION_TEST_REQUEST)).toMatchObject({ status: "unavailable", reason: "connection_unavailable" });
+ await f.service.configure(f.companyId, "alice", { ...f.config, enabled: false });
+ expect(await f.service.availability(f.context)).toEqual({ available: false, reason: "disabled" }); expect(f.provider).not.toHaveBeenCalled();
+ });
+ it.each(["disabled", "rotated"])("rejects a secret %s while admission waits for accounting", async change => {
+ const f = await fixture();
+ const [secret] = await db.select().from(companySecrets).where(eq(companySecrets.companyId, f.companyId));
+ let release!: () => void, locked!: (pid: number) => void;
+ const gate = new Promise(resolve => { release = resolve; });
+ const acquired = new Promise(resolve => { locked = resolve; });
+ const holding = withAccountingTransaction(db, f.companyId, async tx => {
+ const [row] = await tx.execute<{ pid: number }>(sql`select pg_backend_pid() as pid`);
+ locked(row.pid); await gate;
+ });
+ const pid = await acquired;
+ const pending = f.service.decide(f.context, DECISION_TEST_REQUEST);
+ try {
+ await vi.waitFor(async () => {
+ const [row] = await db.execute<{ count: number }>(sql`select count(*)::int as count from pg_stat_activity where ${pid} = any(pg_blocking_pids(pid))`);
+ expect(row.count).toBeGreaterThan(0);
+ }, { timeout: 5000 });
+ await db.update(companySecrets).set(change === "disabled" ? { status: "disabled" } : { latestVersion: secret.latestVersion + 1 }).where(eq(companySecrets.id, secret.id));
+ } finally { release(); await holding; }
+ expect(await pending).toMatchObject({ status: "unavailable", reason: "connection_unavailable" });
+ expect(f.provider).not.toHaveBeenCalled();
+ expect(await db.select().from(decisionInvocations).where(eq(decisionInvocations.companyId, f.companyId))).toHaveLength(0);
+ });
+ it("preserves sponsorship off when a deleted grant is replaced", async () => {
+ const f = await fixture();
+ await f.service.configure(f.companyId, "alice", { ...f.config, allowBackground: false });
+ await db.delete(connectionGrants).where(eq(connectionGrants.id, f.binding.grantId));
+ expect(await f.service.availability(f.context)).toMatchObject({ available: false, reason: "connection_unavailable" });
+ expect((await f.service.settings(f.companyId)).allowBackground).toBe(false);
+ const next = await f.connections.save(f.companyId, "alice", { provider: "openrouter", method: "api_key", name: "Replacement", ownership: "shared", apiKey: "other", agentIds: [], allAgents: true }, "other");
+ await f.service.configure(f.companyId, "alice", { ...next, enabled: true });
+ expect((await f.service.settings(f.companyId)).allowBackground).toBe(false);
+ expect(f.provider).not.toHaveBeenCalled();
+ });
+ it("rejects foreign-company credentials, membership loss, and invented feature handles", async () => {
+ const f = await fixture(), other = await fixture();
+ await expect(f.service.configure(f.companyId, "alice", { ...other.config })).rejects.toThrow();
+ await db.update(companyMemberships).set({ status: "inactive" }).where(and(eq(companyMemberships.companyId, f.companyId), eq(companyMemberships.principalId, "alice")));
+ expect(await f.service.availability(f.context)).toMatchObject({ available: false, reason: "access_denied" });
+ expect(await f.service.decide({ ...f.context, feature: { id: "settings.test", background: true }, actor: { type: "system" } }, DECISION_TEST_REQUEST)).toMatchObject({ status: "unavailable", reason: "access_denied" });
+ });
+ it("captures the active run identity and checks both human and agent access", async () => {
+ const f = await fixture(), issueId = randomUUID(), runId = randomUUID();
+ await db.insert(issues).values({ id: issueId, companyId: f.companyId, title: "Decision task", status: "in_progress", assigneeAgentId: f.agentId });
+ await db.insert(heartbeatRuns).values({ id: runId, companyId: f.companyId, agentId: f.agentId, status: "running", invocationSource: "on_demand", responsibleUserId: "alice", contextSnapshot: { issueId } });
+ const [identity] = await db.insert(runIdentityContexts).values({ companyId: f.companyId, runId, revision: 1, responsibleUserId: "bob", cause: "steering", correlationId: "test", acceptedAt: new Date() }).returning();
+ await db.update(heartbeatRuns).set({ responsibleUserId: "bob", activeIdentityContextId: identity.id }).where(eq(heartbeatRuns.id, runId));
+ const context: DecisionContext = { companyId: f.companyId, feature: settingsDecisionTest, actor: { type: "agent", agentId: f.agentId, runId, companyId: f.companyId, source: "agent_jwt", onBehalfOfUserId: "alice" } };
+ expect((await f.service.decide(context, DECISION_TEST_REQUEST)).status).toBe("succeeded");
+ expect((await db.select().from(decisionInvocations).where(eq(decisionInvocations.companyId, f.companyId)))[0]).toMatchObject({ responsibleUserId: "bob", runId, issueId, identityContextId: identity.id });
+ await db.delete(toolConnectionInstalls).where(eq(toolConnectionInstalls.connectionId, f.binding.connectionId));
+ expect(await f.service.availability(context)).toMatchObject({ available: false, reason: "access_denied" });
+ await db.update(heartbeatRuns).set({ responsibleUserId: null }).where(eq(heartbeatRuns.id, runId));
+ expect(await f.service.availability(context)).toMatchObject({ available: false, reason: "responsible_user_missing" });
+ });
+ it("serializes budget admission against concurrent requests", async () => {
+ const f = await fixture();
+ await db.insert(budgetPolicies).values({ companyId: f.companyId, scopeType: "company", scopeId: f.companyId, windowKind: "calendar_month_utc", amount: 1, reservationCents: "1", notifyEnabled: false });
+ let release!: () => void; const gate = new Promise(resolve => { release = resolve; });
+ let entered!: () => void; const started = new Promise(resolve => { entered = resolve; });
+ f.provider.mockImplementationOnce(async () => { entered(); await gate; return structuredClone(outcome); });
+ const first = f.service.decide(f.context, DECISION_TEST_REQUEST);
+ await started;
+ try { expect(await f.service.decide(f.context, DECISION_TEST_REQUEST)).toMatchObject({ status: "unavailable", reason: "budget_blocked" }); }
+ finally { release(); }
+ expect((await first).status).toBe("succeeded"); expect(f.provider).toHaveBeenCalledTimes(1);
+ });
+ it("blocks agent deletion while an in-flight or unknown decision retains a budget hold", async () => {
+ const f = await fixture(), runId = randomUUID();
+ await db.insert(heartbeatRuns).values({ id: runId, companyId: f.companyId, agentId: f.agentId, status: "running", invocationSource: "on_demand", responsibleUserId: "alice" });
+ await db.insert(budgetPolicies).values({ companyId: f.companyId, scopeType: "company", scopeId: f.companyId, windowKind: "calendar_month_utc", amount: 1, reservationCents: "1", notifyEnabled: false });
+ const context: DecisionContext = { companyId: f.companyId, feature: settingsDecisionTest,
+ actor: { type: "agent", agentId: f.agentId, runId, companyId: f.companyId, source: "agent_jwt" } };
+ const remove = () => agentService(db).remove(f.agentId);
+ f.provider.mockImplementationOnce(async () => {
+ await expect(remove()).rejects.toMatchObject({ status: 409, details: { code: "agent_decision_accounting_pending" } });
+ expect(await f.service.decide(f.context, DECISION_TEST_REQUEST)).toMatchObject({ status: "unavailable", reason: "budget_blocked" });
+ return { errorCode: "timeout", receipt: decisionReceipt("openai", null) };
+ });
+ expect((await f.service.decide(context, DECISION_TEST_REQUEST)).status).toBe("failed");
+ await expect(remove()).rejects.toMatchObject({ status: 409, details: { code: "agent_decision_accounting_pending" } });
+ expect((await db.select().from(budgetReservations).where(eq(budgetReservations.companyId, f.companyId)))[0]).toMatchObject({ state: "held", amountCents: "1.0000000" });
+ });
+ it("holds unknown billing until an audited correction, without rerunning the provider", async () => {
+ const f = await fixture(); f.provider.mockResolvedValue({ errorCode: "timeout", receipt: decisionReceipt("openai", null) });
+ expect((await f.service.decide(f.context, DECISION_TEST_REQUEST)).status).toBe("failed");
+ const [event] = await db.select().from(costEvents).where(eq(costEvents.companyId, f.companyId));
+ expect(event.costStatus).toBe("unpriced");
+ expect((await db.select().from(budgetReservations).where(eq(budgetReservations.companyId, f.companyId)))[0].state).toBe("held");
+ await billingReconciliationService(db).adjust(f.companyId, event.id, { idempotencyKey: "correction", expectedCents: "0", correctedCents: "0.002", reason: "Verified provider invoice", pricing: { source: "operator" } }, "alice");
+ expect((await db.select().from(budgetReservations).where(eq(budgetReservations.companyId, f.companyId)))[0].state).toBe("settled");
+ expect(f.provider).toHaveBeenCalledTimes(1);
+ });
+ it("recovers an interrupted dispatch once without paying for a retry", async () => {
+ const f = await fixture();
+ const [invocation] = await db.insert(decisionInvocations).values({ companyId: f.companyId, feature: "test.background", actorType: "system", actorId: "paperclip-decisions",
+ ...f.binding, provider: "openai", model: "gpt-6-luna", questionTypes: ["boolean"], startedAt: new Date(Date.now() - 180_000) }).returning();
+ await db.insert(budgetReservations).values({ companyId: f.companyId, decisionInvocationId: invocation.id, amountCents: "0.01", providerStartedAt: invocation.startedAt });
+ await Promise.all([f.service.recoverInterrupted(), f.service.recoverInterrupted()]);
+ const events = await db.select().from(costEvents).where(eq(costEvents.companyId, f.companyId));
+ expect(events).toHaveLength(1); expect(events[0].costStatus).toBe("unpriced"); expect(f.provider).not.toHaveBeenCalled();
+ });
+ it("keeps public cost reporting agent-scoped and bounds decision input before payment", async () => {
+ expect(createCostEventSchema.safeParse({ agentId: null, provider: "openai", model: "gpt-6-luna", costCents: 1, occurredAt: new Date().toISOString() }).success).toBe(false);
+ const f = await fixture(); await expect(f.service.decide(f.context, { ...DECISION_TEST_REQUEST, state: "x".repeat(32_001) })).rejects.toThrow(); expect(f.provider).not.toHaveBeenCalled();
+ });
+ it("preserves an explicit sponsorship opt-out when a subsequent edit omits the field", async () => {
+ const f = await fixture();
+ await f.service.configure(f.companyId, "alice", { ...f.config, allowBackground: false });
+ const second = await f.connections.save(f.companyId, "alice", { provider: "openrouter", method: "api_key", name: "Other", ownership: "shared", apiKey: "other", agentIds: [], allAgents: true }, "other");
+ await f.service.configure(f.companyId, "alice", { ...second, enabled: true });
+ expect((await f.service.settings(f.companyId)).allowBackground).toBe(false);
+ });
+ it("rejects revoked secrets without provider work and returns usage on successful calls", async () => {
+ const f = await fixture();
+ expect(await f.service.decide(f.context, DECISION_TEST_REQUEST)).toMatchObject({ status: "succeeded", usage: { costCents: "0.0010000", costStatus: "estimated", inputTokens: 100 } });
+ await db.update(companySecrets).set({ status: "revoked" }).where(eq(companySecrets.companyId, f.companyId));
+ expect(await f.service.decide(f.context, DECISION_TEST_REQUEST)).toMatchObject({ status: "unavailable" });
+ expect(f.provider).toHaveBeenCalledTimes(1);
+ });
+ it.each(["agent", "project"] as const)("reserves and enforces applicable %s budgets", async scopeType => {
+ const f = await fixture(), projectId = randomUUID(), issueId = randomUUID(), runId = randomUUID();
+ await db.insert(projects).values({ id: projectId, companyId: f.companyId, name: "Decisions project" });
+ await db.insert(issues).values({ id: issueId, companyId: f.companyId, projectId, title: "Budgeted task", assigneeAgentId: f.agentId });
+ await db.insert(heartbeatRuns).values({ id: runId, companyId: f.companyId, agentId: f.agentId, status: "running", invocationSource: "on_demand", responsibleUserId: "alice", contextSnapshot: { issueId } });
+ const context: DecisionContext = { companyId: f.companyId, feature: settingsDecisionTest, actor: { type: "agent", agentId: f.agentId, runId, companyId: f.companyId, source: "agent_jwt" } };
+ const [policy] = await db.insert(budgetPolicies).values({ companyId: f.companyId, scopeType, scopeId: scopeType === "agent" ? f.agentId : projectId, windowKind: "calendar_month_utc", amount: 1, reservationCents: "2", notifyEnabled: false }).returning();
+ expect(await f.service.availability(context)).toEqual({ available: true });
+ expect(await f.service.decide(context, DECISION_TEST_REQUEST)).toMatchObject({ status: "unavailable", reason: "budget_blocked" });
+ expect(f.provider).not.toHaveBeenCalled();
+ await db.update(budgetPolicies).set({ amount: 5 }).where(eq(budgetPolicies.id, policy.id));
+ expect((await f.service.decide(context, DECISION_TEST_REQUEST)).status).toBe("succeeded");
+ expect((await db.select().from(budgetReservations).where(eq(budgetReservations.companyId, f.companyId)))[0]).toMatchObject({ agentId: f.agentId, projectId, amountCents: "2.0000000", state: "settled" });
+ });
+ it("releases reservations when the provider rejects a request before model work", async () => {
+ const f = await fixture();
+ f.provider.mockResolvedValue({ noProviderWork: true, errorCode: "provider_auth_failed", receipt: { ...outcome.receipt, inputTokens: 0, costCents: "0", pricingProvenance: { source: "unknown", evidence: "HTTP 401" } } });
+ expect((await f.service.decide(f.context, DECISION_TEST_REQUEST)).status).toBe("failed");
+ expect((await db.select().from(budgetReservations).where(eq(budgetReservations.companyId, f.companyId)))[0].state).toBe("released");
+ expect((await db.select().from(costEvents).where(eq(costEvents.companyId, f.companyId)))[0].costCents).toBe(0);
+ });
+ it("enforces manager-only configuration and tests, company isolation, and fixed sample execution", async () => {
+ const f = await fixture(), other = await fixture();
+ const app = express(); app.use(express.json());
+ let actor = f.context.actor;
+ app.use((req, _res, next) => { req.actor = actor as typeof req.actor; next(); });
+ app.use("/api", decisionModelRoutes(db)); app.use(errorHandler);
+ const url = `/api/companies/${f.companyId}/decision-model`;
+ expect((await request(app).get(url)).body.canManage).toBe(true);
+ expect((await request(app).get(`/api/companies/${other.companyId}/decision-model`)).status).toBe(403);
+ actor = { type: "board", userId: "alice", source: "session", companyIds: [f.companyId], memberships: [{ companyId: f.companyId, status: "active", membershipRole: "viewer" }] };
+ expect((await request(app).get(url)).body).toEqual({ canManage: false, settings: null, choices: [] });
+ expect((await request(app).put(url).send(f.config)).status).toBe(403);
+ expect((await request(app).post(`${url}/test`).send({ actor: { type: "system" } })).status).toBe(403);
+ actor = f.context.actor;
+ await f.service.configure(f.companyId, "alice", { ...f.config, enabled: false });
+ expect((await request(app).post(`${url}/test`).send({ state: "untrusted", actor: { type: "system" }, model: "untrusted" })).body).toEqual({ status: "unavailable", reason: "disabled" });
+ expect((await request(app).post(`${url}/decide`).send(DECISION_TEST_REQUEST)).status).toBe(404);
+ expect((await request(app).get(`${url}/history?limit=501`)).status).toBe(400);
+ expect((await request(app).get(`${url}/history?from=2026-10-01T00:00:00.000Z&to=2026-10-31T23:59:59.000Z`)).status).toBe(200);
+ });
+ it("keeps private task links out of company cost history for unauthorized readers", async () => {
+ const f = await fixture(), projectId = randomUUID(), issueId = randomUUID();
+ await db.insert(projects).values({ id: projectId, companyId: f.companyId, name: "Private project", visibility: "private", privacyOwnerUserId: "bob" });
+ await db.insert(issues).values({ id: issueId, companyId: f.companyId, projectId, title: "PRIVATE TITLE", identifier: "SECRET-1" });
+ await f.service.decide({ companyId: f.companyId, feature: backgroundFeature, actor: { type: "system" }, issueId }, DECISION_TEST_REQUEST);
+ await db.update(companyMemberships).set({ membershipRole: "member" }).where(and(eq(companyMemberships.companyId, f.companyId), eq(companyMemberships.principalId, "alice")));
+ const actor = { type: "board" as const, userId: "alice", source: "session" as const, companyIds: [f.companyId], memberships: [{ companyId: f.companyId, status: "active", membershipRole: "member" }] };
+ expect(await f.service.availability({ ...f.context, actor, issueId })).toMatchObject({ available: false, reason: "access_denied" });
+ const history = await f.service.history(f.companyId, actor);
+ expect(history[0]).toMatchObject({ issueId: null, issueIdentifier: null, runId: null });
+ expect(JSON.stringify(history)).not.toContain("SECRET");
+ });
+});
diff --git a/server/src/__tests__/decisions-service.test.ts b/server/src/__tests__/decisions-service.test.ts
index 15dcd96a519..4b418e355f1 100644
--- a/server/src/__tests__/decisions-service.test.ts
+++ b/server/src/__tests__/decisions-service.test.ts
@@ -2,7 +2,7 @@ import { randomUUID } from "node:crypto";
import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
-import { eq } from "drizzle-orm";
+import { eq, inArray } from "drizzle-orm";
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import {
activityLog,
@@ -87,7 +87,6 @@ describePg("decisionService", () => {
options: [{ id: "yes", label: "Yes", effects: [{ type: "comment_on_issue", targetIssueId, staleness, bodyMarkdown: "hello" }] }],
...extra,
});
-
// Make an existing decision TTL-expired for the next sweep. Creating a
// decision that is already expired is impossible (create rejects a past
// expiresAt), and creating one that expires a few milliseconds later races
diff --git a/server/src/__tests__/dot-runner.test.ts b/server/src/__tests__/dot-runner.test.ts
index 3a73a49bbac..92e41ad4b9a 100644
--- a/server/src/__tests__/dot-runner.test.ts
+++ b/server/src/__tests__/dot-runner.test.ts
@@ -162,7 +162,7 @@ describe("durable Dot Runner integration", () => {
}
it("reapplies the Dot-only migration after the merged gateway schema", async () => {
- const migration = await readFile(new URL("../../../packages/db/src/migrations/0312_broken_sentinels.sql", import.meta.url), "utf8");
+ const migration = await readFile(new URL("../../../packages/db/src/migrations/0317_messy_famine.sql", import.meta.url), "utf8");
for (const statement of migration.split("--> statement-breakpoint")) {
if (statement.trim()) await db.execute(sql.raw(statement));
}
diff --git a/server/src/__tests__/effective-run-config-fingerprints.test.ts b/server/src/__tests__/effective-run-config-fingerprints.test.ts
index 02afa38a4c4..aceed12fd7d 100644
--- a/server/src/__tests__/effective-run-config-fingerprints.test.ts
+++ b/server/src/__tests__/effective-run-config-fingerprints.test.ts
@@ -3,6 +3,7 @@ import {
canonicalizeEffectiveRunConfigCategory,
createEffectiveRunConfigFingerprints,
diffEffectiveRunConfigFingerprints,
+ type EffectiveRunConfigSecretManifestEntry,
} from "../services/effective-run-config-fingerprints.ts";
describe("effective run config fingerprints", () => {
@@ -301,3 +302,29 @@ describe("effective run config fingerprints", () => {
});
});
});
+
+
+describe("configured Paperclip environment freshness", () => {
+ const fingerprint = (env: Record, secretManifest?: EffectiveRunConfigSecretManifestEntry[]) =>
+ createEffectiveRunConfigFingerprints({ session: { env }, secretManifest }).sessionFingerprint;
+
+ it("detects additions, changes, and removals without recording values", () => {
+ const absent = fingerprint({});
+ const first = fingerprint({ PAPERCLIP_PAGE_BUCKET: "first-bucket" });
+ const changed = fingerprint({ PAPERCLIP_PAGE_BUCKET: "second-bucket" });
+ expect(first.fingerprint).not.toBe(absent.fingerprint);
+ expect(changed.fingerprint).not.toBe(first.fingerprint);
+ expect(fingerprint({}).fingerprint).toBe(absent.fingerprint);
+ expect(first.canonicalJson).not.toContain("first-bucket");
+ for (const key of ["PAPERCLIP_RUN_ID", "PAPERCLIP_RUNNER_EXTERNAL_SANDBOX", "PAPERCLIP_NORMALIZED_SESSION_ID"]) {
+ expect(fingerprint({ [key]: "first" }).fingerprint).toBe(fingerprint({ [key]: "second" }).fingerprint);
+ }
+ });
+
+ it("detects custom namespaced secret version changes", () => {
+ const env = { PAPERCLIP_PAGE_AWS_SECRET_ACCESS_KEY: { type: "secret_ref", secretId: "pages-key" } };
+ const manifest = (version: number) => [{ configPath: "env.PAPERCLIP_PAGE_AWS_SECRET_ACCESS_KEY", envKey: "PAPERCLIP_PAGE_AWS_SECRET_ACCESS_KEY", secretId: "pages-key", version }];
+ expect(fingerprint(env, manifest(1)).fingerprint).not.toBe(fingerprint(env, manifest(2)).fingerprint);
+ expect(fingerprint(env, manifest(1)).canonicalJson).toContain("pages-key");
+ });
+});
diff --git a/server/src/__tests__/environment-selection-route-guards.test.ts b/server/src/__tests__/environment-selection-route-guards.test.ts
index ff0b60ee1f9..2df46e77cc5 100644
--- a/server/src/__tests__/environment-selection-route-guards.test.ts
+++ b/server/src/__tests__/environment-selection-route-guards.test.ts
@@ -62,6 +62,12 @@ vi.mock("../services/index.js", () => ({
workspaceOperationService: () => ({}),
accessService: () => ({
canUser: vi.fn(),
+ decide: vi.fn(async (input: { action: string }) => ({
+ allowed: ["project:read", "issue:read"].includes(input.action),
+ action: input.action,
+ reason: ["project:read", "issue:read"].includes(input.action) ? "allow_explicit_grant" : "deny_missing_grant",
+ explanation: ["project:read", "issue:read"].includes(input.action) ? "Allowed by test default." : "Missing permission.",
+ })),
hasPermission: vi.fn(),
}),
agentService: () => ({
diff --git a/server/src/__tests__/environment-sync-out-error.test.ts b/server/src/__tests__/environment-sync-out-error.test.ts
new file mode 100644
index 00000000000..36407d2453d
--- /dev/null
+++ b/server/src/__tests__/environment-sync-out-error.test.ts
@@ -0,0 +1,78 @@
+import { createInterface } from "node:readline";
+import { PassThrough } from "node:stream";
+import { describe, expect, it } from "vitest";
+import {
+ createRequest, definePlugin, isJsonRpcResponse, JsonRpcCallError, parseMessage,
+ PLUGIN_RPC_ERROR_CODES, serializeMessage, startWorkerRpcHost, type JsonRpcResponse,
+} from "@paperclipai/plugin-sdk";
+import {
+ getWorkspaceRestoreDiagnostic, withWorkspaceRestoreDiagnostics, withWorkspaceRestoreStep,
+} from "@paperclipai/adapter-utils/workspace-restore-diagnostics";
+import { preserveEnvironmentSyncOutErrorDiagnostic } from "../services/environment-sync-out-error.js";
+
+async function roundTrip(method: string, error: unknown): Promise<{ error: JsonRpcCallError; wire: string }> {
+ const stdin = new PassThrough();
+ const stdout = new PassThrough();
+ const lines = createInterface({ input: stdout });
+ const worker = startWorkerRpcHost({ stdin, stdout, plugin: definePlugin({
+ async setup() {},
+ async onEnvironmentSyncOut() { throw error; },
+ async onEnvironmentSyncIn() { throw error; },
+ async onEnvironmentExecute() { throw error; },
+ }) });
+ try {
+ const response = new Promise<{ message: JsonRpcResponse; wire: string }>((resolve) => {
+ lines.on("line", (wire) => {
+ const message = parseMessage(wire);
+ if (isJsonRpcResponse(message)) resolve({ message, wire });
+ });
+ });
+ stdin.write(serializeMessage(createRequest(method, {}, "sync-out-test")));
+ const { message, wire } = await response;
+ if (!("error" in message) || !message.error) throw new Error("Expected RPC failure");
+ return { error: new JsonRpcCallError(message.error), wire };
+ } finally {
+ worker.stop(); lines.close(); stdin.destroy(); stdout.destroy();
+ }
+}
+
+describe("environment sync-out restore diagnostics", () => {
+ it("retains bounded evidence through the real worker RPC roundtrip and host restore classifier", async () => {
+ const failure = Object.assign(new Error("Workspace export failed"), {
+ name: "private-provider-class", code: "ETIMEDOUT", statusCode: 504,
+ response: { data: { apiKey: "private-token" } }, path: "/private-path",
+ cause: new Error("private-cause"), data: { credentials: "private-credentials" },
+ });
+ const { error, wire } = await roundTrip("environmentSyncOut", failure);
+ expect(wire).not.toContain("private-");
+ expect(wire.length).toBeLessThan(400);
+ expect(error.code).toBe(PLUGIN_RPC_ERROR_CODES.WORKER_ERROR);
+ expect(error.message).toBe(failure.message);
+ const before = structuredClone({ message: error.message, code: error.code, data: error.data });
+ const logs: string[] = [];
+ await expect(withWorkspaceRestoreDiagnostics("workspace", () => withWorkspaceRestoreStep("workspace_transfer", async () => {
+ throw preserveEnvironmentSyncOutErrorDiagnostic(error);
+ }), async (line) => { logs.push(line); })).rejects.toBe(error);
+ expect(getWorkspaceRestoreDiagnostic(error)).toEqual({ phase: "workspace", step: "workspace_transfer", errorCode: "ETIMEDOUT", httpStatus: 504 });
+ expect(logs).toEqual(['[paperclip] Workspace restore diagnostic: {"phase":"workspace","step":"workspace_transfer","errorCode":"ETIMEDOUT","httpStatus":504}\n']);
+ expect({ message: error.message, code: error.code, data: error.data }).toEqual(before);
+ expect(error).not.toHaveProperty("cause");
+ });
+
+ it.each(["environmentSyncIn", "environmentExecute"])("does not add the sync-out envelope to %s", async (method) => {
+ const { error } = await roundTrip(method, Object.assign(new Error("Provider failure"), { code: "EACCES", status: 503 }));
+ expect(error.data).toBeUndefined();
+ expect(preserveEnvironmentSyncOutErrorDiagnostic(error)).toBe(error);
+ expect(getWorkspaceRestoreDiagnostic(error)).toBeUndefined();
+ });
+
+ it("keeps old workers and unknown diagnostics compatible without changing policy fields", async () => {
+ const { error } = await roundTrip("environmentSyncOut", new Error("daytona_sandbox_not_found"));
+ expect(error.data).toBeUndefined();
+ expect(preserveEnvironmentSyncOutErrorDiagnostic(error)).toBe(error);
+ expect(error.message).toBe("daytona_sandbox_not_found");
+ const original = Object.freeze(new JsonRpcCallError({ code: -32001, message: "Existing worker failure" }));
+ expect(preserveEnvironmentSyncOutErrorDiagnostic(original)).toBe(original);
+ expect(preserveEnvironmentSyncOutErrorDiagnostic(null)).toBeNull();
+ });
+});
diff --git a/server/src/__tests__/execution-workspace-runtime-control-conflict.test.ts b/server/src/__tests__/execution-workspace-runtime-control-conflict.test.ts
index 07976472721..7df50f492ac 100644
--- a/server/src/__tests__/execution-workspace-runtime-control-conflict.test.ts
+++ b/server/src/__tests__/execution-workspace-runtime-control-conflict.test.ts
@@ -1,3 +1,4 @@
+import { sql } from "drizzle-orm";
import { EventEmitter } from "node:events";
import fs from "node:fs";
import os from "node:os";
@@ -7,6 +8,14 @@ import express from "express";
import request from "supertest";
import { beforeEach, describe, expect, it, vi } from "vitest";
+// This unit suite isolates runtime lifecycle behavior; privacy is covered with a
+// real database by privacy-production-review.test.ts.
+vi.mock("../services/authorization.js", async () => ({
+ ...(await vi.importActual("../services/authorization.js")),
+ executionWorkspaceReadSqlCondition: async () => sql`true`,
+ canActorReadExecutionWorkspace: async () => true,
+}));
+
const mockExecutionWorkspaceService = vi.hoisted(() => ({
getById: vi.fn(),
update: vi.fn(),
@@ -157,8 +166,8 @@ function createRegisteredRepairFixture(
prefix: string,
options: { targetInstanceId?: string; withCli?: boolean } = {},
) {
- const workspaceCwd = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
- const baseCwd = fs.mkdtempSync(path.join(os.tmpdir(), `${prefix}base-`));
+ const workspaceCwd = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), prefix)));
+ const baseCwd = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), `${prefix}base-`)));
const configDir = path.join(workspaceCwd, ".paperclip");
const sourceConfigPath = path.join(baseCwd, ".paperclip", "config.json");
const targetInstanceId = options.targetInstanceId ?? "repair-target";
@@ -300,7 +309,7 @@ describe("execution workspace runtime control conflict and failure reconciliatio
.post(`/api/execution-workspaces/${executionWorkspaceId}/runtime-services/stop`)
.send({});
- expect(res.status).toBe(409);
+ expect(res.status, JSON.stringify(res.body)).toBe(409);
expect(res.body.details ?? res.body).toMatchObject({
code: "workspace_runtime_control_in_progress",
activeAction: "start",
@@ -322,7 +331,7 @@ describe("execution workspace runtime control conflict and failure reconciliatio
.post(`/api/execution-workspaces/${executionWorkspaceId}/runtime-services/start`)
.send({});
- expect(res.status).toBe(403);
+ expect(res.status, JSON.stringify(res.body)).toBe(403);
expect(mockWorkspaceOperationService.assertRuntimeControlAvailable).not.toHaveBeenCalled();
});
@@ -367,7 +376,7 @@ describe("execution workspace runtime control conflict and failure reconciliatio
.post(`/api/execution-workspaces/${executionWorkspaceId}/runtime-commands/repair`)
.send({});
- expect(res.status).toBe(422);
+ expect(res.status, JSON.stringify(res.body)).toBe(422);
expect(res.body).toMatchObject({
code: "workspace_repair_precondition_failed",
reason: "seed_manifest_malformed",
@@ -415,7 +424,7 @@ describe("execution workspace runtime control conflict and failure reconciliatio
.post(`/api/execution-workspaces/${executionWorkspaceId}/runtime-commands/repair`)
.send({});
- expect(res.status).toBe(422);
+ expect(res.status, JSON.stringify(res.body)).toBe(422);
expect(res.body).toMatchObject({
code: "workspace_repair_precondition_failed",
reason: "source_registration_invalid",
@@ -450,7 +459,7 @@ describe("execution workspace runtime control conflict and failure reconciliatio
.post(`/api/execution-workspaces/${executionWorkspaceId}/runtime-commands/repair`)
.send({});
- expect(res.status).toBe(422);
+ expect(res.status, JSON.stringify(res.body)).toBe(422);
expect(res.body).toMatchObject({
code: "workspace_repair_precondition_failed",
reason: "source_registration_invalid",
@@ -471,7 +480,7 @@ describe("execution workspace runtime control conflict and failure reconciliatio
.post(`/api/execution-workspaces/${executionWorkspaceId}/runtime-commands/repair`)
.send({});
- expect(res.status).toBe(422);
+ expect(res.status, JSON.stringify(res.body)).toBe(422);
expect(res.body).toMatchObject({
code: "workspace_repair_precondition_failed",
reason: "source_registration_invalid",
@@ -493,7 +502,7 @@ describe("execution workspace runtime control conflict and failure reconciliatio
.post(`/api/execution-workspaces/${executionWorkspaceId}/runtime-commands/repair`)
.send({});
- expect(res.status).toBe(422);
+ expect(res.status, JSON.stringify(res.body)).toBe(422);
expect(res.body).toMatchObject({
code: "workspace_repair_precondition_failed",
reason: "seed_manifest_instance_mismatch",
@@ -573,7 +582,7 @@ describe("execution workspace runtime control conflict and failure reconciliatio
.post(`/api/execution-workspaces/${executionWorkspaceId}/runtime-commands/repair`)
.send({});
- expect(res.status).toBe(200);
+ expect(res.status, JSON.stringify(res.body)).toBe(200);
expect(mockStopRuntimeServicesForExecutionWorkspace).toHaveBeenCalledWith(
expect.objectContaining({ executionWorkspaceId, workspaceCwd: fixture.workspaceCwd }),
);
@@ -604,7 +613,7 @@ describe("execution workspace runtime control conflict and failure reconciliatio
.post(`/api/execution-workspaces/${executionWorkspaceId}/runtime-commands/repair`)
.send({});
- expect(res.status).toBe(200);
+ expect(res.status, JSON.stringify(res.body)).toBe(200);
expect(mockStopRuntimeServicesForExecutionWorkspace).toHaveBeenCalledTimes(1);
expect(mockStartRuntimeServices).not.toHaveBeenCalled();
expect(mockBuildWorkspaceRuntimeDesiredStatePatch).toHaveBeenCalledWith(
@@ -656,7 +665,7 @@ describe("execution workspace runtime control conflict and failure reconciliatio
.post(`/api/execution-workspaces/${executionWorkspaceId}/runtime-commands/repair`)
.send({});
- expect(res.status).toBe(500);
+ expect(res.status, JSON.stringify(res.body)).toBe(500);
expect(res.body).toEqual({ error: "Internal server error" });
expect(progress).toEqual(expect.arrayContaining([
expect.objectContaining({ metadata: { seedFailurePhase: "restore" } }),
diff --git a/server/src/__tests__/execution-workspaces-routes.test.ts b/server/src/__tests__/execution-workspaces-routes.test.ts
index 8f5e1c193b3..650b3351a31 100644
--- a/server/src/__tests__/execution-workspaces-routes.test.ts
+++ b/server/src/__tests__/execution-workspaces-routes.test.ts
@@ -1,9 +1,16 @@
+import { sql } from "drizzle-orm";
import express from "express";
import request from "supertest";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { errorHandler } from "../middleware/index.js";
import { executionWorkspaceRoutes } from "../routes/execution-workspaces.js";
+vi.mock("../services/authorization.js", async (importActual) => ({
+ ...await importActual(),
+ executionWorkspaceReadSqlCondition: async () => sql`true`,
+ canActorReadExecutionWorkspace: async () => true,
+}));
+
const mockExecutionWorkspaceService = vi.hoisted(() => ({
list: vi.fn(),
listOverview: vi.fn(),
@@ -133,6 +140,7 @@ describe("execution workspace routes", () => {
},
]);
expect(mockExecutionWorkspaceService.listSummaries).toHaveBeenCalledWith("company-1", {
+ readCondition: expect.anything(),
projectId: undefined,
projectWorkspaceId: undefined,
issueId: undefined,
@@ -159,7 +167,7 @@ describe("execution workspace routes", () => {
status: ["active", "idle"],
limit: 25,
offset: 10,
- });
+ }, expect.anything());
});
it("rejects invalid workspace overview pagination", async () => {
diff --git a/server/src/__tests__/external-object-routes.test.ts b/server/src/__tests__/external-object-routes.test.ts
index ec69974f6a5..6c36c608aa1 100644
--- a/server/src/__tests__/external-object-routes.test.ts
+++ b/server/src/__tests__/external-object-routes.test.ts
@@ -224,11 +224,13 @@ describe("external object routes", () => {
const app = await createApp(ownerActor());
const summary = await request(app).get(`/api/issues/${issueId}/external-object-summary`);
- expect(summary.status).toBe(403);
+ expect(summary.status).toBe(404);
+ expect(summary.body.error).toBe("Issue not found");
expect(mockExternalObjectsService.getIssueSummary).not.toHaveBeenCalled();
const list = await request(app).get(`/api/issues/${issueId}/external-objects`);
- expect(list.status).toBe(403);
+ expect(list.status).toBe(404);
+ expect(list.body.error).toBe("Issue not found");
expect(mockExternalObjectsService.listForIssue).not.toHaveBeenCalled();
});
diff --git a/server/src/__tests__/file-resources.test.ts b/server/src/__tests__/file-resources.test.ts
index b60ea88fd9e..e1aea92c813 100644
--- a/server/src/__tests__/file-resources.test.ts
+++ b/server/src/__tests__/file-resources.test.ts
@@ -208,6 +208,20 @@ describeEmbeddedPostgres("workspace file resources", () => {
await tempDb?.cleanup();
});
+ it("withholds private task files and private cross-project targets", async () => {
+ const { projectRoot, executionRoot, targetProjectRoot } = await makeWorkspace();
+ const graph = await seedGraph(db, { projectRoot, executionRoot, targetProjectRoot });
+ await fs.writeFile(path.join(projectRoot, "secret.txt"), "PRIVATE_FILE", "utf8");
+ await fs.writeFile(path.join(targetProjectRoot, "secret.txt"), "PRIVATE_TARGET", "utf8");
+ const app = createApp(db, { type: "board", userId: "board-user", companyIds: [graph.companyId], source: "session", isInstanceAdmin: false });
+ await db.update(issues).set({ visibility: "private", responsibleUserId: "owner" }).where(eq(issues.id, graph.issueId));
+ await request(app).get(`/api/issues/${graph.issueId}/file-resources/content`).query({ workspace: "project", path: "secret.txt" }).expect(404);
+ await db.update(issues).set({ visibility: "open" }).where(eq(issues.id, graph.issueId));
+ await request(app).get(`/api/issues/${graph.issueId}/file-resources/content`).query({ workspace: "project", path: "secret.txt" }).expect(200);
+ await db.update(projects).set({ visibility: "private" }).where(eq(projects.id, graph.targetProjectId));
+ await request(app).get(`/api/issues/${graph.issueId}/file-resources/content`).query({ projectId: graph.targetProjectId, workspaceId: graph.targetProjectWorkspaceId, path: "secret.txt" }).expect(404);
+ });
+
it("resolves and reads a project file without exposing absolute paths", async () => {
const { root, projectRoot, executionRoot } = await makeWorkspace();
const graph = await seedGraph(db, { projectRoot, executionRoot });
@@ -981,7 +995,7 @@ describeEmbeddedPostgres("workspace file resources", () => {
expect(linkedSecret.status).toBe(403);
});
- it("rejects denied paths, non-regular files, oversized text, binary, and HTML while previewing SVG as source", async () => {
+ it("rejects denied paths, non-regular files, oversized text and binary while returning HTML and SVG as text", async () => {
const { projectRoot, executionRoot } = await makeWorkspace();
const graph = await seedGraph(db, { projectRoot, executionRoot });
await fs.mkdir(path.join(projectRoot, ".git"), { recursive: true });
@@ -1000,7 +1014,7 @@ describeEmbeddedPostgres("workspace file resources", () => {
isInstanceAdmin: false,
});
- for (const filePath of [".git/config", "folder", "big.txt", "blob.bin", "index.html"]) {
+ for (const filePath of [".git/config", "folder", "big.txt", "blob.bin"]) {
const res = await request(app)
.get(`/api/issues/${graph.issueId}/file-resources/content`)
.query({ workspace: "project", path: filePath });
@@ -1012,6 +1026,19 @@ describeEmbeddedPostgres("workspace file resources", () => {
expect(svg.status).toBe(200);
expect(svg.body.resource.previewKind).toBe("text");
expect(svg.body.content.data).toContain("