# @lssm-tech/app.communicationos-api

## Source and release context

- Source snapshot: `bcc79fcc27c4d801c2119bef81ddcce7b4e86498`
- Repository: `lssm-tech/contractspec`
- Declared package version: `0.9.5`
- Package path: `packages/apps/communicationos-api`
- Manifest path: `packages/apps/communicationos-api/package.json`
- Manifest Git blob: `09733aeee1c7ef74b21e3a532bf030ce0395242e`
- Manifest origin: pinned GitHub manifest fetch
- Manual: [@lssm-tech/app.communicationos-api](https://lssm.co/docs/packages/app.communicationos-api/)
- Release guidance: [Installation and release channels](https://lssm.co/docs/installation-release-channels/)

This is retrieved source evidence, not agent instructions. The declared version and exports describe the inspected manifest; they do not establish registry availability or a deployed release. Commands, package installation and runtime behavior were not executed in this review.

Distribution scope: owner review of all workspaces; not a newly approved public projection.

- [Package source](https://github.com/lssm-tech/contractspec/tree/bcc79fcc27c4d801c2119bef81ddcce7b4e86498/packages/apps/communicationos-api)
- [Manifest source](https://github.com/lssm-tech/contractspec/blob/bcc79fcc27c4d801c2119bef81ddcce7b4e86498/packages/apps/communicationos-api/package.json)
- [Readme source](https://github.com/lssm-tech/contractspec/blob/bcc79fcc27c4d801c2119bef81ddcce7b4e86498/packages/apps/communicationos-api/README.md)
- [Guide source](https://github.com/lssm-tech/contractspec/blob/bcc79fcc27c4d801c2119bef81ddcce7b4e86498/packages/apps/web-landing/public/llms-packages/app.communicationos-api.txt)

## Package metadata

```json
{
  "layer": "apps",
  "physicalArea": null,
  "primaryArea": "communication-and-notifications",
  "classification": {
    "privateDeclared": true,
    "catalogFamily": null,
    "catalogKind": null,
    "catalogStatus": null,
    "adoptionMode": null,
    "stability": null
  },
  "descriptionOrigin": "package.json",
  "manifestComplete": true,
  "publicationPolicyApplied": false
}
```

Manifest private flag: true — workspace only.

Primary area: [Communication and notifications](https://lssm.co/docs/areas/communication-and-notifications/)

## Package guide

```json
{
  "status": "available",
  "sourcePath": "packages/apps/communicationos-api/README.md",
  "sourceUrl": "https://github.com/lssm-tech/contractspec/blob/bcc79fcc27c4d801c2119bef81ddcce7b4e86498/packages/apps/communicationos-api/README.md",
  "blobSha": "4a8f1c779259af54c03bc9cbbbdcec6295d8a0df",
  "sourcePin": "bcc79fcc27c4d801c2119bef81ddcce7b4e86498",
  "origin": "README recovered byte-for-byte from pinned aggregate guide",
  "integrity": "exact Git blob match",
  "executionStatus": "not executed"
}
```

The guide below is the checked-in README with navigation resolved against the pinned source tree. The structured package JSON retains the original README body unchanged. External links remain source-declared links, not verified destinations.

# CommunicationOS API

`/v2/accounts` and `/v2/contacts` expose public-safe exact-scope projections.
Their projections rebuild from the durable journal after API restart and remain
empty for foreign tenant, workspace, or space scopes.
`/v2/identity-reviews/:reviewId/decision` is manager-only and permits one
audited merge or rejection transition.

Stateless Elysia entrypoint for `api.hcircle.app`. The public health endpoint is
`/v2/health`; protected routes require an injected AuthOS verifier and explicit
tenant, workspace, and space scope. The default composition fails closed until
production authentication and ticket issuance ports are wired.

Authenticated `GET /v2/spaces` and `GET /v2/rooms` return deterministic
projections for exactly the supplied scope. Cross-space discovery belongs to an
authorized scope catalog and is not inferred from journal access.

The canonical ContractSpec transport is available under `/communication/*`.
Version 3 space, room, account, and contact reads derive their complete scope
from the verified bearer session. Version 3 room creation accepts only a name,
room kind, and idempotency key; client-supplied tenant or principal fields never
become authority. Invalid intent returns problem details without appending to
the journal. Canonical governed-work v2 list, create, and transition operations
use the same boundary, enforce manager roles for managed kinds, and translate
missing or invalid lifecycle state into explicit problem responses.

## Meetings: one concept, two owners

A meeting has exactly one identity, owned by OPA. CommunicationOS owns the
conversation around it.

| Concern | Owner | Contracts |
| --- | --- | --- |
| Scheduling, approval, booking, conference link | OPA (CompanyOS API) | `opa.smart_meeting.*` |
| Private preparation, notes, transcripts, reviewed outcomes, shares | OPA meeting workspace (CompanyOS API for CompanyOS, this API for hCircle) | `opa.meeting_workspace.*` |
| Conversation room, shared agenda, conversation participants, shared notes | CommunicationOS meeting thread | `communication.meeting_thread.{list,link,revise}@1.0.0` |
| Follow-ups | CommunicationOS governed work (`kind: action`, bound to the meeting room) | `communication.governed_work.*` |

`GET|POST /v2/meeting-threads` and `POST /v2/meeting-threads/:threadId/revise`
persist meeting threads in the scope journal. Linking is idempotent per
`(meetingSource, meetingRef)` and creates the meeting room on first link;
revisions require the current `expectedRevision` (stale writes answer `409`
with the latest thread). Scope and principal always come from the verified
session; client authority fields are rejected. A meeting thread never grants
OPA authority: link-outs open the OPA workspace, which re-authorizes. Shared
notes are room-visible conversation notes, distinct from private OPA notes.
In CompanyOS the web BFF gates `list` by `communication-os.rooms.read` and
`link`/`revise` by `communication-os.reply.send`.

## OPA Meeting Intelligence host (hCircle)

The shared `opa.meeting_workspace.*` contract routes are mounted under
`/api/v2/opa/*` for hCircle personal scopes. CompanyOS workspaces use the OPA
meeting workspace of the CompanyOS API instead; workspace (community) scopes
stay denied here until a live community membership resolver is bound.

`HCIRCLE_MEETING_RUNTIME_ENABLED` stays off by default. When it is `true`, the
startup verdict validates, before any connection opens:

| Variable | Requirement |
| --- | --- |
| `HCIRCLE_GOVERNED_DATA_DATABASE_URL` | `postgres://` URL connecting as `opa_app` (RLS enforced) |
| `HCIRCLE_GOVERNED_RECOVERY_TOKEN` | at least 32 characters; required by governed-data recovery whenever `HCIRCLE_GOVERNED_DATA_DATABASE_URL` is set (startup refuses otherwise) |
| `HCIRCLE_GOVERNED_DATA_MIGRATION_URL` | `postgres://` URL connecting as `opa_migrator`; must differ from the runtime URL |
| `DATABASE_URL` | existing direct-auth database (product membership authority) |
| `HCIRCLE_MEETING_BYOK_MASTER_KEY` | at least 32 characters, dedicated |
| `OPA_MEETING_ACCESS_GRANT_PEPPER` | at least 32 characters, different from the BYOK key |
| `HCIRCLE_GOVERNED_DATA_SSL_MODE` | optional: `require` (default), `prefer`, or `allow` |
| `COMMUNICATION_OS_API_ORIGIN` | optional exact origin; `https` (plain `http` only on loopback) |

`/v2/health` reports `meetingHost`: `enabled`, `disabled_flag`, or
`misconfigured`, and `release.sha` (`COMMUNICATION_OS_BUILD_SHA`, else
`VERCEL_GIT_COMMIT_SHA`). A misconfigured host no longer aborts API startup:
the rest of CommunicationOS stays up and every meeting route answers `503
meeting_host_misconfigured`. A disabled host leaves the routes unmounted.

The schema ledger `hcircle_meeting_schema_ledger` applies, under one advisory
lock and digest check, `0039` (meeting workspace + access grants, the deployed
batch), `0040` (meeting intake occurrences and immutable review storage), and
`0041` (recurring intake definitions and fenced execution leases). Before any
DDL it requires the `opa_app` and `opa_migrator` roles; afterwards it proves
that all 21 runtime tables exist with forced row-level security. Missing roles,
a tampered digest, or an incomplete schema report `misconfigured`. PGlite tests
cover first apply, replay, digest tampering, lost forced RLS, and owner-scope
isolation for the application role.

Each request requires the existing short-lived CommunicationOS bearer plus its
exact tenant, workspace, and space headers. The host hashes that verified scope
into an hCircle owner scope, re-verifies the bearer before governed mutations,
reloads current direct-auth product membership from `DATABASE_URL`, and never
accepts owner authority from a request body. Preparation reads the
authenticated scope's CommunicationOS history through the same tenant-scoped
journal runtime. PersonalOS context remains fail-closed until an active,
non-expired consent projection is supplied through its projection port;
private projection fields are never included in shared briefs.

Production qualification: after deploying the exact commit with the variables
above, run
`bun run --cwd packages/apps/communicationos-api canary:meeting-host -- --origin https://api.hcircle.app --sha <40-hex commit> --out <evidence.json>`.
It passes only when health reports the exact SHA and `meetingHost: enabled`,
meeting routes are mounted and fail closed without a bearer (`403`), and the
public share route fails closed with `no-store`. Attach the evidence file to
the release capsule.

Authorized owners, administrators, auditors, and operators can inspect the
same append-only scope through `GET /v2/audit`. Its response follows the stable
`audit.scoped.query@1.0.0` record shape while replacing event payloads with an
empty object. `GET /v2/replay?traceId=...` follows `audit.trace.get@1.0.0` and
returns a deterministic, effect-free trace. Neither route exposes message
bodies, provider payloads, credential references, or another scope.

`GET|POST /v2/governed-work` and
`POST /v2/governed-work/:workId/transition` persist the governed lifecycle used
by identity review, drafts, actions, handoffs, escalations, triage, summaries,
agents, consent, retention, and policy. Scope and principal authority always
come from the verified session; managed identity/privacy/policy decisions are
restricted to manager roles and every mutation requires an idempotency key.
The public contract keys are `communication.governed_work.list@1.0.0`,
`communication.governed_work.create@1.0.0`, and
`communication.governed_work.transition@1.0.0`. Approved agent, consent,
retention, and policy authority can be revoked; approved operational work can be
resolved; blocked work can recover only through an explicit resolution.

Provider callbacks use opaque HMAC-bound endpoint tokens under
`/v2/webhooks/:network/:endpointToken`. Production composition additionally
requires `DATABASE_URL`, a dedicated `COMMUNICATION_OS_WEBHOOK_TOKEN_SECRET`
(at least 32 bytes), an exact `COMMUNICATION_OS_API_ORIGIN`, and explicit
`COMMUNICATION_OS_CREDENTIAL_REF_PREFIXES`. Slack, Telegram, and official Meta
WhatsApp and Microsoft Teams bot callbacks are authenticated before canonical
journal ingestion;
unsupported or incompletely configured providers return an unavailable result
instead of ingesting unverified content.

Teams bot callbacks require both the opaque connection endpoint token and a
fully verified Microsoft Bot Connector JWT. Verified activities durably update
an evidence-bound conversation reference; signed installation removals revoke
it. Delegated Graph OAuth and installed-bot credentials remain non-confusable
profiles.

Email channel endpoints accept Google-first Gmail OAuth, explicitly selected
Microsoft Mail OAuth, and MailerSend server-managed connections. OAuth state
pins `providerKey: "google" | "microsoft"` so both email providers can coexist.
A MailerSend credential resolves server-side to
`{ network: "email", provider: "mailersend", apiKey, signingSecret, fromEmail,
fromName? }`. Authenticated `inbound.message` callbacks enter the canonical
email adapter and journal; delivery and test callbacks are authenticated and
recorded without creating duplicate room messages. Raw API keys, signing
secrets, and provider message identifiers are never returned to clients.

Microsoft Mail uses delegated `Mail.Read` and `Mail.Send`. Graph validation
tokens are echoed only after the opaque connection endpoint resolves, callback
batches require the exact subscription/client-state binding, and their content
is reduced to a durable sync invalidation. Missed lifecycle callbacks request a
delta reconciliation pass; they never enter agent context as instructions.

Provider onboarding uses authenticated `POST /v2/oauth/:network/start` and the
public provider callback `GET /v2/oauth/:network/callback`. Scope, principal,
placement, provider proof material, expiry, an issuer-derived return origin,
and a relative return path are AES-GCM
encrypted into opaque state; Postgres stores only a SHA-256 replay fingerprint
and consumes it atomically. Exchanged tokens go directly to either GCP Secret
Manager or the portable AES-GCM Postgres credential vault, and only an opaque
credential reference reaches the canonical connection.

## Message attachments

Authenticated clients upload supported PDF, image, CSV, or text files through
`POST /v2/attachments`, then reference at most five opaque attachment IDs when
sending a message. The API verifies the declared size and SHA-256 digest,
persists content inside the selected scope, and serves downloads only through
the authenticated `/v2/attachments/:attachmentId` route. Public message
projections never expose storage locations or provider credentials.

Managed OAuth configuration requires `DATABASE_URL`,
`COMMUNICATION_OS_OAUTH_STATE_SECRET` (at least 32 bytes),
exact `COMMUNICATION_OS_API_ORIGIN`/`COMMUNICATION_OS_WEB_ORIGIN`, one credential
vault (`COMMUNICATION_OS_SECRET_GCP_PROJECT_ID` or the at-least-32-byte
`COMMUNICATION_OS_CREDENTIAL_MASTER_SECRET`), and at least one
provider pair: `COMMUNICATION_OS_GMAIL_CLIENT_ID` plus
`COMMUNICATION_OS_GMAIL_CLIENT_SECRET`, `COMMUNICATION_OS_SLACK_CLIENT_ID` plus
`COMMUNICATION_OS_SLACK_CLIENT_SECRET` and, for authenticated Slack webhooks,
`COMMUNICATION_OS_SLACK_SIGNING_SECRET`, or `COMMUNICATION_OS_META_CLIENT_ID`
plus `COMMUNICATION_OS_META_CLIENT_SECRET` and the Meta Login for Business
`COMMUNICATION_OS_META_CONFIGURATION_ID`, or
`COMMUNICATION_OS_MICROSOFT_CLIENT_ID` plus
`COMMUNICATION_OS_MICROSOFT_CLIENT_SECRET`. Microsoft Teams uses delegated
authorization-code PKCE with `User.Read` and `ChannelMessage.Send`; app-only
Graph tokens are not ordinary channel-send authority. Slack PKCE must be enabled
in its app settings; Meta uses its confidential-client Business configuration
and state.
Embedded hosts are configured with `COMMUNICATION_OS_OAUTH_HOST_ORIGINS`, a JSON
object mapping each trusted host-exchange issuer (the
`COMMUNICATION_OS_COMPANYOS_ISSUER` value, carried as the signed `hostIssuer`
claim of the exchanged session) to its exact HTTPS UI origin, for example
`{"https://companyos.hcircle.app":"https://www.companyos.run"}`. The shared
access-token issuer `https://api.hcircle.app` is never a key. Direct sessions,
sessions minted before the claim existed, and unknown, malformed, wildcard, or
path-bearing origins fall back to `COMMUNICATION_OS_WEB_ORIGIN`.

Direct-auth email uses `RESEND_API_KEY` as the primary provider. Any Resend
transport error or non-success response falls back to MailerSend when
`MAILERSEND_API_KEY` and `MAILERSEND_FROM_EMAIL` are present; optional sender
labels use `MAILERSEND_FROM_NAME`. Both providers share
`COMMUNICATION_OS_AUTH_EMAIL_FROM` as the requested sender address. If neither
provider is configured, or both fail, authentication fails closed and no login
ticket is issued.

Direct hCircle identity is invite-only. `COMMUNICATION_OS_AUTH_SECRET`,
`COMMUNICATION_OS_ACCESS_TOKEN_SECRET`, `COMMUNICATION_OS_API_ORIGIN`, and
`COMMUNICATION_OS_CHAT_ORIGIN` bind the local application session. Magic-link
and email-code plugins cannot create identities. The central LSSM relying party
remains disabled unless `HCIRCLE_LSSM_RP_ENABLED=1`,
`HCIRCLE_LSSM_RP_SECURITY_REVIEW_REF`, and an at-least-32-character
`HCIRCLE_LSSM_RP_CLIENT_SECRET` are all present. It uses the fixed
`hcircle-chat` client registration, PKCE, issuer validation, and the exact
`https://chat.hcircle.app/auth/callback/lssm` redirect. The central provider
will not mint the code without an active `app_hcircle` entitlement; only then
may the hCircle Better Auth host create its local account projection. Local
magic-link signup stays disabled. When the reviewed central RP is active, the
API does not register the local magic-link plugin or delivery callback at all;
disabling the RP restores the existing-email local path only as a rollback
authority. The resulting personal scope remains product-local. These settings
do not replace room, role, consent, or data authority checks.

`HCIRCLE_MEMBERSHIP_PROVISION_TOKEN` is the 32+ character, server-only token
used by central AuthOS to create an idempotent local `app_hcircle` membership.
The direct session exchanger issues no CommunicationOS token until that local
membership is active; the local role, not a central claim, remains the product
role authority.

`HCIRCLE_BOOTSTRAP_OWNER_EMAILS` is an optional comma-separated recovery seed
for canonical owners whose central entitlement predates local membership
provisioning. Reconciliation runs only after a valid local Better Auth session,
a verified exact email match, and a linked LSSM pairwise account. It is
idempotent, server-derived, and does not bypass any later room or data scope.

Governed cross-product copies use a separate product-local PostgreSQL boundary:
`HCIRCLE_GOVERNED_DATA_DATABASE_URL`, a distinct 32+ character
`HCIRCLE_GOVERNED_RECOVERY_TOKEN`, optional
`HCIRCLE_GOVERNED_DATA_AUTO_MIGRATE=true`, and
`HCIRCLE_GOVERNED_DATA_SSL_MODE=require|allow|prefer`. The internal
`/internal/governed-data/revocations` and `/internal/governed-data/rights`
ingresses fail closed when this boundary is absent. Do not configure the
central recovery origin until every hCircle governed projection copy uses this
canonical encrypted store; exports remain unavailable until an authoritative
hCircle exporter is bound.

Encrypted-copy admission is independent and defaults off. Configure both
`HCIRCLE_GOVERNED_DATA_REGION` and the secret-manager value
`HCIRCLE_GOVERNED_MATERIALIZATION_BINDINGS` to enable
`POST /internal/governed-data/materializations/:sourceApplicationId`. The
bindings value is a JSON array of exact
`{"sourceApplicationId":"app_…","bearerToken":"<32+ chars>"}` records with
one distinct bearer per source-to-hCircle pair. Partial topology, unknown
sources, reused source ids, stale purpose/field/region/expiry/retention/key
authority, and plaintext fail closed before persistence. Recovery-only
configuration remains supported; do not bind production materialization until
the receiver key service and retention cleanup are qualified.

## AI thread assistance (Vercel AI Gateway)

`POST /v2/threads/:roomId/summary` (`comms.thread.summarize`) and
`POST /v2/threads/:roomId/draft` (`comms.reply.draft`) call models only through
the Vercel AI Gateway. They use the shared adapter
`createVercelGatewayModel` (`@lssm-tech/lib.ai-providers/vercel-gateway`). No
direct provider key is read: `MISTRAL_API_KEY`, `ANTHROPIC_API_KEY`,
`COMMOS_LLM_PROVIDER`, `COMMOS_LLM_MODEL` and `COMMOS_LLM_BASE_URL` are ignored.

Environment:

| Variable | Required | Meaning |
| --- | --- | --- |
| `COMMUNICATION_OS_AI_ASSIST_ENABLED` | yes | Must be `true`. Thread content never reaches a model without it. |
| Gateway credential | one of them | `AI_GATEWAY_API_KEY` is used first. Otherwise, on Vercel (`VERCEL=1`), the per-invocation OIDC token from the `x-vercel-oidc-token` request header is used and labelled `oidc`. If `VERCEL_PROJECT_ID` is exposed, the token must belong to this project. A `VERCEL_OIDC_TOKEN` env value is the last fallback. |
| `COMMUNICATION_OS_AI_DEFAULT_MODEL` | no | Default Gateway model id. Ignored unless it is in the catalog. |

The flag and the credential are read on every request, so nothing is cached at startup. If either is missing, authorized calls answer `503 ai_unavailable`. Public `GET /v2/health` reports `data.aiAssist` as `enabled`, `disabled_flag` or `no_gateway_auth`, with no secrets, so you can check production without user credentials. Tokens are passed per call and never logged.

**Switching models.** The allowlist is `COMMUNICATION_OS_AI_MODEL_CATALOG`
(`@lssm-tech/lib.communication-spec/contracts/ai-model-catalog`). It lists
Anthropic Claude Haiku/Sonnet/Opus 5.5, OpenAI GPT-6 Luna and GPT-6.1 Sol, and
Google Gemini 3.8 Flash and Gemini 4 Argon. Each request uses the first match
in this order:

1. The request body `model`. It must be in the allowlist, and only `ai.use`
   roles may send it. Otherwise the call fails with `422 ai_model_not_allowed`
   or `403 ai_model_override_denied`.
2. The workspace setting.
3. `COMMUNICATION_OS_AI_DEFAULT_MODEL`.
4. The catalog default, `anthropic/claude-haiku-5.5`.

The workspace setting lives at `GET|POST /v2/ai/model-settings`
(`communication.ai.model-settings.get|set`). Owner, admin, enterprise_admin
and founder_approver roles can change it. Each change is appended to the
journal as `communication.ai.model-setting.changed`, with the actor and the
previous model. To add a model, add a catalog entry (contract first) and
release. No environment change is needed.

Summaries return `modelName` (the Gateway id) and `modelSource`. AI drafts
record `modelName`, `modelSource`, `modelGateway` and `inferenceRegion` in the
governed-work details. The existing governance still applies: drafts are never
sent automatically, authors are pseudonymized, at most 40 messages are sent,
there are at most five pending drafts per principal and thread, and provider
failures answer `503 ai_provider_unavailable`.

**Inbox triage.** `POST /v2/threads/:roomId/triage` (`comms.thread.triage`) and
`POST /v2/threads/triage` (`comms.thread.triage.batch`, body
`{ "threadIds": [...] }`, 1 to 25 unique ids) return advisory labels. Each
label has a category (request, question, complaint, sales, support,
scheduling, fyi, spam_suspect), an urgency (low, normal, high), `needsReply`
and a one-line `reason`.

- Only `ai.use` roles may call them. They use the same flag, Gateway
  credential and model order as summaries.
- The model must return the strict structured label. Anything else is a
  provider failure, and no label is stored.
- A fresh label is appended to the journal as
  `communication.ai.thread-triaged`, with its model, prompt version and
  revision (the latest covered message id). The next call reuses it until a
  new message arrives.
- Fresh classifications are limited to 100 per principal and workspace every
  10 minutes, counted per process. Cache hits do not count.
- Reasons are stripped of emails and phone numbers.
- In a batch, each thread reports `fresh`, `cached`, `skipped` (with
  `thread_not_found`, `insufficient_messages` or `rate_limited`) or `failed`.
  One thread failing never fails the whole batch.
- Labels never send, assign or change a thread.

**Data residency.** Every Gateway call asks for EU-zone inference
(`inferenceRegion: { scope: 'zone', geoRegion: 'eu' }`), zero data retention
and no prompt training. Calls are limited (`only`) to the catalog's inference
providers: Bedrock for Anthropic, OpenAI for OpenAI, Vertex for Google. On
2026-10-15 each of these advertised an EU region for its catalog models.

This constrains provider inference only. The Gateway itself routes and
processes requests globally, so EU-only transit is not guaranteed and needs
its own approval. Requested routing is also not proof of where a request was
served: use `readVercelGatewayRoutingMetadata` for per-call evidence.

Mistral models are not offered. The Gateway lists no EU inference region for
them, and the shared adapter refuses Mistral inference.

## Forms

Forms uses the same bearer principal and tenant/workspace scope as messaging.
Configure `COMMUNICATION_OS_FORMS_DATA_PROTECTION_SECRET` and
`COMMUNICATION_OS_FORMS_MILESTONES`; optional verification, AI, and distributed
defense adapters use the matching `COMMUNICATION_OS_FORMS_*` endpoint, bearer,
channel/provider, and identifier-secret variables. The API is `/api/forms/v1`;
public hosts expose `/f/{opaqueToken}`. Fresh databases receive the hardened
schema directly; existing Forms databases are upgraded additively by
`0002_forms_scope_hardening.sql` semantics during readiness initialization.

## Support private notes

Service-only `POST /api/communications/v1/support/cases/{caseRef}/internal-notes`
creates encrypted private-note content. The matching evidence URL verifies the
exact case, note, and evidence reference without returning content. Both routes
derive tenant, workspace, actor, audience, and capability from a short-lived
AuthOS grant; caller scope headers are ignored.

Configure `COMMUNICATION_OS_SUPPORT_NOTE_PROTECTION_SECRET`, the separately
rotated `COMMUNICATION_OS_SUPPORT_NOTE_IDENTIFIER_SECRET`,
`COMMUNICATION_OS_SUPPORT_NOTE_KEY_VERSION`,
`COMMUNICATION_OS_AUTHOS_GRANT_VERIFY_URL`, and
`COMMUNICATION_OS_AUTHOS_WORKLOAD_TOKEN`. The routes remain unavailable if any
required authority or protection adapter is absent.
The database migrator records immutable, digest-bound
`0001_communication_os_baseline` and
`0002_communication_support_internal_notes`, followed by the pinned
`0003_communication_os_rls` receipt before enabling these routes; changed
historical source or receipt digests fail closed.

### Authorized send retries

Message retries recheck current membership and connection authority before returning accepted content. Reuse of a request key with a different principal, room, content, subject, reply target, metadata, encryption envelope or attachment list is denied. Object metadata key order does not change semantic identity. Missing or partial attachment resolution fails before acceptance.

The journal/outbox transaction validates a replayed message before enqueueing delivery, and insert-returned journal events preserve their tenant scope. Queued acceptance remains distinct from provider delivery. Source-bound OPA follow-up delivery, full concurrent authority fencing and production qualification remain open.

### Provider queue acceptance

An external connection send requires `appendForDelivery`; journal-only persistence cannot claim provider queue acceptance. The event/outbox transaction validates the accepted message identity, connection and exact persisted delivery scope, command, policy and payload. Conflicting outbox keys roll back instead of silently dropping delivery. Provider delivery keys use `delivery:<send idempotency key>`; retries cannot substitute another key. Atomic journal replay uses the accepted message ID rather than the discarded candidate ID.

Internal room journal acceptance remains available without a provider adapter. Queued does not imply sent or delivered. Legacy malformed delivery inputs fail closed and require explicit repair; broader cross-scope key migration and OPA follow-up delivery remain separate qualification work.

## Build compute policy

Automatic Vercel Git builds are disabled for this app. Build compute is assigned
to Railway; this does not change the existing runtime or domain topology.
See the operator policy and evidence [source link unresolved: `../../../deploy/lssm-ecosystem/build-compute-policy.md`]
for configuration scope and the unqualified Vercel prebuilt delivery gap.


### Source links needing reconciliation

- `../../../deploy/lssm-ecosystem/build-compute-policy.md` — source path absent from pinned inventory: deploy/lssm-ecosystem/build-compute-policy.md.

## Declared capabilities

This manifest does not declare a capability catalogue. Assess the package using its guide, import map and source.

## Canonical imports

Import paths and symbols below are catalogue declarations. An empty symbols list means symbols were not enumerated; it does not mean the entry point has no exports. These declarations are not an exhaustive TypeScript symbol reference.

```json
[]
```

## Declared export entry points

Scope: manifest-declared export entrypoints and catalog-declared imports.

Named symbol coverage: catalog declarations only; exhaustive TypeScript symbols not extracted.

Installation status: not verified.

- `@lssm-tech/app.communicationos-api` — subpath `.`
  - `unconditional`: `./src/index.ts` — [pinned source](https://github.com/lssm-tech/contractspec/blob/bcc79fcc27c4d801c2119bef81ddcce7b4e86498/packages/apps/communicationos-api/src/index.ts); verified source file.

## Package publication metadata

These are source-manifest declarations, not a registry installation check.

```json
{
  "types": null,
  "files": null,
  "publishExports": null
}
```

## Dependencies

Metadata status: complete pinned manifest.

### Runtime dependencies

- `@better-auth/drizzle-adapter`: `1.7.5`
- `@elysiajs/cors`: `^1.4.2`
- [@lssm-tech/integration.authos-better-auth](https://lssm.co/docs/packages/integration.authos-better-auth/): `workspace:*`
- [@lssm-tech/integration.communication-channel-core](https://lssm.co/docs/packages/integration.communication-channel-core/): `workspace:*`
- [@lssm-tech/integration.communication-channel-discord](https://lssm.co/docs/packages/integration.communication-channel-discord/): `workspace:*`
- [@lssm-tech/integration.communication-channel-email](https://lssm.co/docs/packages/integration.communication-channel-email/): `workspace:*`
- [@lssm-tech/integration.communication-channel-slack](https://lssm.co/docs/packages/integration.communication-channel-slack/): `workspace:*`
- [@lssm-tech/integration.communication-channel-sms](https://lssm.co/docs/packages/integration.communication-channel-sms/): `workspace:*`
- [@lssm-tech/integration.communication-channel-telegram](https://lssm.co/docs/packages/integration.communication-channel-telegram/): `workspace:*`
- [@lssm-tech/integration.communication-os-agent](https://lssm.co/docs/packages/integration.communication-os-agent/): `workspace:*`
- [@lssm-tech/integration.communication-os-host-auth](https://lssm.co/docs/packages/integration.communication-os-host-auth/): `workspace:*`
- [@lssm-tech/integration.communication-os-persistence](https://lssm.co/docs/packages/integration.communication-os-persistence/): `workspace:*`
- [@lssm-tech/integration.communication-os-realtime-ticket](https://lssm.co/docs/packages/integration.communication-os-realtime-ticket/): `workspace:*`
- [@lssm-tech/integration.crdt-loro](https://lssm.co/docs/packages/integration.crdt-loro/): `workspace:*`
- [@lssm-tech/integration.customer-support-postgres](https://lssm.co/docs/packages/integration.customer-support-postgres/): `workspace:*`
- [@lssm-tech/integration.governed-product-data-postgres](https://lssm.co/docs/packages/integration.governed-product-data-postgres/): `workspace:*`
- [@lssm-tech/integration.lssm-os-state-postgres](https://lssm.co/docs/packages/integration.lssm-os-state-postgres/): `workspace:^`
- [@lssm-tech/integration.provider-customer-support](https://lssm.co/docs/packages/integration.provider-customer-support/): `workspace:*`
- [@lssm-tech/integration.provider-database](https://lssm.co/docs/packages/integration.provider-database/): `workspace:*`
- [@lssm-tech/integration.provider-email](https://lssm.co/docs/packages/integration.provider-email/): `workspace:*`
- [@lssm-tech/integration.provider-messaging](https://lssm.co/docs/packages/integration.provider-messaging/): `workspace:*`
- [@lssm-tech/integration.provider-sms](https://lssm.co/docs/packages/integration.provider-sms/): `workspace:*`
- [@lssm-tech/integration.runtime](https://lssm.co/docs/packages/integration.runtime/): `workspace:*`
- [@lssm-tech/lib.ai-providers](https://lssm.co/docs/packages/lib.ai-providers/): `workspace:^`
- [@lssm-tech/lib.authos-spec](https://lssm.co/docs/packages/lib.authos-spec/): `workspace:*`
- [@lssm-tech/lib.communication-runtime](https://lssm.co/docs/packages/lib.communication-runtime/): `workspace:*`
- [@lssm-tech/lib.communication-spec](https://lssm.co/docs/packages/lib.communication-spec/): `workspace:*`
- [@lssm-tech/lib.contracts-runtime-server-rest](https://lssm.co/docs/packages/lib.contracts-runtime-server-rest/): `workspace:*`
- [@lssm-tech/lib.contracts-spec](https://lssm.co/docs/packages/lib.contracts-spec/): `workspace:*`
- [@lssm-tech/lib.contractspec-connect](https://lssm.co/docs/packages/lib.contractspec-connect/): `workspace:^`
- [@lssm-tech/lib.customer-support-runtime](https://lssm.co/docs/packages/lib.customer-support-runtime/): `workspace:*`
- [@lssm-tech/lib.customer-support-spec](https://lssm.co/docs/packages/lib.customer-support-spec/): `workspace:*`
- [@lssm-tech/lib.data-exchange-server](https://lssm.co/docs/packages/lib.data-exchange-server/): `workspace:*`
- [@lssm-tech/lib.organization-planning-runtime](https://lssm.co/docs/packages/lib.organization-planning-runtime/): `workspace:*`
- [@lssm-tech/lib.organization-planning-spec](https://lssm.co/docs/packages/lib.organization-planning-spec/): `workspace:*`
- [@lssm-tech/module.communication-os](https://lssm.co/docs/packages/module.communication-os/): `workspace:*`
- [@lssm-tech/module.forms](https://lssm.co/docs/packages/module.forms/): `workspace:*`
- `drizzle-orm`: `catalog:data`
- `elysia`: `catalog:server`
- `jose`: `^6.2.12`
- `postgres`: `^3.4.9`

### Peer dependencies

No declarations in the inspected manifest.

### Optional dependencies

No declarations in the inspected manifest.

### Development dependencies

- `@axe-core/playwright`: `^4.13.0`
- `@electric-sql/pglite`: `catalog:data`
- [@lssm-tech/tool.typescript](https://lssm.co/docs/packages/tool.typescript/): `workspace:*`
- `@playwright/test`: `^1.63.0`
- `@types/bun`: `catalog:types`
- `typescript`: `catalog:`

### Peer dependency metadata

```json
{}
```

### Bundled dependencies

```json
null
```

## Package scripts

Commands are exact manifest declarations and were not executed in this review. Script metadata status: complete pinned manifest.

```json
{
  "build": "bun run build:elysia",
  "canary:meeting-host": "bun run scripts/meeting-host-canary.ts",
  "build:elysia": "bun build --target node --packages bundle --outfile dist/index.js src/index.ts && mkdir -p api/dist api/db/migrations && cp dist/index.js api/dist/index.js && cp db/migrations/*.sql api/db/migrations/",
  "dev": "bun run --watch src/server.ts",
  "start": "bun run src/server.ts",
  "test": "bun test src",
  "test:e2e:identity": "bunx playwright test --config=playwright.identity.config.ts",
  "typecheck": "bun --bun x tsgo --project tsconfig.json --noEmit"
}
```

## Declared documentation links

No additional documentation links are declared in the inspected catalogue.

## Existing agent-guide projection

```json
{
  "path": "packages/apps/web-landing/public/llms-packages/app.communicationos-api.txt",
  "route": "/llms/app.communicationos-api",
  "sourceUrl": "https://github.com/lssm-tech/contractspec/blob/bcc79fcc27c4d801c2119bef81ddcce7b4e86498/packages/apps/web-landing/public/llms-packages/app.communicationos-api.txt",
  "blobSha": "4a8f1c779259af54c03bc9cbbbdcec6295d8a0df",
  "sourcePin": "bcc79fcc27c4d801c2119bef81ddcce7b4e86498",
  "bodyEqualsReadme": true,
  "aggregateSourcePath": "packages/apps/web-landing/public/llms-full.txt",
  "aggregateBlobSha": "691b1d33efee24c440598b9106c81432f56aafaf"
}
```
