Repository navigation
Releases
v2.261115.8
✨ Highlights
- omni-channels: Attach Telegram through a wizard host (
678e971) - omni-channels: Check a code with an outside service and relay its reply (
3c30f5a) - omni-channels: Admit a sender by a single-use code from a staff code list (
ff6e1f1) - doctor: Flag an instance that an Omni agent and an attached app may both answer (
2f63e76) - connector-github: Receive GitHub issue and pull-request events (
fcbe711) - omni-channels: Draw the phone pane as a full chat view with a message bar (
f6d1bc1)
💥 Breaking changes
- core: Remove OpenClaw integration (
39dc234) - auth: Reconcile existing agent bindings before dispatch — Startup revokes active system:auto-provision agent keys with NULL or empty instance grants once. Bound instances automatically get fresh narrow keys; old widened secrets no longer work. Route-only agents may stop answering: startup warns once per revoked key without a binding, naming the agent. Fix by binding it to an instance with
omni instances update <instance-id> --agent <agent-id>. Detect bindings without an explicit scoped system key (no-tenant dispatch retains its legacy name lookup) withSELECT i.id, i.agent_id, a.name FROM instances i JOIN agents a ON a.id = i.agent_id WHERE NOT EXISTS (SELECT 1 FROM api_keys k WHERE k.status = 'active' AND k.created_by = 'system:auto-provision' AND (k.name = 'agent:' || a.name OR (i.tenant_id IS NOT NULL AND k.name = 'agent:' || i.tenant_id::text || ':' || a.name)) AND i.id = ANY(k.instance_ids)). Fix by unbinding then rebinding the saved agent:omni instances update <instance-id> --agent null, thenomni instances update <instance-id> --agent <saved-agent-id>. Full upgrade note: https://github.com/automagik-dev/omni/blob/dev/docs/deployment/agent-key-scope-upgrade.md (fd41377)
🗄️ Database migrations
This release adds 19 database migrations. Migrations are additive and idempotent
per the repository migration contract, and the API applies them automatically at boot
(migrateDb()) — no manual upgrade step is required. See packages/db/drizzle/ for details.
0080_event_journal_ready.sql— Opt-in journal readiness gate for durable event consumers (Vox fluid-chat proposal, item 4).0081_instances_outbound_pacing.sql— Opt-in immediate outbound pacing per instance (Vox fluid-chat PR-B).0082_durable_consumers_instance_scope.sql— Opt-in instance scoping + ownership for durable event consumers.0083_event_access_decision.sql— Opt-in ingest access verdict on the journal + access-filtered durable consumers.0084_instances_audio_transcription.sql— Per-instance opt-in switch for server-side transcription of inbound audio.0085_instances_inbound_reply_context.sql— Per-instance opt-in for typed inbound reply context (PR #1297).0086_human_login.sql— Human login on Better Auth (wish: omni-labs-distribution).0087_login_hardening.sql— Human login hardening (wish: omni-labs-distribution; review of the Better Auth login).0088_api_key_parent.sql— API key lineage (wish: omni-chat-threads, Group 1).0089_connectors.sql— Connectors (wish: connectors-first-slice-clickup, Group 1).0090_connector_event_ownership.sql— Connector event ownership (wish: connectors-first-slice-clickup, finding F3).0091_durable_consumers_tenant_scope.sql— Durable consumer tenant ownership (paired-agents R2-3, O11). Stamp new consumers from the authenticated caller, independent of instance restrictions and OMNI_DB_ENFORCEMENT. Existing rows deliberately remain NULL: their tenant cannot be established safely, so tenant keys must not see them. Legacy credentials retain their existing access rules. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0092_connector_ingress.sql— Connector-keyed ingress schema and typed journal ownership. Wish: gitlab-sdlc-connector, Group 2. Existing ClickUp bindings keep their route and secret. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0093_dead_letter_tenant_scope.sql— Dead-letter ownership and enforced-RLS retries (#1467). Derive ownership from the authenticated transaction, or a persisted source event for off-request writers. Never accept NEW.tenant_id or payload claims. Existing NULL rows remain unowned and hidden under enforcement. Their ownership repair belongs to the G6 tenancy backfill, not this migration. no-schema-change: replaces the frozen 0041 ownership trigger body only. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0094_paired_agent_consumers.sql— Paired-agents slice 2: provenance, agent-owned consumers and source grants. Wish: paired-agents-slice-2; DESIGN row 5, R13-3 (no grant writer in this slice). Hand-written following the 0043/0044/0052 precedent (additive, idempotent). Large-journal prerequisite: run online preparation from the exact candidate checkout before upgrading, per docs/deployment/paired-agent-journal-indexes.md. The estimate-based boot preflight backs up this operator-held prerequisite.0095_webhook_event_ownership.sql— Generic webhook event ownership (follow-up to #1531 / #1476). An owned source has no chat/instance parent; derive its journal owner from the persisted source identified by server-stamped metadata.webhookSourceId. Payload tenant claims and source names are never ownership evidence. Missing, malformed, unowned or RLS-hidden sources derive no owner; existing RLS rejects the insert under enforcement. Preserve every 0092 parent/connector check.0096_zenvia_channel.sql— Zenvia channel — per-instance configuration.0097_whatsapp_business_provider.sql— WhatsApp Business (Meta Cloud API) — Meta-compatible provider settings.0098_clear_telegram_pictures.sql— Telegram pictures could expose the channel credential; clear existing pictures (#1747). no-schema-change: Data-only cleanup of previously saved pictures. Hand-written following the 0043/0044/0052 precedent (idempotent).
🚀 Features
- api: keep a metadata object on access rules (
7374135) - api: let connect set or rotate the Zenvia webhook verify token (
43d2602) - api: add events:consume so a paired agent host runs its own consumers (
54d4093) - api: add the omni-agent-host device client, read events only (#1461)
- api: expose paired-agent status and rollback guidance (
12dd981) - api: deliver agent-owned consumers through active grants (
d99dd3f) - api: enforce agent-owned consumer access (
4137ef3) - api: stamp trusted journal producer provenance ([
192eb47](https://github.com/automagik-si/omni/co...
v2.261115.6
✨ Highlights
- omni-channels: Attach Telegram through a wizard host (
678e971) - omni-channels: Check a code with an outside service and relay its reply (
3c30f5a) - omni-channels: Admit a sender by a single-use code from a staff code list (
ff6e1f1) - doctor: Flag an instance that an Omni agent and an attached app may both answer (
2f63e76) - connector-github: Receive GitHub issue and pull-request events (
fcbe711) - omni-channels: Draw the phone pane as a full chat view with a message bar (
f6d1bc1)
💥 Breaking changes
- core: Remove OpenClaw integration (
39dc234) - auth: Reconcile existing agent bindings before dispatch — Startup revokes active system:auto-provision agent keys with NULL or empty instance grants once. Bound instances automatically get fresh narrow keys; old widened secrets no longer work. Route-only agents may stop answering: startup warns once per revoked key without a binding, naming the agent. Fix by binding it to an instance with
omni instances update <instance-id> --agent <agent-id>. Detect bindings without an explicit scoped system key (no-tenant dispatch retains its legacy name lookup) withSELECT i.id, i.agent_id, a.name FROM instances i JOIN agents a ON a.id = i.agent_id WHERE NOT EXISTS (SELECT 1 FROM api_keys k WHERE k.status = 'active' AND k.created_by = 'system:auto-provision' AND (k.name = 'agent:' || a.name OR (i.tenant_id IS NOT NULL AND k.name = 'agent:' || i.tenant_id::text || ':' || a.name)) AND i.id = ANY(k.instance_ids)). Fix by unbinding then rebinding the saved agent:omni instances update <instance-id> --agent null, thenomni instances update <instance-id> --agent <saved-agent-id>. Full upgrade note: https://github.com/automagik-dev/omni/blob/dev/docs/deployment/agent-key-scope-upgrade.md (fd41377)
🗄️ Database migrations
This release adds 19 database migrations. Migrations are additive and idempotent
per the repository migration contract, and the API applies them automatically at boot
(migrateDb()) — no manual upgrade step is required. See packages/db/drizzle/ for details.
0080_event_journal_ready.sql— Opt-in journal readiness gate for durable event consumers (Vox fluid-chat proposal, item 4).0081_instances_outbound_pacing.sql— Opt-in immediate outbound pacing per instance (Vox fluid-chat PR-B).0082_durable_consumers_instance_scope.sql— Opt-in instance scoping + ownership for durable event consumers.0083_event_access_decision.sql— Opt-in ingest access verdict on the journal + access-filtered durable consumers.0084_instances_audio_transcription.sql— Per-instance opt-in switch for server-side transcription of inbound audio.0085_instances_inbound_reply_context.sql— Per-instance opt-in for typed inbound reply context (PR #1297).0086_human_login.sql— Human login on Better Auth (wish: omni-labs-distribution).0087_login_hardening.sql— Human login hardening (wish: omni-labs-distribution; review of the Better Auth login).0088_api_key_parent.sql— API key lineage (wish: omni-chat-threads, Group 1).0089_connectors.sql— Connectors (wish: connectors-first-slice-clickup, Group 1).0090_connector_event_ownership.sql— Connector event ownership (wish: connectors-first-slice-clickup, finding F3).0091_durable_consumers_tenant_scope.sql— Durable consumer tenant ownership (paired-agents R2-3, O11). Stamp new consumers from the authenticated caller, independent of instance restrictions and OMNI_DB_ENFORCEMENT. Existing rows deliberately remain NULL: their tenant cannot be established safely, so tenant keys must not see them. Legacy credentials retain their existing access rules. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0092_connector_ingress.sql— Connector-keyed ingress schema and typed journal ownership. Wish: gitlab-sdlc-connector, Group 2. Existing ClickUp bindings keep their route and secret. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0093_dead_letter_tenant_scope.sql— Dead-letter ownership and enforced-RLS retries (#1467). Derive ownership from the authenticated transaction, or a persisted source event for off-request writers. Never accept NEW.tenant_id or payload claims. Existing NULL rows remain unowned and hidden under enforcement. Their ownership repair belongs to the G6 tenancy backfill, not this migration. no-schema-change: replaces the frozen 0041 ownership trigger body only. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0094_paired_agent_consumers.sql— Paired-agents slice 2: provenance, agent-owned consumers and source grants. Wish: paired-agents-slice-2; DESIGN row 5, R13-3 (no grant writer in this slice). Hand-written following the 0043/0044/0052 precedent (additive, idempotent). Large-journal prerequisite: run online preparation from the exact candidate checkout before upgrading, per docs/deployment/paired-agent-journal-indexes.md. The estimate-based boot preflight backs up this operator-held prerequisite.0095_webhook_event_ownership.sql— Generic webhook event ownership (follow-up to #1531 / #1476). An owned source has no chat/instance parent; derive its journal owner from the persisted source identified by server-stamped metadata.webhookSourceId. Payload tenant claims and source names are never ownership evidence. Missing, malformed, unowned or RLS-hidden sources derive no owner; existing RLS rejects the insert under enforcement. Preserve every 0092 parent/connector check.0096_zenvia_channel.sql— Zenvia channel — per-instance configuration.0097_whatsapp_business_provider.sql— WhatsApp Business (Meta Cloud API) — Meta-compatible provider settings.0098_clear_telegram_pictures.sql— Telegram pictures could expose the channel credential; clear existing pictures (#1747). no-schema-change: Data-only cleanup of previously saved pictures. Hand-written following the 0043/0044/0052 precedent (idempotent).
🚀 Features
- api: keep a metadata object on access rules (
7374135) - api: let connect set or rotate the Zenvia webhook verify token (
43d2602) - api: add events:consume so a paired agent host runs its own consumers (
54d4093) - api: add the omni-agent-host device client, read events only (#1461)
- api: expose paired-agent status and rollback guidance (
12dd981) - api: deliver agent-owned consumers through active grants (
d99dd3f) - api: enforce agent-owned consumer access (
4137ef3) - api: stamp trusted journal producer provenance ([
192eb47](https://github.com/automagik-si/omni/co...
v2.261115.4
✨ Highlights
- doctor: Flag an instance that an Omni agent and an attached app may both answer (
2f63e76) - omni-channels: Draw the phone pane as a full chat view with a message bar (
f6d1bc1) - omni-channels: Staff send their own message from the phone pane (
35182f9) - omni-channels: Reply once to a sender no allow rule lets in (
c0abcc3) - omni-channels: Tell the team when an answer child's person needs someone (
74e9d15) - omni-channels: Tell a bound child the prefix of its own person's tools (
80b1fad)
💥 Breaking changes
- core: Remove OpenClaw integration (
39dc234) - auth: Reconcile existing agent bindings before dispatch — Startup revokes active system:auto-provision agent keys with NULL or empty instance grants once. Bound instances automatically get fresh narrow keys; old widened secrets no longer work. Route-only agents may stop answering: startup warns once per revoked key without a binding, naming the agent. Fix by binding it to an instance with
omni instances update <instance-id> --agent <agent-id>. Detect bindings without an explicit scoped system key (no-tenant dispatch retains its legacy name lookup) withSELECT i.id, i.agent_id, a.name FROM instances i JOIN agents a ON a.id = i.agent_id WHERE NOT EXISTS (SELECT 1 FROM api_keys k WHERE k.status = 'active' AND k.created_by = 'system:auto-provision' AND (k.name = 'agent:' || a.name OR (i.tenant_id IS NOT NULL AND k.name = 'agent:' || i.tenant_id::text || ':' || a.name)) AND i.id = ANY(k.instance_ids)). Fix by unbinding then rebinding the saved agent:omni instances update <instance-id> --agent null, thenomni instances update <instance-id> --agent <saved-agent-id>. Full upgrade note: https://github.com/automagik-dev/omni/blob/dev/docs/deployment/agent-key-scope-upgrade.md (fd41377)
🗄️ Database migrations
This release adds 18 database migrations. Migrations are additive and idempotent
per the repository migration contract, and the API applies them automatically at boot
(migrateDb()) — no manual upgrade step is required. See packages/db/drizzle/ for details.
0080_event_journal_ready.sql— Opt-in journal readiness gate for durable event consumers (Vox fluid-chat proposal, item 4).0081_instances_outbound_pacing.sql— Opt-in immediate outbound pacing per instance (Vox fluid-chat PR-B).0082_durable_consumers_instance_scope.sql— Opt-in instance scoping + ownership for durable event consumers.0083_event_access_decision.sql— Opt-in ingest access verdict on the journal + access-filtered durable consumers.0084_instances_audio_transcription.sql— Per-instance opt-in switch for server-side transcription of inbound audio.0085_instances_inbound_reply_context.sql— Per-instance opt-in for typed inbound reply context (PR #1297).0086_human_login.sql— Human login on Better Auth (wish: omni-labs-distribution).0087_login_hardening.sql— Human login hardening (wish: omni-labs-distribution; review of the Better Auth login).0088_api_key_parent.sql— API key lineage (wish: omni-chat-threads, Group 1).0089_connectors.sql— Connectors (wish: connectors-first-slice-clickup, Group 1).0090_connector_event_ownership.sql— Connector event ownership (wish: connectors-first-slice-clickup, finding F3).0091_durable_consumers_tenant_scope.sql— Durable consumer tenant ownership (paired-agents R2-3, O11). Stamp new consumers from the authenticated caller, independent of instance restrictions and OMNI_DB_ENFORCEMENT. Existing rows deliberately remain NULL: their tenant cannot be established safely, so tenant keys must not see them. Legacy credentials retain their existing access rules. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0092_connector_ingress.sql— Connector-keyed ingress schema and typed journal ownership. Wish: gitlab-sdlc-connector, Group 2. Existing ClickUp bindings keep their route and secret. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0093_dead_letter_tenant_scope.sql— Dead-letter ownership and enforced-RLS retries (#1467). Derive ownership from the authenticated transaction, or a persisted source event for off-request writers. Never accept NEW.tenant_id or payload claims. Existing NULL rows remain unowned and hidden under enforcement. Their ownership repair belongs to the G6 tenancy backfill, not this migration. no-schema-change: replaces the frozen 0041 ownership trigger body only. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0094_paired_agent_consumers.sql— Paired-agents slice 2: provenance, agent-owned consumers and source grants. Wish: paired-agents-slice-2; DESIGN row 5, R13-3 (no grant writer in this slice). Hand-written following the 0043/0044/0052 precedent (additive, idempotent). Large-journal prerequisite: run online preparation from the exact candidate checkout before upgrading, per docs/deployment/paired-agent-journal-indexes.md. The estimate-based boot preflight backs up this operator-held prerequisite.0095_webhook_event_ownership.sql— Generic webhook event ownership (follow-up to #1531 / #1476). An owned source has no chat/instance parent; derive its journal owner from the persisted source identified by server-stamped metadata.webhookSourceId. Payload tenant claims and source names are never ownership evidence. Missing, malformed, unowned or RLS-hidden sources derive no owner; existing RLS rejects the insert under enforcement. Preserve every 0092 parent/connector check.0096_zenvia_channel.sql— Zenvia channel — per-instance configuration.0097_whatsapp_business_provider.sql— WhatsApp Business (Meta Cloud API) — Meta-compatible provider settings.
🚀 Features
- api: keep a metadata object on access rules (
7374135) - api: let connect set or rotate the Zenvia webhook verify token (
43d2602) - api: add events:consume so a paired agent host runs its own consumers (
54d4093) - api: add the omni-agent-host device client, read events only (#1461)
- api: expose paired-agent status and rollback guidance (
12dd981) - api: deliver agent-owned consumers through active grants (
d99dd3f) - api: enforce agent-owned consumer access (
4137ef3) - api: stamp trusted journal producer provenance (
192eb47) - api: accept per-connector webhook deliveries (
ca95762) - api: manage connector ingress subscriptions and hook secrets ([
60c5821](60c5821...
v2.261115.2
✨ Highlights
- omni-channels: Draw the phone pane as a full chat view with a message bar (
f6d1bc1) - omni-channels: Staff send their own message from the phone pane (
35182f9) - omni-channels: Reply once to a sender no allow rule lets in (
c0abcc3) - omni-channels: Tell the team when an answer child's person needs someone (
74e9d15) - omni-channels: Tell a bound child the prefix of its own person's tools (
80b1fad) - omni-channels: Each person's answer child carries that person's own context and capability (
f6f3652)
💥 Breaking changes
- core: Remove OpenClaw integration (
39dc234) - auth: Reconcile existing agent bindings before dispatch — Startup revokes active system:auto-provision agent keys with NULL or empty instance grants once. Bound instances automatically get fresh narrow keys; old widened secrets no longer work. Route-only agents may stop answering: startup warns once per revoked key without a binding, naming the agent. Fix by binding it to an instance with
omni instances update <instance-id> --agent <agent-id>. Detect bindings without an explicit scoped system key (no-tenant dispatch retains its legacy name lookup) withSELECT i.id, i.agent_id, a.name FROM instances i JOIN agents a ON a.id = i.agent_id WHERE NOT EXISTS (SELECT 1 FROM api_keys k WHERE k.status = 'active' AND k.created_by = 'system:auto-provision' AND (k.name = 'agent:' || a.name OR (i.tenant_id IS NOT NULL AND k.name = 'agent:' || i.tenant_id::text || ':' || a.name)) AND i.id = ANY(k.instance_ids)). Fix by unbinding then rebinding the saved agent:omni instances update <instance-id> --agent null, thenomni instances update <instance-id> --agent <saved-agent-id>. Full upgrade note: https://github.com/automagik-dev/omni/blob/dev/docs/deployment/agent-key-scope-upgrade.md (fd41377)
🗄️ Database migrations
This release adds 18 database migrations. Migrations are additive and idempotent
per the repository migration contract, and the API applies them automatically at boot
(migrateDb()) — no manual upgrade step is required. See packages/db/drizzle/ for details.
0080_event_journal_ready.sql— Opt-in journal readiness gate for durable event consumers (Vox fluid-chat proposal, item 4).0081_instances_outbound_pacing.sql— Opt-in immediate outbound pacing per instance (Vox fluid-chat PR-B).0082_durable_consumers_instance_scope.sql— Opt-in instance scoping + ownership for durable event consumers.0083_event_access_decision.sql— Opt-in ingest access verdict on the journal + access-filtered durable consumers.0084_instances_audio_transcription.sql— Per-instance opt-in switch for server-side transcription of inbound audio.0085_instances_inbound_reply_context.sql— Per-instance opt-in for typed inbound reply context (PR #1297).0086_human_login.sql— Human login on Better Auth (wish: omni-labs-distribution).0087_login_hardening.sql— Human login hardening (wish: omni-labs-distribution; review of the Better Auth login).0088_api_key_parent.sql— API key lineage (wish: omni-chat-threads, Group 1).0089_connectors.sql— Connectors (wish: connectors-first-slice-clickup, Group 1).0090_connector_event_ownership.sql— Connector event ownership (wish: connectors-first-slice-clickup, finding F3).0091_durable_consumers_tenant_scope.sql— Durable consumer tenant ownership (paired-agents R2-3, O11). Stamp new consumers from the authenticated caller, independent of instance restrictions and OMNI_DB_ENFORCEMENT. Existing rows deliberately remain NULL: their tenant cannot be established safely, so tenant keys must not see them. Legacy credentials retain their existing access rules. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0092_connector_ingress.sql— Connector-keyed ingress schema and typed journal ownership. Wish: gitlab-sdlc-connector, Group 2. Existing ClickUp bindings keep their route and secret. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0093_dead_letter_tenant_scope.sql— Dead-letter ownership and enforced-RLS retries (#1467). Derive ownership from the authenticated transaction, or a persisted source event for off-request writers. Never accept NEW.tenant_id or payload claims. Existing NULL rows remain unowned and hidden under enforcement. Their ownership repair belongs to the G6 tenancy backfill, not this migration. no-schema-change: replaces the frozen 0041 ownership trigger body only. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0094_paired_agent_consumers.sql— Paired-agents slice 2: provenance, agent-owned consumers and source grants. Wish: paired-agents-slice-2; DESIGN row 5, R13-3 (no grant writer in this slice). Hand-written following the 0043/0044/0052 precedent (additive, idempotent). Large-journal prerequisite: run online preparation from the exact candidate checkout before upgrading, per docs/deployment/paired-agent-journal-indexes.md. The estimate-based boot preflight backs up this operator-held prerequisite.0095_webhook_event_ownership.sql— Generic webhook event ownership (follow-up to #1531 / #1476). An owned source has no chat/instance parent; derive its journal owner from the persisted source identified by server-stamped metadata.webhookSourceId. Payload tenant claims and source names are never ownership evidence. Missing, malformed, unowned or RLS-hidden sources derive no owner; existing RLS rejects the insert under enforcement. Preserve every 0092 parent/connector check.0096_zenvia_channel.sql— Zenvia channel — per-instance configuration.0097_whatsapp_business_provider.sql— WhatsApp Business (Meta Cloud API) — Meta-compatible provider settings.
🚀 Features
- api: keep a metadata object on access rules (
7374135) - api: let connect set or rotate the Zenvia webhook verify token (
43d2602) - api: add events:consume so a paired agent host runs its own consumers (
54d4093) - api: add the omni-agent-host device client, read events only (#1461)
- api: expose paired-agent status and rollback guidance (
12dd981) - api: deliver agent-owned consumers through active grants (
d99dd3f) - api: enforce agent-owned consumer access (
4137ef3) - api: stamp trusted journal producer provenance (
192eb47) - api: accept per-connector webhook deliveries (
ca95762) - api: manage connector ingress subscriptions and hook secrets ([
60c5821](60c5821e6e56cffb0d43ccda1f02a...
v2.261114.6
✨ Highlights
- omni-channels: Draw the phone pane as a full chat view with a message bar (
f6d1bc1) - omni-channels: Staff send their own message from the phone pane (
35182f9) - omni-channels: Reply once to a sender no allow rule lets in (
c0abcc3) - omni-channels: Tell the team when an answer child's person needs someone (
74e9d15) - omni-channels: Tell a bound child the prefix of its own person's tools (
80b1fad) - omni-channels: Each person's answer child carries that person's own context and capability (
f6f3652)
💥 Breaking changes
- core: Remove OpenClaw integration (
39dc234) - auth: Reconcile existing agent bindings before dispatch — Startup revokes active system:auto-provision agent keys with NULL or empty instance grants once. Bound instances automatically get fresh narrow keys; old widened secrets no longer work. Route-only agents may stop answering: startup warns once per revoked key without a binding, naming the agent. Fix by binding it to an instance with
omni instances update <instance-id> --agent <agent-id>. Detect bindings without an explicit scoped system key (no-tenant dispatch retains its legacy name lookup) withSELECT i.id, i.agent_id, a.name FROM instances i JOIN agents a ON a.id = i.agent_id WHERE NOT EXISTS (SELECT 1 FROM api_keys k WHERE k.status = 'active' AND k.created_by = 'system:auto-provision' AND (k.name = 'agent:' || a.name OR (i.tenant_id IS NOT NULL AND k.name = 'agent:' || i.tenant_id::text || ':' || a.name)) AND i.id = ANY(k.instance_ids)). Fix by unbinding then rebinding the saved agent:omni instances update <instance-id> --agent null, thenomni instances update <instance-id> --agent <saved-agent-id>. Full upgrade note: https://github.com/automagik-dev/omni/blob/dev/docs/deployment/agent-key-scope-upgrade.md (fd41377)
🗄️ Database migrations
This release adds 18 database migrations. Migrations are additive and idempotent
per the repository migration contract, and the API applies them automatically at boot
(migrateDb()) — no manual upgrade step is required. See packages/db/drizzle/ for details.
0080_event_journal_ready.sql— Opt-in journal readiness gate for durable event consumers (Vox fluid-chat proposal, item 4).0081_instances_outbound_pacing.sql— Opt-in immediate outbound pacing per instance (Vox fluid-chat PR-B).0082_durable_consumers_instance_scope.sql— Opt-in instance scoping + ownership for durable event consumers.0083_event_access_decision.sql— Opt-in ingest access verdict on the journal + access-filtered durable consumers.0084_instances_audio_transcription.sql— Per-instance opt-in switch for server-side transcription of inbound audio.0085_instances_inbound_reply_context.sql— Per-instance opt-in for typed inbound reply context (PR #1297).0086_human_login.sql— Human login on Better Auth (wish: omni-labs-distribution).0087_login_hardening.sql— Human login hardening (wish: omni-labs-distribution; review of the Better Auth login).0088_api_key_parent.sql— API key lineage (wish: omni-chat-threads, Group 1).0089_connectors.sql— Connectors (wish: connectors-first-slice-clickup, Group 1).0090_connector_event_ownership.sql— Connector event ownership (wish: connectors-first-slice-clickup, finding F3).0091_durable_consumers_tenant_scope.sql— Durable consumer tenant ownership (paired-agents R2-3, O11). Stamp new consumers from the authenticated caller, independent of instance restrictions and OMNI_DB_ENFORCEMENT. Existing rows deliberately remain NULL: their tenant cannot be established safely, so tenant keys must not see them. Legacy credentials retain their existing access rules. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0092_connector_ingress.sql— Connector-keyed ingress schema and typed journal ownership. Wish: gitlab-sdlc-connector, Group 2. Existing ClickUp bindings keep their route and secret. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0093_dead_letter_tenant_scope.sql— Dead-letter ownership and enforced-RLS retries (#1467). Derive ownership from the authenticated transaction, or a persisted source event for off-request writers. Never accept NEW.tenant_id or payload claims. Existing NULL rows remain unowned and hidden under enforcement. Their ownership repair belongs to the G6 tenancy backfill, not this migration. no-schema-change: replaces the frozen 0041 ownership trigger body only. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0094_paired_agent_consumers.sql— Paired-agents slice 2: provenance, agent-owned consumers and source grants. Wish: paired-agents-slice-2; DESIGN row 5, R13-3 (no grant writer in this slice). Hand-written following the 0043/0044/0052 precedent (additive, idempotent). Large-journal prerequisite: run online preparation from the exact candidate checkout before upgrading, per docs/deployment/paired-agent-journal-indexes.md. The estimate-based boot preflight backs up this operator-held prerequisite.0095_webhook_event_ownership.sql— Generic webhook event ownership (follow-up to #1531 / #1476). An owned source has no chat/instance parent; derive its journal owner from the persisted source identified by server-stamped metadata.webhookSourceId. Payload tenant claims and source names are never ownership evidence. Missing, malformed, unowned or RLS-hidden sources derive no owner; existing RLS rejects the insert under enforcement. Preserve every 0092 parent/connector check.0096_zenvia_channel.sql— Zenvia channel — per-instance configuration.0097_whatsapp_business_provider.sql— WhatsApp Business (Meta Cloud API) — Meta-compatible provider settings.
🚀 Features
- api: keep a metadata object on access rules (
7374135) - api: let connect set or rotate the Zenvia webhook verify token (
43d2602) - api: add events:consume so a paired agent host runs its own consumers (
54d4093) - api: add the omni-agent-host device client, read events only (#1461)
- api: expose paired-agent status and rollback guidance (
12dd981) - api: deliver agent-owned consumers through active grants (
d99dd3f) - api: enforce agent-owned consumer access (
4137ef3) - api: stamp trusted journal producer provenance (
192eb47) - api: accept per-connector webhook deliveries (
ca95762) - api: manage connector ingress subscriptions and hook secrets ([
60c5821](60c5821e6e56cffb0d43ccda1f02a...
v2.261114.4
✨ Highlights
- omni-channels: Draw the phone pane as a full chat view with a message bar (
f6d1bc1) - omni-channels: Staff send their own message from the phone pane (
35182f9) - omni-channels: Tell the team when an answer child's person needs someone (
74e9d15) - omni-channels: Tell a bound child the prefix of its own person's tools (
80b1fad) - omni-channels: Each person's answer child carries that person's own context and capability (
f6f3652) - api: Keep a metadata object on access rules (
7374135)
💥 Breaking changes
- core: Remove OpenClaw integration (
39dc234) - auth: Reconcile existing agent bindings before dispatch — Startup revokes active system:auto-provision agent keys with NULL or empty instance grants once. Bound instances automatically get fresh narrow keys; old widened secrets no longer work. Route-only agents may stop answering: startup warns once per revoked key without a binding, naming the agent. Fix by binding it to an instance with
omni instances update <instance-id> --agent <agent-id>. Detect bindings without an explicit scoped system key (no-tenant dispatch retains its legacy name lookup) withSELECT i.id, i.agent_id, a.name FROM instances i JOIN agents a ON a.id = i.agent_id WHERE NOT EXISTS (SELECT 1 FROM api_keys k WHERE k.status = 'active' AND k.created_by = 'system:auto-provision' AND (k.name = 'agent:' || a.name OR (i.tenant_id IS NOT NULL AND k.name = 'agent:' || i.tenant_id::text || ':' || a.name)) AND i.id = ANY(k.instance_ids)). Fix by unbinding then rebinding the saved agent:omni instances update <instance-id> --agent null, thenomni instances update <instance-id> --agent <saved-agent-id>. Full upgrade note: https://github.com/automagik-dev/omni/blob/dev/docs/deployment/agent-key-scope-upgrade.md (fd41377)
🗄️ Database migrations
This release adds 18 database migrations. Migrations are additive and idempotent
per the repository migration contract, and the API applies them automatically at boot
(migrateDb()) — no manual upgrade step is required. See packages/db/drizzle/ for details.
0080_event_journal_ready.sql— Opt-in journal readiness gate for durable event consumers (Vox fluid-chat proposal, item 4).0081_instances_outbound_pacing.sql— Opt-in immediate outbound pacing per instance (Vox fluid-chat PR-B).0082_durable_consumers_instance_scope.sql— Opt-in instance scoping + ownership for durable event consumers.0083_event_access_decision.sql— Opt-in ingest access verdict on the journal + access-filtered durable consumers.0084_instances_audio_transcription.sql— Per-instance opt-in switch for server-side transcription of inbound audio.0085_instances_inbound_reply_context.sql— Per-instance opt-in for typed inbound reply context (PR #1297).0086_human_login.sql— Human login on Better Auth (wish: omni-labs-distribution).0087_login_hardening.sql— Human login hardening (wish: omni-labs-distribution; review of the Better Auth login).0088_api_key_parent.sql— API key lineage (wish: omni-chat-threads, Group 1).0089_connectors.sql— Connectors (wish: connectors-first-slice-clickup, Group 1).0090_connector_event_ownership.sql— Connector event ownership (wish: connectors-first-slice-clickup, finding F3).0091_durable_consumers_tenant_scope.sql— Durable consumer tenant ownership (paired-agents R2-3, O11). Stamp new consumers from the authenticated caller, independent of instance restrictions and OMNI_DB_ENFORCEMENT. Existing rows deliberately remain NULL: their tenant cannot be established safely, so tenant keys must not see them. Legacy credentials retain their existing access rules. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0092_connector_ingress.sql— Connector-keyed ingress schema and typed journal ownership. Wish: gitlab-sdlc-connector, Group 2. Existing ClickUp bindings keep their route and secret. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0093_dead_letter_tenant_scope.sql— Dead-letter ownership and enforced-RLS retries (#1467). Derive ownership from the authenticated transaction, or a persisted source event for off-request writers. Never accept NEW.tenant_id or payload claims. Existing NULL rows remain unowned and hidden under enforcement. Their ownership repair belongs to the G6 tenancy backfill, not this migration. no-schema-change: replaces the frozen 0041 ownership trigger body only. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0094_paired_agent_consumers.sql— Paired-agents slice 2: provenance, agent-owned consumers and source grants. Wish: paired-agents-slice-2; DESIGN row 5, R13-3 (no grant writer in this slice). Hand-written following the 0043/0044/0052 precedent (additive, idempotent). Large-journal prerequisite: run online preparation from the exact candidate checkout before upgrading, per docs/deployment/paired-agent-journal-indexes.md. The estimate-based boot preflight backs up this operator-held prerequisite.0095_webhook_event_ownership.sql— Generic webhook event ownership (follow-up to #1531 / #1476). An owned source has no chat/instance parent; derive its journal owner from the persisted source identified by server-stamped metadata.webhookSourceId. Payload tenant claims and source names are never ownership evidence. Missing, malformed, unowned or RLS-hidden sources derive no owner; existing RLS rejects the insert under enforcement. Preserve every 0092 parent/connector check.0096_zenvia_channel.sql— Zenvia channel — per-instance configuration.0097_whatsapp_business_provider.sql— WhatsApp Business (Meta Cloud API) — Meta-compatible provider settings.
🚀 Features
- api: keep a metadata object on access rules (
7374135) - api: let connect set or rotate the Zenvia webhook verify token (
43d2602) - api: add events:consume so a paired agent host runs its own consumers (
54d4093) - api: add the omni-agent-host device client, read events only (#1461)
- api: expose paired-agent status and rollback guidance (
12dd981) - api: deliver agent-owned consumers through active grants (
d99dd3f) - api: enforce agent-owned consumer access (
4137ef3) - api: stamp trusted journal producer provenance (
192eb47) - api: accept per-connector webhook deliveries (
ca95762) - api: manage connector ingress subscriptions and hook secrets (
60c5821) - ...
v2.261114.2
✨ Highlights
- omni-channels: Draw the phone pane as a full chat view with a message bar (
f6d1bc1) - omni-channels: Staff send their own message from the phone pane (
35182f9) - omni-channels: Tell the team when an answer child's person needs someone (
74e9d15) - omni-channels: Tell a bound child the prefix of its own person's tools (
80b1fad) - omni-channels: Each person's answer child carries that person's own context and capability (
f6f3652) - api: Keep a metadata object on access rules (
7374135)
💥 Breaking changes
- core: Remove OpenClaw integration (
39dc234) - auth: Reconcile existing agent bindings before dispatch — Startup revokes active system:auto-provision agent keys with NULL or empty instance grants once. Bound instances automatically get fresh narrow keys; old widened secrets no longer work. Route-only agents may stop answering: startup warns once per revoked key without a binding, naming the agent. Fix by binding it to an instance with
omni instances update <instance-id> --agent <agent-id>. Detect bindings without an explicit scoped system key (no-tenant dispatch retains its legacy name lookup) withSELECT i.id, i.agent_id, a.name FROM instances i JOIN agents a ON a.id = i.agent_id WHERE NOT EXISTS (SELECT 1 FROM api_keys k WHERE k.status = 'active' AND k.created_by = 'system:auto-provision' AND (k.name = 'agent:' || a.name OR (i.tenant_id IS NOT NULL AND k.name = 'agent:' || i.tenant_id::text || ':' || a.name)) AND i.id = ANY(k.instance_ids)). Fix by unbinding then rebinding the saved agent:omni instances update <instance-id> --agent null, thenomni instances update <instance-id> --agent <saved-agent-id>. Full upgrade note: https://github.com/automagik-dev/omni/blob/dev/docs/deployment/agent-key-scope-upgrade.md (fd41377)
🗄️ Database migrations
This release adds 18 database migrations. Migrations are additive and idempotent
per the repository migration contract, and the API applies them automatically at boot
(migrateDb()) — no manual upgrade step is required. See packages/db/drizzle/ for details.
0080_event_journal_ready.sql— Opt-in journal readiness gate for durable event consumers (Vox fluid-chat proposal, item 4).0081_instances_outbound_pacing.sql— Opt-in immediate outbound pacing per instance (Vox fluid-chat PR-B).0082_durable_consumers_instance_scope.sql— Opt-in instance scoping + ownership for durable event consumers.0083_event_access_decision.sql— Opt-in ingest access verdict on the journal + access-filtered durable consumers.0084_instances_audio_transcription.sql— Per-instance opt-in switch for server-side transcription of inbound audio.0085_instances_inbound_reply_context.sql— Per-instance opt-in for typed inbound reply context (PR #1297).0086_human_login.sql— Human login on Better Auth (wish: omni-labs-distribution).0087_login_hardening.sql— Human login hardening (wish: omni-labs-distribution; review of the Better Auth login).0088_api_key_parent.sql— API key lineage (wish: omni-chat-threads, Group 1).0089_connectors.sql— Connectors (wish: connectors-first-slice-clickup, Group 1).0090_connector_event_ownership.sql— Connector event ownership (wish: connectors-first-slice-clickup, finding F3).0091_durable_consumers_tenant_scope.sql— Durable consumer tenant ownership (paired-agents R2-3, O11). Stamp new consumers from the authenticated caller, independent of instance restrictions and OMNI_DB_ENFORCEMENT. Existing rows deliberately remain NULL: their tenant cannot be established safely, so tenant keys must not see them. Legacy credentials retain their existing access rules. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0092_connector_ingress.sql— Connector-keyed ingress schema and typed journal ownership. Wish: gitlab-sdlc-connector, Group 2. Existing ClickUp bindings keep their route and secret. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0093_dead_letter_tenant_scope.sql— Dead-letter ownership and enforced-RLS retries (#1467). Derive ownership from the authenticated transaction, or a persisted source event for off-request writers. Never accept NEW.tenant_id or payload claims. Existing NULL rows remain unowned and hidden under enforcement. Their ownership repair belongs to the G6 tenancy backfill, not this migration. no-schema-change: replaces the frozen 0041 ownership trigger body only. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0094_paired_agent_consumers.sql— Paired-agents slice 2: provenance, agent-owned consumers and source grants. Wish: paired-agents-slice-2; DESIGN row 5, R13-3 (no grant writer in this slice). Hand-written following the 0043/0044/0052 precedent (additive, idempotent). Large-journal prerequisite: run online preparation from the exact candidate checkout before upgrading, per docs/deployment/paired-agent-journal-indexes.md. The estimate-based boot preflight backs up this operator-held prerequisite.0095_webhook_event_ownership.sql— Generic webhook event ownership (follow-up to #1531 / #1476). An owned source has no chat/instance parent; derive its journal owner from the persisted source identified by server-stamped metadata.webhookSourceId. Payload tenant claims and source names are never ownership evidence. Missing, malformed, unowned or RLS-hidden sources derive no owner; existing RLS rejects the insert under enforcement. Preserve every 0092 parent/connector check.0096_zenvia_channel.sql— Zenvia channel — per-instance configuration.0097_whatsapp_business_provider.sql— WhatsApp Business (Meta Cloud API) — Meta-compatible provider settings.
🚀 Features
- api: keep a metadata object on access rules (
7374135) - api: let connect set or rotate the Zenvia webhook verify token (
43d2602) - api: add events:consume so a paired agent host runs its own consumers (
54d4093) - api: add the omni-agent-host device client, read events only (#1461)
- api: expose paired-agent status and rollback guidance (
12dd981) - api: deliver agent-owned consumers through active grants (
d99dd3f) - api: enforce agent-owned consumer access (
4137ef3) - api: stamp trusted journal producer provenance (
192eb47) - api: accept per-connector webhook deliveries (
ca95762) - api: manage connector ingress subscriptions and hook secrets (
60c5821) - ...
v2.261113.8
✨ Highlights
- omni-channels: Staff send their own message from the phone pane (
35182f9) - omni-channels: Tell the team when an answer child's person needs someone (
74e9d15) - omni-channels: Tell a bound child the prefix of its own person's tools (
80b1fad) - omni-channels: Each person's answer child carries that person's own context and capability (
f6f3652) - api: Keep a metadata object on access rules (
7374135) - omni-channels: Answer mode runs on Omni's default bot (
86d8cff)
💥 Breaking changes
- core: Remove OpenClaw integration (
39dc234) - auth: Reconcile existing agent bindings before dispatch — Startup revokes active system:auto-provision agent keys with NULL or empty instance grants once. Bound instances automatically get fresh narrow keys; old widened secrets no longer work. Route-only agents may stop answering: startup warns once per revoked key without a binding, naming the agent. Fix by binding it to an instance with
omni instances update <instance-id> --agent <agent-id>. Detect bindings without an explicit scoped system key (no-tenant dispatch retains its legacy name lookup) withSELECT i.id, i.agent_id, a.name FROM instances i JOIN agents a ON a.id = i.agent_id WHERE NOT EXISTS (SELECT 1 FROM api_keys k WHERE k.status = 'active' AND k.created_by = 'system:auto-provision' AND (k.name = 'agent:' || a.name OR (i.tenant_id IS NOT NULL AND k.name = 'agent:' || i.tenant_id::text || ':' || a.name)) AND i.id = ANY(k.instance_ids)). Fix by unbinding then rebinding the saved agent:omni instances update <instance-id> --agent null, thenomni instances update <instance-id> --agent <saved-agent-id>. Full upgrade note: https://github.com/automagik-dev/omni/blob/dev/docs/deployment/agent-key-scope-upgrade.md (fd41377)
🗄️ Database migrations
This release adds 18 database migrations. Migrations are additive and idempotent
per the repository migration contract, and the API applies them automatically at boot
(migrateDb()) — no manual upgrade step is required. See packages/db/drizzle/ for details.
0080_event_journal_ready.sql— Opt-in journal readiness gate for durable event consumers (Vox fluid-chat proposal, item 4).0081_instances_outbound_pacing.sql— Opt-in immediate outbound pacing per instance (Vox fluid-chat PR-B).0082_durable_consumers_instance_scope.sql— Opt-in instance scoping + ownership for durable event consumers.0083_event_access_decision.sql— Opt-in ingest access verdict on the journal + access-filtered durable consumers.0084_instances_audio_transcription.sql— Per-instance opt-in switch for server-side transcription of inbound audio.0085_instances_inbound_reply_context.sql— Per-instance opt-in for typed inbound reply context (PR #1297).0086_human_login.sql— Human login on Better Auth (wish: omni-labs-distribution).0087_login_hardening.sql— Human login hardening (wish: omni-labs-distribution; review of the Better Auth login).0088_api_key_parent.sql— API key lineage (wish: omni-chat-threads, Group 1).0089_connectors.sql— Connectors (wish: connectors-first-slice-clickup, Group 1).0090_connector_event_ownership.sql— Connector event ownership (wish: connectors-first-slice-clickup, finding F3).0091_durable_consumers_tenant_scope.sql— Durable consumer tenant ownership (paired-agents R2-3, O11). Stamp new consumers from the authenticated caller, independent of instance restrictions and OMNI_DB_ENFORCEMENT. Existing rows deliberately remain NULL: their tenant cannot be established safely, so tenant keys must not see them. Legacy credentials retain their existing access rules. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0092_connector_ingress.sql— Connector-keyed ingress schema and typed journal ownership. Wish: gitlab-sdlc-connector, Group 2. Existing ClickUp bindings keep their route and secret. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0093_dead_letter_tenant_scope.sql— Dead-letter ownership and enforced-RLS retries (#1467). Derive ownership from the authenticated transaction, or a persisted source event for off-request writers. Never accept NEW.tenant_id or payload claims. Existing NULL rows remain unowned and hidden under enforcement. Their ownership repair belongs to the G6 tenancy backfill, not this migration. no-schema-change: replaces the frozen 0041 ownership trigger body only. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0094_paired_agent_consumers.sql— Paired-agents slice 2: provenance, agent-owned consumers and source grants. Wish: paired-agents-slice-2; DESIGN row 5, R13-3 (no grant writer in this slice). Hand-written following the 0043/0044/0052 precedent (additive, idempotent). Large-journal prerequisite: run online preparation from the exact candidate checkout before upgrading, per docs/deployment/paired-agent-journal-indexes.md. The estimate-based boot preflight backs up this operator-held prerequisite.0095_webhook_event_ownership.sql— Generic webhook event ownership (follow-up to #1531 / #1476). An owned source has no chat/instance parent; derive its journal owner from the persisted source identified by server-stamped metadata.webhookSourceId. Payload tenant claims and source names are never ownership evidence. Missing, malformed, unowned or RLS-hidden sources derive no owner; existing RLS rejects the insert under enforcement. Preserve every 0092 parent/connector check.0096_zenvia_channel.sql— Zenvia channel — per-instance configuration.0097_whatsapp_business_provider.sql— WhatsApp Business (Meta Cloud API) — Meta-compatible provider settings.
🚀 Features
- api: keep a metadata object on access rules (
7374135) - api: let connect set or rotate the Zenvia webhook verify token (
43d2602) - api: add events:consume so a paired agent host runs its own consumers (
54d4093) - api: add the omni-agent-host device client, read events only (#1461)
- api: expose paired-agent status and rollback guidance (
12dd981) - api: deliver agent-owned consumers through active grants (
d99dd3f) - api: enforce agent-owned consumer access (
4137ef3) - api: stamp trusted journal producer provenance (
192eb47) - api: accept per-connector webhook deliveries (
ca95762) - api: manage connector ingress subscriptions and hook secrets (
60c5821) - api: expose vali...
v2.261113.6
✨ Highlights
- omni-channels: Tell the team when an answer child's person needs someone (
74e9d15) - omni-channels: Tell a bound child the prefix of its own person's tools (
80b1fad) - omni-channels: Each person's answer child carries that person's own context and capability (
f6f3652) - api: Keep a metadata object on access rules (
7374135) - omni-channels: Answer mode runs on Omni's default bot (
86d8cff) - omni-channels: Answer bots read knowledge only from a folder staff choose (
0ff0375)
💥 Breaking changes
- core: Remove OpenClaw integration (
39dc234) - auth: Reconcile existing agent bindings before dispatch — Startup revokes active system:auto-provision agent keys with NULL or empty instance grants once. Bound instances automatically get fresh narrow keys; old widened secrets no longer work. Route-only agents may stop answering: startup warns once per revoked key without a binding, naming the agent. Fix by binding it to an instance with
omni instances update <instance-id> --agent <agent-id>. Detect bindings without an explicit scoped system key (no-tenant dispatch retains its legacy name lookup) withSELECT i.id, i.agent_id, a.name FROM instances i JOIN agents a ON a.id = i.agent_id WHERE NOT EXISTS (SELECT 1 FROM api_keys k WHERE k.status = 'active' AND k.created_by = 'system:auto-provision' AND (k.name = 'agent:' || a.name OR (i.tenant_id IS NOT NULL AND k.name = 'agent:' || i.tenant_id::text || ':' || a.name)) AND i.id = ANY(k.instance_ids)). Fix by unbinding then rebinding the saved agent:omni instances update <instance-id> --agent null, thenomni instances update <instance-id> --agent <saved-agent-id>. Full upgrade note: https://github.com/automagik-dev/omni/blob/dev/docs/deployment/agent-key-scope-upgrade.md (fd41377)
🗄️ Database migrations
This release adds 18 database migrations. Migrations are additive and idempotent
per the repository migration contract, and the API applies them automatically at boot
(migrateDb()) — no manual upgrade step is required. See packages/db/drizzle/ for details.
0080_event_journal_ready.sql— Opt-in journal readiness gate for durable event consumers (Vox fluid-chat proposal, item 4).0081_instances_outbound_pacing.sql— Opt-in immediate outbound pacing per instance (Vox fluid-chat PR-B).0082_durable_consumers_instance_scope.sql— Opt-in instance scoping + ownership for durable event consumers.0083_event_access_decision.sql— Opt-in ingest access verdict on the journal + access-filtered durable consumers.0084_instances_audio_transcription.sql— Per-instance opt-in switch for server-side transcription of inbound audio.0085_instances_inbound_reply_context.sql— Per-instance opt-in for typed inbound reply context (PR #1297).0086_human_login.sql— Human login on Better Auth (wish: omni-labs-distribution).0087_login_hardening.sql— Human login hardening (wish: omni-labs-distribution; review of the Better Auth login).0088_api_key_parent.sql— API key lineage (wish: omni-chat-threads, Group 1).0089_connectors.sql— Connectors (wish: connectors-first-slice-clickup, Group 1).0090_connector_event_ownership.sql— Connector event ownership (wish: connectors-first-slice-clickup, finding F3).0091_durable_consumers_tenant_scope.sql— Durable consumer tenant ownership (paired-agents R2-3, O11). Stamp new consumers from the authenticated caller, independent of instance restrictions and OMNI_DB_ENFORCEMENT. Existing rows deliberately remain NULL: their tenant cannot be established safely, so tenant keys must not see them. Legacy credentials retain their existing access rules. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0092_connector_ingress.sql— Connector-keyed ingress schema and typed journal ownership. Wish: gitlab-sdlc-connector, Group 2. Existing ClickUp bindings keep their route and secret. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0093_dead_letter_tenant_scope.sql— Dead-letter ownership and enforced-RLS retries (#1467). Derive ownership from the authenticated transaction, or a persisted source event for off-request writers. Never accept NEW.tenant_id or payload claims. Existing NULL rows remain unowned and hidden under enforcement. Their ownership repair belongs to the G6 tenancy backfill, not this migration. no-schema-change: replaces the frozen 0041 ownership trigger body only. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0094_paired_agent_consumers.sql— Paired-agents slice 2: provenance, agent-owned consumers and source grants. Wish: paired-agents-slice-2; DESIGN row 5, R13-3 (no grant writer in this slice). Hand-written following the 0043/0044/0052 precedent (additive, idempotent). Large-journal prerequisite: run online preparation from the exact candidate checkout before upgrading, per docs/deployment/paired-agent-journal-indexes.md. The estimate-based boot preflight backs up this operator-held prerequisite.0095_webhook_event_ownership.sql— Generic webhook event ownership (follow-up to #1531 / #1476). An owned source has no chat/instance parent; derive its journal owner from the persisted source identified by server-stamped metadata.webhookSourceId. Payload tenant claims and source names are never ownership evidence. Missing, malformed, unowned or RLS-hidden sources derive no owner; existing RLS rejects the insert under enforcement. Preserve every 0092 parent/connector check.0096_zenvia_channel.sql— Zenvia channel — per-instance configuration.0097_whatsapp_business_provider.sql— WhatsApp Business (Meta Cloud API) — Meta-compatible provider settings.
🚀 Features
- api: keep a metadata object on access rules (
7374135) - api: let connect set or rotate the Zenvia webhook verify token (
43d2602) - api: add events:consume so a paired agent host runs its own consumers (
54d4093) - api: add the omni-agent-host device client, read events only (#1461)
- api: expose paired-agent status and rollback guidance (
12dd981) - api: deliver agent-owned consumers through active grants (
d99dd3f) - api: enforce agent-owned consumer access (
4137ef3) - api: stamp trusted journal producer provenance (
192eb47) - api: accept per-connector webhook deliveries (
ca95762) - api: manage connector ingress subscriptions and hook secrets (
60c5821) - api: e...
v2.261113.4
✨ Highlights
- omni-channels: Tell a bound child the prefix of its own person's tools (
80b1fad) - omni-channels: Each person's answer child carries that person's own context and capability (
f6f3652) - api: Keep a metadata object on access rules (
7374135) - omni-channels: Answer mode runs on Omni's default bot (
86d8cff) - omni-channels: Answer bots read knowledge only from a folder staff choose (
0ff0375) - omni-channels: Answer shared notes hold up to 32000 characters (
073058c)
💥 Breaking changes
- core: Remove OpenClaw integration (
39dc234) - auth: Reconcile existing agent bindings before dispatch — Startup revokes active system:auto-provision agent keys with NULL or empty instance grants once. Bound instances automatically get fresh narrow keys; old widened secrets no longer work. Route-only agents may stop answering: startup warns once per revoked key without a binding, naming the agent. Fix by binding it to an instance with
omni instances update <instance-id> --agent <agent-id>. Detect bindings without an explicit scoped system key (no-tenant dispatch retains its legacy name lookup) withSELECT i.id, i.agent_id, a.name FROM instances i JOIN agents a ON a.id = i.agent_id WHERE NOT EXISTS (SELECT 1 FROM api_keys k WHERE k.status = 'active' AND k.created_by = 'system:auto-provision' AND (k.name = 'agent:' || a.name OR (i.tenant_id IS NOT NULL AND k.name = 'agent:' || i.tenant_id::text || ':' || a.name)) AND i.id = ANY(k.instance_ids)). Fix by unbinding then rebinding the saved agent:omni instances update <instance-id> --agent null, thenomni instances update <instance-id> --agent <saved-agent-id>. Full upgrade note: https://github.com/automagik-dev/omni/blob/dev/docs/deployment/agent-key-scope-upgrade.md (fd41377)
🗄️ Database migrations
This release adds 18 database migrations. Migrations are additive and idempotent
per the repository migration contract, and the API applies them automatically at boot
(migrateDb()) — no manual upgrade step is required. See packages/db/drizzle/ for details.
0080_event_journal_ready.sql— Opt-in journal readiness gate for durable event consumers (Vox fluid-chat proposal, item 4).0081_instances_outbound_pacing.sql— Opt-in immediate outbound pacing per instance (Vox fluid-chat PR-B).0082_durable_consumers_instance_scope.sql— Opt-in instance scoping + ownership for durable event consumers.0083_event_access_decision.sql— Opt-in ingest access verdict on the journal + access-filtered durable consumers.0084_instances_audio_transcription.sql— Per-instance opt-in switch for server-side transcription of inbound audio.0085_instances_inbound_reply_context.sql— Per-instance opt-in for typed inbound reply context (PR #1297).0086_human_login.sql— Human login on Better Auth (wish: omni-labs-distribution).0087_login_hardening.sql— Human login hardening (wish: omni-labs-distribution; review of the Better Auth login).0088_api_key_parent.sql— API key lineage (wish: omni-chat-threads, Group 1).0089_connectors.sql— Connectors (wish: connectors-first-slice-clickup, Group 1).0090_connector_event_ownership.sql— Connector event ownership (wish: connectors-first-slice-clickup, finding F3).0091_durable_consumers_tenant_scope.sql— Durable consumer tenant ownership (paired-agents R2-3, O11). Stamp new consumers from the authenticated caller, independent of instance restrictions and OMNI_DB_ENFORCEMENT. Existing rows deliberately remain NULL: their tenant cannot be established safely, so tenant keys must not see them. Legacy credentials retain their existing access rules. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0092_connector_ingress.sql— Connector-keyed ingress schema and typed journal ownership. Wish: gitlab-sdlc-connector, Group 2. Existing ClickUp bindings keep their route and secret. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0093_dead_letter_tenant_scope.sql— Dead-letter ownership and enforced-RLS retries (#1467). Derive ownership from the authenticated transaction, or a persisted source event for off-request writers. Never accept NEW.tenant_id or payload claims. Existing NULL rows remain unowned and hidden under enforcement. Their ownership repair belongs to the G6 tenancy backfill, not this migration. no-schema-change: replaces the frozen 0041 ownership trigger body only. Hand-written following the 0043/0044/0052 precedent (additive, idempotent).0094_paired_agent_consumers.sql— Paired-agents slice 2: provenance, agent-owned consumers and source grants. Wish: paired-agents-slice-2; DESIGN row 5, R13-3 (no grant writer in this slice). Hand-written following the 0043/0044/0052 precedent (additive, idempotent). Large-journal prerequisite: run online preparation from the exact candidate checkout before upgrading, per docs/deployment/paired-agent-journal-indexes.md. The estimate-based boot preflight backs up this operator-held prerequisite.0095_webhook_event_ownership.sql— Generic webhook event ownership (follow-up to #1531 / #1476). An owned source has no chat/instance parent; derive its journal owner from the persisted source identified by server-stamped metadata.webhookSourceId. Payload tenant claims and source names are never ownership evidence. Missing, malformed, unowned or RLS-hidden sources derive no owner; existing RLS rejects the insert under enforcement. Preserve every 0092 parent/connector check.0096_zenvia_channel.sql— Zenvia channel — per-instance configuration.0097_whatsapp_business_provider.sql— WhatsApp Business (Meta Cloud API) — Meta-compatible provider settings.
🚀 Features
- api: keep a metadata object on access rules (
7374135) - api: let connect set or rotate the Zenvia webhook verify token (
43d2602) - api: add events:consume so a paired agent host runs its own consumers (
54d4093) - api: add the omni-agent-host device client, read events only (#1461)
- api: expose paired-agent status and rollback guidance (
12dd981) - api: deliver agent-owned consumers through active grants (
d99dd3f) - api: enforce agent-owned consumer access (
4137ef3) - api: stamp trusted journal producer provenance (
192eb47) - api: accept per-connector webhook deliveries (
ca95762) - api: manage connector ingress subscriptions and hook secrets (
60c5821) - api: expose vali...